source: branches/fitshead-branch/Cubes/outputSpectra.cc @ 1441

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

Four major sets of changes and a couple of minor ones:

  • Changed name of saved recon/resid FITS file, so that it incorporates all reconstruction parameters.
  • Removed MW parameters from header file
  • Added hashed box to be drawn over MW range in spectral plots
  • Fixed bug that meant reon would be done in 1- or 2-d even if recon array has been read in.

Summary:
param.hh -- prototypes for FITS file name calculation functions
param.cc -- FITS file name calculation functions
Cubes/plots.hh -- drawMWRange function
ATrous/ReconSearch.cc -- tests to see if reconExists for 1- and 2-D recon
Cubes/cubes.cc -- work out enclosed flux correctly for flagNegative
Cubes/detectionIO.cc -- added reconDim line to VOTable output
Cubes/outputSpectra.cc -- added code to draw MW range
Cubes/readRecon.cc -- added call to FITS file name function, and removed

MW params and superfluous tests on atrous parameters

Cubes/saveImage.cc -- improved logical flow. added call to FITS file name func

removed MW keywords.

Detection/columns.cc -- added extra column to fluxes if negative.

File size: 8.9 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <sstream>
4#include <string>
5#include <stdio.h>
6#include <cpgplot.h>
7#include <math.h>
8#include <wcs.h>
9#include <Cubes/cubes.hh>
10#include <Cubes/plots.hh>
11#include <Utils/utils.hh>
12
13void getSmallVelRange(Detection &obj, FitsHeader head, float *minvel, float *maxvel);
14void getSmallZRange(Detection &obj, float *minz, float *maxz);
15
16void Cube::outputSpectra()
17{
18  /**
19   *   Cube::outputSpectra()
20   *
21   *    The way to print out the spectra of the detected objects.
22   *    Make use of the SpectralPlot class in plots.h, which sizes everything correctly.
23   *    Main choice is whether to use the peak pixel, in which case the spectrum is just
24   *     that of the peak pixel, or the sum, where the spectrum is summed over all spatial
25   *     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 indicating the
29   *     spatial size.
30   */
31
32  string spectrafile = this->par.getSpectraFile() + "/vcps";
33  Plot::SpectralPlot newplot;
34  newplot.setUpPlot(spectrafile.c_str());
35
36  for(int nobj=0;nobj<this->objectList.size();nobj++){
37    // for each object in the cube:
38    this->plotSpectrum(this->objectList[nobj],newplot);
39
40  }// end of loop over objects.
41
42  cpgclos();
43
44}
45
46void Cube::plotSpectrum(Detection obj, Plot::SpectralPlot &plot)
47{
48  /**
49   *   Cube::plotSpectrum(obj)
50   *
51   *    The way to print out the spectrum of a Detection.
52   *    Make use of the SpectralPlot class in plots.hh, which sizes everything correctly.
53   *    Main choice is whether to use the peak pixel, in which case the spectrum is just
54   *     that of the peak pixel, or the sum, where the spectrum is summed over all spatial
55   *     pixels that are in the object.
56   *    If a reconstruction has been done, that spectrum is plotted in red.
57   *    The limits of the detection are marked in blue.
58   *    A 0th moment map of the detection is also plotted, with a scale bar indicating the
59   *     spatial size.
60   */
61
62  long xdim = this->axisDim[0];
63  long ydim = this->axisDim[1];
64  long zdim = this->axisDim[2];
65  float beam = this->par.getBeamSize();
66
67  obj.calcParams();
68
69  double minMWvel,maxMWvel,xval,yval,zval;
70  xval = double(obj.getXcentre());
71  yval = double(obj.getYcentre());
72  if(this->par.getFlagMW()){
73    zval = double(this->par.getMinMW());
74    minMWvel = this->head.pixToVel(xval,yval,zval);
75    zval = double(this->par.getMaxMW());
76    maxMWvel = this->head.pixToVel(xval,yval,zval);
77  }
78
79  float *specx  = new float[zdim];
80  float *specy  = new float[zdim];
81  for(int i=0;i<zdim;i++) specy[i] = 0.;
82  float *specy2 = new float[zdim];
83  for(int i=0;i<zdim;i++) specy2[i] = 0.;
84
85  for(int i=0;i<zdim;i++) specy[i] = 0.;
86  if(this->par.getFlagATrous()) 
87    for(int i=0;i<zdim;i++) specy2[i] = 0.;
88   
89  if(this->head.isWCS())
90    for(zval=0;zval<zdim;zval++) specx[int(zval)] = this->head.pixToVel(xval,yval,zval);
91  else
92    for(zval=0;zval<zdim;zval++) specx[int(zval)] = zval;
93
94  string fluxLabel = "Flux";
95
96  if(this->par.getSpectralMethod()=="sum"){
97    if(this->head.isWCS()) fluxLabel += " [Jy]";
98    bool *done = new bool[xdim*ydim];
99    for(int i=0;i<xdim*ydim;i++) done[i]=false;
100    int thisSize = obj.getSize();
101    for(int pix=0;pix<thisSize;pix++){
102      int pos = obj.getX(pix) + xdim * obj.getY(pix);
103      if(!done[pos]){
104        done[pos] = true;
105        for(int z=0;z<zdim;z++){
106          if(!(this->isBlank(pos+z*xdim*ydim))){
107            specy[z] += this->array[pos + z*xdim*ydim] / beam;
108            if(this->par.getFlagATrous())
109              specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
110          }
111        }
112      }
113    }
114    delete [] done;
115  }
116  else {// if(par.getSpectralMethod()=="peak"){
117    if(this->head.isWCS()) fluxLabel += " [Jy/beam]";
118    for(int z=0;z<zdim;z++){
119      int pos = obj.getXPeak() + xdim*obj.getYPeak();
120      specy[z] = this->array[pos + z*xdim*ydim];
121      if(this->par.getFlagATrous()) specy2[z] = this->recon[pos + z*xdim*ydim];
122    }
123  }
124   
125  float vmax,vmin;
126  vmax = vmin = specx[0];
127  for(int i=1;i<zdim;i++){
128    if(specx[i]>vmax) vmax=specx[i];
129    if(specx[i]<vmin) vmin=specx[i];
130  }
131  float max,min;
132  int loc=0;
133  if(this->par.getMinMW()>0) max = min = specy[0];
134  else max = min = specx[this->par.getMaxMW()+1];
135  for(int i=0;i<zdim;i++){
136    if(!this->par.isInMW(i)){
137      if(specy[i]>max) max=specy[i];
138      if(specy[i]<min){
139        min=specy[i];
140        loc = i;
141      }
142    }
143  }
144  // widen the flux range slightly so that the top & bottom don't lie on the axes.
145  float width = max - min;
146  max += width * 0.05;
147  min -= width * 0.05;
148
149  // now plot the resulting spectrum
150  string label;
151  if(this->head.isWCS()){
152    label = "Velocity [" + this->head.getSpectralUnits() + "]";
153    plot.gotoHeader(label);
154  }
155  else plot.gotoHeader("Spectral pixel value");
156
157  if(this->head.isWCS()){
158    label = obj.outputLabelWCS();
159    plot.firstHeaderLine(label);
160  }
161  label = obj.outputLabelInfo();
162  plot.secondHeaderLine(label);
163  label = obj.outputLabelPix();
164  plot.thirdHeaderLine(label);
165   
166  plot.gotoMainSpectrum(vmin,vmax,min,max,fluxLabel);
167  cpgline(zdim,specx,specy);
168  if(this->par.getFlagATrous()){
169    cpgsci(2);
170    cpgline(zdim,specx,specy2);   
171    cpgsci(1);
172  }
173  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
174  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
175  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
176
177  /**************************/
178  // ZOOM IN SPECTRALLY ON THE DETECTION.
179
180  float minvel,maxvel;
181  if(this->head.isWCS()) getSmallVelRange(obj,this->head,&minvel,&maxvel);
182  else getSmallZRange(obj,&minvel,&maxvel);
183
184  // Find new max & min flux values
185  swap(max,min);
186  int ct = 0;
187  for(int i=0;i<zdim;i++){
188    if((specx[i]>=minvel)&&(specx[i]<=maxvel)){
189      ct++;
190      if(specy[i]>max) max=specy[i];
191      if(specy[i]<min) min=specy[i];
192    }
193  }
194  // widen the flux range slightly so that the top & bottom don't lie on the axes.
195  width = max - min;
196  max += width * 0.05;
197  min -= width * 0.05;
198
199  plot.gotoZoomSpectrum(minvel,maxvel,min,max);
200  cpgline(zdim,specx,specy);
201  if(this->par.getFlagATrous()){
202    cpgsci(2);
203    cpgline(zdim,specx,specy2);   
204    cpgsci(1);
205  }
206  if(this->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
207  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
208  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
209   
210  /**************************/
211
212  // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
213  plot.gotoMap();
214  this->drawMomentCutout(obj);
215
216  delete [] specx;
217  delete [] specy;
218  delete [] specy2;
219 
220}
221
222
223void getSmallVelRange(Detection &obj, FitsHeader head, float *minvel, float *maxvel)
224{
225  /**
226   * getSmallVelRange(obj,wcs,minvel,maxvel)
227   *  Routine to calculate the velocity range for the zoomed-in region.
228   *  This range should be the maximum of 20 pixels, or 3x the wdith of the detection.
229   *  Need to :
230   *      Calculate pixel width of a 3x-detection-width region.
231   *      If smaller than 20, calculate velocities of central vel +- 10 pixels
232   *      If not, use the 3x-detection-width
233   *  Range returned via "minvel" and "maxvel" parameters.
234   */
235
236  double *pixcrd = new double[3];
237  double *world  = new double[3];
238  float minpix,maxpix;
239  // define new velocity extrema -- make it 3x wider than the width of the detection.
240  *minvel = 0.5*(obj.getVelMin()+obj.getVelMax()) - 1.5*obj.getVelWidth();
241  *maxvel = 0.5*(obj.getVelMin()+obj.getVelMax()) + 1.5*obj.getVelWidth();
242  // Find velocity range in number of pixels:
243  world[0] = obj.getRA();
244  world[1] = obj.getDec();
245  world[2] = head.velToSpec(*minvel);
246  head.wcsToPix(world,pixcrd);
247  minpix = pixcrd[2];
248  world[2] = head.velToSpec(*maxvel);
249  head.wcsToPix(world,pixcrd);
250  maxpix = pixcrd[2];
251  if(maxpix<minpix) swap(maxpix,minpix);
252   
253  if((maxpix - minpix + 1) < 20){
254    pixcrd[0] = double(obj.getXcentre());
255    pixcrd[1] = double(obj.getYcentre());
256    pixcrd[2] = obj.getZcentre() - 10.;
257    head.pixToWCS(pixcrd,world);
258    //    *minvel = setVel_kms(wcs,world[2]);
259    *minvel = head.specToVel(world[2]);
260    pixcrd[2] = obj.getZcentre() + 10.;
261    head.pixToWCS(pixcrd,world);
262//     *maxvel = setVel_kms(wcs,world[2]);
263    *maxvel = head.specToVel(world[2]);
264    if(*maxvel<*minvel) swap(*maxvel,*minvel);
265  }
266  delete [] pixcrd;
267  delete [] world;
268
269}
270
271void getSmallZRange(Detection &obj, float *minz, float *maxz)
272{
273  /**
274   * getSmallZRange(obj,minz,maxz)
275   *  Routine to calculate the pixel range for the zoomed-in spectrum.
276   *  This range should be the maximum of 20 pixels, or 3x the wdith of the detection.
277   *  Need to :
278   *      Calculate pixel width of a 3x-detection-width region.
279   *       If smaller than 20, use central pixel +- 10 pixels
280   *  Range returned via "minz" and "maxz" parameters.
281   */
282
283  *minz = 2.*obj.getZmin() - obj.getZmax();
284  *maxz = 2.*obj.getZmax() - obj.getZmin();
285   
286  if((*maxz - *minz + 1) < 20){
287    *minz = obj.getZcentre() - 10.;
288    *maxz = obj.getZcentre() + 10.;
289  }
290
291}
Note: See TracBrowser for help on using the repository browser.