source: branches/fitshead-branch/ATrous/atrous_1d_reconstruct.cc @ 95

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

Large commit, mostly removing dud commented code, and adding comments and
documentation to the existing code. No new features.

File size: 4.5 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 atrous1DReconstruct(long &xdim, float *&input,float *&output, Param &par)
11{
12  /**
13   *  atrous1DReconstruct(xdim, input, output, par)
14   *
15   *  A routine that uses the a trous wavelet method to reconstruct a
16   *   1-dimensional spectrum.
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 length "xdim", and the reconstructed
21   *   array is in "output".
22   */
23
24
25  extern Filter reconFilter;
26  const float SNR_THRESH=par.getAtrousCut();
27  const int MIN_SCALE=par.getMinScale();
28
29  bool flagBlank=par.getFlagBlankPix();
30  float blankPixValue = par.getBlankPixVal();
31  int numScales = reconFilter.getNumScales(xdim);
32  double *sigmaFactors = new double[numScales+1];
33  for(int i=0;i<=numScales;i++){
34    if(i<=reconFilter.maxFactor(1)) sigmaFactors[i] = reconFilter.sigmaFactor(1,i);
35    else sigmaFactors[i] = sigmaFactors[i-1] / sqrt(2.);
36  }
37
38  float mean,sigma,originalSigma,originalMean,oldsigma,newsigma;
39  bool *isGood = new bool[xdim];
40  for(int pos=0;pos<xdim;pos++)
41    isGood[pos] = !par.isBlank(input[pos]);
42
43  float *coeffs = new float[xdim];
44  float *wavelet = new float[xdim];
45
46  for(int pos=0;pos<xdim;pos++) output[pos]=0.;
47
48  int filterHW = reconFilter.width()/2;
49  double *filter = new double[reconFilter.width()];
50  for(int i=0;i<reconFilter.width();i++) filter[i] = reconFilter.coeff(i);
51
52
53  // No trimming done in 1D case.
54
55  int iteration=0;
56  newsigma = 1.e9;
57  do{
58    if(par.isVerbose()) std::cout << "Iteration #"<<++iteration<<":             ";
59    // first, get the value of oldsigma and set it to the previous newsigma value
60    oldsigma = newsigma;
61    // all other times round, we are transforming the residual array
62    for(int i=0;i<xdim;i++)  coeffs[i] = input[i] - output[i];
63   
64    float *array = new float[xdim];
65    int goodSize=0;
66    for(int i=0;i<xdim;i++) if(isGood[i]) array[goodSize++] = input[i];
67    findMedianStats(array,goodSize,originalMean,originalSigma);
68    originalSigma /= correctionFactor; // correct from MADFM to sigma estimator.
69    delete [] array;
70
71    int spacing = 1;
72    for(int scale = 1; scale<=numScales; scale++){
73
74      if(par.isVerbose()) {
75        std::cout << "\b\b\b\b\b\b\b\b\b\b\b\bScale ";
76        std::cout << setw(2)<<scale<<" /"<<setw(2)<<numScales<<std::flush;
77      }
78
79      for(int xpos = 0; xpos<xdim; xpos++){
80            // loops over each pixel in the image
81        int pos = xpos;
82
83        wavelet[pos] = coeffs[pos];
84       
85        if(!isGood[pos] )  wavelet[pos] = 0.;
86        else{
87
88          for(int xoffset=-filterHW; xoffset<=filterHW; xoffset++){
89            int x = xpos + spacing*xoffset;
90
91            while((x<0)||(x>=xdim)){
92              if(x<0) x = 0 - x;                    // boundary conditions are 
93              else if(x>=xdim) x = 2*(xdim-1) - x;  //    reflection.               
94            }
95
96            int filterpos = (xoffset+filterHW);
97            int oldpos = x;
98
99            if(isGood[oldpos])
100              wavelet[pos] -= filter[filterpos]*coeffs[oldpos];
101             
102          } //-> end of xoffset loop
103        } //-> end of else{ ( from if(!isGood[pos])  )
104           
105      } //-> end of xpos loop
106
107      for(int pos=0;pos<xdim;pos++) coeffs[pos] = coeffs[pos] - wavelet[pos];
108
109      // Have found wavelet coeffs for this scale -- now threshold
110      if(scale>=MIN_SCALE){
111        array = new float[xdim];
112        goodSize=0;
113        for(int pos=0;pos<xdim;pos++) if(isGood[pos]) array[goodSize++] = wavelet[pos];
114        findMedianStats(array,goodSize,mean,sigma);
115        delete [] array;
116       
117        for(int pos=0;pos<xdim;pos++){
118          // preserve the Blank pixel values in the output.
119          if(!isGood[pos]) output[pos] = blankPixValue;
120          else if(fabs(wavelet[pos])>(mean+SNR_THRESH*originalSigma*sigmaFactors[scale]))
121            output[pos] += wavelet[pos];
122        }
123      }
124 
125      spacing *= 2;
126
127    } //-> end of scale loop
128
129    for(int pos=0;pos<xdim;pos++) if(isGood[pos]) output[pos] += coeffs[pos];
130
131    array = new float[xdim];
132    goodSize=0;
133    for(int i=0;i<xdim;i++) if(isGood[i]) array[goodSize++] = input[i] - output[i];
134    findNormalStats(array,goodSize,mean,newsigma);
135    delete [] array;
136
137    if(par.isVerbose())     std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
138
139  } while( (iteration==1) ||
140           (fabsf(oldsigma-newsigma)/newsigma > reconTolerance) );
141
142  if(par.isVerbose()) std::cout << "Completed "<<iteration<<" iterations. ";
143
144  delete [] coeffs;
145  delete [] wavelet;
146  delete [] isGood;
147  delete [] filter;
148  delete [] sigmaFactors;
149}
Note: See TracBrowser for help on using the repository browser.