source: trunk/src/ATrous/atrous_2d_reconstruct.cc @ 205

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

Changes here mostly aimed at reducing/removing memory leaks. These were one of:

  • Forgetting to delete something allocated with "new". The Cube destructor has improved with the use of bool variables to keep track of when recon & baseline ahave been allocated.
  • Incorrectly using the wcs->flag parameter (eg. wcsIO had it set to -1 *after* calling wcsini)
  • Not closing a fits file once finished with (dataIO)
  • Allocating the wcsprm structs with calloc before calling wcsini, so that wcsvfree can work (it calls "free", so the memory needs to be allocated with calloc or malloc).

The only other change was the following:

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