source: tags/release-0.9.2/Cubes/drawMomentCutout.cc @ 1327

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

Bug-fixing for drawMomentCutout.cc and plotting.cc.
The scale bar on the moment cutout now works in general case, using an
iterative process to get to the correct length.
RA axes are now done correctly on the full-scale maps.

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