source: trunk/src/ATrous/atrous_1d_reconstruct.cc @ 285

Last change on this file since 285 was 285, checked in by Matthew Whiting, 17 years ago

Changes worth talking about are:

  • New parameters:
    • The trimming is now controlled by flagTrim. The BLANK etc keywords are always read in -- if they aren't there, flagTrim set to false. User access of flagBlankPix and blankPixVal is disabled. For clarity, flagTrimmed changed to hasBeenTrimmed.
    • Default value of kernMin set to -1 -- then if it is found to be negative, it is set to match kernMaj.
    • Slight changes to parameter output.
  • Fixed bug in findAllStats, so that the correct array is used.
  • Number of pixels for FDR setup set to 2*beamsize only if we are 3-dimensional.
  • Added pixel information to VOTable.
  • Simplified some code in drawMomentCutout
  • Added check for recon array allocation at start of ReconSearch?, as well as checks on dimensionality of cube.
  • Updated images and documentation.
File size: 5.1 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <math.h>
4#include <duchamp.hh>
5#include <param.hh>
6#include <Utils/utils.hh>
7#include <Utils/feedback.hh>
8#include <ATrous/atrous.hh>
9#include <ATrous/filter.hh>
10#include <Utils/Statistics.hh>
11using Statistics::madfmToSigma;
12
13void atrous1DReconstruct(long &xdim, float *&input, float *&output, Param &par)
14{
15  /**
16   *  A routine that uses the a trous wavelet method to reconstruct a
17   *   1-dimensional spectrum.
18   *  The Param object "par" contains all necessary info about the filter and
19   *   reconstruction parameters.
20   *
21   *  If all pixels are BLANK (and we are testing for BLANKs), the
22   *  reconstruction will simply give BLANKs back, so we return the
23   *  input array as the output array.
24   *
25   *  \param xdim The length of the spectrum.
26   *  \param input The input spectrum.
27   *  \param output The returned reconstructed spectrum. This array needs to
28   *    be declared beforehand.
29   *  \param par The Param set.
30   */
31
32  const float SNR_THRESH=par.getAtrousCut();
33  const int MIN_SCALE=par.getMinScale();
34
35  int numScales = par.filter().getNumScales(xdim);
36  double *sigmaFactors = new double[numScales+1];
37  for(int i=0;i<=numScales;i++){
38    if(i<=par.filter().maxFactor(1))
39      sigmaFactors[i] = par.filter().sigmaFactor(1,i);
40    else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(2.);
41  }
42
43  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
44  bool *isGood = new bool[xdim];
45  int goodSize=0;
46  for(int pos=0;pos<xdim;pos++) {
47    isGood[pos] = !par.isBlank(input[pos]);
48    if(isGood[pos]) goodSize++;
49  }
50
51  if(goodSize == 0){
52    // There are no good pixels -- everything is BLANK for some reason.
53    // Return the input array as the output.
54
55    for(int pos=0;pos<xdim; pos++) output[pos] = input[pos];
56
57  }
58  else{
59    // Otherwise, all is good, and we continue.
60
61
62    float *coeffs = new float[xdim];
63    float *wavelet = new float[xdim];
64
65    for(int pos=0;pos<xdim;pos++) output[pos]=0.;
66
67    int filterHW = par.filter().width()/2;
68    double *filter = new double[par.filter().width()];
69    for(int i=0;i<par.filter().width();i++) filter[i] = par.filter().coeff(i);
70
71
72    // No trimming done in 1D case.
73
74    int iteration=0;
75    newsigma = 1.e9;
76    do{
77      if(par.isVerbose()) {
78        std::cout << "Iteration #"<<++iteration<<":";
79        printSpace(13);
80      }
81      // first, get the value of oldsigma and set it to the previous
82      //   newsigma value
83      oldsigma = newsigma;
84      // all other times round, we are transforming the residual array
85      for(int i=0;i<xdim;i++)  coeffs[i] = input[i] - output[i];
86   
87      float *array = new float[xdim];
88      goodSize=0;
89      for(int i=0;i<xdim;i++) if(isGood[i]) array[goodSize++] = input[i];
90      findMedianStats(array,goodSize,originalMean,originalSigma);
91      originalSigma = madfmToSigma(originalSigma);
92      delete [] array;
93
94      int spacing = 1;
95      for(int scale = 1; scale<=numScales; scale++){
96
97        if(par.isVerbose()) {
98          printBackSpace(12);
99          std::cout << "Scale " << std::setw(2) << scale
100                    << " /"     << std::setw(2) << numScales <<std::flush;
101        }
102
103        for(int xpos = 0; xpos<xdim; xpos++){
104          // loops over each pixel in the image
105          int pos = xpos;
106
107          wavelet[pos] = coeffs[pos];
108       
109          if(!isGood[pos] )  wavelet[pos] = 0.;
110          else{
111
112            for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
113              int x = xpos + spacing*xoffset;
114
115              while((x<0)||(x>=xdim)){
116                // boundary conditions are reflection.
117                if(x<0) x = 0 - x;
118                else if(x>=xdim) x = 2*(xdim-1) - x;
119              }
120
121              int filterpos = (xoffset+filterHW);
122              int oldpos = x;
123
124              if(isGood[oldpos])
125                wavelet[pos] -= filter[filterpos]*coeffs[oldpos];
126             
127            } //-> end of xoffset loop
128          } //-> end of else{ ( from if(!isGood[pos])  )
129           
130        } //-> end of xpos loop
131
132        // Need to do this after we've done *all* the convolving
133        for(int pos=0;pos<xdim;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
134
135        // Have found wavelet coeffs for this scale -- now threshold
136        if(scale>=MIN_SCALE){
137          array = new float[xdim];
138          goodSize=0;
139          for(int pos=0;pos<xdim;pos++)
140            if(isGood[pos]) array[goodSize++] = wavelet[pos];
141          findMedianStats(array,goodSize,mean,sigma);
142          delete [] array;
143       
144          for(int pos=0;pos<xdim;pos++){
145            // preserve the Blank pixel values in the output.
146            if(!isGood[pos]) output[pos] = input[pos];
147            else if( fabs(wavelet[pos]) >
148                     (mean+SNR_THRESH*originalSigma*sigmaFactors[scale]) )
149              output[pos] += wavelet[pos];
150          }
151        }
152 
153        spacing *= 2;
154
155      } //-> end of scale loop
156
157      for(int pos=0;pos<xdim;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
158
159      array = new float[xdim];
160      goodSize=0;
161      for(int i=0;i<xdim;i++)
162        if(isGood[i]) array[goodSize++] = input[i] - output[i];
163      findMedianStats(array,goodSize,mean,newsigma);
164      newsigma = madfmToSigma(newsigma);
165      delete [] array;
166
167      if(par.isVerbose()) printBackSpace(26);
168
169    } while( (iteration==1) ||
170             (fabs(oldsigma-newsigma)/newsigma > reconTolerance) );
171
172    if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
173
174    delete [] filter;
175    delete [] coeffs;
176    delete [] wavelet;
177
178  }
179
180  delete [] isGood;
181  delete [] sigmaFactors;
182}
Note: See TracBrowser for help on using the repository browser.