source: tags/release-1.0.2/src/Utils/wcsFunctions.cc @ 167

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

Introduced error and warning reporting functions, to normalise the format
of errors and warnings. Definitions of functions go in duchamp.cc.
Changed all code that reports errors/warnings to use these new functions.

Fixed a couple of bugs that affected the way 2D images were dealt with:
ReconSearch? now looks at how many dimensions there are in the data array
before choosing the dimension of the reconstruction, and the minChannels
test was improved for the case of minChannels=0.

Some minor additions made to the Guide as well.

File size: 7.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(wcsprm *wcs, const double *pix, double *world)
10{
11  /**
12   *  pixToWCSSingle(wcsprm *wcs, const double *pix, double *world)
13   *   Uses wcs to convert the three-dimensional pixel position referenced by pix
14   *   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   *   Offsets these pixel values by 1 to account for the C arrays being indexed to 0.
17   */
18
19  int nelem=3,npts=1,flag;
20
21  double *newpix = new double[nelem*npts];
22  for(int i=0;i<nelem*npts;i++) newpix[i] = pix[i] + 1.; 
23  // correct from 0-indexed to 1-indexed pixel array
24
25  int    *stat   = new int[npts];
26  double *imgcrd = new double[nelem*npts];
27  double *phi    = new double[npts];
28  double *theta  = new double[npts];
29  if(flag=wcsp2s(wcs, npts, nelem, newpix, imgcrd, phi, theta, world, stat)>0){
30    std::stringstream errmsg;
31    errmsg << "WCS Error Code = " <<flag<<": " << wcs_errmsg[flag]
32           << "\nstat value is " << stat[0] << std::endl;
33    duchampError("pixToWCSSingle",errmsg.str());
34  }
35  delete [] stat;
36  delete [] imgcrd;
37  delete [] phi;
38  delete [] theta;
39  delete [] newpix;
40  return flag;
41}
42
43int wcsToPixSingle(wcsprm *wcs, const double *world, double *pix)
44{
45  /**
46   *  wcsToPixSingle(wcsprm *wcs, const double *world, double *pix)
47   *   Uses wcs to convert the three-dimensional world coordinate position referenced by world
48   *   to pixel coordinates, which are placed in the array pix[].
49   *   Assumes that world only has one point (three values eg. RA, Dec, Velocity)
50   *   Offsets the pixel values by 1 to account for the C arrays being indexed to 0.
51   */
52
53  int nelem=3,npts=1,flag;
54  int    *stat   = new int[npts];
55  double *imgcrd = new double[nelem*npts];
56  double *phi    = new double[npts];
57  double *theta  = new double[npts];
58  if(flag=wcss2p(wcs, npts, nelem, world, phi, theta, imgcrd, pix, stat)>0){
59    std::stringstream errmsg;
60    errmsg << "WCS Error Code = " <<flag<<": " << wcs_errmsg[flag]
61           << "\nstat value is " << stat[0] << std::endl;
62    duchampError("wcsToPixSingle",errmsg.str());
63  }
64
65  for(int i=0;i<nelem;i++) pix[i] -= 1.;  // correct from 1-indexed to 0-indexed pixel array
66
67  delete [] stat;
68  delete [] imgcrd;
69  delete [] phi;
70  delete [] theta;
71  return flag;
72}
73
74int pixToWCSMulti(wcsprm *wcs, const double *pix, double *world, const int npts)
75{
76  /**
77   *  pixToWCSSingle(wcsprm *wcs, const double *pix, double *world)
78   *   Uses wcs to convert the three-dimensional pixel positions referenced by pix
79   *   to world coordinates, which are placed in the array world[].
80   *   pix is assumed to hold the positions of npts points.
81   *   Offsets these pixel values by 1 to account for the C arrays being indexed to 0.
82   */
83
84  int nelem=3,flag;
85
86  double *newpix = new double[nelem*npts];
87  for(int i=0;i<nelem*npts;i++) newpix[i] = pix[i] + 1.; 
88  // correct from 0-indexed to 1-indexed pixel array
89
90  int    *stat   = new int[npts];
91  double *imgcrd = new double[nelem*npts];
92  double *phi    = new double[npts];
93  double *theta  = new double[npts];
94  if(flag=wcsp2s(wcs, npts, nelem, newpix, imgcrd, phi, theta, world, stat)>0){
95    std::stringstream errmsg;
96    errmsg << "WCS Error Code = " <<flag<<": " << wcs_errmsg[flag]
97           << "\nstat value is " << stat[0] << std::endl;
98    duchampError("pixToWCSMulti",errmsg.str());
99  }
100  delete [] stat;
101  delete [] imgcrd;
102  delete [] phi;
103  delete [] theta;
104  delete [] newpix;
105  return flag;
106}
107
108int wcsToPixMulti(wcsprm *wcs, const double *world, double *pix, const int npts)
109{
110  /**
111   *  wcsToPixSingle(wcsprm *wcs, const double *world, double *pix)
112   *   Uses wcs to convert the three-dimensional world coordinate position referenced by world
113   *   to pixel coordinates, which are placed in the array pix[].
114   *   world is assumed to hold the positions of npts points.
115   *   Offsets the pixel values by 1 to account for the C arrays being indexed to 0.
116   */
117
118  int nelem=3,flag=0;
119  int    *stat   = new int[npts];
120  double *imgcrd = new double[nelem*npts];
121  double *phi    = new double[npts];
122  double *theta  = new double[npts];
123  if(flag=wcss2p(wcs, npts, nelem, world, phi, theta, imgcrd, pix, stat)>0){
124    std::stringstream errmsg;
125    errmsg << "WCS Error Code = " <<flag<<": " <<wcs_errmsg[flag]
126           << "\nstat value is " << stat[0] << std::endl;
127    duchampError("wcsToPixMulti",errmsg.str());
128  }
129
130  for(int i=0;i<nelem;i++) pix[i] -= 1.;  // correct from 1-indexed to 0-indexed pixel array
131
132  delete [] stat;
133  delete [] imgcrd;
134  delete [] phi;
135  delete [] theta;
136  return flag;
137}
138
139double pixelToVelocity(wcsprm *wcs, double &x, double &y, double &z, string velUnits)
140{
141  /**
142   *  pixelToVelocity(wcsprm *wcs, double &x, double &y, double &z, string velUnits)
143   *   Uses wcs to convert the three-dimensional pixel position (x,y,z)
144   *   to world coordinates.
145   *   Returns the velocity in the units given by velUnits.
146   */
147
148  int    *stat   = new int[1];
149  double *pixcrd = new double[3];
150  double *imgcrd = new double[3];
151  double *world  = new double[3];
152  double *phi    = new double[1];
153  double *theta  = new double[1];
154  // correct from 0-indexed to 1-indexed pixel array by adding 1 to pixel values.
155  pixcrd[0] = x + 1;
156  pixcrd[1] = y + 1;
157  pixcrd[2] = z + 1;
158  if(int flag=wcsp2s(wcs, 1, 3, pixcrd, imgcrd, phi, theta, world, stat)>0){
159    std::stringstream errmsg;
160    errmsg <<"WCS Error Code = "<<flag<<": "<<wcs_errmsg[flag]
161           << "\nstat value is "<<stat[0]<<std::endl;
162    duchampError("pixelToVelocity",errmsg.str());
163  }
164
165  double vel = coordToVel(wcs, world[2], velUnits);
166
167  delete [] stat;
168  delete [] pixcrd;
169  delete [] imgcrd;
170  delete [] world;
171  delete [] phi;
172  delete [] theta;
173 
174  return vel;
175}
176 
177double coordToVel(wcsprm *wcs, const double coord, string outputUnits)
178{
179  /**
180   *  coordToVel(wcsprm *wcs, const double coord, string outputUnits)
181   *   Convert the wcs coordinate given by coord to a velocity in km/s.
182   *   Does this by checking the ztype parameter in wcs to see if it is FREQ or otherwise,
183   *   and converts accordingly.
184   */
185
186  static int errflag = 0;
187  double scale, offset, power;
188  int flag = wcsunits( wcs->cunit[2], outputUnits.c_str(), &scale, &offset, &power);
189
190  if(flag>0){
191    if(errflag==0){
192      std::stringstream errmsg;
193      errmsg << "WCSUNITS Error Code = " << flag << ":"
194             << wcsunits_errmsg[flag];
195      if(flag==10) errmsg << "\nTried to get conversion from " << wcs->cunit[2]
196                          << " to " << outputUnits.c_str();
197      errmsg << "\nUsing coordinate value instead.\n";
198      duchampError("coordToVel", errmsg.str());
199      errflag = 1;
200    }
201    return coord;
202  }
203  else return pow( (coord*scale + offset), power);
204
205}
206
207double velToCoord(wcsprm *wcs, const float velocity, string outputUnits)
208{
209  /**
210   *  velToCoord(wcsprm *wcs, const double coord)
211   *   Convert the velocity given to the appropriate world coordinate for wcs.
212   *   Does this by checking the ztype parameter in wcs to see if it is FREQ or otherwise,
213   *   and converts accordingly.
214   */
215
216  double scale, offset, power;
217  int flag = wcsunits( wcs->cunit[2], outputUnits.c_str(), &scale, &offset, &power);
218
219  if(flag>0){
220    std::stringstream errmsg;
221    errmsg << "WCSUNITS Error Code = " << flag << ":"
222           << wcsunits_errmsg[flag] << "\nUsing coordinate value instead.\n";
223    duchampError("velToCoord",errmsg.str());
224    return velocity;
225  }
226  else return (pow(velocity, 1./power) - offset) / scale;
227 
228}
Note: See TracBrowser for help on using the repository browser.