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
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 <param.hh>
9#include <PixelMap/Object3D.hh>
10#include <Cubes/cubes.hh>
11#include <Cubes/plots.hh>
12#include <Utils/utils.hh>
13#include <Utils/mycpgplot.hh>
14
15using namespace mycpgplot;
16using namespace PixelInfo;
17
18void getSmallVelRange(Detection &obj, FitsHeader head, float *minvel, float *maxvel);
19void getSmallZRange(Detection &obj, float *minz, float *maxz);
20
21void Cube::outputSpectra()
22{
23  /**
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.
34   */
35
36  if(this->fullCols.size()==0) this->setupColumns();
37  // in case cols haven't been set -- need the precisions for printing values.
38
39  std::string spectrafile = this->par.getSpectraFile() + "/vcps";
40  Plot::SpectralPlot newplot;
41  if(newplot.setUpPlot(spectrafile.c_str())>0) {
42
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.
48
49    cpgclos();
50  }
51}
52
53void Cube::plotSpectrum(Detection obj, Plot::SpectralPlot &plot)
54{
55  /**
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.
68   */
69
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
75  obj.calcFluxes(this->array, this->axisDim);
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
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
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.;
96   
97  if(this->head.isWCS())
98    for(zval=0;zval<zdim;zval++)
99      specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
100  else
101    for(zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
102
103  std::string fluxLabel = "Flux";
104
105  if(this->par.getSpectralMethod()=="sum"){
106    fluxLabel = "Integrated " + fluxLabel;
107    if(this->head.isWCS())
108      fluxLabel += " ["+this->head.getIntFluxUnits()+"]";
109    bool *done = new bool[xdim*ydim];
110    for(int i=0;i<xdim*ydim;i++) done[i]=false;
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();
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;
119//          if(this->par.getFlagATrous())
120            if(this->reconExists)
121              specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
122          }
123        }
124      }
125    }
126    delete [] done;
127  }
128  else {// if(par.getSpectralMethod()=="peak"){
129    if(this->head.isWCS())
130      fluxLabel += " [" + this->head.getFluxUnits() + "]";
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];
134//if(this->par.getFlagATrous()) specy2[z] = this->recon[pos + z*xdim*ydim];
135      if(this->reconExists) specy2[z] = this->recon[pos + z*xdim*ydim];
136    }
137  }
138   
139  float vmax,vmin,width;
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  }
145 
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)){
152      if(specy[i]>max) max=specy[i];
153      if(specy[i]<min){
154        min=specy[i];
155        loc = i;
156      }
157    }
158  }
159  // widen the ranges slightly so that the top & bottom & edges don't
160  // lie on the axes.
161  width = max - min;
162  max += width * 0.05;
163  min -= width * 0.05;
164  width = vmax -vmin;
165  vmax += width * 0.01;
166  vmin -= width * 0.01;
167
168  // now plot the resulting spectrum
169  std::string label;
170  if(this->head.isWCS()){
171    label = this->head.getSpectralDescription() + " [" +
172      this->head.getSpectralUnits() + "]";
173    plot.gotoHeader(label);
174  }
175  else plot.gotoHeader("Spectral pixel value");
176
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);
185   
186  plot.gotoMainSpectrum(vmin,vmax,min,max,fluxLabel);
187  cpgline(zdim,specx,specy);
188//   if(this->par.getFlagATrous()){
189  if(this->reconExists){
190    cpgsci(RED);
191    cpgline(zdim,specx,specy2);   
192    cpgsci(FOREGND);
193  }
194  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
195  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
196  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
197
198  /**************************/
199  // ZOOM IN SPECTRALLY ON THE DETECTION.
200
201  float minvel,maxvel;
202  if(this->head.isWCS()) getSmallVelRange(obj,this->head,&minvel,&maxvel);
203  else getSmallZRange(obj,&minvel,&maxvel);
204
205  // Find new max & min flux values
206  swap(max,min);
207  int ct = 0;
208  for(int i=0;i<zdim;i++){
209    if((!this->par.isInMW(i))&&(specx[i]>=minvel)&&(specx[i]<=maxvel)){
210      ct++;
211      if(specy[i]>max) max=specy[i];
212      if(specy[i]<min) min=specy[i];
213    }
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;
219
220  plot.gotoZoomSpectrum(minvel,maxvel,min,max);
221  cpgline(zdim,specx,specy);
222//   if(this->par.getFlagATrous()){
223  if(this->reconExists){
224    cpgsci(RED);
225    cpgline(zdim,specx,specy2);   
226    cpgsci(FOREGND);
227  }
228  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
229  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
230  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
231   
232  /**************************/
233
234  // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
235  plot.gotoMap();
236  this->drawMomentCutout(obj);
237
238  delete [] specx;
239  delete [] specy;
240  delete [] specy2;
241 
242}
243
244
245void getSmallVelRange(Detection &obj, FitsHeader head,
246                      float *minvel, float *maxvel)
247{
248  /**
249   *  Routine to calculate the velocity range for the zoomed-in region.
250   *  This range should be the maximum of 20 pixels, or 3x the wdith of
251   *   the detection.
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.
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
261   */
262
263  double *pixcrd = new double[3];
264  double *world  = new double[3];
265  float minpix,maxpix;
266  // define new velocity extrema
267  //    -- make it 3x wider than the width of the detection.
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();
273  world[2] = head.velToSpec(*minvel);
274  head.wcsToPix(world,pixcrd);
275  minpix = pixcrd[2];
276  world[2] = head.velToSpec(*maxvel);
277  head.wcsToPix(world,pixcrd);
278  maxpix = pixcrd[2];
279  if(maxpix<minpix) swap(maxpix,minpix);
280   
281  if((maxpix - minpix + 1) < 20){
282    pixcrd[0] = double(obj.getXcentre());
283    pixcrd[1] = double(obj.getYcentre());
284    pixcrd[2] = obj.getZcentre() - 10.;
285    head.pixToWCS(pixcrd,world);
286    //    *minvel = setVel_kms(wcs,world[2]);
287    *minvel = head.specToVel(world[2]);
288    pixcrd[2] = obj.getZcentre() + 10.;
289    head.pixToWCS(pixcrd,world);
290    //     *maxvel = setVel_kms(wcs,world[2]);
291    *maxvel = head.specToVel(world[2]);
292    if(*maxvel<*minvel) swap(*maxvel,*minvel);
293  }
294  delete [] pixcrd;
295  delete [] world;
296
297}
298
299void getSmallZRange(Detection &obj, float *minz, float *maxz)
300{
301  /**
302   *  Routine to calculate the pixel range for the zoomed-in spectrum.
303   *  This range should be the maximum of 20 pixels, or 3x the width
304   *   of the detection.
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.
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
312   */
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.