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

Last change on this file since 251 was 246, checked in by Matthew Whiting, 17 years ago

Summary of changes:

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