source: tags/release-1.1.11/src/Cubes/spectraUtils.cc @ 1441

Last change on this file since 1441 was 791, checked in by MatthewWhiting, 13 years ago

Making sure it works with the redesigned needBeamSize function (ie. not using it before reading beam from file). Also removing a lot of redundant code.

File size: 10.3 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, long 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, long 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, long *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(int i=0;i<dimArray[2];i++) spec[i] = 0.;
105    long xySize = dimArray[0]*dimArray[1];
106    bool *done = new bool[xySize];
107    for(int 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      int pos = vox->getX() + dimArray[0] * vox->getY();
112      if(!done[pos]){
113        done[pos] = true;
114        for(int 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, long *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    long xySize = dimArray[0]*dimArray[1];
140    int pos = object.getXPeak() + dimArray[0]*object.getYPeak();
141    for(int z=0;z<dimArray[2];z++){
142      if(mask[pos + z*xySize])
143        spec[z] = fluxArray[pos + z*xySize];
144    }
145  }
146  //--------------------------------------------------------------------
147
148
149  void Cube::getSpectralArrays(int objNum, float *specx, float *specy,
150                               float *specRecon, float *specBase)
151  {
152    /// @details
153    ///  A utility function that goes and calculates, for a given
154    ///  Detection, the spectral arrays, according to whether we want
155    ///  the peak or integrated flux. The arrays can be used by
156    ///  Cube::plotSpectrum() and Cube::writeSpectralData(). The arrays
157    ///  calculated are listed below. Their length is given by the
158    ///  length of the Cube's spectral dimension.
159    ///
160    ///  Note that the arrays need to be allocated prior to calling
161    ///  this function.
162    ///
163    ///  \param objNum The number of the object under consideration
164    ///  \param specx The array of frequency/velocity/channel/etc
165    ///         values (the x-axis on the spectral plot).
166    ///  \param specy The array of flux values, matching the specx
167    ///         array.
168    ///  \param specRecon The reconstructed or smoothed array, done in
169    ///         the same way as specy.
170    ///  \param specBase The fitted baseline values, done in the same
171    ///         way as specy.
172
173    long xdim = this->axisDim[0];
174    long ydim = this->axisDim[1];
175    long zdim = this->axisDim[2];
176       
177    for(int i=0;i<zdim;i++) specy[i]     = 0.;
178    for(int i=0;i<zdim;i++) specRecon[i] = 0.;
179    for(int i=0;i<zdim;i++) specBase[i]  = 0.;
180       
181    if(this->head.isWCS()){
182      double xval = double(this->objectList->at(objNum).getXcentre());
183      double yval = double(this->objectList->at(objNum).getYcentre());
184      for(double zval=0;zval<zdim;zval++)
185        specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
186    }
187    else
188      for(double zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
189       
190    float beamCorrection;
191    if(this->header().needBeamSize())
192      beamCorrection = this->head.beam().area();
193    else beamCorrection = 1.;
194       
195    if(this->par.getSpectralMethod()=="sum"){
196      bool *done = new bool[xdim*ydim];
197      for(int i=0;i<xdim*ydim;i++) done[i]=false;
198      std::vector<Voxel> voxlist = this->objectList->at(objNum).getPixelSet();
199      std::vector<Voxel>::iterator vox;
200      for(vox=voxlist.begin();vox<voxlist.end();vox++){
201        int pos = vox->getX() + xdim * vox->getY();
202        if(!done[pos]){
203          done[pos] = true;
204          for(int z=0;z<zdim;z++){
205            if(!(this->isBlank(pos+z*xdim*ydim))){
206              specy[z] += this->array[pos + z*xdim*ydim] / beamCorrection;
207              if(this->reconExists)
208                specRecon[z] += this->recon[pos + z*xdim*ydim] / beamCorrection;
209              if(this->par.getFlagBaseline())
210                specBase[z] += this->baseline[pos + z*xdim*ydim] / beamCorrection;
211            }       
212          }
213        }
214      }
215      delete [] done;
216    }
217    else {// if(par.getSpectralMethod()=="peak"){
218      int pos = this->objectList->at(objNum).getXPeak() +
219        xdim*this->objectList->at(objNum).getYPeak();
220      for(int z=0;z<zdim;z++){
221        specy[z] = this->array[pos + z*xdim*ydim];
222        if(this->reconExists)
223          specRecon[z] = this->recon[pos + z*xdim*ydim];
224        if(this->par.getFlagBaseline())
225          specBase[z] = this->baseline[pos + z*xdim*ydim];
226      }
227    }
228
229//     long zdim = this->axisDim[2];
230//     Detection obj = this->objectList->at(objNum);
231//     getSpecAbscissae(obj, this->head, zdim, specx);
232
233//     float beamCorrection;
234//     if(this->header().needBeamSize())
235//       beamCorrection = this->par.getBeamSize();
236//     else beamCorrection = 1.;
237
238//     bool *mask = this->makeBlankMask();
239//     if(!this->reconExists)
240//       for(int i=0;i<this->axisDim[2];i++) specRecon[i] = 0.;
241//     if(!this->par.getFlagBaseline())
242//       for(int i=0;i<this->axisDim[2];i++) specBase[i]  = 0.;
243
244//     if(this->par.getSpectralMethod()=="sum"){
245//       getIntSpec(obj, this->array, this->axisDim, mask, beamCorrection, specy);
246//       if(this->reconExists){
247//      getIntSpec(obj, this->recon, this->axisDim, mask, beamCorrection, specRecon);
248//       }
249//       if(this->par.getFlagBaseline()){
250//      getIntSpec(obj, this->baseline, this->axisDim, mask, beamCorrection, specBase);
251//       }
252//     }
253//     else{ // if(.getSpectralMethod()=="peak"){
254//       getPeakSpec(obj, this->array, this->axisDim, mask, specy);
255//       if(this->reconExists)
256//      getPeakSpec(obj, this->recon, this->axisDim, mask, specRecon);
257//       if(this->par.getFlagBaseline())
258//      getPeakSpec(obj, this->baseline, this->axisDim, mask, specBase);
259//     }
260
261  }
262  //--------------------------------------------------------------------
263
264}
Note: See TracBrowser for help on using the repository browser.