source: tags/release-1.0.2/src/Cubes/drawMomentCutout.cc @ 1455

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

Some bugfixes, and improved image/spectrum extraction routines:
Corrected bug that meant blank pixels weren't being seen by the
drawMomentMap function. Improved the blankpixel testing in that
function, and changed getImage so that the blank pixel info is
always stored (if it is in the fits header).
Added new functions to Image class that can read a spectrum or
channel map given a cube and a channel/pixel number.
Other minor corrections as well:
src/Utils/cpgcumul.c -- changed way _swap is declared (pointers
rather than references, which don't work in C)
src/Cubes/cubes.cc -- new extraction functions
src/Cubes/cubes.hh -- prototypes thereof
src/Cubes/drawMomentCutout.cc -- improved blank pixel handling
src/Cubes/getImage.cc -- made sure blank pixel info is always
read in.
src/param.cc -- tidied up code slightly.
src/Detection/thresholding_functions.cc -- corrected setupFDR
to remove potential for accessing outside allocated memory.

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