source: trunk/src/ATrous/baselineSubtract.cc @ 1441

Last change on this file since 1441 was 1259, checked in by MatthewWhiting, 11 years ago

Ticket #107 - Implementing the median baseline algorithm, with a few tweaks to make it work. The interface is now similar to the atrous baseline algorithm (which has been renamed).

File size: 6.2 KB
RevLine 
[299]1// -----------------------------------------------------------------------
2// baselineSubtract.cc: Obtaining and subtracting spectral baselines.
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
[3]28#include <iostream>
29#include <iomanip>
[103]30#include <math.h>
[393]31#include <duchamp/param.hh>
32#include <duchamp/ATrous/filter.hh>
33#include <duchamp/ATrous/atrous.hh>
34#include <duchamp/Utils/utils.hh>
35#include <duchamp/Utils/feedback.hh>
[3]36
[378]37namespace duchamp
[3]38{
[232]39
[888]40  void baselineSubtract(size_t numSpec, size_t specLength, float *originalCube,
[378]41                        float *baselineValues, Param &par)
42  {
[528]43    ///  A routine to find the baseline of each spectrum in a cube (the spectral
44    ///    direction is assumed to be the third dimension) and subtract it off
45    ///    the original.
46    /// \param numSpec Number of spatial pixels in original cube.
47    /// \param specLength Size of spectral dimension of original cube.
48    /// \param originalCube The cube that is to have its baseline removed.
49    /// \param baselineValues The cube of baseline values -- the same
50    ///                       size as the original.
51    /// \param par The Param set: information on BLANK values and on how
52    ///            the subtraction is done.
[3]53
[378]54    float *spec     = new float[specLength];
55    float *thisBaseline = new float[specLength];
56    int minscale = par.getMinScale();
57    par.setMinScale(par.filter().getNumScales(specLength));
58    float atrouscut = par.getAtrousCut();
59    par.setAtrousCut(1);
60    bool flagVerb = par.isVerbose();
61    par.setVerbosity(false);
[3]62
[378]63    ProgressBar bar;
64    if(flagVerb) bar.init(numSpec);
[846]65    for(size_t pix=0; pix<numSpec; pix++){ // for each spatial pixel...
[3]66
[378]67      if(flagVerb) bar.update(pix+1);
[3]68
[846]69      for(size_t z=0; z<specLength; z++)
[378]70        spec[z] = originalCube[z*numSpec + pix];
[3]71
[378]72      atrous1DReconstruct(specLength,spec,thisBaseline,par);
[3]73
[846]74      for(size_t z=0; z<specLength; z++) {
[378]75        baselineValues[z*numSpec+pix] = thisBaseline[z];
76        if(!par.isBlank(originalCube[z*numSpec+pix]))
77          originalCube[z*numSpec+pix] = originalCube[z*numSpec+pix] -
78            baselineValues[z*numSpec+pix];
79      }
[3]80
[378]81    }   
82    if(flagVerb) bar.rewind();
83
84    par.setMinScale(minscale);
85    par.setAtrousCut(atrouscut);
86    par.setVerbosity(flagVerb);
[3]87 
[378]88    delete [] spec;
89    delete [] thisBaseline;
[3]90   
[378]91  }
[3]92
[1259]93  void findAtrousBaseline(size_t size, float *input, float *baseline, Param &par)
[378]94  {
[528]95    ///   Uses the a trous reconstruction, keeping only the highest two scales,
96    ///     to reconstruct the baseline.
97    ///    To avoid contamination by very strong signals, the input spectrum is
98    ///     trimmed at 5*MADFM above the median before reconstruction.
99    ///     This reduces the strong dips created by the presence of very strong
100    ///     signals.
101    ///  \param size Length of the spectrum.
102    ///  \param input The input array : this is not affected.
103    ///  \param baseline The returned baseline array. This needs to be allocated
104    ///   before the function is called.
105    ///  \param par The Param set, needed for the atrous reconstruction.
[3]106
[378]107    int minscale = par.getMinScale();
108    par.setMinScale(par.filter().getNumScales(size));
109    float atrouscut = par.getAtrousCut();
110    par.setAtrousCut(1);
111    bool flagVerb = par.isVerbose();
112    par.setVerbosity(false);
[43]113
[378]114    float *spec = new float[size];
115    float med,sig;
116    findMedianStats(input,size,med,sig);
117    float threshold = 5. * sig;
[846]118    for(size_t i=0;i<size;i++) {
[378]119      if(fabs(input[i]-med)>threshold){
120        if(input[i]>med) spec[i] = med + threshold;
121        else spec[i] = med - threshold;
122      }
123      else spec[i] = input[i];
[43]124    }
125
[378]126    //    atrous1DReconstruct(size, input, baseline, par);
127    atrous1DReconstruct(size, spec, baseline, par);
[43]128
[378]129    par.setMinScale(minscale);
130    par.setAtrousCut(atrouscut);
131    par.setVerbosity(flagVerb);
[43]132
[378]133    delete [] spec;
[43]134
[378]135  }
[43]136
[846]137 
[1259]138  void findAtrousBaseline(size_t size, float *input, float *baseline)
[378]139  {
[528]140    ///  This version is designed for programs not using Param classes -- it
141    ///   keeps that side of things hidden from the user.
142    ///  Uses the a trous reconstruction, keeping only the highest two scales,
143    ///   to reconstruct the baseline.
144    ///  To avoid contamination by very strong signals, the input spectrum is
145    ///   trimmed at 8*MADFM above the median before reconstruction. This
146    ///   reduces the strong dips created by the presence of very strong
147    ///   signals.
148    ///  \param size Length of the spectrum.
149    ///  \param input The input array : this is not affected.
150    ///  \param baseline The returned baseline array. This needs to be allocated
151    ///   before the function is called.
[3]152
[378]153    Param par;
154    par.setMinScale(par.filter().getNumScales(size));
155    par.setAtrousCut(1);
156    par.setVerbosity(false);
[43]157
[378]158    float *spec = new float[size];
159    float med,sig;
160    findMedianStats(input,size,med,sig);
161    float threshold = 8. * sig;
[846]162    for(size_t i=0;i<size;i++) {
[378]163      if(fabs(input[i]-med)>threshold){
164        if(input[i]>med) spec[i] = med + threshold;
165        else spec[i] = med - threshold;
166      }
167      else spec[i] = input[i];
[43]168    }
169
[378]170    atrous1DReconstruct(size, spec, baseline, par);
[43]171
[378]172    delete [] spec;
[43]173
[378]174  }
175
[3]176}
Note: See TracBrowser for help on using the repository browser.