source: branches/fitshead-branch/ATrous/atrous_2d_reconstruct.cc @ 1441

Last change on this file since 1441 was 96, checked in by Matthew Whiting, 18 years ago

Two sets of large changes:
1) Added reconDim, to select which dimension of reconstruction to use.
2) Changed the way the MW channels are dealt with -- now not set to 0. but

simply ignored for searching purposes.

Summary of changes for each file:
duchamp.hh -- added keyword info for reconDim
param.hh -- Introduced reconDim and flagUsingBlank and isInMW.
param.cc -- Introduced reconDim and flagUsingBlank: initialisation etc commands
InputComplete? -- Added reconDim info
mainDuchamp.cc -- Removed the removeMW call. Changed search function names
docs/Guide.tex -- New code to deal with changes: reconDim, MW removal,

up-to-date output examples, better hints & notes section

Detection/thresholding_functions.cc -- minor typo correction

Cubes/cubes.hh -- added isBlank and removeMW functions in Image class, and

renamed search function prototypes

Cubes/cubes.cc -- added removeMW function for Image class, cleaned up

Cube::removeMW as well (although now not used)

Cubes/outputSpectra.cc -- Improved use of isBlank and isInMW functions: now

show MW channels but don't use them in calculating
the flux range

Cubes/getImage.cc -- added line to indicate whether the Param's blank value

is being used, rather than the FITS header.

Cubes/cubicSearch.cc -- renamed functions: front end is now CubicSearch?, and

searching function is search3DArray.

-- Improved way MW removal is dealt with. Changed

location of stats calculations.

Cubes/saveImage.cc -- added code for saving reconDim info
Cubes/readRecon.cc -- added code for reading reconDim info (and added status

intialisations before all cfitsio commands)

ATrous/ReconSearch.cc -- renamed functions: front end is now ReconSearch?, and

searching function is searchReconArray.
Using reconDim to decide which reconstruction to use.

-- Improved way MW removal is dealt with. Changed

location of stats calculations.

ATrous/atrous_1d_reconstruct.cc -- using Median stats
ATrous/atrous_2d_reconstruct.cc -- made code up to date, to conform with 1- &

3-d code. Removed boundary conditions.

ATrous/atrous_3d_reconstruct.cc -- corrected typo (avGapY /= float(xdim)).

Using median stats.

Cubes/cubicSearchNMerge.cc -- Deleted. (not used)
Cubes/readParams.cc -- Deleted. (not used)

