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

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

Large collection of changes. Mostly minor fixes, but major additions are:

  • ability to store flagMW in the recon FITS file
  • slight change to way precision is dealt with in output files
  • improvement to VOTable output
  • generalisation of spectral plotting.

Summary of changes:
duchamp.hh -- added keywords/comments for storing flagMW in FITS files
Utils/wcsFunctions.cc -- minor correction
Cubes/plotting.cc -- minor corrections
Cubes/saveImage.cc -- writing flagMW as header keyword
Cubes/readRecon.cc -- able to read in flagMW. Improved formatting of comments
Cubes/detectionIO.cc -- made VOTable output able to cope with Column

definitions. Added new columns.

Cubes/cubes.hh -- added frontends to wcs-pix functions. Changed prototypes

of some plotting functions.

Cubes/plots.hh -- generalised some functionality of the classes
Cubes/drawMomentCutout.cc -- made a class function
Cubes/outputSpectra.cc -- made a Cube class function that plots a

single spectrum.

param.cc -- improved calling of local variables, and the way units are

dealt with.

docs/example_moment_map.pdf -- new version
docs/cover_image.ps -- new version
docs/example_spectrum.pdf -- new version
docs/cover_image.pdf -- new version
docs/example_moment_map.ps -- new version
docs/example_spectrum.ps -- new version
mainDuchamp.cc -- fixed order of some function calls. Other minor corrections.
ATrous/atrous_2d_reconstruct.cc -- improved speed of loop execution
ATrous/atrous_3d_reconstruct.cc -- improved speed of loop execution
Makefile -- addition of columns.cc
Detection/detection.cc -- minor corrections (removal of commented code)
Detection/outputDetection.cc -- minor change to output style and

precision variable name.

Detection/columns.cc -- use new precision variable
Detection/columns.hh -- new precision variables for position and position

width columns

param.hh -- added prototype for makelower(string) function.

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