source: trunk/src/Utils/wcsFunctions.cc @ 204

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

A large commit, based on improving memory usage, allocation, etc:

  • src/param.hh :
    • Added a delete command for the offsets array in Param. Keep track of size via new sizeOffsets variable.
    • Changed "wcsprm" to "struct wcsprm", for clarity.
    • Put wcsvfree in the FitsHeader? destructor so that memory is deallocated correctly.
  • src/param.cc :
    • Improved the FitsHeader? constructor functions, so that memory for the wcsprm structures is allocated appropriately.
    • Other wcsprm-related tweaks.
    • Included code for sizeOffsets -- the size of the offsets array in Param, so that we can properly deallocate its memory in the destructor function.
  • src/FitsIO/subsection.cc : Changed "wcsprm" to "struct wcsprm", for clarity, and added a sizeOffsets to track the memory allocation for offsets.
  • src/FitsIO/dataIO.cc : renamed the local variable array to pixarray so that there is no confusion. Added delete[] commands for local arrays.
  • src/FitsIO/wcsIO.cc : Improved the struct wcsprm memory allocation. Now using a local wcs variable so that we don't get confusion with the FitsHeader? one.
  • src/Utils/wcsFunctions.cc : changed "wcsprm" to "struct wcsprm", for clarity.
  • src/Cubes/CubicSearch.cc : removed two allocation calls (to new) that were not needed, as well as unused commented-out code.
  • src/Cubes/plotting.cc :
    • Corrected the way the detection map is worked out and the scale bar range calculated.
    • Changed "wcsprm" to "struct wcsprm", for clarity.
  • src/duchamp.hh : better implementation of the rewind() and remove() functions for ProgressBar?
  • src/Utils/getStats.cc : minor diffs
  • src/Utils/utils.hh : changed prototypes
  • src/Cubes/cubes.cc : Changed the way the setCubeStats() function works, so that stats aren't needlessly calculated if the threshold has already been specified.
  • src/Cubes/cubes.hh : minor presentation changes
  • src/Cubes/drawMomentCutout.cc : Tried to improve the scale-bar drawing function, to cope with very high angular resolution data. Not quite working properly yet.
  • src/Cubes/outputSpectra.cc : Corrected the flux labels so that the appropriate units are used, and not just Jy or Jy/beam.
