source: tags/release-1.1.9/src/Utils/wcsFunctions.cc @ 1441

Last change on this file since 1441 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 13.9 KB
Line 
1// -----------------------------------------------------------------------
2// wcsFunctions.cc: Functions to convert between pixel and world
3//                  coordinates -- user-friendly front ends to the
4//                  WCSLIB functions.
5// -----------------------------------------------------------------------
6// Copyright (C) 2006, Matthew Whiting, ATNF
7//
8// This program is free software; you can redistribute it and/or modify it
9// under the terms of the GNU General Public License as published by the
10// Free Software Foundation; either version 2 of the License, or (at your
11// option) any later version.
12//
13// Duchamp is distributed in the hope that it will be useful, but WITHOUT
14// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16// for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with Duchamp; if not, write to the Free Software Foundation,
20// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
21//
22// Correspondence concerning Duchamp may be directed to:
23//    Internet email: Matthew.Whiting [at] atnf.csiro.au
24//    Postal address: Dr. Matthew Whiting
25//                    Australia Telescope National Facility, CSIRO
26//                    PO Box 76
27//                    Epping NSW 1710
28//                    AUSTRALIA
29// -----------------------------------------------------------------------
30#include <iostream>
31#include <sstream>
32#include <math.h>
33#include <wcslib/wcs.h>
34#include <wcslib/wcsunits.h>
35#include <duchamp/duchamp.hh>
36#include <duchamp/Utils/utils.hh>
37
38int pixToWCSSingle(struct wcsprm *wcs, const double *pix, double *world)
39{
40  ///  @details
41  ///   Uses wcs to convert the three-dimensional pixel position referenced
42  ///    by pix to world coordinates, which are placed in the array world[].
43  ///   Assumes that pix only has one point with an x,y,and z pixel positions.
44  ///   If there are any other axes present (eg. Stokes), these are set to the
45  ///    first pixel in that axis.
46  ///   Offsets these pixel values by 1 to account for the C arrays being
47  ///    indexed to 0.
48  ///
49  /// \param wcs The wcsprm struct containing the WCS information.
50  /// \param pix The array of pixel coordinates.
51  /// \param world The returned array of world coordinates.
52
53  int naxis=wcs->naxis,npts=1,status;
54  int specAxis = wcs->spec;
55  if(specAxis<0) specAxis=2;
56  if(specAxis>=naxis) specAxis = naxis-1;
57
58  double *newpix = new double[naxis*npts];
59  // correct from 0-indexed to 1-indexed pixel array
60  for(int i=0;i<naxis;i++) newpix[i] = 1.;
61  newpix[wcs->lng] += pix[0];
62  newpix[wcs->lat] += pix[1];
63  newpix[specAxis]+= pix[2];
64
65  int    *stat      = new int[npts];
66  double *imgcrd    = new double[naxis*npts];
67  double *tempworld = new double[naxis*npts];
68  double *phi       = new double[npts];
69  double *theta     = new double[npts];
70  status=wcsp2s(wcs, npts, naxis, newpix, imgcrd,
71                phi, theta, tempworld, stat);
72  if(status>0){
73    std::stringstream errmsg;
74    errmsg << "WCS Error Code = " << status <<": " << wcs_errmsg[status]
75           << "\nstat value is " << stat[0] << std::endl;
76    duchamp::duchampError("pixToWCSSingle",errmsg.str());
77  }
78
79  //return just the spatial/velocity information
80  world[0] = tempworld[wcs->lng];
81  world[1] = tempworld[wcs->lat];
82  world[2] = tempworld[specAxis];
83
84  delete [] stat;
85  delete [] imgcrd;
86  delete [] tempworld;
87  delete [] phi;
88  delete [] theta;
89  delete [] newpix;
90  return status;
91}
92
93int wcsToPixSingle(struct wcsprm *wcs, const double *world, double *pix)
94{
95  ///  @details
96  ///   Uses wcs to convert the three-dimensional world coordinate position
97  ///    referenced by world to pixel coordinates, which are placed in the
98  ///    array pix[].
99  ///   Assumes that world only has one point (three values eg RA Dec Velocity)
100  ///   Offsets the pixel values by 1 to account for the C arrays being
101  ///    indexed to 0.
102  ///
103  /// \param wcs The wcsprm struct containing the WCS information.
104  /// \param world The array of world coordinates.
105  /// \param pix The returned array of pixel coordinates.
106
107  int naxis=wcs->naxis,npts=1,status;
108  int specAxis = wcs->spec;
109  if(specAxis<0) specAxis=2;
110  if(specAxis>=naxis) specAxis = naxis-1;
111
112  double *tempworld = new double[naxis*npts];
113  for(int i=0;i<naxis;i++) tempworld[i] = wcs->crval[i];
114  tempworld[wcs->lng]  = world[0];
115  tempworld[wcs->lat]  = world[1];
116  tempworld[specAxis] = world[2];
117
118  int    *stat    = new int[npts];
119  double *temppix = new double[naxis*npts];
120  double *imgcrd  = new double[naxis*npts];
121  double *phi     = new double[npts];
122  double *theta   = new double[npts];
123
124  status=wcss2p(wcs, npts, naxis, tempworld,
125                phi, theta, imgcrd, temppix, stat);
126
127  if( status > 0 ){
128    std::stringstream errmsg;
129    errmsg << "WCS Error Code = " <<status<<": " << wcs_errmsg[status]
130           << "\nstat value is " << stat[0] << std::endl;
131    duchamp::duchampError("wcsToPixSingle",errmsg.str());
132  }
133
134  pix[0] = temppix[wcs->lng] - 1.;
135  pix[1] = temppix[wcs->lat] - 1.;
136  pix[2] = temppix[specAxis] - 1.;
137  // correct from 1-indexed to 0-indexed pixel array
138  //  and only return the spatial & frequency information
139
140  delete [] stat;
141  delete [] imgcrd;
142  delete [] temppix;
143  delete [] phi;
144  delete [] theta;
145  delete [] tempworld;
146  return status;
147}
148
149int pixToWCSMulti(struct wcsprm *wcs, const double *pix,
150                  double *world, const int npts)
151{
152  ///  @details
153  ///   Uses wcs to convert the three-dimensional pixel positions referenced
154  ///    by pix to world coordinates, which are placed in the array world[].
155  ///   pix is assumed to hold the positions of npts points.
156  ///   Offsets these pixel values by 1 to account for the C arrays being
157  ///    indexed to 0.
158  ///
159  /// \param wcs The wcsprm struct containing the WCS information.
160  /// \param pix The array of pixel coordinates.
161  /// \param world The returned array of world coordinates.
162  /// \param npts The number of distinct pixels in the arrays.
163
164  int naxis=wcs->naxis,status;
165  int specAxis = wcs->spec;
166  if(specAxis<0) specAxis=2;
167  if(specAxis>=naxis) specAxis = naxis-1;
168
169  // correct from 0-indexed to 1-indexed pixel array
170  // Add entries for any other axes that are present, keeping the
171  //   order of pixel positions the same
172  double *newpix = new double[naxis*npts];
173  for(int pt=0;pt<npts;pt++){
174    for(int i=0;i<naxis;i++) newpix[pt*naxis+i] = 1.;
175    newpix[pt*naxis+wcs->lng]  += pix[pt*3+0];
176    newpix[pt*naxis+wcs->lat]  += pix[pt*3+1];
177    newpix[pt*naxis+specAxis] += pix[pt*3+2];
178  }
179
180  int    *stat      = new int[npts];
181  double *imgcrd    = new double[naxis*npts];
182  double *tempworld = new double[naxis*npts];
183  double *phi       = new double[npts];
184  double *theta     = new double[npts];
185  status=wcsp2s(wcs, npts, naxis, newpix, imgcrd,
186                phi, theta, tempworld, stat);
187  if(status>0){
188    std::stringstream errmsg;
189    errmsg << "WCS Error Code = " <<status<<": " << wcs_errmsg[status]
190           << "\nstat value is " << stat[0] << std::endl;
191    duchamp::duchampError("pixToWCSMulti",errmsg.str());
192  }
193  else{
194    //return just the spatial/velocity information, keeping the
195    //  order of the pixel positions the same.
196    for(int pt=0;pt<npts;pt++){
197      world[pt*3+0] = tempworld[pt*naxis + wcs->lng];
198      world[pt*3+1] = tempworld[pt*naxis + wcs->lat];
199      world[pt*3+2] = tempworld[pt*naxis + specAxis];
200    }
201   
202  }
203
204  delete [] stat;
205  delete [] imgcrd;
206  delete [] tempworld;
207  delete [] phi;
208  delete [] theta;
209  delete [] newpix;
210  return status;
211}
212
213int wcsToPixMulti(struct wcsprm *wcs, const double *world,
214                  double *pix, const int npts)
215{
216  ///  @details
217  ///   Uses wcs to convert the three-dimensional world coordinate position
218  ///    referenced by world to pixel coordinates, which are placed in the
219  ///    array pix[].
220  ///   world is assumed to hold the positions of npts points.
221  ///   Offsets the pixel values by 1 to account for the C arrays being
222  ///    indexed to 0.
223  ///
224  /// \param wcs The wcsprm struct containing the WCS information.
225  /// \param world The array of world coordinates.
226  /// \param pix The returned array of pixel coordinates.
227  /// \param npts The number of distinct pixels in the arrays.
228
229  int naxis=wcs->naxis,status=0;
230  int specAxis = wcs->spec;
231  if(specAxis<0) specAxis=2;
232  if(specAxis>=naxis) specAxis = naxis-1;
233
234  // Test to see if there are other axes present, eg. stokes
235  if(wcs->naxis>naxis) naxis = wcs->naxis;
236
237  // Add entries for any other axes that are present, keeping the
238  //   order of pixel positions the same
239  double *tempworld = new double[naxis*npts];
240  for(int pt=0;pt<npts;pt++){
241    for(int axis=0;axis<naxis;axis++)
242      tempworld[pt*naxis+axis] = wcs->crval[axis];
243    tempworld[pt*naxis + wcs->lng]  = world[pt*3+0];
244    tempworld[pt*naxis + wcs->lat]  = world[pt*3+1];
245    tempworld[pt*naxis + specAxis] = world[pt*3+2];
246  }
247
248  int    *stat   = new int[npts];
249  double *temppix = new double[naxis*npts];
250  double *imgcrd = new double[naxis*npts];
251  double *phi    = new double[npts];
252  double *theta  = new double[npts];
253  status=wcss2p(wcs,npts,naxis,tempworld,phi,theta,
254                imgcrd,temppix,stat);
255  if(status>0){
256    std::stringstream errmsg;
257    errmsg << "WCS Error Code = " <<status<<": " <<wcs_errmsg[status]
258           << "\nstat value is " << stat[0] << std::endl;
259    duchamp::duchampError("wcsToPixMulti",errmsg.str());
260  }
261  else{
262    // correct from 1-indexed to 0-indexed pixel array
263    //  and return just the spatial/velocity information,
264    //  keeping the order of the pixel positions the same.
265    for(int pt=0;pt<npts;pt++){
266      pix[pt*naxis + 0] = temppix[pt*naxis + wcs->lng] - 1.;
267      pix[pt*naxis + 1] = temppix[pt*naxis + wcs->lat] - 1.;
268      pix[pt*naxis + 2] = temppix[pt*naxis + specAxis] - 1.;
269    }
270  }
271
272  delete [] stat;
273  delete [] imgcrd;
274  delete [] temppix;
275  delete [] phi;
276  delete [] theta;
277  delete [] tempworld;
278  return status;
279}
280
281double pixelToVelocity(struct wcsprm *wcs, double &x, double &y, double &z,
282                       std::string velUnits)
283{
284  ///  @details
285  ///   Uses wcs to convert the three-dimensional pixel position (x,y,z)
286  ///   to world coordinates.
287  ///   Returns the velocity in the units given by velUnits.
288  ///
289  /// \param wcs  The wcsprm struct containing the WCS information.
290  /// \param x The x pixel coordinate.
291  /// \param y The y pixel coordinate.
292  /// \param z The z pixel coordinate.
293  /// \param velUnits The string containing the units of the output velocity.
294  /// \return The velocity of the pixel.
295
296  int naxis=wcs->naxis,status=0;
297  int    *stat   = new int[1];
298  double *pixcrd = new double[naxis];
299  double *imgcrd = new double[naxis];
300  double *world  = new double[naxis];
301  double *phi    = new double[1];
302  double *theta  = new double[1];
303
304  int specAxis = wcs->spec;
305  if(specAxis<0) specAxis=2;
306  if(specAxis>=naxis) specAxis = naxis-1;
307
308  // correct from 0-indexed to 1-indexed pixel array by adding 1 to
309  // pixel values.
310  for(int i=0;i<naxis;i++) pixcrd[i] = 1.;
311  pixcrd[wcs->lng] += x;
312  pixcrd[wcs->lat] += y;
313  pixcrd[specAxis]+= z;
314  status=wcsp2s(wcs, 1, naxis, pixcrd, imgcrd,
315                phi, theta, world, stat);
316  if(status>0){
317    std::stringstream errmsg;
318    errmsg <<"WCS Error Code = "<<status<<": "<<wcs_errmsg[status]
319           << "\nstat value is "<<stat[0]<<std::endl;
320    duchamp::duchampError("pixelToVelocity",errmsg.str());
321  }
322
323  double vel = coordToVel(wcs, world[specAxis], velUnits);
324
325  delete [] stat;
326  delete [] pixcrd;
327  delete [] imgcrd;
328  delete [] world;
329  delete [] phi;
330  delete [] theta;
331 
332  return vel;
333}
334 
335double coordToVel(struct wcsprm *wcs, const double coord,
336                  std::string outputUnits)
337{
338  ///  @details
339  ///   Convert the wcs coordinate given by coord to a velocity in km/s.
340  ///   Does this by checking the ztype parameter in wcs to see if it is
341  ///    FREQ or otherwise, and converts accordingly.
342  ///
343  /// \param wcs  The wcsprm struct containing the WCS information.
344  /// \param coord The input WCS coordinate.
345  /// \param outputUnits The string containing the units of the output velocity.
346  /// \return The velocity of the input coord value.
347
348  static int errflag = 0;
349  double scale, offset, power;
350  int specIndex = wcs->spec;
351  if(specIndex<0) specIndex = 2;
352  if(specIndex>=wcs->naxis) specIndex = wcs->naxis-1;
353  int status = wcsunits( wcs->cunit[specIndex], outputUnits.c_str(),
354                         &scale, &offset, &power);
355
356  if(status > 0){
357    if(errflag==0){
358      std::stringstream errmsg;
359      errmsg << "WCSUNITS Error Code = " << status << ":"
360             << wcsunits_errmsg[status];
361      if(status == 10) errmsg << "\nTried to get conversion from "
362                              << wcs->cunit[specIndex]
363                              << " to " << outputUnits.c_str();
364      errmsg << "\nUsing coordinate value instead.\n";
365      duchamp::duchampError("coordToVel", errmsg.str());
366      errflag = 1;
367    }
368    return coord;
369  }
370  else return pow( (coord*scale + offset), power);
371
372}
373
374double velToCoord(struct wcsprm *wcs, const float velocity,
375                  std::string outputUnits)
376{
377  ///  @details
378  ///   Convert the velocity given to the appropriate world coordinate for wcs.
379  ///   Does this by checking the ztype parameter in wcs to see if it is
380  ///    FREQ or otherwise, and converts accordingly.
381  ///
382  /// \param wcs  The wcsprm struct containing the WCS information.
383  /// \param velocity The input velocity.
384  /// \param outputUnits The string containing the units of the input velocity.
385  /// \return The WCS coordinate corresponding to the input velocity.
386
387  double scale, offset, power;
388  int specIndex = wcs->spec;
389  if(specIndex<0) specIndex = 2;
390  if(specIndex>=wcs->naxis) specIndex = wcs->naxis-1;
391  int status = wcsunits( outputUnits.c_str(), wcs->cunit[specIndex],
392                         &scale, &offset, &power);
393
394  if(status > 0){
395    std::stringstream errmsg;
396    errmsg << "WCSUNITS Error Code = " << status << ":"
397           << wcsunits_errmsg[status] << "\nUsing coordinate value instead.\n";
398    duchamp::duchampError("velToCoord",errmsg.str());
399    return velocity;
400  }
401  else return (pow(velocity, 1./power) - offset) / scale;
402 
403}
Note: See TracBrowser for help on using the repository browser.