File size: 7.0 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <math.h>
4#include <ATrous/atrous.hh>
5#include <Utils/utils.hh>
6
7using std::endl;
8using std::setw;
9
10void atrous2DReconstruct(long &xdim, long &ydim, float *&input, float *&output, Param &par)
11{
12  /**
13   *  atrous2DReconstruct(xdim, ydim, input, output, par)
14   *
15   *  A routine that uses the a trous wavelet method to reconstruct a
16   *   2-dimensional image.
17   *  The Param object "par" contains all necessary info about the filter and
18   *   reconstruction parameters, although a Filter object has to be declared
19   *   elsewhere previously.
20   *  The input array is in "input", of dimensions "xdim"x"ydim", and the reconstructed
21   *   array is in "output".
22   */
23
24  extern Filter reconFilter;
25  bool flagBlank=par.getFlagBlankPix();
26  float blankPixValue = par.getBlankPixVal();
27  long size = xdim * ydim;
28  long mindim = xdim;
29  if (ydim<mindim) mindim = ydim;
30  int numScales = reconFilter.getNumScales(mindim);
31  double *sigmaFactors = new double[numScales+1];
32  for(int i=0;i<=numScales;i++){
33    if(i<=reconFilter.maxFactor(2)) sigmaFactors[i] = reconFilter.sigmaFactor(2,i);
34    else sigmaFactors[i] = sigmaFactors[i-1] / 2.;
35  }
36
37  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
38  bool *isGood = new bool[size];
39  for(int pos=0;pos<size;pos++) isGood[pos] = !par.isBlank(input[pos]);
40 
41  float *array = new float[size];
42  int goodSize=0;
43  for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i];
44  findMedianStats(array,goodSize,originalMean,originalSigma);
45  originalSigma /= correctionFactor; // correct from MADFM to sigma estimator.
46  delete [] array;
47 
48  float *coeffs    = new float[size];
49  float *wavelet   = new float[size];
50
51  for(int pos=0;pos<size;pos++) output[pos]=0.;
52
53  int filterwidth = reconFilter.width();
54  int filterHW = filterwidth/2;
55  double *filter = new double[filterwidth*filterwidth];
56  for(int i=0;i<filterwidth;i++){
57    for(int j=0;j<filterwidth;j++){
58      filter[i*filterwidth+j] = reconFilter.coeff(i) * reconFilter.coeff(j);
59    }
60  }
61
62  int *xLim1 = new int[ydim];
63  for(int i=0;i<ydim;i++) xLim1[i] = 0;
64  int *yLim1 = new int[xdim];
65  for(int i=0;i<xdim;i++) yLim1[i] = 0;
66  int *xLim2 = new int[ydim];
67  for(int i=0;i<ydim;i++) xLim2[i] = xdim-1;
68  int *yLim2 = new int[xdim];
69  for(int i=0;i<xdim;i++) yLim2[i] = ydim-1;
70
71  if(par.getFlagBlankPix()){
72    float avGapX = 0, avGapY = 0;
73    for(int row=0;row<ydim;row++){
74      int ct1 = 0;
75      int ct2 = xdim - 1;
76      while((ct1<ct2)&&(input[row*xdim+ct1]==blankPixValue) ) ct1++;
77      while((ct2>ct1)&&(input[row*xdim+ct2]==blankPixValue) ) ct2--;
78      xLim1[row] = ct1;
79      xLim2[row] = ct2;
80      avGapX += ct2 - ct1;
81    }
82    avGapX /= float(ydim);
83   
84    for(int col=0;col<xdim;col++){
85      int ct1=0;
86      int ct2=ydim-1;
87      while((ct1<ct2)&&(input[col+xdim*ct1]==blankPixValue) ) ct1++;
88      while((ct2>ct1)&&(input[col+xdim*ct2]==blankPixValue) ) ct2--;
89      yLim1[col] = ct1;
90      yLim2[col] = ct2;
91      avGapY += ct2 - ct1;
92    }
93    avGapY /= float(xdim);
94   
95    mindim = int(avGapX);
96    if(avGapY < avGapX) mindim = int(avGapY);
97    numScales = reconFilter.getNumScales(mindim);
98  }
99
100  float threshold;
101  int iteration=0;
102  newsigma = 1.e9;
103  for(int i=0;i<size;i++) output[i] = 0;
104  do{
105    if(par.isVerbose()) std::cout << "Iteration #"<<setw(2)<<++iteration<<":             ";
106    // first, get the value of oldsigma and set it to the previous newsigma value
107    oldsigma = newsigma;
108    // we are transforming the residual array
109    for(int i=0;i<size;i++)  coeffs[i] = input[i] - output[i]; 
110
111    int spacing = 1;
112    for(int scale = 1; scale<numScales; scale++){
113
114      if(par.isVerbose()){
115        std::cout << "Scale ";
116        std::cout << setw(2)<<scale<<" / "<<setw(2)<<numScales
117                  << "\b\b\b\b\b\b\b\b\b\b\b\b\b"<<std::flush;
118      }
119
120      for(int ypos = 0; ypos<ydim; ypos++){
121        for(int xpos = 0; xpos<xdim; xpos++){
122          // loops over each pixel in the image
123          int pos = ypos*xdim + xpos;
124         
125          wavelet[pos] = coeffs[pos];
126
127          if(!isGood[pos]) wavelet[pos] = 0.;
128          else{
129
130            int filterpos = -1;
131            for(int yoffset=-filterHW; yoffset<=filterHW; yoffset++){
132              int y = ypos + spacing*yoffset;
133              // Boundary conditions -- assume reflection at boundaries.
134              // Use limits as calculated above
135//            if(yLim1[xpos]!=yLim2[xpos]){
136//              // if these are equal we will get into an infinite loop here
137//              while((y<yLim1[xpos])||(y>yLim2[xpos])){
138//                if(y<yLim1[xpos]) y = 2*yLim1[xpos] - y;     
139//                else if(y>yLim2[xpos]) y = 2*yLim2[xpos] - y;     
140//              }
141//            }
142              int oldrow = y * xdim;
143         
144              for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
145                int x = xpos + spacing*xoffset;
146                // Boundary conditions -- assume reflection at boundaries.
147                // Use limits as calculated above
148//              if(xLim1[ypos]!=xLim2[ypos]){
149//                // if these are equal we will get into an infinite loop here
150//                while((x<xLim1[ypos])||(x>xLim2[ypos])){
151//                  if(x<xLim1[ypos]) x = 2*xLim1[ypos] - x;     
152//                  else if(x>xLim2[ypos]) x = 2*xLim2[ypos] - x;     
153//                }
154//              }
155
156                int oldpos = oldrow + x;
157
158                float oldCoeff;
159                if((y>=yLim1[xpos])&&(y<=yLim2[xpos])&&(x>=xLim1[ypos])&&(x<=xLim2[ypos]))
160                  oldCoeff = coeffs[oldpos];
161                else oldCoeff = 0.;
162
163                filterpos++;
164
165                if(isGood[pos]) wavelet[pos] -= filter[filterpos] * oldCoeff;
166//                wavelet[pos] -= filter[filterpos] * coeffs[oldpos];
167
168              } //-> end of xoffset loop
169            } //-> end of yoffset loop
170          } //-> end of else{ ( from if(!isGood[pos])  )
171       
172        } //-> end of xpos loop
173      } //-> end of ypos loop
174
175      // Need to do this after we've done *all* the convolving
176      for(int pos=0;pos<size;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
177
178      // Have found wavelet coeffs for this scale -- now threshold   
179      if(scale>=par.getMinScale()){
180        array = new float[size];
181        goodSize=0;
182        for(int pos=0;pos<size;pos++) if(isGood[pos]) array[goodSize++] = wavelet[pos];
183        findMedianStats(array,goodSize,mean,sigma);
184        delete [] array;
185
186        threshold = mean + par.getAtrousCut() * originalSigma * sigmaFactors[scale];
187        for(int pos=0;pos<size;pos++){
188          if(!isGood[pos]) output[pos] = blankPixValue; // preserve the Blank pixel values in the output.
189          else if( fabs(wavelet[pos]) > threshold ) output[pos] += wavelet[pos];
190        }
191      }
192      spacing *= 2;
193
194    } // END OF LOOP OVER SCALES
195
196    for(int pos=0;pos<size;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
197
198    array = new float[size];
199    goodSize=0;
200    for(int i=0;i<size;i++) if(isGood[i]) array[goodSize++] = input[i] - output[i];
201    findMedianStats(array,goodSize,mean,newsigma);
202    newsigma /= correctionFactor; // correct from MADFM to sigma estimator.
203    delete [] array;
204   
205    if(par.isVerbose()) std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
206
207  } while( (iteration==1) ||
208           (fabsf(oldsigma-newsigma)/newsigma > reconTolerance) );
209
210  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
211
212  delete [] xLim1,xLim2,yLim1,yLim2;
213  delete [] coeffs;
214  delete [] wavelet;
215  delete [] isGood;
216  delete [] filter;
217  delete [] sigmaFactors;
218}
219   
220   
Note: See TracBrowser for help on using the repository browser.