File size: 10.4 KB
Line 
1#include <iostream>
2#include <sstream>
3#include <math.h>
4#include <wcs.h>
5#include <wcsunits.h>
6#include <duchamp.hh>
7#include <Utils/utils.hh>
8
9int pixToWCSSingle(struct wcsprm *wcs, const double *pix, double *world)
10{
11  /**
12   *  pixToWCSSingle(struct wcsprm *wcs, const double *pix, double *world)
13   *   Uses wcs to convert the three-dimensional pixel position referenced
14   *    by pix to world coordinates, which are placed in the array world[].
15   *   Assumes that pix only has one point with an x,y,and z pixel positions.
16   *   If there are any other axes present (eg. Stokes), these are set to the
17   *    first pixel in that axis.
18   *   Offsets these pixel values by 1 to account for the C arrays being
19   *    indexed to 0.
20   */
21
22  int naxis=wcs->naxis,npts=1,flag;
23
24  double *newpix = new double[naxis*npts];
25  // correct from 0-indexed to 1-indexed pixel array
26  for(int i=0;i<naxis;i++) newpix[i] = 1.;
27  newpix[wcs->lng] += pix[0];
28  newpix[wcs->lat] += pix[1];
29  newpix[wcs->spec]+= pix[2];
30
31  int    *stat      = new int[npts];
32  double *imgcrd    = new double[naxis*npts];
33  double *tempworld = new double[naxis*npts];
34  double *phi       = new double[npts];
35  double *theta     = new double[npts];
36  if(flag=wcsp2s(wcs, npts, naxis, newpix, imgcrd, phi,
37                 theta, tempworld, stat)>0){
38    std::stringstream errmsg;
39    errmsg << "WCS Error Code = " <<flag<<": " << wcs_errmsg[flag]
40           << "\nstat value is " << stat[0] << std::endl;
41    duchampError("pixToWCSSingle",errmsg.str());
42  }
43
44  //return just the spatial/velocity information
45  world[0] = tempworld[wcs->lng];
46  world[1] = tempworld[wcs->lat];
47  world[2] = tempworld[wcs->spec];
48
49  delete [] stat;
50  delete [] imgcrd;
51  delete [] tempworld;
52  delete [] phi;
53  delete [] theta;
54  delete [] newpix;
55  return flag;
56}
57
58int wcsToPixSingle(struct wcsprm *wcs, const double *world, double *pix)
59{
60  /**
61   *  wcsToPixSingle(struct wcsprm *wcs, const double *world, double *pix)
62   *   Uses wcs to convert the three-dimensional world coordinate position
63   *    referenced by world to pixel coordinates, which are placed in the
64   *    array pix[].
65   *   Assumes that world only has one point (three values eg RA Dec Velocity)
66   *   Offsets the pixel values by 1 to account for the C arrays being
67   *    indexed to 0.
68   */
69
70  int naxis=wcs->naxis,npts=1,flag;
71
72  double *tempworld = new double[naxis*npts];
73  for(int i=0;i<naxis;i++) tempworld[i] = wcs->crval[i];
74  tempworld[wcs->lng]  = world[0];
75  tempworld[wcs->lat]  = world[1];
76  tempworld[wcs->spec] = world[2];
77
78  int    *stat    = new int[npts];
79  double *temppix = new double[naxis*npts];
80  double *imgcrd  = new double[naxis*npts];
81  double *phi     = new double[npts];
82  double *theta   = new double[npts];
83
84  flag=wcss2p(wcs, npts, naxis, tempworld, phi, theta, imgcrd, temppix, stat);
85
86  if( flag > 0 ){
87    std::stringstream errmsg;
88    errmsg << "WCS Error Code = " <<flag<<": " << wcs_errmsg[flag]
89           << "\nstat value is " << stat[0] << std::endl;
90    duchampError("wcsToPixSingle",errmsg.str());
91  }
92
93  pix[0] = temppix[wcs->lng] - 1.;
94  pix[1] = temppix[wcs->lat] - 1.;
95  pix[2] = temppix[wcs->spec] - 1.;
96  // correct from 1-indexed to 0-indexed pixel array
97  //  and only return the spatial & frequency information
98
99  delete [] stat;
100  delete [] imgcrd;
101  delete [] temppix;
102  delete [] phi;
103  delete [] theta;
104  delete [] tempworld;
105  return flag;
106}
107
108int pixToWCSMulti(struct wcsprm *wcs, const double *pix, double *world, const int npts)
109{
110  /**
111   *  pixToWCSSingle(struct wcsprm *wcs, const double *pix, double *world)
112   *   Uses wcs to convert the three-dimensional pixel positions referenced
113   *    by pix to world coordinates, which are placed in the array world[].
114   *   pix is assumed to hold the positions of npts points.
115   *   Offsets these pixel values by 1 to account for the C arrays being
116   *    indexed to 0.
117   */
118
119  int naxis=wcs->naxis,flag;
120
121  // correct from 0-indexed to 1-indexed pixel array
122  // Add entries for any other axes that are present, keeping the
123  //   order of pixel positions the same
124  double *newpix = new double[naxis*npts];
125  for(int pt=0;pt<npts;pt++){
126    for(int i=0;i<naxis;i++) newpix[pt*naxis+i] = 1.;
127    newpix[pt*naxis+wcs->lng]  += pix[pt*3+0];
128    newpix[pt*naxis+wcs->lat]  += pix[pt*3+1];
129    newpix[pt*naxis+wcs->spec] += pix[pt*3+2];
130  }
131
132  int    *stat      = new int[npts];
133  double *imgcrd    = new double[naxis*npts];
134  double *tempworld = new double[naxis*npts];
135  double *phi       = new double[npts];
136  double *theta     = new double[npts];
137
138  if(flag=wcsp2s(wcs, npts, naxis, newpix, imgcrd,
139                 phi, theta, tempworld, stat)     >0){
140    std::stringstream errmsg;
141    errmsg << "WCS Error Code = " <<flag<<": " << wcs_errmsg[flag]
142           << "\nstat value is " << stat[0] << std::endl;
143    duchampError("pixToWCSMulti",errmsg.str());
144  }
145  else{
146    //return just the spatial/velocity information, keeping the
147    //  order of the pixel positions the same.
148    for(int pt=0;pt<npts;pt++){
149      world[pt*3+0] = tempworld[pt*naxis + wcs->lng];
150      world[pt*3+1] = tempworld[pt*naxis + wcs->lat];
151      world[pt*3+2] = tempworld[pt*naxis + wcs->spec];
152    }
153   
154  }
155
156  delete [] stat;
157  delete [] imgcrd;
158  delete [] tempworld;
159  delete [] phi;
160  delete [] theta;
161  delete [] newpix;
162  return flag;
163}
164
165int wcsToPixMulti(struct wcsprm *wcs, const double *world, double *pix, const int npts)
166{
167  /**
168   *  wcsToPixSingle(struct wcsprm *wcs, const double *world, double *pix)
169   *   Uses wcs to convert the three-dimensional world coordinate position
170   *    referenced by world to pixel coordinates, which are placed in the
171   *    array pix[].
172   *   world is assumed to hold the positions of npts points.
173   *   Offsets the pixel values by 1 to account for the C arrays being
174   *    indexed to 0.
175   */
176
177  int naxis=wcs->naxis,flag=0;
178  // Test to see if there are other axes present, eg. stokes
179  if(wcs->naxis>naxis) naxis = wcs->naxis;
180
181  // Add entries for any other axes that are present, keeping the
182  //   order of pixel positions the same
183  double *tempworld = new double[naxis*npts];
184  for(int pt=0;pt<npts;pt++){
185    for(int axis=0;axis<naxis;axis++)
186      tempworld[pt*naxis+axis] = wcs->crval[axis];
187    tempworld[pt*naxis + wcs->lng]  = world[pt*3+0];
188    tempworld[pt*naxis + wcs->lat]  = world[pt*3+1];
189    tempworld[pt*naxis + wcs->spec] = world[pt*3+2];
190  }
191
192  int    *stat   = new int[npts];
193  double *temppix = new double[naxis*npts];
194  double *imgcrd = new double[naxis*npts];
195  double *phi    = new double[npts];
196  double *theta  = new double[npts];
197  if(flag=wcss2p(wcs, npts, naxis, tempworld,
198                 phi, theta, imgcrd, temppix, stat)>0){
199    std::stringstream errmsg;
200    errmsg << "WCS Error Code = " <<flag<<": " <<wcs_errmsg[flag]
201           << "\nstat value is " << stat[0] << std::endl;
202    duchampError("wcsToPixMulti",errmsg.str());
203  }
204  else{
205    // correct from 1-indexed to 0-indexed pixel array
206    //  and return just the spatial/velocity information,
207    //  keeping the order of the pixel positions the same.
208    for(int pt=0;pt<npts;pt++){
209      pix[pt*naxis + 0] = temppix[pt*naxis + wcs->lng] - 1.;
210      pix[pt*naxis + 1] = temppix[pt*naxis + wcs->lat] - 1.;
211      pix[pt*naxis + 2] = temppix[pt*naxis + wcs->spec] - 1.;
212    }
213  }
214
215  delete [] stat;
216  delete [] imgcrd;
217  delete [] temppix;
218  delete [] phi;
219  delete [] theta;
220  delete [] tempworld;
221  return flag;
222}
223
224double pixelToVelocity(struct wcsprm *wcs, double &x, double &y, double &z,
225                       string velUnits)
226{
227  /**
228   *  pixelToVelocity(struct wcsprm *wcs, double &x, double &y, double &z,
229   *                  string velUnits)
230   *   Uses wcs to convert the three-dimensional pixel position (x,y,z)
231   *   to world coordinates.
232   *   Returns the velocity in the units given by velUnits.
233   */
234
235  int naxis=wcs->naxis,flag=0;
236  int    *stat   = new int[1];
237  double *pixcrd = new double[naxis];
238  double *imgcrd = new double[naxis];
239  double *world  = new double[naxis];
240  double *phi    = new double[1];
241  double *theta  = new double[1];
242  // correct from 0-indexed to 1-indexed pixel array by adding 1 to pixel values.
243  for(int i=0;i<naxis;i++) pixcrd[i] = 1.;
244  pixcrd[wcs->lng] += x;
245  pixcrd[wcs->lat] += y;
246  pixcrd[wcs->spec]+= z;
247
248  if(flag=wcsp2s(wcs, 1, naxis, pixcrd, imgcrd, phi, theta, world, stat)>0){
249    std::stringstream errmsg;
250    errmsg <<"WCS Error Code = "<<flag<<": "<<wcs_errmsg[flag]
251           << "\nstat value is "<<stat[0]<<std::endl;
252    duchampError("pixelToVelocity",errmsg.str());
253  }
254
255  double vel = coordToVel(wcs, world[wcs->spec], velUnits);
256
257  delete [] stat;
258  delete [] pixcrd;
259  delete [] imgcrd;
260  delete [] world;
261  delete [] phi;
262  delete [] theta;
263 
264  return vel;
265}
266 
267double coordToVel(struct wcsprm *wcs, const double coord, string outputUnits)
268{
269  /**
270   *  coordToVel(struct wcsprm *wcs, const double coord, string outputUnits)
271   *   Convert the wcs coordinate given by coord to a velocity in km/s.
272   *   Does this by checking the ztype parameter in wcs to see if it is
273   *    FREQ or otherwise, and converts accordingly.
274   */
275
276  static int errflag = 0;
277  double scale, offset, power;
278  int specIndex = wcs->spec;
279  int flag = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
280                       &scale, &offset, &power);
281
282  if(flag>0){
283    if(errflag==0){
284      std::stringstream errmsg;
285      errmsg << "WCSUNITS Error Code = " << flag << ":"
286             << wcsunits_errmsg[flag];
287      if(flag==10) errmsg << "\nTried to get conversion from "
288                          << wcs->cunit[specIndex]
289                          << " to " << outputUnits.c_str();
290      errmsg << "\nUsing coordinate value instead.\n";
291      duchampError("coordToVel", errmsg.str());
292      errflag = 1;
293    }
294    return coord;
295  }
296  else return pow( (coord*scale + offset), power);
297
298}
299
300double velToCoord(struct wcsprm *wcs, const float velocity, string outputUnits)
301{
302  /**
303   *  velToCoord(struct wcsprm *wcs, const double coord)
304   *   Convert the velocity given to the appropriate world coordinate for wcs.
305   *   Does this by checking the ztype parameter in wcs to see if it is
306   *    FREQ or otherwise, and converts accordingly.
307   */
308
309  double scale, offset, power;
310  int specIndex = wcs->spec;
311  int flag = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
312                       &scale, &offset, &power);
313
314  if(flag>0){
315    std::stringstream errmsg;
316    errmsg << "WCSUNITS Error Code = " << flag << ":"
317           << wcsunits_errmsg[flag] << "\nUsing coordinate value instead.\n";
318    duchampError("velToCoord",errmsg.str());
319    return velocity;
320  }
321  else return (pow(velocity, 1./power) - offset) / scale;
322 
323}
Note: See TracBrowser for help on using the repository browser.