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

Last change on this file since 482 was 463, checked in by MatthewWhiting, 16 years ago

Changes aimed at calculating the w50 and w20 parameters, and printing them out.

File size: 10.1 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 <cpgplot.h>
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    /**
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    /**
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
77    if(head.isWCS()){
78      double xval = double(xpt);
79      double yval = double(ypt);
80      for(double zval=0;zval<zdim;zval++)
81        abscissae[int(zval)] = head.pixToVel(xval,yval,zval);
82    }
83    else
84      for(double zval=0;zval<zdim;zval++) abscissae[int(zval)] = zval;
85
86  }
87  //--------------------------------------------------------------------
88
89  void getIntSpec(Detection &object, float *fluxArray, long *dimArray, bool *mask,
90                  float beamCorrection, float *spec)
91  {
92    /**
93     *  The base function that extracts an integrated spectrum for a
94     *  given object from a pixel array. The spectrum is returned as
95     *  the integrated flux, corrected for the beam using the given
96     *  correction factor.
97     *   \param object The Detection in question
98     *   \param fluxArray The full array of pixel values.
99     *   \param dimArray The axis dimensions for the fluxArray
100     *   \param mask A mask array indicating whether given pixels are valid
101     *   \param beamCorrection How much to divide the summed spectrum
102     *   by to return the integrated flux.
103     *   \param spec The integrated spectrum for the object -- must be allocated first.
104     */
105
106    for(int i=0;i<dimArray[2];i++) spec[i] = 0.;
107    long xySize = dimArray[0]*dimArray[1];
108    bool *done = new bool[xySize];
109    for(int i=0;i<xySize;i++) done[i]=false;
110    std::vector<Voxel> voxlist = object.pixels().getPixelSet();
111    for(int pix=0;pix<voxlist.size();pix++){
112      int pos = voxlist[pix].getX() + dimArray[0] * voxlist[pix].getY();
113      if(!done[pos]){
114        done[pos] = true;
115        for(int z=0;z<dimArray[2];z++){
116          if(mask[pos+z*xySize]){
117            spec[z] += fluxArray[pos + z*xySize] / beamCorrection;
118          }         
119        }
120      }
121    }
122    delete [] done;
123
124  }
125  //--------------------------------------------------------------------
126
127  void getPeakSpec(Detection &object, float *fluxArray, long *dimArray, bool *mask, float *spec)
128  {
129    /**
130     *  The base function that extracts an peak spectrum for a
131     *  given object from a pixel array. The spectrum is returned as
132     *  the integrated flux, corrected for the beam using the given
133     *  correction factor.
134     *   \param object The Detection in question
135     *   \param fluxArray The full array of pixel values.
136     *   \param dimArray The axis dimensions for the fluxArray
137     *   \param mask A mask array indicating whether given pixels are valid
138     *   \param spec The peak spectrum for the object -- must be allocated first
139     */
140
141    long xySize = dimArray[0]*dimArray[1];
142    int pos = object.getXPeak() + dimArray[0]*object.getYPeak();
143    for(int z=0;z<dimArray[2];z++){
144      if(mask[pos + z*xySize])
145        spec[z] = fluxArray[pos + z*xySize];
146    }
147  }
148  //--------------------------------------------------------------------
149
150
151  void Cube::getSpectralArrays(int objNum, float *specx, float *specy,
152                               float *specRecon, float *specBase)
153  {
154    /**
155     *  A utility function that goes and calculates, for a given
156     *  Detection, the spectral arrays, according to whether we want
157     *  the peak or integrated flux. The arrays can be used by
158     *  Cube::plotSpectrum() and Cube::writeSpectralData(). The arrays
159     *  calculated are listed below. Their length is given by the
160     *  length of the Cube's spectral dimension.
161     *
162     *  Note that the arrays need to be allocated prior to calling
163     *  this function.
164     *
165     *  \param objNum The number of the object under consideration
166     *  \param specx The array of frequency/velocity/channel/etc
167     *         values (the x-axis on the spectral plot).
168     *  \param specy The array of flux values, matching the specx
169     *         array.
170     *  \param specRecon The reconstructed or smoothed array, done in
171     *         the same way as specy.
172     *  \param specBase The fitted baseline values, done in the same
173     *         way as specy.
174     */
175
176    long xdim = this->axisDim[0];
177    long ydim = this->axisDim[1];
178    long zdim = this->axisDim[2];
179       
180    for(int i=0;i<zdim;i++) specy[i]     = 0.;
181    for(int i=0;i<zdim;i++) specRecon[i] = 0.;
182    for(int i=0;i<zdim;i++) specBase[i]  = 0.;
183       
184    if(this->head.isWCS()){
185      double xval = double(this->objectList->at(objNum).getXcentre());
186      double yval = double(this->objectList->at(objNum).getYcentre());
187      for(double zval=0;zval<zdim;zval++)
188        specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
189    }
190    else
191      for(double zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
192       
193    float beamCorrection;
194    if(this->header().needBeamSize())
195      beamCorrection = this->par.getBeamSize();
196    else beamCorrection = 1.;
197       
198    if(this->par.getSpectralMethod()=="sum"){
199      bool *done = new bool[xdim*ydim];
200      for(int i=0;i<xdim*ydim;i++) done[i]=false;
201      std::vector<Voxel> voxlist = this->objectList->at(objNum).pixels().getPixelSet();
202      for(int pix=0;pix<voxlist.size();pix++){
203        int pos = voxlist[pix].getX() + xdim * voxlist[pix].getY();
204        if(!done[pos]){
205          done[pos] = true;
206          for(int z=0;z<zdim;z++){
207            if(!(this->isBlank(pos+z*xdim*ydim))){
208              specy[z] += this->array[pos + z*xdim*ydim] / beamCorrection;
209              if(this->reconExists)
210                specRecon[z] += this->recon[pos + z*xdim*ydim] / beamCorrection;
211              if(this->par.getFlagBaseline())
212                specBase[z] += this->baseline[pos + z*xdim*ydim] / beamCorrection;
213            }       
214          }
215        }
216      }
217      delete [] done;
218    }
219    else {// if(par.getSpectralMethod()=="peak"){
220      int pos = this->objectList->at(objNum).getXPeak() +
221        xdim*this->objectList->at(objNum).getYPeak();
222      for(int z=0;z<zdim;z++){
223        specy[z] = this->array[pos + z*xdim*ydim];
224        if(this->reconExists)
225          specRecon[z] = this->recon[pos + z*xdim*ydim];
226        if(this->par.getFlagBaseline())
227          specBase[z] = this->baseline[pos + z*xdim*ydim];
228      }
229    }
230
231//     long zdim = this->axisDim[2];
232//     Detection obj = this->objectList->at(objNum);
233//     getSpecAbscissae(obj, this->head, zdim, specx);
234
235//     float beamCorrection;
236//     if(this->header().needBeamSize())
237//       beamCorrection = this->par.getBeamSize();
238//     else beamCorrection = 1.;
239
240//     bool *mask = this->makeBlankMask();
241//     if(!this->reconExists)
242//       for(int i=0;i<this->axisDim[2];i++) specRecon[i] = 0.;
243//     if(!this->par.getFlagBaseline())
244//       for(int i=0;i<this->axisDim[2];i++) specBase[i]  = 0.;
245
246//     if(this->par.getSpectralMethod()=="sum"){
247//       getIntSpec(obj, this->array, this->axisDim, mask, beamCorrection, specy);
248//       if(this->reconExists){
249//      getIntSpec(obj, this->recon, this->axisDim, mask, beamCorrection, specRecon);
250//       }
251//       if(this->par.getFlagBaseline()){
252//      getIntSpec(obj, this->baseline, this->axisDim, mask, beamCorrection, specBase);
253//       }
254//     }
255//     else{ // if(.getSpectralMethod()=="peak"){
256//       getPeakSpec(obj, this->array, this->axisDim, mask, specy);
257//       if(this->reconExists)
258//      getPeakSpec(obj, this->recon, this->axisDim, mask, specRecon);
259//       if(this->par.getFlagBaseline())
260//      getPeakSpec(obj, this->baseline, this->axisDim, mask, specBase);
261//     }
262
263  }
264  //--------------------------------------------------------------------
265
266}
Note: See TracBrowser for help on using the repository browser.