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

Last change on this file since 187 was 187, checked in by Matthew Whiting, 18 years ago

Large suite of edits, mostly due to testing with valgrind, which clear up bad memory allocations and so on.
Improved the printing of progress bars in some routines by introducing a new ProgressBar? class, with associated functions to do the printing (now much cleaner).

File size: 9.4 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   *   Cube::outputSpectra()
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  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   *   Cube::plotSpectrum(obj)
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   */
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.calcParams();
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  string fluxLabel = "Flux";
102
103  if(this->par.getSpectralMethod()=="sum"){
104    if(this->head.isWCS()) fluxLabel += " [Jy]";
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              specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
117          }
118        }
119      }
120    }
121    delete [] done;
122  }
123  else {// if(par.getSpectralMethod()=="peak"){
124    if(this->head.isWCS()) fluxLabel += " [Jy/beam]";
125    for(int z=0;z<zdim;z++){
126      int pos = obj.getXPeak() + xdim*obj.getYPeak();
127      specy[z] = this->array[pos + z*xdim*ydim];
128      if(this->par.getFlagATrous()) specy2[z] = this->recon[pos + z*xdim*ydim];
129    }
130  }
131   
132  float vmax,vmin,width;
133  vmax = vmin = specx[0];
134  for(int i=1;i<zdim;i++){
135    if(specx[i]>vmax) vmax=specx[i];
136    if(specx[i]<vmin) vmin=specx[i];
137  }
138 
139  float max,min;
140  int loc=0;
141  if(this->par.getMinMW()>0) max = min = specy[0];
142  else max = min = specx[this->par.getMaxMW()+1];
143  for(int i=0;i<zdim;i++){
144    if(!this->par.isInMW(i)){
145      if(specy[i]>max) max=specy[i];
146      if(specy[i]<min){
147        min=specy[i];
148        loc = i;
149      }
150    }
151  }
152  // widen the ranges slightly so that the top & bottom & edges don't
153  // lie on the axes.
154  width = max - min;
155  max += width * 0.05;
156  min -= width * 0.05;
157  width = vmax -vmin;
158  vmax += width * 0.01;
159  vmin -= width * 0.01;
160
161  // now plot the resulting spectrum
162  string label;
163  if(this->head.isWCS()){
164    label = this->head.getSpectralDescription() + " [" +
165      this->head.getSpectralUnits() + "]";
166    plot.gotoHeader(label);
167  }
168  else plot.gotoHeader("Spectral pixel value");
169
170  if(this->head.isWCS()){
171    label = obj.outputLabelWCS();
172    plot.firstHeaderLine(label);
173  }
174  label = obj.outputLabelInfo();
175  plot.secondHeaderLine(label);
176  label = obj.outputLabelPix();
177  plot.thirdHeaderLine(label);
178   
179  plot.gotoMainSpectrum(vmin,vmax,min,max,fluxLabel);
180  cpgline(zdim,specx,specy);
181  if(this->par.getFlagATrous()){
182    cpgsci(RED);
183    cpgline(zdim,specx,specy2);   
184    cpgsci(BLACK);
185  }
186  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
187  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
188  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
189
190  /**************************/
191  // ZOOM IN SPECTRALLY ON THE DETECTION.
192
193  float minvel,maxvel;
194  if(this->head.isWCS()) getSmallVelRange(obj,this->head,&minvel,&maxvel);
195  else getSmallZRange(obj,&minvel,&maxvel);
196
197  // Find new max & min flux values
198  swap(max,min);
199  int ct = 0;
200  for(int i=0;i<zdim;i++){
201    if((!this->par.isInMW(i))&&(specx[i]>=minvel)&&(specx[i]<=maxvel)){
202      ct++;
203      if(specy[i]>max) max=specy[i];
204      if(specy[i]<min) min=specy[i];
205    }
206  }
207  // widen the flux range slightly so that the top & bottom don't lie on the axes.
208  width = max - min;
209  max += width * 0.05;
210  min -= width * 0.05;
211
212  plot.gotoZoomSpectrum(minvel,maxvel,min,max);
213  cpgline(zdim,specx,specy);
214  if(this->par.getFlagATrous()){
215    cpgsci(RED);
216    cpgline(zdim,specx,specy2);   
217    cpgsci(BLACK);
218  }
219  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
220  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
221  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
222   
223  /**************************/
224
225  // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
226  plot.gotoMap();
227  this->drawMomentCutout(obj);
228
229  delete [] specx;
230  delete [] specy;
231  delete [] specy2;
232 
233}
234
235
236void getSmallVelRange(Detection &obj, FitsHeader head,
237                      float *minvel, float *maxvel)
238{
239  /**
240   * getSmallVelRange(obj,wcs,minvel,maxvel)
241   *  Routine to calculate the velocity range for the zoomed-in region.
242   *  This range should be the maximum of 20 pixels, or 3x the wdith of
243   *   the detection.
244   *  Need to :
245   *      Calculate pixel width of a 3x-detection-width region.
246   *      If smaller than 20, calculate velocities of central vel +- 10 pixels
247   *      If not, use the 3x-detection-width
248   *  Range returned via "minvel" and "maxvel" parameters.
249   */
250
251  double *pixcrd = new double[3];
252  double *world  = new double[3];
253  float minpix,maxpix;
254  // define new velocity extrema
255  //    -- make it 3x wider than the width of the detection.
256  *minvel = 0.5*(obj.getVelMin()+obj.getVelMax()) - 1.5*obj.getVelWidth();
257  *maxvel = 0.5*(obj.getVelMin()+obj.getVelMax()) + 1.5*obj.getVelWidth();
258  // Find velocity range in number of pixels:
259  world[0] = obj.getRA();
260  world[1] = obj.getDec();
261  world[2] = head.velToSpec(*minvel);
262  head.wcsToPix(world,pixcrd);
263  minpix = pixcrd[2];
264  world[2] = head.velToSpec(*maxvel);
265  head.wcsToPix(world,pixcrd);
266  maxpix = pixcrd[2];
267  if(maxpix<minpix) swap(maxpix,minpix);
268   
269  if((maxpix - minpix + 1) < 20){
270    pixcrd[0] = double(obj.getXcentre());
271    pixcrd[1] = double(obj.getYcentre());
272    pixcrd[2] = obj.getZcentre() - 10.;
273    head.pixToWCS(pixcrd,world);
274    //    *minvel = setVel_kms(wcs,world[2]);
275    *minvel = head.specToVel(world[2]);
276    pixcrd[2] = obj.getZcentre() + 10.;
277    head.pixToWCS(pixcrd,world);
278    //     *maxvel = setVel_kms(wcs,world[2]);
279    *maxvel = head.specToVel(world[2]);
280    if(*maxvel<*minvel) swap(*maxvel,*minvel);
281  }
282  delete [] pixcrd;
283  delete [] world;
284
285}
286
287void getSmallZRange(Detection &obj, float *minz, float *maxz)
288{
289  /**
290   * getSmallZRange(obj,minz,maxz)
291   *  Routine to calculate the pixel range for the zoomed-in spectrum.
292   *  This range should be the maximum of 20 pixels, or 3x the width
293   *   of the detection.
294   *  Need to :
295   *      Calculate pixel width of a 3x-detection-width region.
296   *       If smaller than 20, use central pixel +- 10 pixels
297   *  Range returned via "minz" and "maxz" parameters.
298   */
299
300  *minz = 2.*obj.getZmin() - obj.getZmax();
301  *maxz = 2.*obj.getZmax() - obj.getZmin();
302   
303  if((*maxz - *minz + 1) < 20){
304    *minz = obj.getZcentre() - 10.;
305    *maxz = obj.getZcentre() + 10.;
306  }
307
308}
Note: See TracBrowser for help on using the repository browser.