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

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

Changes here mostly aimed at reducing/removing memory leaks. These were one of:

  • Forgetting to delete something allocated with "new". The Cube destructor has improved with the use of bool variables to keep track of when recon & baseline ahave been allocated.
  • Incorrectly using the wcs->flag parameter (eg. wcsIO had it set to -1 *after* calling wcsini)
  • Not closing a fits file once finished with (dataIO)
  • Allocating the wcsprm structs with calloc before calling wcsini, so that wcsvfree can work (it calls "free", so the memory needs to be allocated with calloc or malloc).

The only other change was the following:

  • A new way of doing the Cube::setCubeStats -- rather than calling the functions in getStats.cc, we explicitly do the calculations. This means we can sort the tempArray that has the BLANKS etc removed. This saves a great deal of memory usage on large FITS files (such as Enno's 2Gb one)
  • The old setCubeStats function is still there but called setCubeStatsOld.
File size: 10.5 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,status;
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(status=wcsp2s(wcs, npts, naxis, newpix, imgcrd, phi,
37                   theta, tempworld, stat)>0){
38    std::stringstream errmsg;
39    errmsg << "WCS Error Code = " << status <<": " << wcs_errmsg[status]
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 status;
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,status;
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  status=wcss2p(wcs, npts, naxis, tempworld, phi, theta, imgcrd, temppix, stat);
85
86  if( status > 0 ){
87    std::stringstream errmsg;
88    errmsg << "WCS Error Code = " <<status<<": " << wcs_errmsg[status]
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 status;
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,status;
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(status=wcsp2s(wcs, npts, naxis, newpix, imgcrd,
139                 phi, theta, tempworld, stat)     >0){
140    std::stringstream errmsg;
141    errmsg << "WCS Error Code = " <<status<<": " << wcs_errmsg[status]
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 status;
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,status=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(status=wcss2p(wcs, npts, naxis, tempworld,
198                 phi, theta, imgcrd, temppix, stat)>0){
199    std::stringstream errmsg;
200    errmsg << "WCS Error Code = " <<status<<": " <<wcs_errmsg[status]
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 status;
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,status=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(status=wcsp2s(wcs, 1, naxis, pixcrd, imgcrd, phi, theta, world, stat)>0){
249    std::stringstream errmsg;
250    errmsg <<"WCS Error Code = "<<status<<": "<<wcs_errmsg[status]
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 status = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
280                         &scale, &offset, &power);
281
282  if(status > 0){
283    if(errflag==0){
284      std::stringstream errmsg;
285      errmsg << "WCSUNITS Error Code = " << status << ":"
286             << wcsunits_errmsg[status];
287      if(status == 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 status = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
312                         &scale, &offset, &power);
313
314  if(status > 0){
315    std::stringstream errmsg;
316    errmsg << "WCSUNITS Error Code = " << status << ":"
317           << wcsunits_errmsg[status] << "\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.