source: tags/release-1.0/src/Cubes/outputSpectra.cc @ 1323

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

Changed source tree structure: added a src/ directory that contains all the
code. Makefile.in and configure.ac changed to match.

File size: 8.9 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->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
173  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
174  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
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((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->head.isWCS()) plot.drawVelRange(obj.getVelMin(),obj.getVelMax());
206  else plot.drawVelRange(obj.getZmin(),obj.getZmax());
207  if(this->par.getFlagMW()) plot.drawMWRange(minMWvel,maxMWvel);
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.