source: branches/pixel-map-branch/src/Cubes/outputSpectra.cc

Last change on this file was 252, checked in by Matthew Whiting, 17 years ago
  • Have put all classes in the files in src/PixelMap/ into a PixelInfo? namespace.
  • Added "using namespace PixelInfo?" to all necessary files.
  • Removed "friend class Detection" from Voxel and Object3D classes -- not necessary and complicated now by them being in the namespace
  • Various minor changes, including fixing up commentary.
File size: 10.1 KB
RevLine 
[3]1#include <iostream>
2#include <iomanip>
3#include <sstream>
4#include <string>
5#include <cpgplot.h>
6#include <math.h>
7#include <wcs.h>
[243]8#include <param.hh>
9#include <PixelMap/Object3D.hh>
[3]10#include <Cubes/cubes.hh>
[11]11#include <Cubes/plots.hh>
[3]12#include <Utils/utils.hh>
[146]13#include <Utils/mycpgplot.hh>
[252]14
[146]15using namespace mycpgplot;
[252]16using namespace PixelInfo;
[3]17
[103]18void getSmallVelRange(Detection &obj, FitsHeader head, float *minvel, float *maxvel);
[49]19void getSmallZRange(Detection &obj, float *minz, float *maxz);
[86]20
[3]21void Cube::outputSpectra()
22{
[86]23  /**
[220]24   * The way to print out the spectra of the detected objects.
25   * Make use of the SpectralPlot class in plots.h, which sizes everything
26   *   correctly.
27   * Main choice is whether to use the peak pixel, in which case the
28   *  spectrum is just that of the peak pixel, or the sum, where the
29   *  spectrum is summed over all spatial pixels that are in the object.
30   * If a reconstruction has been done, that spectrum is plotted in red.
31   * The limits of the detection are marked in blue.
32   * A 0th moment map of the detection is also plotted, with a scale bar
33   *  indicating the spatial scale.
[86]34   */
[3]35
[144]36  if(this->fullCols.size()==0) this->setupColumns();
37  // in case cols haven't been set -- need the precisions for printing values.
38
[232]39  std::string spectrafile = this->par.getSpectraFile() + "/vcps";
[11]40  Plot::SpectralPlot newplot;
[187]41  if(newplot.setUpPlot(spectrafile.c_str())>0) {
[3]42
[187]43    for(int nobj=0;nobj<this->objectList.size();nobj++){
44      // for each object in the cube:
45      this->plotSpectrum(this->objectList[nobj],newplot);
46     
47    }// end of loop over objects.
[103]48
[187]49    cpgclos();
50  }
[103]51}
52
53void Cube::plotSpectrum(Detection obj, Plot::SpectralPlot &plot)
54{
55  /**
[220]56   * The way to print out the spectrum of a Detection.
57   * Makes use of the SpectralPlot class in plots.hh, which sizes
58   *  everything correctly.
59   * Main choice is whether to use the peak pixel, in which case the
60   *  spectrum is just that of the peak pixel, or the sum, where the
61   *  spectrum is summed over all spatial pixels that are in the object.
62   * If a reconstruction has been done, that spectrum is plotted in red.
63   * The limits of the detection are marked in blue.
64   * A 0th moment map of the detection is also plotted, with a scale bar
65   *  indicating the spatial size.
66   * \param obj The Detection to be plotted.
67   * \param plot The PGPLOT device to plot the spectrum on.
[103]68   */
69
[3]70  long xdim = this->axisDim[0];
71  long ydim = this->axisDim[1];
72  long zdim = this->axisDim[2];
73  float beam = this->par.getBeamSize();
74
[246]75  obj.calcFluxes(this->array, this->axisDim);
[103]76
77  double minMWvel,maxMWvel,xval,yval,zval;
78  xval = double(obj.getXcentre());
79  yval = double(obj.getYcentre());
80  if(this->par.getFlagMW()){
81    zval = double(this->par.getMinMW());
82    minMWvel = this->head.pixToVel(xval,yval,zval);
83    zval = double(this->par.getMaxMW());
84    maxMWvel = this->head.pixToVel(xval,yval,zval);
85  }
86
[3]87  float *specx  = new float[zdim];
88  float *specy  = new float[zdim];
89  for(int i=0;i<zdim;i++) specy[i] = 0.;
90  float *specy2 = new float[zdim];
91  for(int i=0;i<zdim;i++) specy2[i] = 0.;
92
[103]93  for(int i=0;i<zdim;i++) specy[i] = 0.;
94  if(this->par.getFlagATrous()) 
95    for(int i=0;i<zdim;i++) specy2[i] = 0.;
[3]96   
[103]97  if(this->head.isWCS())
[144]98    for(zval=0;zval<zdim;zval++)
99      specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
[103]100  else
101    for(zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
[3]102
[232]103  std::string fluxLabel = "Flux";
[45]104
[103]105  if(this->par.getSpectralMethod()=="sum"){
[204]106    fluxLabel = "Integrated " + fluxLabel;
107    if(this->head.isWCS())
108      fluxLabel += " ["+this->head.getIntFluxUnits()+"]";
[103]109    bool *done = new bool[xdim*ydim];
110    for(int i=0;i<xdim*ydim;i++) done[i]=false;
[243]111    std::vector<Voxel> voxlist = obj.pixels().getPixelSet();
112    for(int pix=0;pix<voxlist.size();pix++){
113      int pos = voxlist[pix].getX() + xdim * voxlist[pix].getY();
[103]114      if(!done[pos]){
115        done[pos] = true;
116        for(int z=0;z<zdim;z++){
117          if(!(this->isBlank(pos+z*xdim*ydim))){
118            specy[z] += this->array[pos + z*xdim*ydim] / beam;
[201]119//          if(this->par.getFlagATrous())
120            if(this->reconExists)
[103]121              specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
[3]122          }
123        }
124      }
125    }
[103]126    delete [] done;
127  }
128  else {// if(par.getSpectralMethod()=="peak"){
[204]129    if(this->head.isWCS())
130      fluxLabel += " [" + this->head.getFluxUnits() + "]";
[103]131    for(int z=0;z<zdim;z++){
132      int pos = obj.getXPeak() + xdim*obj.getYPeak();
133      specy[z] = this->array[pos + z*xdim*ydim];
[204]134//if(this->par.getFlagATrous()) specy2[z] = this->recon[pos + z*xdim*ydim];
[201]135      if(this->reconExists) specy2[z] = this->recon[pos + z*xdim*ydim];
[45]136    }
[103]137  }
[3]138   
[142]139  float vmax,vmin,width;
[103]140  vmax = vmin = specx[0];
141  for(int i=1;i<zdim;i++){
142    if(specx[i]>vmax) vmax=specx[i];
143    if(specx[i]<vmin) vmin=specx[i];
144  }
[142]145 
[103]146  float max,min;
147  int loc=0;
148  if(this->par.getMinMW()>0) max = min = specy[0];
149  else max = min = specx[this->par.getMaxMW()+1];
150  for(int i=0;i<zdim;i++){
151    if(!this->par.isInMW(i)){
[3]152      if(specy[i]>max) max=specy[i];
153      if(specy[i]<min){
154        min=specy[i];
155        loc = i;
156      }
157    }
[103]158  }
[142]159  // widen the ranges slightly so that the top & bottom & edges don't
160  // lie on the axes.
161  width = max - min;
[103]162  max += width * 0.05;
163  min -= width * 0.05;
[142]164  width = vmax -vmin;
165  vmax += width * 0.01;
166  vmin -= width * 0.01;
[3]167
[103]168  // now plot the resulting spectrum
[232]169  std::string label;
[103]170  if(this->head.isWCS()){
[186]171    label = this->head.getSpectralDescription() + " [" +
172      this->head.getSpectralUnits() + "]";
[103]173    plot.gotoHeader(label);
174  }
175  else plot.gotoHeader("Spectral pixel value");
[3]176
[103]177  if(this->head.isWCS()){
178    label = obj.outputLabelWCS();
179    plot.firstHeaderLine(label);
180  }
181  label = obj.outputLabelInfo();
182  plot.secondHeaderLine(label);
183  label = obj.outputLabelPix();
184  plot.thirdHeaderLine(label);
[49]185   
[103]186  plot.gotoMainSpectrum(vmin,vmax,min,max,fluxLabel);
187  cpgline(zdim,specx,specy);
[201]188//   if(this->par.getFlagATrous()){
189  if(this->reconExists){
[146]190    cpgsci(RED);
[103]191    cpgline(zdim,specx,specy2);   
[201]192    cpgsci(FOREGND);
[103]193  }
[112]194  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
[103]195  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
196  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
[3]197
[103]198  /**************************/
199  // ZOOM IN SPECTRALLY ON THE DETECTION.
[3]200
[103]201  float minvel,maxvel;
202  if(this->head.isWCS()) getSmallVelRange(obj,this->head,&minvel,&maxvel);
203  else getSmallZRange(obj,&minvel,&maxvel);
[3]204
[103]205  // Find new max & min flux values
206  swap(max,min);
207  int ct = 0;
208  for(int i=0;i<zdim;i++){
[112]209    if((!this->par.isInMW(i))&&(specx[i]>=minvel)&&(specx[i]<=maxvel)){
[103]210      ct++;
211      if(specy[i]>max) max=specy[i];
212      if(specy[i]<min) min=specy[i];
[3]213    }
[103]214  }
215  // widen the flux range slightly so that the top & bottom don't lie on the axes.
216  width = max - min;
217  max += width * 0.05;
218  min -= width * 0.05;
[3]219
[103]220  plot.gotoZoomSpectrum(minvel,maxvel,min,max);
221  cpgline(zdim,specx,specy);
[201]222//   if(this->par.getFlagATrous()){
223  if(this->reconExists){
[146]224    cpgsci(RED);
[103]225    cpgline(zdim,specx,specy2);   
[201]226    cpgsci(FOREGND);
[103]227  }
[112]228  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
[103]229  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
230  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
[3]231   
[103]232  /**************************/
[3]233
[103]234  // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
235  plot.gotoMap();
236  this->drawMomentCutout(obj);
[3]237
238  delete [] specx;
239  delete [] specy;
240  delete [] specy2;
241 
242}
243
[103]244
[147]245void getSmallVelRange(Detection &obj, FitsHeader head,
246                      float *minvel, float *maxvel)
[3]247{
[86]248  /**
249   *  Routine to calculate the velocity range for the zoomed-in region.
[147]250   *  This range should be the maximum of 20 pixels, or 3x the wdith of
251   *   the detection.
[86]252   *  Need to :
253   *      Calculate pixel width of a 3x-detection-width region.
254   *      If smaller than 20, calculate velocities of central vel +- 10 pixels
255   *      If not, use the 3x-detection-width
256   *  Range returned via "minvel" and "maxvel" parameters.
[220]257   *  \param obj Detection under examination.
258   *  \param head FitsHeader, containing the WCS information.
259   *  \param minvel Returned value of minimum velocity
260   *  \param maxvel Returned value of maximum velocity
[86]261   */
[3]262
263  double *pixcrd = new double[3];
264  double *world  = new double[3];
265  float minpix,maxpix;
[147]266  // define new velocity extrema
267  //    -- make it 3x wider than the width of the detection.
[3]268  *minvel = 0.5*(obj.getVelMin()+obj.getVelMax()) - 1.5*obj.getVelWidth();
269  *maxvel = 0.5*(obj.getVelMin()+obj.getVelMax()) + 1.5*obj.getVelWidth();
270  // Find velocity range in number of pixels:
271  world[0] = obj.getRA();
272  world[1] = obj.getDec();
[103]273  world[2] = head.velToSpec(*minvel);
274  head.wcsToPix(world,pixcrd);
[3]275  minpix = pixcrd[2];
[103]276  world[2] = head.velToSpec(*maxvel);
277  head.wcsToPix(world,pixcrd);
[3]278  maxpix = pixcrd[2];
279  if(maxpix<minpix) swap(maxpix,minpix);
280   
[49]281  if((maxpix - minpix + 1) < 20){
[3]282    pixcrd[0] = double(obj.getXcentre());
283    pixcrd[1] = double(obj.getYcentre());
[45]284    pixcrd[2] = obj.getZcentre() - 10.;
[103]285    head.pixToWCS(pixcrd,world);
286    //    *minvel = setVel_kms(wcs,world[2]);
287    *minvel = head.specToVel(world[2]);
[45]288    pixcrd[2] = obj.getZcentre() + 10.;
[103]289    head.pixToWCS(pixcrd,world);
[186]290    //     *maxvel = setVel_kms(wcs,world[2]);
[103]291    *maxvel = head.specToVel(world[2]);
[3]292    if(*maxvel<*minvel) swap(*maxvel,*minvel);
293  }
294  delete [] pixcrd;
295  delete [] world;
296
297}
[49]298
299void getSmallZRange(Detection &obj, float *minz, float *maxz)
300{
[86]301  /**
302   *  Routine to calculate the pixel range for the zoomed-in spectrum.
[147]303   *  This range should be the maximum of 20 pixels, or 3x the width
304   *   of the detection.
[86]305   *  Need to :
306   *      Calculate pixel width of a 3x-detection-width region.
307   *       If smaller than 20, use central pixel +- 10 pixels
308   *  Range returned via "minz" and "maxz" parameters.
[220]309   *  \param obj Detection under examination.
310   *  \param minz Returned value of minimum z-pixel coordinate
311   *  \param maxz Returned value of maximum z-pixel coordinate
[86]312   */
[49]313
314  *minz = 2.*obj.getZmin() - obj.getZmax();
315  *maxz = 2.*obj.getZmax() - obj.getZmin();
316   
317  if((*maxz - *minz + 1) < 20){
318    *minz = obj.getZcentre() - 10.;
319    *maxz = obj.getZcentre() + 10.;
320  }
321
322}
Note: See TracBrowser for help on using the repository browser.