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

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

Some minor fixes to the spectral plots to aid readability and consistency
of presentation.
Some minor edits to the Guide.

File size: 7.8 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, wcsprm *wcs, 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  long xdim = this->axisDim[0];
37  long ydim = this->axisDim[1];
38  long zdim = this->axisDim[2];
39  int numObjects = this->objectList.size();
40  float beam = this->par.getBeamSize();
41
42  float *specx  = new float[zdim];
43  float *specy  = new float[zdim];
44  for(int i=0;i<zdim;i++) specy[i] = 0.;
45  float *specy2 = new float[zdim];
46  for(int i=0;i<zdim;i++) specy2[i] = 0.;
47
48  for(int nobj=0;nobj<numObjects;nobj++){
49    // for each object in the cube:
50    Detection *obj = new Detection;
51    *obj = this->objectList[nobj];
52    obj->calcParams();
53
54    for(int i=0;i<zdim;i++) specy[i] = 0.;
55    if(this->par.getFlagATrous()) 
56      for(int i=0;i<zdim;i++) specy2[i] = 0.;
57   
58    double x = double(obj->getXcentre());
59    double y = double(obj->getYcentre());
60    if(this->flagWCS)
61      for(double z=0;z<zdim;z++) specx[int(z)] = pixelToVelocity(this->wcs,x,y,z);
62    else
63      for(double z=0;z<zdim;z++) specx[int(z)] = z;
64
65    string fluxLabel = "Flux";
66
67    if(par.getSpectralMethod()=="sum"){
68      if(this->flagWCS) fluxLabel += " [Jy]";
69      bool *done = new bool[xdim*ydim];
70      for(int i=0;i<xdim*ydim;i++) done[i]=false;
71      int thisSize = obj->getSize();
72      for(int pix=0;pix<thisSize;pix++){
73        int pos = obj->getX(pix) + xdim * obj->getY(pix);
74        if(!done[pos]){
75          done[pos] = true;
76          for(int z=0;z<zdim;z++){
77            if(!(this->par.isBlank(this->array[pos+z*xdim*ydim]))){
78              specy[z] += this->array[pos + z*xdim*ydim] / beam;
79              if(this->par.getFlagATrous())
80                specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
81            }
82          }
83        }
84      }
85      delete [] done;
86    }
87    else {// if(par.getSpectralMethod()=="peak"){
88      if(this->flagWCS) fluxLabel += " [Jy/beam]";
89      for(int z=0;z<zdim;z++){
90        int pos = obj->getXPeak() + xdim*obj->getYPeak();
91        specy[z] = this->array[pos + z*xdim*ydim];
92        if(this->par.getFlagATrous()) specy2[z] = this->recon[pos + z*xdim*ydim];
93      }
94    }
95   
96    float vmax,vmin;
97    vmax = vmin = specx[0];
98    for(int i=1;i<zdim;i++){
99      if(specx[i]>vmax) vmax=specx[i];
100      if(specx[i]<vmin) vmin=specx[i];
101    }
102    float max,min;
103    int loc=0;
104    max = min = specy[0];
105    for(int i=1;i<zdim;i++){
106      if(specy[i]>max) max=specy[i];
107      if(specy[i]<min){
108        min=specy[i];
109        loc = i;
110      }
111    }
112    // widen the flux range slightly so that the top & bottom don't lie on the axes.
113    float width = max - min;
114    max += width * 0.05;
115    min -= width * 0.05;
116
117    // now plot the resulting spectrum
118    if(this->flagWCS) newplot.gotoHeader("Velocity [km s\\u-1\\d]");
119    else newplot.gotoHeader("Spectral pixel value");
120
121    string label;
122    if(this->flagWCS){
123      label = obj->outputLabelWCS();
124      newplot.firstHeaderLine(label);
125    }
126    label = obj->outputLabelInfo();
127    newplot.secondHeaderLine(label);
128    label = obj->outputLabelPix();
129    newplot.thirdHeaderLine(label);
130   
131    newplot.gotoMainSpectrum(vmin,vmax,min,max,fluxLabel);
132    cpgline(zdim,specx,specy);
133    if(this->par.getFlagATrous()){
134      cpgsci(2);
135      cpgline(zdim,specx,specy2);   
136      cpgsci(1);
137    }
138    if(this->flagWCS) newplot.drawVelRange(obj->getVelMin(),obj->getVelMax());
139    else newplot.drawVelRange(obj->getZmin(),obj->getZmax());
140
141    /**************************/
142    // ZOOM IN SPECTRALLY ON THE DETECTION.
143
144    float minvel,maxvel;
145    if(this->flagWCS) getSmallVelRange(*obj,this->wcs,&minvel,&maxvel);
146    else getSmallZRange(*obj,&minvel,&maxvel);
147
148    // Find new max & min flux values
149    swap(max,min);
150    int ct = 0;
151    for(int i=0;i<zdim;i++){
152      if((specx[i]>=minvel)&&(specx[i]<=maxvel)){
153        ct++;
154        if(specy[i]>max) max=specy[i];
155        if(specy[i]<min) min=specy[i];
156      }
157    }
158    // widen the flux range slightly so that the top & bottom don't lie on the axes.
159    width = max - min;
160    max += width * 0.05;
161    min -= width * 0.05;
162
163    newplot.gotoZoomSpectrum(minvel,maxvel,min,max);
164    cpgline(zdim,specx,specy);
165    if(this->par.getFlagATrous()){
166      cpgsci(2);
167      cpgline(zdim,specx,specy2);   
168      cpgsci(1);
169    }
170    if(this->flagWCS) newplot.drawVelRange(obj->getVelMin(),obj->getVelMax());
171    else newplot.drawVelRange(obj->getZmin(),obj->getZmax());
172   
173    /**************************/
174
175    // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
176    newplot.gotoMap();
177    drawMomentCutout(*this,*obj);
178
179    delete obj;
180
181  }// end of loop over objects.
182
183  delete [] specx;
184  delete [] specy;
185  delete [] specy2;
186 
187}
188
189void getSmallVelRange(Detection &obj, wcsprm *wcs, float *minvel, float *maxvel)
190{
191  /**
192   * getSmallVelRange(obj,wcs,minvel,maxvel)
193   *  Routine to calculate the velocity range for the zoomed-in region.
194   *  This range should be the maximum of 20 pixels, or 3x the wdith of the detection.
195   *  Need to :
196   *      Calculate pixel width of a 3x-detection-width region.
197   *      If smaller than 20, calculate velocities of central vel +- 10 pixels
198   *      If not, use the 3x-detection-width
199   *  Range returned via "minvel" and "maxvel" parameters.
200   */
201
202  double *pixcrd = new double[3];
203  double *world  = new double[3];
204  float minpix,maxpix;
205  // define new velocity extrema -- make it 3x wider than the width of the detection.
206  *minvel = 0.5*(obj.getVelMin()+obj.getVelMax()) - 1.5*obj.getVelWidth();
207  *maxvel = 0.5*(obj.getVelMin()+obj.getVelMax()) + 1.5*obj.getVelWidth();
208  // Find velocity range in number of pixels:
209  world[0] = obj.getRA();
210  world[1] = obj.getDec();
211  world[2] = velToCoord(wcs,*minvel);
212  wcsToPixSingle(wcs,world,pixcrd);
213  minpix = pixcrd[2];
214  world[2] = velToCoord(wcs,*maxvel);
215  wcsToPixSingle(wcs,world,pixcrd);
216  maxpix = pixcrd[2];
217  if(maxpix<minpix) swap(maxpix,minpix);
218   
219  if((maxpix - minpix + 1) < 20){
220    pixcrd[0] = double(obj.getXcentre());
221    pixcrd[1] = double(obj.getYcentre());
222    pixcrd[2] = obj.getZcentre() - 10.;
223    pixToWCSSingle(wcs,pixcrd,world);
224    *minvel = setVel_kms(wcs,world[2]);
225    pixcrd[2] = obj.getZcentre() + 10.;
226    pixToWCSSingle(wcs,pixcrd,world);
227    *maxvel = setVel_kms(wcs,world[2]);
228    if(*maxvel<*minvel) swap(*maxvel,*minvel);
229  }
230  delete [] pixcrd;
231  delete [] world;
232
233}
234
235void getSmallZRange(Detection &obj, float *minz, float *maxz)
236{
237  /**
238   * getSmallZRange(obj,minz,maxz)
239   *  Routine to calculate the pixel range for the zoomed-in spectrum.
240   *  This range should be the maximum of 20 pixels, or 3x the wdith of the detection.
241   *  Need to :
242   *      Calculate pixel width of a 3x-detection-width region.
243   *       If smaller than 20, use central pixel +- 10 pixels
244   *  Range returned via "minz" and "maxz" parameters.
245   */
246
247  *minz = 2.*obj.getZmin() - obj.getZmax();
248  *maxz = 2.*obj.getZmax() - obj.getZmin();
249   
250  if((*maxz - *minz + 1) < 20){
251    *minz = obj.getZcentre() - 10.;
252    *maxz = obj.getZcentre() + 10.;
253  }
254
255}
Note: See TracBrowser for help on using the repository browser.