source: branches/fitshead-branch/Cubes/drawMomentCutout.cc @ 1441

Last change on this file since 1441 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: 6.3 KB
Line 
1#include <iostream>
2#include <sstream>
3#include <cpgplot.h>
4#include <math.h>
5#include <wcs.h>
6#include <Cubes/cubes.hh>
7#include <Utils/utils.hh>
8
9void Cube::drawMomentCutout(Detection &object)
10{
11  /**
12   *  Cube::drawMomentCutout(object)
13   *
14   *   A routine to draw the 0th moment for the given detection
15   *    using the flux given by the pixel array in the Cube.
16   *   The 0th moment is constructed by adding the flux of each
17   *    pixel within the full extent of the object (this may be more
18   *    pixels than were actually detected in the object)
19   *   A tick mark is also drawn to indicate angular scale (but only
20   *    if the WCS for the Cube is valid).
21   */
22
23  float x1,x2,y1,y2;
24  cpgqwin(&x1,&x2,&y1,&y2);
25
26  long size = (object.getXmax()-object.getXmin()+1);
27  if(size<(object.getYmax()-object.getYmin()+1))
28    size = object.getYmax()-object.getYmin()+1;
29  size += 20;
30
31  float blankVal = this->par.getBlankPixVal();
32
33  long xmin = (object.getXmax()+object.getXmin())/2 - size/2 + 1;
34  long xmax = (object.getXmax()+object.getXmin())/2 + size/2;
35  long ymin = (object.getYmax()+object.getYmin())/2 - size/2 + 1;
36  long ymax = (object.getYmax()+object.getYmin())/2 + size/2;
37  long zmin = object.getZmin();
38  long zmax = object.getZmax();
39
40  float *image = new float[size*size];
41  for(int i=0;i<size*size;i++) image[i]=blankVal;
42
43  int imPos,cubePos;
44  float val;
45  for(int z=zmin; z<=zmax; z++){
46    for(int x=xmin; x<=xmax; x++){
47      for(int y=ymin; y<=ymax; y++){
48        imPos = (y-ymin) * size + (x-xmin);
49        cubePos = (z)*this->axisDim[0]*this->axisDim[1]+(y)*this->axisDim[0]+(x);
50        if((x<0)||(x>=this->axisDim[0])||(y<0)||(y>=this->axisDim[1])) // if outside the boundaries
51          image[imPos] = blankVal;
52        else{
53          val = this->array[cubePos];
54          if (!this->par.isBlank(val)) // if pixel's not blank
55            image[imPos] += val;
56        }
57      }
58    }
59  }
60
61  for(int i=0;i<size*size;i++){
62    if(image[i]!=blankVal){ // if there is some signal on this pixel
63      image[i]-=blankVal;   // remove the starting value so we just have the signal
64      image[i] /= float(zmax-zmin+1); // normalise by the velocity width
65    }
66  }
67
68  // now work out the greyscale display limits, excluding blank pixels where necessary.
69  float z1,z2,median,madfm;
70  int ct=0;
71  while(image[ct]==this->par.getBlankPixVal()) ct++;
72  z1 = z2 = image[ct];
73  for(int i=1;i<size*size;i++){
74    if(image[i]!=blankVal){
75      if(image[i]<z1) z1=image[i];
76      if(image[i]>z2) z2=image[i];
77    }
78  }
79
80  float tr[6] = {xmin-1,1.,0.,ymin-1,0.,1.};
81
82  cpgswin(xmin-0.5,xmax-0.5,ymin-0.5,ymax-0.5);
83  cpggray(image, size, size, 1, size, 1, size, z1, z2, tr);
84
85  delete [] image;
86
87  // Draw the borders around the object
88  int ci;
89  cpgqci(&ci);
90  cpgsci(4);
91  cpgsfs(2);
92  if(this->par.drawBorders())
93    object.drawBorders(xmin,ymin);
94  else
95    cpgrect(object.getXmin()-xmin+0.5,object.getXmax()-xmin+1.5,
96            object.getYmin()-ymin+0.5,object.getYmax()-ymin+1.5);
97  /*
98    To get the borders localised correctly, we need to subtract (xmin-1) from the
99    X values. We then subtract 0.5 for the left hand border (to place it on the
100    pixel border), and add 0.5 for the right hand border. Similarly for y.
101  */
102  cpgsci(ci);
103
104  if(this->head.isWCS()){
105    // Now draw a tick mark to indicate size -- 15 arcmin in length
106    this->drawScale(xmin+2.,ymin+2.,object.getZcentre(),0.25);
107  }
108
109  cpgsci(1);
110  cpgswin(x1,x2,y1,y2);
111
112}
113
114void Cube::drawScale(float xstart, float ystart, float channel, float scaleLength)
115{
116  /**
117   *  Cube::drawScale(xstart, ystart, channel, scaleLength)
118   *
119   *   A routine to draw a scale bar on a (pre-existing) PGPlot image.
120   *   It uses an iterative technique to move from the given start position
121   *    (xstart,ystart) along the positive x-direction so that the length is
122   *    within 1% of the requested value scaleLength.
123   *   The parameter "channel" is required for the wcslib calculations, as the
124   *    positions could theoretically change with channel.
125   */
126
127  double *pix1   = new double[3];
128  double *pix2   = new double[3];
129  double *world1 = new double[3];
130  double *world2 = new double[3];
131  pix1[0] = pix2[0] = xstart + this->par.getXOffset();
132  pix1[1] = pix2[1] = ystart + this->par.getYOffset();
133  pix1[2] = pix2[2] = channel;
134  this->head.pixToWCS(pix1,world1);
135
136  double angSep=0.;
137  bool keepGoing=false;
138  float step = 1.;
139  do{
140    if(angSep>scaleLength){
141      pix2[0] -= step;
142      step /= 2.;
143    }
144    pix2[0] += step;
145    this->head.pixToWCS(pix2,world2);
146    angSep = angularSeparation(world1[0],world1[1],world2[0],world2[1]);
147  }while((fabs(angSep-scaleLength)/scaleLength)>0.01); // look for 1% change
148
149  float tickpt1 = pix1[0] - this->par.getXOffset();
150  float tickpt2 = pix2[0] - this->par.getXOffset();
151  float tickpt3 = ystart;
152  int colour;
153  cpgqci(&colour);
154  cpgsci(2);
155  int thick;
156  cpgqlw(&thick);
157  cpgslw(3);
158  cpgerrx(1,&tickpt1,&tickpt2,&tickpt3,2.);
159  cpgslw(thick);
160
161  std::stringstream text;
162  text << scaleLength*60 << "'";
163  float size,xch,ych;
164  cpgqch(&size);
165  cpgsch(0.4);
166  cpgqcs(4,&xch,&ych); // get the character size in world coords
167  cpgptxt((tickpt1+tickpt2)/2., ystart+ych, 0, 0.5, text.str().c_str());
168  cpgsch(size);
169  cpgsci(colour);
170
171  delete [] pix1,pix2;
172  delete [] world1,world2;
173
174
175}
176
177
178void Detection::drawBorders(int xoffset, int yoffset)
179{
180
181  float x1,x2,y1,y2;
182  cpgqwin(&x1,&x2,&y1,&y2);
183  int xsize = int(x2 - x1) + 1;
184  int ysize = int(y2 - y1) + 1;
185
186  bool *isObj = new bool[xsize*ysize];
187  for(int i=0;i<xsize*ysize;i++) isObj[i]=false;
188  for(int i=0;i<this->pix.size();i++)
189    isObj[ (this->pix[i].getY()-yoffset)*xsize + (this->pix[i].getX()-xoffset) ] = true;
190 
191
192  cpgswin(0,xsize-1,0,ysize-1);
193  for(int x=this->xmin; x<=this->xmax; x++){
194    // for each column...
195    for(int y=1;y<ysize;y++){
196      int current = y*xsize + (x-xoffset);
197      int previous = (y-1)*xsize + (x-xoffset);
198      if((isObj[current]&&!isObj[previous])||(!isObj[current]&&isObj[previous])){
199        cpgmove(x-xoffset+0, y+0);
200        cpgdraw(x-xoffset+1, y+0);
201      }
202    }
203  }
204  for(int y=this->ymin; y<=this->ymax; y++){
205    // now for each row...
206    for(int x=1;x<xsize;x++){
207      int current = (y-yoffset)*xsize + x;
208      int previous = (y-yoffset)*xsize + x - 1;
209      if((isObj[current]&&!isObj[previous])||(!isObj[current]&&isObj[previous])){
210        cpgmove(x+0, y-yoffset+0);
211        cpgdraw(x+0, y-yoffset+1);
212      }
213    }
214  }
215  cpgswin(x1,x2,y1,y2);
216 
217  delete [] isObj;
218
219}   
Note: See TracBrowser for help on using the repository browser.