source: trunk/src/Cubes/outputSpectra.cc @ 221

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