source: tags/release-1.0.1/src/Cubes/outputSpectra.cc @ 1077

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

Several bug fixes:

  • The determination of the blank pixel value was not working correctly, due

to confusion between which out of par and head had the correct values.
getCube now reads the header values into the FitsHeader? class, and then these
are copied into the Param class by the new function Param::copyHeaderInfo.

  • The zoom box in the spectral output was scaling the flux scale by all data

points, and this caused problems when the MW channels were in view. These
channels are now omitted in the determination of the flux axis range.

  • The precision in the implied position given by the IAU name has been

increased -- it is now of the format J125345-362412 or G323.124+05.457.

Also added a CHANGES file, as we want to go to v.1.0.1, and updated
the version number in configure.ac.

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