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

Last change on this file since 258 was 258, checked in by Matthew Whiting, 17 years ago

Merging pixel-map-branch revisions 236:257 back into trunk.
The use of the PixelMap? functions is sorted now, so we put everything back into a uniform location.

File size: 9.9 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   *   Uses wcs to convert the three-dimensional pixel position referenced
13   *    by pix to world coordinates, which are placed in the array world[].
14   *   Assumes that pix only has one point with an x,y,and z pixel positions.
15   *   If there are any other axes present (eg. Stokes), these are set to the
16   *    first pixel in that axis.
17   *   Offsets these pixel values by 1 to account for the C arrays being
18   *    indexed to 0.
19   */
20
21  int naxis=wcs->naxis,npts=1,status;
22
23  double *newpix = new double[naxis*npts];
24  // correct from 0-indexed to 1-indexed pixel array
25  for(int i=0;i<naxis;i++) newpix[i] = 1.;
26  newpix[wcs->lng] += pix[0];
27  newpix[wcs->lat] += pix[1];
28  newpix[wcs->spec]+= pix[2];
29
30  int    *stat      = new int[npts];
31  double *imgcrd    = new double[naxis*npts];
32  double *tempworld = new double[naxis*npts];
33  double *phi       = new double[npts];
34  double *theta     = new double[npts];
35  if(status=wcsp2s(wcs, npts, naxis, newpix, imgcrd, phi,
36                   theta, tempworld, stat)>0){
37    std::stringstream errmsg;
38    errmsg << "WCS Error Code = " << status <<": " << wcs_errmsg[status]
39           << "\nstat value is " << stat[0] << std::endl;
40    duchampError("pixToWCSSingle",errmsg.str());
41  }
42
43  //return just the spatial/velocity information
44  world[0] = tempworld[wcs->lng];
45  world[1] = tempworld[wcs->lat];
46  world[2] = tempworld[wcs->spec];
47
48  delete [] stat;
49  delete [] imgcrd;
50  delete [] tempworld;
51  delete [] phi;
52  delete [] theta;
53  delete [] newpix;
54  return status;
55}
56
57int wcsToPixSingle(struct wcsprm *wcs, const double *world, double *pix)
58{
59  /**
60   *   Uses wcs to convert the three-dimensional world coordinate position
61   *    referenced by world to pixel coordinates, which are placed in the
62   *    array pix[].
63   *   Assumes that world only has one point (three values eg RA Dec Velocity)
64   *   Offsets the pixel values by 1 to account for the C arrays being
65   *    indexed to 0.
66   */
67
68  int naxis=wcs->naxis,npts=1,status;
69
70  double *tempworld = new double[naxis*npts];
71  for(int i=0;i<naxis;i++) tempworld[i] = wcs->crval[i];
72  tempworld[wcs->lng]  = world[0];
73  tempworld[wcs->lat]  = world[1];
74  tempworld[wcs->spec] = world[2];
75
76  int    *stat    = new int[npts];
77  double *temppix = new double[naxis*npts];
78  double *imgcrd  = new double[naxis*npts];
79  double *phi     = new double[npts];
80  double *theta   = new double[npts];
81
82  status=wcss2p(wcs, npts, naxis, tempworld, phi, theta, imgcrd, temppix, stat);
83
84  if( status > 0 ){
85    std::stringstream errmsg;
86    errmsg << "WCS Error Code = " <<status<<": " << wcs_errmsg[status]
87           << "\nstat value is " << stat[0] << std::endl;
88    duchampError("wcsToPixSingle",errmsg.str());
89  }
90
91  pix[0] = temppix[wcs->lng] - 1.;
92  pix[1] = temppix[wcs->lat] - 1.;
93  pix[2] = temppix[wcs->spec] - 1.;
94  // correct from 1-indexed to 0-indexed pixel array
95  //  and only return the spatial & frequency information
96
97  delete [] stat;
98  delete [] imgcrd;
99  delete [] temppix;
100  delete [] phi;
101  delete [] theta;
102  delete [] tempworld;
103  return status;
104}
105
106int pixToWCSMulti(struct wcsprm *wcs, const double *pix, double *world, const int npts)
107{
108  /**
109   *   Uses wcs to convert the three-dimensional pixel positions referenced
110   *    by pix to world coordinates, which are placed in the array world[].
111   *   pix is assumed to hold the positions of npts points.
112   *   Offsets these pixel values by 1 to account for the C arrays being
113   *    indexed to 0.
114   */
115
116  int naxis=wcs->naxis,status;
117
118  // correct from 0-indexed to 1-indexed pixel array
119  // Add entries for any other axes that are present, keeping the
120  //   order of pixel positions the same
121  double *newpix = new double[naxis*npts];
122  for(int pt=0;pt<npts;pt++){
123    for(int i=0;i<naxis;i++) newpix[pt*naxis+i] = 1.;
124    newpix[pt*naxis+wcs->lng]  += pix[pt*3+0];
125    newpix[pt*naxis+wcs->lat]  += pix[pt*3+1];
126    newpix[pt*naxis+wcs->spec] += pix[pt*3+2];
127  }
128
129  int    *stat      = new int[npts];
130  double *imgcrd    = new double[naxis*npts];
131  double *tempworld = new double[naxis*npts];
132  double *phi       = new double[npts];
133  double *theta     = new double[npts];
134
135  if(status=wcsp2s(wcs, npts, naxis, newpix, imgcrd,
136                 phi, theta, tempworld, stat)     >0){
137    std::stringstream errmsg;
138    errmsg << "WCS Error Code = " <<status<<": " << wcs_errmsg[status]
139           << "\nstat value is " << stat[0] << std::endl;
140    duchampError("pixToWCSMulti",errmsg.str());
141  }
142  else{
143    //return just the spatial/velocity information, keeping the
144    //  order of the pixel positions the same.
145    for(int pt=0;pt<npts;pt++){
146      world[pt*3+0] = tempworld[pt*naxis + wcs->lng];
147      world[pt*3+1] = tempworld[pt*naxis + wcs->lat];
148      world[pt*3+2] = tempworld[pt*naxis + wcs->spec];
149    }
150   
151  }
152
153  delete [] stat;
154  delete [] imgcrd;
155  delete [] tempworld;
156  delete [] phi;
157  delete [] theta;
158  delete [] newpix;
159  return status;
160}
161
162int wcsToPixMulti(struct wcsprm *wcs, const double *world, double *pix, const int npts)
163{
164  /**
165   *   Uses wcs to convert the three-dimensional world coordinate position
166   *    referenced by world to pixel coordinates, which are placed in the
167   *    array pix[].
168   *   world is assumed to hold the positions of npts points.
169   *   Offsets the pixel values by 1 to account for the C arrays being
170   *    indexed to 0.
171   */
172
173  int naxis=wcs->naxis,status=0;
174  // Test to see if there are other axes present, eg. stokes
175  if(wcs->naxis>naxis) naxis = wcs->naxis;
176
177  // Add entries for any other axes that are present, keeping the
178  //   order of pixel positions the same
179  double *tempworld = new double[naxis*npts];
180  for(int pt=0;pt<npts;pt++){
181    for(int axis=0;axis<naxis;axis++)
182      tempworld[pt*naxis+axis] = wcs->crval[axis];
183    tempworld[pt*naxis + wcs->lng]  = world[pt*3+0];
184    tempworld[pt*naxis + wcs->lat]  = world[pt*3+1];
185    tempworld[pt*naxis + wcs->spec] = world[pt*3+2];
186  }
187
188  int    *stat   = new int[npts];
189  double *temppix = new double[naxis*npts];
190  double *imgcrd = new double[naxis*npts];
191  double *phi    = new double[npts];
192  double *theta  = new double[npts];
193  if(status=wcss2p(wcs, npts, naxis, tempworld,
194                 phi, theta, imgcrd, temppix, stat)>0){
195    std::stringstream errmsg;
196    errmsg << "WCS Error Code = " <<status<<": " <<wcs_errmsg[status]
197           << "\nstat value is " << stat[0] << std::endl;
198    duchampError("wcsToPixMulti",errmsg.str());
199  }
200  else{
201    // correct from 1-indexed to 0-indexed pixel array
202    //  and return just the spatial/velocity information,
203    //  keeping the order of the pixel positions the same.
204    for(int pt=0;pt<npts;pt++){
205      pix[pt*naxis + 0] = temppix[pt*naxis + wcs->lng] - 1.;
206      pix[pt*naxis + 1] = temppix[pt*naxis + wcs->lat] - 1.;
207      pix[pt*naxis + 2] = temppix[pt*naxis + wcs->spec] - 1.;
208    }
209  }
210
211  delete [] stat;
212  delete [] imgcrd;
213  delete [] temppix;
214  delete [] phi;
215  delete [] theta;
216  delete [] tempworld;
217  return status;
218}
219
220double pixelToVelocity(struct wcsprm *wcs, double &x, double &y, double &z,
221                       std::string velUnits)
222{
223  /**
224   *   Uses wcs to convert the three-dimensional pixel position (x,y,z)
225   *   to world coordinates.
226   *   Returns the velocity in the units given by velUnits.
227   */
228
229  int naxis=wcs->naxis,status=0;
230  int    *stat   = new int[1];
231  double *pixcrd = new double[naxis];
232  double *imgcrd = new double[naxis];
233  double *world  = new double[naxis];
234  double *phi    = new double[1];
235  double *theta  = new double[1];
236  // correct from 0-indexed to 1-indexed pixel array by adding 1 to pixel values.
237  for(int i=0;i<naxis;i++) pixcrd[i] = 1.;
238  pixcrd[wcs->lng] += x;
239  pixcrd[wcs->lat] += y;
240  pixcrd[wcs->spec]+= z;
241
242  if(status=wcsp2s(wcs, 1, naxis, pixcrd, imgcrd, phi, theta, world, stat)>0){
243    std::stringstream errmsg;
244    errmsg <<"WCS Error Code = "<<status<<": "<<wcs_errmsg[status]
245           << "\nstat value is "<<stat[0]<<std::endl;
246    duchampError("pixelToVelocity",errmsg.str());
247  }
248
249  double vel = coordToVel(wcs, world[wcs->spec], velUnits);
250
251  delete [] stat;
252  delete [] pixcrd;
253  delete [] imgcrd;
254  delete [] world;
255  delete [] phi;
256  delete [] theta;
257 
258  return vel;
259}
260 
261double coordToVel(struct wcsprm *wcs, const double coord, std::string outputUnits)
262{
263  /**
264   *   Convert the wcs coordinate given by coord to a velocity in km/s.
265   *   Does this by checking the ztype parameter in wcs to see if it is
266   *    FREQ or otherwise, and converts accordingly.
267   */
268
269  static int errflag = 0;
270  double scale, offset, power;
271  int specIndex = wcs->spec;
272  int status = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
273                         &scale, &offset, &power);
274
275  if(status > 0){
276    if(errflag==0){
277      std::stringstream errmsg;
278      errmsg << "WCSUNITS Error Code = " << status << ":"
279             << wcsunits_errmsg[status];
280      if(status == 10) errmsg << "\nTried to get conversion from "
281                              << wcs->cunit[specIndex]
282                              << " to " << outputUnits.c_str();
283      errmsg << "\nUsing coordinate value instead.\n";
284      duchampError("coordToVel", errmsg.str());
285      errflag = 1;
286    }
287    return coord;
288  }
289  else return pow( (coord*scale + offset), power);
290
291}
292
293double velToCoord(struct wcsprm *wcs, const float velocity, std::string outputUnits)
294{
295  /**
296   *   Convert the velocity given to the appropriate world coordinate for wcs.
297   *   Does this by checking the ztype parameter in wcs to see if it is
298   *    FREQ or otherwise, and converts accordingly.
299   */
300
301  double scale, offset, power;
302  int specIndex = wcs->spec;
303  int status = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
304                         &scale, &offset, &power);
305
306  if(status > 0){
307    std::stringstream errmsg;
308    errmsg << "WCSUNITS Error Code = " << status << ":"
309           << wcsunits_errmsg[status] << "\nUsing coordinate value instead.\n";
310    duchampError("velToCoord",errmsg.str());
311    return velocity;
312  }
313  else return (pow(velocity, 1./power) - offset) / scale;
314 
315}
Note: See TracBrowser for help on using the repository browser.