source: trunk/src/Cubes/cubicSearchNMerge.cc @ 1441

Last change on this file since 1441 was 1393, checked in by MatthewWhiting, 10 years ago

A large changeset that moves all use of bool arrays (ie. bool *) to std::vector<bool>. This will be a bit safer, plus potentially cheaper in memory usage. Interfaces to all stats functions with masks have changed accordingly, as well as the Gaussian smoothing functions and some spectral utility functions.

File size: 7.8 KB
Line 
1// -----------------------------------------------------------------------
2// cubicSearchNMerge.cc: Combining both the searching and the merging
3//                       functions.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <iostream>
30#include <iomanip>
31#include <fstream>
32#include <vector>
33#include <duchamp/Cubes/cubes.hh>
34#include <duchamp/Utils/utils.hh>
35using std::endl;
36using std::setw;
37
38vector <Detection> cubicSearchNMerge(long *dim, float *Array, Param &par)
39{
40  /// @details
41  ///  Takes a dimension array and data array as input (and Parameter set)
42  ///  and searches for detections in a combination of 1D and 2D searches.
43  ///  Returns a vector list of Detections.
44  ///  No reconstruction is assumed to have taken place, so statistics are
45  ///  calculated (using robust methods) from the data array itself.
46
47  vector <Detection> outputList;
48  int zdim = dim[2];
49  size_t xySize = dim[0] * dim[1];
50  size_t fullSize = zdim * xySize;
51  int num=0;
52
53  //  bool flagBlank=par.getFlagBlankPix();
54  float blankPixValue = par.getBlankPixVal();
55  std::vector<bool> isGood(fullSize);
56  for(size_t pos=0;pos<fullSize;pos++)
57    isGood[pos] = !par.isBlank(Array[pos]);
58    //    isGood[pos] = (!flagBlank) || (Array[pos]!=blankPixValue);
59 
60  float dud;
61
62  // FIRST SEARCH --  IN EACH SPECTRUM.
63  // FIRST, GET STATS
64  if(zdim>1){
65    if(par.isVerbose()) std::cout << "  1D: |                    |" << std::flush;
66//     if(par.isVerbose()) std::cout << "Done  0%" << "\b\b\b\b\b\b\b\b" << std::flush;
67    float *specMedian = new float[xySize];
68    float *specSigma = new float[xySize];
69
70    for(int npix=0; npix<xySize; npix++){
71      float *spec = new float[zdim];
72      int goodSize=0;
73      for(int z=0;z<zdim;z++) if(isGood[z*xySize+npix]) spec[goodSize++] = Array[z*xySize+npix];
74      if(goodSize>0) findMedianStats(spec,goodSize,specMedian[npix],dud);
75      else specMedian[npix] = blankPixValue;
76      //     if(goodSize>0) findNormalStats(spec,goodSize,dud,specSigma[npix]);
77      if(goodSize>0){
78        findMedianStats(spec,goodSize,dud,specSigma[npix]);
79        specSigma[npix] /= correctionFactor;
80      }
81      else specSigma[npix] = 1.;
82      delete spec;
83    }
84    // NEXT, DO SOURCE FINDING
85    int numSearches = xySize + zdim;
86    for(int npix=0; npix<xySize; npix++){
87
88//       if(par.isVerbose() && ((1000*npix/xySize)%10==0) )
89//      std::cout << "Done " << setw(2) << 100*npix/xySize << "%\b\b\b\b\b\b\b\b" << std::flush;
90      if( par.isVerbose() && ((100*(npix+1)/xySize)%5 == 0) ){
91        std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
92        for(int i=0;i<(100*(npix+1)/xySize)/5;i++) std::cout << "#";
93        for(int i=(100*(npix+1)/xySize)/5;i<20;i++) std::cout << " ";
94        std::cout << "|" << std::flush;
95      }
96
97      float *spec = new float[zdim];
98      for(int z=0;z<zdim;z++) spec[z] = Array[z*xySize + npix];
99      long *specdim = new long[2];
100      specdim[0] = zdim; specdim[1]=1;
101      Image *spectrum = new Image(specdim);
102      spectrum->saveParam(par);
103      spectrum->pars().setBeamSize(2.); // for spectrum, only neighbouring channels correlated
104      spectrum->saveArray(spec,zdim);
105      spectrum->setStats(specMedian[npix],specSigma[npix],par.getCut());
106      if(par.getFlagFDR()) spectrum->setupFDR();
107      spectrum->findSources2D();
108      for(int obj=0;obj<spectrum->getNumObj();obj++){
109        Detection *object = new Detection;
110        *object = spectrum->getObject(obj);
111//      if(par.getFlagGrowth()) growObject(*object,*spectrum);
112        for(int pix=0;pix<object->getSize();pix++) {
113          // Fix up coordinates of each pixel to match original array
114          object->setZ(pix, object->getX(pix));
115          object->setX(pix, npix%dim[0]);
116          object->setY(pix, npix/dim[0]);
117        }
118        object->addOffsets(par);
119        object->calcParams();
120        //      outputList.push_back(*object);
121        mergeIntoList(*object,outputList,par);
122        delete object;
123      }
124      delete spectrum;
125      delete spec;
126      delete specdim;
127    }
128
129    delete [] specMedian;
130    delete [] specSigma;
131
132    num = outputList.size();
133    if(par.isVerbose())
134      std::cout <<"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bFound " << num <<";" << std::flush;
135
136  }
137
138  // SECOND SEARCH --  IN EACH CHANNEL
139  // FIRST, GET STATS
140  if(par.isVerbose()) std::cout << "  2D: |                    |" << std::flush;
141//   if(par.isVerbose()) std::cout << "Done  0%" << "\b\b\b\b\b\b\b\b" << std::flush;
142  float *imageMedian = new float[zdim];
143  float *imageSigma = new float[zdim];
144  for(int z=0; z<zdim; z++){
145    float *image = new float[xySize];
146    int goodSize=0;
147    for(int npix=0; npix<xySize; npix++)
148      if(isGood[z*xySize + npix]) image[goodSize++] = Array[z*xySize + npix];
149    if(goodSize>0) findMedianStats(image,goodSize,imageMedian[z],dud);
150    else imageMedian[z] = blankPixValue;
151    if(goodSize>0) findNormalStats(image,goodSize,dud,imageSigma[z]);
152    else imageSigma[z] = 1.;
153    delete image;
154  }
155  // NEXT, DO SOURCE FINDING
156  std::vector<bool> doChannel(zdim);
157  for(int z=0;z<zdim;z++)
158      doChannel[z] = !par.isFlaggedChannel(z);
159
160  for(int z=0; z<zdim; z++){
161
162//     if(par.isVerbose() && ((1000*z/zdim)%10==0) )
163//       std::cout << "Done " << setw(2) << 100*z/zdim << "%\b\b\b\b\b\b\b\b" << std::flush;
164    if( par.isVerbose() && ((100*(z+1)/zdim)%5 == 0) ){
165      std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b|";
166      for(int i=0;i<(100*(z+1)/zdim)/5;i++) std::cout << "#";
167      for(int i=(100*(z+1)/zdim)/5;i<20;i++) std::cout << " ";
168      std::cout << "|" << std::flush;
169    }
170
171    if( doChannel[z] ){
172
173      float *image = new float[xySize];
174      for(int npix=0; npix<xySize; npix++) image[npix] = Array[z*xySize + npix];
175      long *imdim = new long[2];
176      imdim[0] = dim[0]; imdim[1] = dim[1];
177      Image *channelImage = new Image(imdim);
178      channelImage->saveParam(par);
179      channelImage->saveArray(image,xySize);
180      channelImage->setStats(imageMedian[z],imageSigma[z],par.getCut());
181      if(par.getFlagFDR()) channelImage->setupFDR();
182      channelImage->findSources2D();
183      for(int obj=0;obj<channelImage->getNumObj();obj++){
184        Detection *object = new Detection;
185        *object = channelImage->getObject(obj);
186//      if(par.getFlagGrowth()) growObject(*object,*channelImage);
187        // Fix up coordinates of each pixel to match original array
188        for(int pix=0;pix<object->getSize();pix++) object->setZ(pix, z);
189        object->addOffsets(par);
190        object->calcParams();
191        mergeIntoList(*object,outputList,par);
192        //      outputList.push_back(*object);
193        delete object;
194      }
195      delete image;
196      delete channelImage;
197      delete imdim;
198    }
199
200  }
201
202  if(par.isVerbose())
203    std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bFound " << outputList.size() - num
204              << ".                                           " << std::endl << std::flush;
205 
206  delete [] imageMedian;
207  delete [] imageSigma;
208
209  return outputList;
210}
211
Note: See TracBrowser for help on using the repository browser.