source: tags/release-0.9/Cubes/outputSpectra.cc @ 813

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

Wrote a new class to deal with the plotting of spectra -- SpectralPlot? --
which contains code to get the positioning of boxes etc correct.
This simplified the code in outputSpectra.cc
Have put this class in a namespace Plot, together with ImagePlot? (that was
in plotting.cc) and put them in a header file plots.hh.

File size: 5.3 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 Cube::outputSpectra()
15{
16
17  string spectrafile = this->par.getSpectraFile() + "/vcps";
18  Plot::SpectralPlot newplot;
19  newplot.setUpPlot(spectrafile.c_str());
20
21  long xdim = this->axisDim[0];
22  long ydim = this->axisDim[1];
23  long zdim = this->axisDim[2];
24  int numObjects = this->objectList.size();
25  float beam = this->par.getBeamSize();
26
27  float *specx  = new float[zdim];
28  float *specy  = new float[zdim];
29  for(int i=0;i<zdim;i++) specy[i] = 0.;
30  float *specy2 = new float[zdim];
31  for(int i=0;i<zdim;i++) specy2[i] = 0.;
32
33  for(int nobj=0;nobj<numObjects;nobj++){
34    // for each object in the cube:
35    Detection *obj = new Detection;
36    *obj = this->objectList[nobj];
37    obj->calcParams();
38
39    for(int i=0;i<zdim;i++) specy[i] = 0.;
40    if(this->par.getFlagATrous()) 
41      for(int i=0;i<zdim;i++) specy2[i] = 0.;
42   
43    double x = double(obj->getXcentre());
44    double y = double(obj->getYcentre());
45    for(double z=0;z<zdim;z++) specx[int(z)] = pixelToVelocity(this->wcs,x,y,z);
46
47    bool *done = new bool[xdim*ydim];
48    for(int i=0;i<xdim*ydim;i++) done[i]=false;
49    int thisSize = obj->getSize();
50    for(int pix=0;pix<thisSize;pix++){
51      int pos = obj->getX(pix) + xdim * obj->getY(pix);
52      if(!done[pos]){
53        done[pos] = true;
54        for(int z=0;z<zdim;z++){
55          if(!(this->par.isBlank(this->array[pos+z*xdim*ydim]))){
56            specy[z] += this->array[pos + z*xdim*ydim] / beam;
57            if(this->par.getFlagATrous())
58              specy2[z] += this->recon[pos + z*xdim*ydim] / beam;
59          }
60        }
61      }
62    }
63    delete [] done;
64   
65    float vmax,vmin;
66    vmax = vmin = specx[0];
67    for(int i=1;i<zdim;i++){
68      if(specx[i]>vmax) vmax=specx[i];
69      if(specx[i]<vmin) vmin=specx[i];
70    }
71    float max,min;
72    int loc=0;
73    max = min = specy[0];
74    for(int i=1;i<zdim;i++){
75      if(specy[i]>max) max=specy[i];
76      if(specy[i]<min){
77        min=specy[i];
78        loc = i;
79      }
80    }
81
82    // now plot the resulting spectrum
83    newplot.gotoHeader("Velocity [km s\\u-1\\d]");
84
85    string label = obj->outputLabelWCS();
86    newplot.firstHeaderLine(label);
87    label = obj->outputLabelInfo();
88    newplot.secondHeaderLine(label);
89    label = obj->outputLabelPix();
90    newplot.thirdHeaderLine(label);
91
92    newplot.gotoMainSpectrum(vmin,vmax,min,max,"Flux [Jy]");
93    cpgline(zdim,specx,specy);
94    if(this->par.getFlagATrous()){
95      cpgsci(2);
96      cpgline(zdim,specx,specy2);   
97      cpgsci(1);
98    }
99    newplot.drawVelRange(obj->getVelMin(),obj->getVelMax());
100
101    /**************************/
102    // ZOOM IN SPECTRALLY ON THE DETECTION.
103
104    float minvel,maxvel;
105    getSmallVelRange(*obj,wcs,&minvel,&maxvel);
106
107    // Find new max & min flux values
108    swap(max,min);
109    int ct = 0;
110    for(int i=0;i<zdim;i++){
111      if((specx[i]>=minvel)&&(specx[i]<=maxvel)){
112        ct++;
113        if(specy[i]>max) max=specy[i];
114        if(specy[i]<min) min=specy[i];
115      }
116    }
117    // widen the flux range slightly so that the top & bottom don't lie on the axes.
118    float width = max - min;
119    max += width * 0.05;
120    min -= width * 0.05;
121
122    newplot.gotoZoomSpectrum(minvel,maxvel,min,max);
123    cpgline(zdim,specx,specy);
124    if(this->par.getFlagATrous()){
125      cpgsci(2);
126      cpgline(zdim,specx,specy2);   
127      cpgsci(1);
128    }
129    newplot.drawVelRange(obj->getVelMin(),obj->getVelMax());
130   
131    /**************************/
132
133    // DRAW THE MOMENT MAP OF THE DETECTION -- SUMMED OVER ALL CHANNELS
134    newplot.gotoMap();
135    drawMomentCutout(*this,*obj);
136
137    delete obj;
138
139  }// end of loop over objects.
140
141  delete [] specx;
142  delete [] specy;
143  delete [] specy2;
144 
145}
146
147void getSmallVelRange(Detection &obj, wcsprm *wcs, float *minvel, float *maxvel)
148{
149  // Want the velocity range for the zoomed in region to be maximum of
150  // 16 pixels or 3x width of detection. Need to:
151  //   * Calculate pixel width of a 3x-detection-width region.
152  //   * If smaller than 16, calculate velocities of central vel +- 8pixels
153  //   * If not, use those velocities
154
155  double *pixcrd = new double[3];
156  double *world  = new double[3];
157  float minpix,maxpix;
158  // define new velocity extrema -- make it 3x wider than the width of the detection.
159  *minvel = 0.5*(obj.getVelMin()+obj.getVelMax()) - 1.5*obj.getVelWidth();
160  *maxvel = 0.5*(obj.getVelMin()+obj.getVelMax()) + 1.5*obj.getVelWidth();
161  // Find velocity range in number of pixels:
162  world[0] = obj.getRA();
163  world[1] = obj.getDec();
164  world[2] = velToCoord(wcs,*minvel);
165  wcsToPixSingle(wcs,world,pixcrd);
166  minpix = pixcrd[2];
167  world[2] = velToCoord(wcs,*maxvel);
168  wcsToPixSingle(wcs,world,pixcrd);
169  maxpix = pixcrd[2];
170  if(maxpix<minpix) swap(maxpix,minpix);
171   
172  if((maxpix - minpix + 1) < 16){
173    pixcrd[0] = double(obj.getXcentre());
174    pixcrd[1] = double(obj.getYcentre());
175    pixcrd[2] = floor(obj.getZcentre() - 8.);
176    pixToWCSSingle(wcs,pixcrd,world);
177    *minvel = setVel_kms(wcs,world[2]);
178    pixcrd[2] = ceil(obj.getZcentre() + 8.);
179    pixToWCSSingle(wcs,pixcrd,world);
180    *maxvel = setVel_kms(wcs,world[2]);
181    if(*maxvel<*minvel) swap(*maxvel,*minvel);
182  }
183  delete [] pixcrd;
184  delete [] world;
185
186}
Note: See TracBrowser for help on using the repository browser.