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

Last change on this file since 221 was 220, checked in by Matthew Whiting, 17 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
Line 
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>
9#include <Cubes/plots.hh>
10#include <Utils/utils.hh>
11#include <Utils/mycpgplot.hh>
12using namespace mycpgplot;
13
14void getSmallVelRange(Detection &obj, FitsHeader head, float *minvel, float *maxvel);
15void getSmallZRange(Detection &obj, float *minz, float *maxz);
16
17void Cube::outputSpectra()
18{
19  /**
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.
30   */
31
32  if(this->fullCols.size()==0) this->setupColumns();
33  // in case cols haven't been set -- need the precisions for printing values.
34
35  string spectrafile = this->par.getSpectraFile() + "/vcps";
36  Plot::SpectralPlot newplot;
37  if(newplot.setUpPlot(spectrafile.c_str())>0) {
38
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.
44
45    cpgclos();
46  }
47}
48
49void Cube::plotSpectrum(Detection obj, Plot::SpectralPlot &plot)
50{
51  /**
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.
64   */
65
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
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
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
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.;
92   
93  if(this->head.isWCS())
94    for(zval=0;zval<zdim;zval++)
95      specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
96  else
97    for(zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
98
99  string fluxLabel = "Flux";
100
101  if(this->par.getSpectralMethod()=="sum"){
102    fluxLabel = "Integrated " + fluxLabel;
103    if(this->head.isWCS())
104      fluxLabel += " ["+this->head.getIntFluxUnits()+"]";
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;
115//          if(this->par.getFlagATrous())
116            if(this->reconExists)
117              specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
118          }
119        }
120      }
121    }
122    delete [] done;
123  }
124  else {// if(par.getSpectralMethod()=="peak"){
125    if(this->head.isWCS())
126      fluxLabel += " [" + this->head.getFluxUnits() + "]";
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];
130//if(this->par.getFlagATrous()) specy2[z] = this->recon[pos + z*xdim*ydim];
131      if(this->reconExists) specy2[z] = this->recon[pos + z*xdim*ydim];
132    }
133  }
134   
135  float vmax,vmin,width;
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  }
141 
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)){
148      if(specy[i]>max) max=specy[i];
149      if(specy[i]<min){
150        min=specy[i];
151        loc = i;
152      }
153    }
154  }
155  // widen the ranges slightly so that the top & bottom & edges don't
156  // lie on the axes.
157  width = max - min;
158  max += width * 0.05;
159  min -= width * 0.05;
160  width = vmax -vmin;
161  vmax += width * 0.01;
162  vmin -= width * 0.01;
163
164  // now plot the resulting spectrum
165  string label;
166  if(this->head.isWCS()){
167    label = this->head.getSpectralDescription() + " [" +
168      this->head.getSpectralUnits() + "]";
169    plot.gotoHeader(label);
170  }
171  else plot.gotoHeader("Spectral pixel value");
172
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);
181   
182  plot.gotoMainSpectrum(vmin,vmax,min,max,fluxLabel);
183  cpgline(zdim,specx,specy);
184//   if(this->par.getFlagATrous()){
185  if(this->reconExists){
186    cpgsci(RED);
187    cpgline(zdim,specx,specy2);   
188    cpgsci(FOREGND);
189  }
190  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
191  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
192  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
193
194  /**************************/
195  // ZOOM IN SPECTRALLY ON THE DETECTION.
196
197  float minvel,maxvel;
198  if(this->head.isWCS()) getSmallVelRange(obj,this->head,&minvel,&maxvel);
199  else getSmallZRange(obj,&minvel,&maxvel);
200
201  // Find new max & min flux values
202  swap(max,min);
203  int ct = 0;
204  for(int i=0;i<zdim;i++){
205    if((!this->par.isInMW(i))&&(specx[i]>=minvel)&&(specx[i]<=maxvel)){
206      ct++;
207      if(specy[i]>max) max=specy[i];
208      if(specy[i]<min) min=specy[i];
209    }
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;
215
216  plot.gotoZoomSpectrum(minvel,maxvel,min,max);
217  cpgline(zdim,specx,specy);
218//   if(this->par.getFlagATrous()){
219  if(this->reconExists){
220    cpgsci(RED);
221    cpgline(zdim,specx,specy2);   
222    cpgsci(FOREGND);
223  }
224  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
225  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
226  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
227   
228  /**************************/
229
230  // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
231  plot.gotoMap();
232  this->drawMomentCutout(obj);
233
234  delete [] specx;
235  delete [] specy;
236  delete [] specy2;
237 
238}
239
240
241void getSmallVelRange(Detection &obj, FitsHeader head,
242                      float *minvel, float *maxvel)
243{
244  /**
245   *  Routine to calculate the velocity range for the zoomed-in region.
246   *  This range should be the maximum of 20 pixels, or 3x the wdith of
247   *   the detection.
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.
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
257   */
258
259  double *pixcrd = new double[3];
260  double *world  = new double[3];
261  float minpix,maxpix;
262  // define new velocity extrema
263  //    -- make it 3x wider than the width of the detection.
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();
269  world[2] = head.velToSpec(*minvel);
270  head.wcsToPix(world,pixcrd);
271  minpix = pixcrd[2];
272  world[2] = head.velToSpec(*maxvel);
273  head.wcsToPix(world,pixcrd);
274  maxpix = pixcrd[2];
275  if(maxpix<minpix) swap(maxpix,minpix);
276   
277  if((maxpix - minpix + 1) < 20){
278    pixcrd[0] = double(obj.getXcentre());
279    pixcrd[1] = double(obj.getYcentre());
280    pixcrd[2] = obj.getZcentre() - 10.;
281    head.pixToWCS(pixcrd,world);
282    //    *minvel = setVel_kms(wcs,world[2]);
283    *minvel = head.specToVel(world[2]);
284    pixcrd[2] = obj.getZcentre() + 10.;
285    head.pixToWCS(pixcrd,world);
286    //     *maxvel = setVel_kms(wcs,world[2]);
287    *maxvel = head.specToVel(world[2]);
288    if(*maxvel<*minvel) swap(*maxvel,*minvel);
289  }
290  delete [] pixcrd;
291  delete [] world;
292
293}
294
295void getSmallZRange(Detection &obj, float *minz, float *maxz)
296{
297  /**
298   *  Routine to calculate the pixel range for the zoomed-in spectrum.
299   *  This range should be the maximum of 20 pixels, or 3x the width
300   *   of the detection.
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.
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
308   */
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.