source: tags/release-1.1.7/src/Cubes/spectraUtils.cc @ 1455

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

Including the recent minor changes to 1.1.7.

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(uint 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(uint 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.