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

Last change on this file since 971 was 935, checked in by MatthewWhiting, 12 years ago

A bunch of int --> size_t conversions.

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