WCSLIB  6.2
wcsfix.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  WCSLIB 6.2 - an implementation of the FITS WCS standard.
4  Copyright (C) 1995-2018, Mark Calabretta
5 
6  This file is part of WCSLIB.
7 
8  WCSLIB is free software: you can redistribute it and/or modify it under the
9  terms of the GNU Lesser General Public License as published by the Free
10  Software Foundation, either version 3 of the License, or (at your option)
11  any later version.
12 
13  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16  more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with WCSLIB. If not, see http://www.gnu.org/licenses.
20 
21  Direct correspondence concerning WCSLIB to mark@calabretta.id.au
22 
23  Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
24  http://www.atnf.csiro.au/people/Mark.Calabretta
25  $Id: wcsfix.h,v 6.2 2018/10/20 10:03:13 mcalabre Exp $
26 *=============================================================================
27 *
28 * WCSLIB 6.2 - C routines that implement the FITS World Coordinate System
29 * (WCS) standard. Refer to the README file provided with WCSLIB for an
30 * overview of the library.
31 *
32 *
33 * Summary of the wcsfix routines
34 * ------------------------------
35 * Routines in this suite identify and translate various forms of construct
36 * known to occur in FITS headers that violate the FITS World Coordinate System
37 * (WCS) standard described in
38 *
39 = "Representations of world coordinates in FITS",
40 = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I)
41 =
42 = "Representations of celestial coordinates in FITS",
43 = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II)
44 =
45 = "Representations of spectral coordinates in FITS",
46 = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
47 = 2006, A&A, 446, 747 (WCS Paper III)
48 =
49 = "Representations of time coordinates in FITS -
50 = Time and relative dimension in space",
51 = Rots, A.H., Bunclark, P.S., Calabretta, M.R., Allen, S.L.,
52 = Manchester, R.N., & Thompson, W.T. 2015, A&A, 574, A36 (WCS Paper VII)
53 *
54 * Repairs effected by these routines range from the translation of
55 * non-standard values for standard WCS keywords, to the repair of malformed
56 * coordinate representations. Some routines are also provided to check the
57 * consistency of pairs of keyvalues that define the same measure in two
58 * different ways, for example, as a date and an MJD.
59 *
60 * Non-standard keyvalues:
61 * -----------------------
62 * AIPS-convention celestial projection types, NCP and GLS, and spectral
63 * types, 'FREQ-LSR', 'FELO-HEL', etc., set in CTYPEia are translated
64 * on-the-fly by wcsset() but without modifying the relevant ctype[], pv[] or
65 * specsys members of the wcsprm struct. That is, only the information
66 * extracted from ctype[] is translated when wcsset() fills in wcsprm::cel
67 * (celprm struct) or wcsprm::spc (spcprm struct).
68 *
69 * On the other hand, these routines do change the values of wcsprm::ctype[],
70 * wcsprm::pv[], wcsprm::specsys and other wcsprm struct members as
71 * appropriate to produce the same result as if the FITS header itself had
72 * been translated.
73 *
74 * Auxiliary WCS header information not used directly by WCSLIB may also be
75 * translated. For example, the older DATE-OBS date format (wcsprm::dateobs)
76 * is recast to year-2000 standard form, and MJD-OBS (wcsprm::mjdobs) will be
77 * deduced from it if not already set.
78 *
79 * Certain combinations of keyvalues that result in malformed coordinate
80 * systems, as described in Sect. 7.3.4 of Paper I, may also be repaired.
81 * These are handled by cylfix().
82 *
83 * Non-standard keywords:
84 * ----------------------
85 * The AIPS-convention CROTAn keywords are recognized as quasi-standard
86 * and as such are accomodated by wcsprm::crota[] and translated to
87 * wcsprm::pc[][] by wcsset(). These are not dealt with here, nor are any
88 * other non-standard keywords since these routines work only on the contents
89 * of a wcsprm struct and do not deal with FITS headers per se. In
90 * particular, they do not identify or translate CD00i00j, PC00i00j, PROJPn,
91 * EPOCH, VELREF or VSOURCEa keywords; this may be done by the FITS WCS
92 * header parser supplied with WCSLIB, refer to wcshdr.h.
93 *
94 * wcsfix() and wcsfixi() apply all of the corrections handled by the following
95 * specific functions which may also be invoked separately:
96 *
97 * - cdfix(): Sets the diagonal element of the CDi_ja matrix to 1.0 if all
98 * CDi_ja keywords associated with a particular axis are omitted.
99 *
100 * - datfix(): recast an older DATE-OBS date format in dateobs to year-2000
101 * standard form.
102 *
103 * Derive mjdobs from dateobs if not already set. Alternatively, if mjdobs
104 * is set and dateobs isn't, then derive dateobs from it. If both are set,
105 * then check consistency. Likewise for datebeg and mjdbeg; dateavg and
106 * mjdavg; and dateend and mjdend.
107 *
108 * - obsfix(): if only one half of obsgeo[] is set, then derive the other
109 * half from it. If both halves are set, then check consistency.
110 *
111 * - unitfix(): translate some commonly used but non-standard unit strings in
112 * the CUNITia keyvalues, e.g. 'DEG' -> 'deg'.
113 *
114 * - spcfix(): translate AIPS-convention spectral types, 'FREQ-LSR',
115 * 'FELO-HEL', etc., in ctype[] as set from CTYPEia.
116 *
117 * - celfix(): translate AIPS-convention celestial projection types, NCP and
118 * GLS, in ctype[] as set from CTYPEia.
119 *
120 * - cylfix(): fixes WCS keyvalues for malformed cylindrical projections that
121 * suffer from the problem described in Sect. 7.3.4 of Paper I.
122 *
123 *
124 * wcsfix() - Translate a non-standard WCS struct
125 * ----------------------------------------------
126 * wcsfix() is identical to wcsfixi(), but lacks the info argument.
127 *
128 *
129 * wcsfixi() - Translate a non-standard WCS struct
130 * -----------------------------------------------
131 * wcsfixi() applies all of the corrections handled separately by cdfix(),
132 * datfix(), obsfix(), unitfix(), spcfix(), celfix(), and cylfix().
133 *
134 * Given:
135 * ctrl int Do potentially unsafe translations of non-standard
136 * unit strings as described in the usage notes to
137 * wcsutrn().
138 *
139 * naxis const int []
140 * Image axis lengths. If this array pointer is set to
141 * zero then cylfix() will not be invoked.
142 *
143 * Given and returned:
144 * wcs struct wcsprm*
145 * Coordinate transformation parameters.
146 *
147 * Returned:
148 * stat int [NWCSFIX]
149 * Status returns from each of the functions. Use the
150 * preprocessor macros NWCSFIX to dimension this vector
151 * and CDFIX, DATFIX, OBSFIX, UNITFIX, SPCFIX, CELFIX,
152 * and CYLFIX to access its elements. A status value
153 * of -2 is set for functions that were not invoked.
154 *
155 * info struct wcserr [NWCSFIX]
156 * Status messages from each of the functions. Use the
157 * preprocessor macros NWCSFIX to dimension this vector
158 * and CDFIX, DATFIX, OBSFIX, UNITFIX, SPCFIX, CELFIX,
159 * and CYLFIX to access its elements.
160 *
161 * Function return value:
162 * int Status return value:
163 * 0: Success.
164 * 1: One or more of the translation functions
165 * returned an error.
166 *
167 *
168 * cdfix() - Fix erroneously omitted CDi_ja keywords
169 * -------------------------------------------------
170 * cdfix() sets the diagonal element of the CDi_ja matrix to unity if all
171 * CDi_ja keywords associated with a given axis were omitted. According to
172 * Paper I, if any CDi_ja keywords at all are given in a FITS header then those
173 * not given default to zero. This results in a singular matrix with an
174 * intersecting row and column of zeros.
175 *
176 * Given and returned:
177 * wcs struct wcsprm*
178 * Coordinate transformation parameters.
179 *
180 * Function return value:
181 * int Status return value:
182 * -1: No change required (not an error).
183 * 0: Success.
184 * 1: Null wcsprm pointer passed.
185 *
186 *
187 * datfix() - Translate DATE-OBS and derive MJD-OBS or vice versa
188 * --------------------------------------------------------------
189 * datfix() translates the old DATE-OBS date format set in wcsprm::dateobs to
190 * year-2000 standard form (yyyy-mm-ddThh:mm:ss).
191 *
192 * datfix() derives wcsprm::mjdobs from wcsprm::datobs if not already set.
193 * Alternatively, if mjdobs is set and dateobs isn't, then it derives dateobs
194 * from it. If both are set but disagree by more than 0.001 day (86.4 seconds)
195 * then status 5 is returned. Likewise for wcsprm::datebeg and wcsprm::mjdbeg;
196 * wcsprm::dateavg and wcsprm::mjdavg; and wcsprm::dateend and wcsprm::mjdend.
197 *
198 * If neither dateobs nor mjdobs are set, but wcsprm::jepoch (primarily) or
199 * wcsprm::bepoch is, then both are derived from it. If jepoch and/or bepoch
200 * are set but disagree with dateobs or mjdobs by more than 0.000002 year
201 * (63.2 seconds), an informative message is produced.
202 *
203 * Given and returned:
204 * wcs struct wcsprm*
205 * Coordinate transformation parameters.
206 * wcsprm::dateobs and/or wcsprm::mjdobs may be changed.
207 * wcsprm::datebeg and/or wcsprm::mjdbeg may be changed.
208 * wcsprm::dateavg and/or wcsprm::mjdavg may be changed.
209 * wcsprm::dateend and/or wcsprm::mjdend may be changed.
210 *
211 * Function return value:
212 * int Status return value:
213 * -1: No change required (not an error).
214 * 0: Success.
215 * 1: Null wcsprm pointer passed.
216 * 5: Invalid parameter value.
217 *
218 * For returns > 1, a detailed error message is set in
219 * wcsprm::err if enabled, see wcserr_enable().
220 *
221 * Notes:
222 * The MJD algorithms used by datfix() are from D.A. Hatcher, 1984, QJRAS,
223 * 25, 53-55, as modified by P.T. Wallace for use in SLALIB subroutines CLDJ
224 * and DJCL.
225 *
226 *
227 * obsfix() - complete the OBSGEO-[XYZLBH] vector of observatory coordinates
228 * -------------------------------------------------------------------------
229 * obsfix() completes the wcsprm::obsgeo vector of observatory coordinates.
230 * That is, if only the (x,y,z) Cartesian coordinate triplet or the (l,b,h)
231 * geodetic coordinate triplet are set, then it derives the other triplet from
232 * it. If both triplets are set, then it checks for consistency at the level
233 * of 1 metre.
234 *
235 * Given:
236 * ctrl int Flag that controls behaviour if one triplet is
237 * defined and the other is only partially defined:
238 * 0: Reset only the undefined elements of an
239 * incomplete coordinate triplet.
240 * 1: Reset all elements of an incomplete triplet.
241 * 2: Don't make any changes, check for consistency
242 * only. Returns an error if either of the two
243 * triplets is incomplete.
244 *
245 * Given and returned:
246 * wcs struct wcsprm*
247 * Coordinate transformation parameters.
248 * wcsprm::obsgeo may be changed.
249 *
250 * Function return value:
251 * int Status return value:
252 * -1: No change required (not an error).
253 * 0: Success.
254 * 1: Null wcsprm pointer passed.
255 * 5: Invalid parameter value.
256 *
257 * For returns > 1, a detailed error message is set in
258 * wcsprm::err if enabled, see wcserr_enable().
259 *
260 * Notes:
261 * 1: While the International Terrestrial Reference System (ITRS) is based
262 * solely on Cartesian coordinates, it recommends the use of the GRS80
263 * ellipsoid in converting to geodetic coordinates. However, while WCS
264 * Paper III recommends ITRS Cartesian coordinates, Paper VII prescribes
265 * the use of the IAU(1976) ellipsoid for geodetic coordinates, and
266 * consequently that is what is used here.
267 *
268 * 2: For reference, parameters of commonly used global reference ellipsoids:
269 *
270 = a (m) 1/f Standard
271 = --------- ------------- --------------------------------
272 = 6378140 298.2577 IAU(1976)
273 = 6378137 298.257222101 GRS80
274 = 6378137 298.257223563 WGS84
275 = 6378136 298.257 IERS(1989)
276 = 6378136.6 298.25642 IERS(2003,2010), IAU(2009/2012)
277 *
278 * where f = (a - b) / a is the flattening, and a and b are the semi-major
279 * and semi-minor radii in metres.
280 *
281 * 3: The transformation from geodetic (lng,lat,hgt) to Cartesian (x,y,z) is
282 *
283 = x = (n + hgt)*coslng*coslat,
284 = y = (n + hgt)*sinlng*coslat,
285 = z = (n*(1.0 - e^2) + hgt)*sinlat,
286 *
287 * where the "prime vertical radius", n, is a function of latitude
288 *
289 = n = a / sqrt(1 - (e*sinlat)^2),
290 *
291 * and a, the equatorial radius, and e^2 = (2 - f)*f, the (first)
292 * eccentricity of the ellipsoid, are constants. obsfix() inverts these
293 * iteratively by writing
294 *
295 = x = rho*coslng*coslat,
296 = y = rho*sinlng*coslat,
297 = zeta = rho*sinlat,
298 *
299 * where
300 *
301 = rho = n + hgt,
302 = = sqrt(x^2 + y^2 + zeta^2),
303 = zeta = z / (1 - n*e^2/rho),
304 *
305 * and iterating over the value of zeta. Since e is small, a good first
306 * approximation is given by zeta = z.
307 *
308 *
309 * unitfix() - Correct aberrant CUNITia keyvalues
310 * ----------------------------------------------
311 * unitfix() applies wcsutrn() to translate non-standard CUNITia keyvalues,
312 * e.g. 'DEG' -> 'deg', also stripping off unnecessary whitespace.
313 *
314 * Given:
315 * ctrl int Do potentially unsafe translations described in the
316 * usage notes to wcsutrn().
317 *
318 * Given and returned:
319 * wcs struct wcsprm*
320 * Coordinate transformation parameters.
321 *
322 * Function return value:
323 * int Status return value:
324 * -1: No change required (not an error).
325 * 0: Success (an alias was applied).
326 * 1: Null wcsprm pointer passed.
327 *
328 * When units are translated (i.e. status 0), status -2
329 * is set in the wcserr struct to allow an informative
330 * message to be returned.
331 *
332 *
333 * spcfix() - Translate AIPS-convention spectral types
334 * ---------------------------------------------------
335 * spcfix() translates AIPS-convention spectral coordinate types,
336 * '{FREQ,FELO,VELO}-{LSR,HEL,OBS}' (e.g. 'FREQ-OBS', 'FELO-HEL', 'VELO-LSR')
337 * set in wcsprm::ctype[], subject to VELREF set in wcsprm::velref.
338 *
339 * Note that if wcs::specsys is already set then it will not be overridden.
340 *
341 * Given and returned:
342 * wcs struct wcsprm*
343 * Coordinate transformation parameters. wcsprm::ctype[]
344 * and/or wcsprm::specsys may be changed.
345 *
346 * Function return value:
347 * int Status return value:
348 * -1: No change required (not an error).
349 * 0: Success.
350 * 1: Null wcsprm pointer passed.
351 * 2: Memory allocation failed.
352 * 3: Linear transformation matrix is singular.
353 * 4: Inconsistent or unrecognized coordinate axis
354 * types.
355 * 5: Invalid parameter value.
356 * 6: Invalid coordinate transformation parameters.
357 * 7: Ill-conditioned coordinate transformation
358 * parameters.
359 *
360 * For returns > 1, a detailed error message is set in
361 * wcsprm::err if enabled, see wcserr_enable().
362 *
363 *
364 * celfix() - Translate AIPS-convention celestial projection types
365 * ---------------------------------------------------------------
366 * celfix() translates AIPS-convention celestial projection types, NCP and
367 * GLS, set in the ctype[] member of the wcsprm struct.
368 *
369 * Two additional pv[] keyvalues are created when translating NCP, and three
370 * are created when translating GLS with non-zero reference point. If the pv[]
371 * array was initially allocated by wcsini() then the array will be expanded if
372 * necessary. Otherwise, error 2 will be returned if sufficient empty slots
373 * are not already available for use.
374 *
375 * Given and returned:
376 * wcs struct wcsprm*
377 * Coordinate transformation parameters. wcsprm::ctype[]
378 * and/or wcsprm::pv[] may be changed.
379 *
380 * Function return value:
381 * int Status return value:
382 * -1: No change required (not an error).
383 * 0: Success.
384 * 1: Null wcsprm pointer passed.
385 * 2: Memory allocation failed.
386 * 3: Linear transformation matrix is singular.
387 * 4: Inconsistent or unrecognized coordinate axis
388 * types.
389 * 5: Invalid parameter value.
390 * 6: Invalid coordinate transformation parameters.
391 * 7: Ill-conditioned coordinate transformation
392 * parameters.
393 *
394 * For returns > 1, a detailed error message is set in
395 * wcsprm::err if enabled, see wcserr_enable().
396 *
397 *
398 * cylfix() - Fix malformed cylindrical projections
399 * ------------------------------------------------
400 * cylfix() fixes WCS keyvalues for malformed cylindrical projections that
401 * suffer from the problem described in Sect. 7.3.4 of Paper I.
402 *
403 * Given:
404 * naxis const int []
405 * Image axis lengths.
406 *
407 * Given and returned:
408 * wcs struct wcsprm*
409 * Coordinate transformation parameters.
410 *
411 * Function return value:
412 * int Status return value:
413 * -1: No change required (not an error).
414 * 0: Success.
415 * 1: Null wcsprm pointer passed.
416 * 2: Memory allocation failed.
417 * 3: Linear transformation matrix is singular.
418 * 4: Inconsistent or unrecognized coordinate axis
419 * types.
420 * 5: Invalid parameter value.
421 * 6: Invalid coordinate transformation parameters.
422 * 7: Ill-conditioned coordinate transformation
423 * parameters.
424 * 8: All of the corner pixel coordinates are invalid.
425 * 9: Could not determine reference pixel coordinate.
426 * 10: Could not determine reference pixel value.
427 *
428 * For returns > 1, a detailed error message is set in
429 * wcsprm::err if enabled, see wcserr_enable().
430 *
431 *
432 * Global variable: const char *wcsfix_errmsg[] - Status return messages
433 * ---------------------------------------------------------------------
434 * Error messages to match the status value returned from each function.
435 *
436 *===========================================================================*/
437 
438 #ifndef WCSLIB_WCSFIX
439 #define WCSLIB_WCSFIX
440 
441 #include "wcs.h"
442 #include "wcserr.h"
443 
444 #ifdef __cplusplus
445 extern "C" {
446 #endif
447 
448 #define CDFIX 0
449 #define DATFIX 1
450 #define OBSFIX 2
451 #define UNITFIX 3
452 #define SPCFIX 4
453 #define CELFIX 5
454 #define CYLFIX 6
455 #define NWCSFIX 7
456 
457 extern const char *wcsfix_errmsg[];
458 #define cylfix_errmsg wcsfix_errmsg
459 
461  FIXERR_OBSGEO_FIX = -5, /* Observatory coordinates amended. */
462  FIXERR_DATE_FIX = -4, /* Date string reformatted. */
463  FIXERR_SPC_UPDATE = -3, /* Spectral axis type modified. */
464  FIXERR_UNITS_ALIAS = -2, /* Units alias translation. */
465  FIXERR_NO_CHANGE = -1, /* No change. */
466  FIXERR_SUCCESS = 0, /* Success. */
467  FIXERR_NULL_POINTER = 1, /* Null wcsprm pointer passed. */
468  FIXERR_MEMORY = 2, /* Memory allocation failed. */
469  FIXERR_SINGULAR_MTX = 3, /* Linear transformation matrix is
470  singular. */
471  FIXERR_BAD_CTYPE = 4, /* Inconsistent or unrecognized coordinate
472  axis types. */
473  FIXERR_BAD_PARAM = 5, /* Invalid parameter value. */
474  FIXERR_BAD_COORD_TRANS = 6, /* Invalid coordinate transformation
475  parameters. */
476  FIXERR_ILL_COORD_TRANS = 7, /* Ill-conditioned coordinate transformation
477  parameters. */
478  FIXERR_BAD_CORNER_PIX = 8, /* All of the corner pixel coordinates are
479  invalid. */
480  FIXERR_NO_REF_PIX_COORD = 9, /* Could not determine reference pixel
481  coordinate. */
482  FIXERR_NO_REF_PIX_VAL = 10 /* Could not determine reference pixel
483  value. */
484 };
485 
486 int wcsfix(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[]);
487 
488 int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[],
489  struct wcserr info[]);
490 
491 int cdfix(struct wcsprm *wcs);
492 
493 int datfix(struct wcsprm *wcs);
494 
495 int obsfix(int ctrl, struct wcsprm *wcs);
496 
497 int unitfix(int ctrl, struct wcsprm *wcs);
498 
499 int spcfix(struct wcsprm *wcs);
500 
501 int celfix(struct wcsprm *wcs);
502 
503 int cylfix(const int naxis[], struct wcsprm *wcs);
504 
505 
506 #ifdef __cplusplus
507 }
508 #endif
509 
510 #endif /* WCSLIB_WCSFIX */
Definition: wcsfix.h:474
int unitfix(int ctrl, struct wcsprm *wcs)
Correct aberrant CUNITia keyvalues.
int wcsfix(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[])
Translate a non-standard WCS struct.
Definition: wcsfix.h:478
Error message handling.
Definition: wcserr.h:223
Definition: wcsfix.h:462
Definition: wcsfix.h:480
Definition: wcsfix.h:473
int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[], struct wcserr info[])
Translate a non-standard WCS struct.
Definition: wcsfix.h:482
int obsfix(int ctrl, struct wcsprm *wcs)
complete the OBSGEO-[XYZLBH] vector of observatory coordinates.
wcsfix_errmsg_enum
Definition: wcsfix.h:460
Definition: wcsfix.h:464
const char * wcsfix_errmsg[]
Status return messages.
Coordinate transformation parameters.
Definition: wcs.h:1730
Definition: wcsfix.h:463
Definition: wcsfix.h:468
Definition: wcsfix.h:466
int cylfix(const int naxis[], struct wcsprm *wcs)
Fix malformed cylindrical projections.
Definition: wcsfix.h:476
Definition: wcsfix.h:465
Definition: wcsfix.h:461
Definition: wcsfix.h:467
int spcfix(struct wcsprm *wcs)
Translate AIPS-convention spectral types.
Definition: wcsfix.h:471
int cdfix(struct wcsprm *wcs)
Fix erroneously omitted CDi_ja keywords.
int datfix(struct wcsprm *wcs)
Translate DATE-OBS and derive MJD-OBS or vice versa.
Definition: wcsfix.h:469
int celfix(struct wcsprm *wcs)
Translate AIPS-convention celestial projection types.