source: tags/release-1.0.5/src/Utils/wcsFunctions.cc @ 1455

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

Changed the way the FITS file is read in, so that it can deal with
naxis>4 files, where the order of the dimensions is not necessarily
lng,lat,spec,...

Summary of changes:

*Cubes/getImage.cc:

*Removed most of the code that goes in new functions.
*Changed order of tasks, so that the WCS is derived first, then the data array, and then the remaining header information.
*Also reports both the FITS dimensions and the data array dimensions.

*FitsIO/headerIO.cc:

*Moved defineWCS to wcsIO.cc.
*Made array declarations more robust (use CFITSIO constants for lengths).
*Changed type of BLANK keyword to TINT.

*FitsIO/dataIO.cc:

*New function, designed to read in data from FITS file.
*Reads in subset of just the spatial and spectral axes.
*Also takes care of setting blank pixels to appropriate value.

*FitsIO/wcsIO.cc:

*New file, contains the function FitsHeader::defineWCS

  • Utils/wcsFunctions.cc:

*Generalised the wcs functions, so that they make no

assumptions about the location of the spatial and spectral axes.

*Cubes/cubes.cc:

*Improved Cube::initialiseCube so that it gets the dimensions correct.
*Enabled Cube::getopts to deal with non-existant param file.
*Improved error reporting in saveArray functions.

*Cubes/cubes.hh:

*Changed prototypes for readParam. Added one for getFITSdata

*Cubes/ReadAndSearch?.cc :

*Minor comment added.

*param.cc:

*Generalised way fixUnits works, to cope with new axis concept.
*Made readParams return int, so it can indicate whether reading failed.

*ATrous/ReconSearch.cc:

*Improved way the goodness of the pixels and channels was determined.

*src/param.hh

*New prototype for Param::readParams

*Guide:

*Changed text about dimensionality of FITS files.
*Changed location of images.
*Minor changes to improve readability.

File size: 10.3 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
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(wcsprm *wcs, const double *world, double *pix)
59{
60  /**
61   *  wcsToPixSingle(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(wcsprm *wcs, const double *pix, double *world, const int npts)
109{
110  /**
111   *  pixToWCSSingle(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(wcsprm *wcs, const double *world, double *pix, const int npts)
166{
167  /**
168   *  wcsToPixSingle(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(wcsprm *wcs, double &x, double &y, double &z,
225                       string velUnits)
226{
227  /**
228   *  pixelToVelocity(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(wcsprm *wcs, const double coord, string outputUnits)
268{
269  /**
270   *  coordToVel(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(wcsprm *wcs, const float velocity, string outputUnits)
301{
302  /**
303   *  velToCoord(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.