source: trunk/src/Cubes/spectraUtils.cc @ 528

Last change on this file since 528 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 10.2 KB
Line 
1// -----------------------------------------------------------------------
2// spectraUtils.cc: Utility functions to obtain & manipulate spectra
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// -----------------------------------------------------------------------
28#include <iostream>
29#include <fstream>
30#include <iomanip>
31#include <sstream>
32#include <string>
33#include <math.h>
34#include <wcslib/wcs.h>
35#include <duchamp/Cubes/cubeUtils.hh>
36#include <duchamp/param.hh>
37#include <duchamp/duchamp.hh>
38#include <duchamp/fitsHeader.hh>
39#include <duchamp/PixelMap/Object3D.hh>
40#include <duchamp/Cubes/cubes.hh>
41#include <duchamp/Utils/utils.hh>
42
43using namespace PixelInfo;
44
45namespace duchamp
46{
47
48  void getSpecAbscissae(Detection &object, FitsHeader &head, long zdim, float *abscissae)
49  {
50    /// @details
51    ///  A function that returns an array of
52    ///  frequency/velocity/channel/etc values (that can be used as the
53    ///  abscissae on the spectral plot).
54    ///  \param object The object on which our spectrum is centered (in
55    ///  case the spectral value changes with x & y
56    ///  \param head The FitsHeader set of parameters that determine the coordinate transformation.
57    ///  \param zdim The length of the spectral axis
58    ///  \param abscissae The array of spectral values -- must be allocated first
59
60    getSpecAbscissae(head,object.getXcentre(),object.getYcentre(),zdim, abscissae);
61  }
62
63  void getSpecAbscissae(FitsHeader &head, float xpt, float ypt, long zdim, float *abscissae)
64  {
65    /// @details
66    ///  A function that returns an array of
67    ///  frequency/velocity/channel/etc values (that can be used as the
68    ///  horizontal axis on the spectral plot).
69    ///  \param head The FitsHeader set of parameters that determine the coordinate transformation.
70    ///  \param xpt The x-value of the spatial position on which our spectrum is centred.
71    ///  \param ypt The y-value of the spatial position on which our spectrum is centred.
72    ///  \param zdim The length of the spectral axis
73    ///  \param abscissae The array of spectral values -- must be allocated first.
74
75    if(head.isWCS()){
76      double xval = double(xpt);
77      double yval = double(ypt);
78      for(double zval=0;zval<zdim;zval++)
79        abscissae[int(zval)] = head.pixToVel(xval,yval,zval);
80    }
81    else
82      for(double zval=0;zval<zdim;zval++) abscissae[int(zval)] = zval;
83
84  }
85  //--------------------------------------------------------------------
86
87  void getIntSpec(Detection &object, float *fluxArray, long *dimArray, bool *mask,
88                  float beamCorrection, float *spec)
89  {
90    /// @details
91    ///  The base function that extracts an integrated spectrum for a
92    ///  given object from a pixel array. The spectrum is returned as
93    ///  the integrated flux, corrected for the beam using the given
94    ///  correction factor.
95    ///   \param object The Detection in question
96    ///   \param fluxArray The full array of pixel values.
97    ///   \param dimArray The axis dimensions for the fluxArray
98    ///   \param mask A mask array indicating whether given pixels are valid
99    ///   \param beamCorrection How much to divide the summed spectrum
100    ///   by to return the integrated flux.
101    ///   \param spec The integrated spectrum for the object -- must be allocated first.
102
103    for(int i=0;i<dimArray[2];i++) spec[i] = 0.;
104    long xySize = dimArray[0]*dimArray[1];
105    bool *done = new bool[xySize];
106    for(int i=0;i<xySize;i++) done[i]=false;
107    std::vector<Voxel> voxlist = object.pixels().getPixelSet();
108    for(int pix=0;pix<voxlist.size();pix++){
109      int pos = voxlist[pix].getX() + dimArray[0] * voxlist[pix].getY();
110      if(!done[pos]){
111        done[pos] = true;
112        for(int z=0;z<dimArray[2];z++){
113          if(mask[pos+z*xySize]){
114            spec[z] += fluxArray[pos + z*xySize] / beamCorrection;
115          }         
116        }
117      }
118    }
119    delete [] done;
120
121  }
122  //--------------------------------------------------------------------
123
124  void getPeakSpec(Detection &object, float *fluxArray, long *dimArray, bool *mask, float *spec)
125  {
126    /// @details
127    ///  The base function that extracts an peak spectrum for a
128    ///  given object from a pixel array. The spectrum is returned as
129    ///  the integrated flux, corrected for the beam using the given
130    ///  correction factor.
131    ///   \param object The Detection in question
132    ///   \param fluxArray The full array of pixel values.
133    ///   \param dimArray The axis dimensions for the fluxArray
134    ///   \param mask A mask array indicating whether given pixels are valid
135    ///   \param spec The peak spectrum for the object -- must be allocated first
136
137    long xySize = dimArray[0]*dimArray[1];
138    int pos = object.getXPeak() + dimArray[0]*object.getYPeak();
139    for(int z=0;z<dimArray[2];z++){
140      if(mask[pos + z*xySize])
141        spec[z] = fluxArray[pos + z*xySize];
142    }
143  }
144  //--------------------------------------------------------------------
145
146
147  void Cube::getSpectralArrays(int objNum, float *specx, float *specy,
148                               float *specRecon, float *specBase)
149  {
150    /// @details
151    ///  A utility function that goes and calculates, for a given
152    ///  Detection, the spectral arrays, according to whether we want
153    ///  the peak or integrated flux. The arrays can be used by
154    ///  Cube::plotSpectrum() and Cube::writeSpectralData(). The arrays
155    ///  calculated are listed below. Their length is given by the
156    ///  length of the Cube's spectral dimension.
157    ///
158    ///  Note that the arrays need to be allocated prior to calling
159    ///  this function.
160    ///
161    ///  \param objNum The number of the object under consideration
162    ///  \param specx The array of frequency/velocity/channel/etc
163    ///         values (the x-axis on the spectral plot).
164    ///  \param specy The array of flux values, matching the specx
165    ///         array.
166    ///  \param specRecon The reconstructed or smoothed array, done in
167    ///         the same way as specy.
168    ///  \param specBase The fitted baseline values, done in the same
169    ///         way as specy.
170
171    long xdim = this->axisDim[0];
172    long ydim = this->axisDim[1];
173    long zdim = this->axisDim[2];
174       
175    for(int i=0;i<zdim;i++) specy[i]     = 0.;
176    for(int i=0;i<zdim;i++) specRecon[i] = 0.;
177    for(int i=0;i<zdim;i++) specBase[i]  = 0.;
178       
179    if(this->head.isWCS()){
180      double xval = double(this->objectList->at(objNum).getXcentre());
181      double yval = double(this->objectList->at(objNum).getYcentre());
182      for(double zval=0;zval<zdim;zval++)
183        specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
184    }
185    else
186      for(double zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
187       
188    float beamCorrection;
189    if(this->header().needBeamSize())
190      beamCorrection = this->par.getBeamSize();
191    else beamCorrection = 1.;
192       
193    if(this->par.getSpectralMethod()=="sum"){
194      bool *done = new bool[xdim*ydim];
195      for(int i=0;i<xdim*ydim;i++) done[i]=false;
196      std::vector<Voxel> voxlist = this->objectList->at(objNum).pixels().getPixelSet();
197      for(int pix=0;pix<voxlist.size();pix++){
198        int pos = voxlist[pix].getX() + xdim * voxlist[pix].getY();
199        if(!done[pos]){
200          done[pos] = true;
201          for(int z=0;z<zdim;z++){
202            if(!(this->isBlank(pos+z*xdim*ydim))){
203              specy[z] += this->array[pos + z*xdim*ydim] / beamCorrection;
204              if(this->reconExists)
205                specRecon[z] += this->recon[pos + z*xdim*ydim] / beamCorrection;
206              if(this->par.getFlagBaseline())
207                specBase[z] += this->baseline[pos + z*xdim*ydim] / beamCorrection;
208            }       
209          }
210        }
211      }
212      delete [] done;
213    }
214    else {// if(par.getSpectralMethod()=="peak"){
215      int pos = this->objectList->at(objNum).getXPeak() +
216        xdim*this->objectList->at(objNum).getYPeak();
217      for(int z=0;z<zdim;z++){
218        specy[z] = this->array[pos + z*xdim*ydim];
219        if(this->reconExists)
220          specRecon[z] = this->recon[pos + z*xdim*ydim];
221        if(this->par.getFlagBaseline())
222          specBase[z] = this->baseline[pos + z*xdim*ydim];
223      }
224    }
225
226//     long zdim = this->axisDim[2];
227//     Detection obj = this->objectList->at(objNum);
228//     getSpecAbscissae(obj, this->head, zdim, specx);
229
230//     float beamCorrection;
231//     if(this->header().needBeamSize())
232//       beamCorrection = this->par.getBeamSize();
233//     else beamCorrection = 1.;
234
235//     bool *mask = this->makeBlankMask();
236//     if(!this->reconExists)
237//       for(int i=0;i<this->axisDim[2];i++) specRecon[i] = 0.;
238//     if(!this->par.getFlagBaseline())
239//       for(int i=0;i<this->axisDim[2];i++) specBase[i]  = 0.;
240
241//     if(this->par.getSpectralMethod()=="sum"){
242//       getIntSpec(obj, this->array, this->axisDim, mask, beamCorrection, specy);
243//       if(this->reconExists){
244//      getIntSpec(obj, this->recon, this->axisDim, mask, beamCorrection, specRecon);
245//       }
246//       if(this->par.getFlagBaseline()){
247//      getIntSpec(obj, this->baseline, this->axisDim, mask, beamCorrection, specBase);
248//       }
249//     }
250//     else{ // if(.getSpectralMethod()=="peak"){
251//       getPeakSpec(obj, this->array, this->axisDim, mask, specy);
252//       if(this->reconExists)
253//      getPeakSpec(obj, this->recon, this->axisDim, mask, specRecon);
254//       if(this->par.getFlagBaseline())
255//      getPeakSpec(obj, this->baseline, this->axisDim, mask, specBase);
256//     }
257
258  }
259  //--------------------------------------------------------------------
260
261}
Note: See TracBrowser for help on using the repository browser.