source: tags/release-1.0.7/src/Cubes/outputSpectra.cc

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

A large commit, based on improving memory usage, allocation, etc:

  • src/param.hh :
    • Added a delete command for the offsets array in Param. Keep track of size via new sizeOffsets variable.
    • Changed "wcsprm" to "struct wcsprm", for clarity.
    • Put wcsvfree in the FitsHeader? destructor so that memory is deallocated correctly.
  • src/param.cc :
    • Improved the FitsHeader? constructor functions, so that memory for the wcsprm structures is allocated appropriately.
    • Other wcsprm-related tweaks.
    • Included code for sizeOffsets -- the size of the offsets array in Param, so that we can properly deallocate its memory in the destructor function.
  • src/FitsIO/subsection.cc : Changed "wcsprm" to "struct wcsprm", for clarity, and added a sizeOffsets to track the memory allocation for offsets.
  • src/FitsIO/dataIO.cc : renamed the local variable array to pixarray so that there is no confusion. Added delete[] commands for local arrays.
  • src/FitsIO/wcsIO.cc : Improved the struct wcsprm memory allocation. Now using a local wcs variable so that we don't get confusion with the FitsHeader? one.
  • src/Utils/wcsFunctions.cc : changed "wcsprm" to "struct wcsprm", for clarity.
  • src/Cubes/CubicSearch.cc : removed two allocation calls (to new) that were not needed, as well as unused commented-out code.
  • src/Cubes/plotting.cc :
    • Corrected the way the detection map is worked out and the scale bar range calculated.
    • Changed "wcsprm" to "struct wcsprm", for clarity.
  • src/duchamp.hh : better implementation of the rewind() and remove() functions for ProgressBar?
  • src/Utils/getStats.cc : minor diffs
  • src/Utils/utils.hh : changed prototypes
  • src/Cubes/cubes.cc : Changed the way the setCubeStats() function works, so that stats aren't needlessly calculated if the threshold has already been specified.
  • src/Cubes/cubes.hh : minor presentation changes
  • src/Cubes/drawMomentCutout.cc : Tried to improve the scale-bar drawing function, to cope with very high angular resolution data. Not quite working properly yet.
  • src/Cubes/outputSpectra.cc : Corrected the flux labels so that the appropriate units are used, and not just Jy or Jy/beam.
File size: 9.6 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    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    int thisSize = obj.getSize();
110    for(int pix=0;pix<thisSize;pix++){
111      int pos = obj.getX(pix) + xdim * obj.getY(pix);
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  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   * getSmallVelRange(obj,wcs,minvel,maxvel)
248   *  Routine to calculate the velocity range for the zoomed-in region.
249   *  This range should be the maximum of 20 pixels, or 3x the wdith of
250   *   the detection.
251   *  Need to :
252   *      Calculate pixel width of a 3x-detection-width region.
253   *      If smaller than 20, calculate velocities of central vel +- 10 pixels
254   *      If not, use the 3x-detection-width
255   *  Range returned via "minvel" and "maxvel" parameters.
256   */
257
258  double *pixcrd = new double[3];
259  double *world  = new double[3];
260  float minpix,maxpix;
261  // define new velocity extrema
262  //    -- make it 3x wider than the width of the detection.
263  *minvel = 0.5*(obj.getVelMin()+obj.getVelMax()) - 1.5*obj.getVelWidth();
264  *maxvel = 0.5*(obj.getVelMin()+obj.getVelMax()) + 1.5*obj.getVelWidth();
265  // Find velocity range in number of pixels:
266  world[0] = obj.getRA();
267  world[1] = obj.getDec();
268  world[2] = head.velToSpec(*minvel);
269  head.wcsToPix(world,pixcrd);
270  minpix = pixcrd[2];
271  world[2] = head.velToSpec(*maxvel);
272  head.wcsToPix(world,pixcrd);
273  maxpix = pixcrd[2];
274  if(maxpix<minpix) swap(maxpix,minpix);
275   
276  if((maxpix - minpix + 1) < 20){
277    pixcrd[0] = double(obj.getXcentre());
278    pixcrd[1] = double(obj.getYcentre());
279    pixcrd[2] = obj.getZcentre() - 10.;
280    head.pixToWCS(pixcrd,world);
281    //    *minvel = setVel_kms(wcs,world[2]);
282    *minvel = head.specToVel(world[2]);
283    pixcrd[2] = obj.getZcentre() + 10.;
284    head.pixToWCS(pixcrd,world);
285    //     *maxvel = setVel_kms(wcs,world[2]);
286    *maxvel = head.specToVel(world[2]);
287    if(*maxvel<*minvel) swap(*maxvel,*minvel);
288  }
289  delete [] pixcrd;
290  delete [] world;
291
292}
293
294void getSmallZRange(Detection &obj, float *minz, float *maxz)
295{
296  /**
297   * getSmallZRange(obj,minz,maxz)
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   */
306
307  *minz = 2.*obj.getZmin() - obj.getZmax();
308  *maxz = 2.*obj.getZmax() - obj.getZmin();
309   
310  if((*maxz - *minz + 1) < 20){
311    *minz = obj.getZcentre() - 10.;
312    *maxz = obj.getZcentre() + 10.;
313  }
314
315}
Note: See TracBrowser for help on using the repository browser.