WCSLIB  7.6
wcsfix.h
Go to the documentation of this file.
1 /*============================================================================
2  WCSLIB 7.6 - an implementation of the FITS WCS standard.
3  Copyright (C) 1995-2021, Mark Calabretta
4 
5  This file is part of WCSLIB.
6 
7  WCSLIB is free software: you can redistribute it and/or modify it under the
8  terms of the GNU Lesser General Public License as published by the Free
9  Software Foundation, either version 3 of the License, or (at your option)
10  any later version.
11 
12  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
13  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15  more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with WCSLIB. If not, see http://www.gnu.org/licenses.
19 
20  Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
21  http://www.atnf.csiro.au/people/Mark.Calabretta
22  $Id: wcsfix.h,v 7.6 2021/04/13 12:57:01 mcalabre Exp $
23 *=============================================================================
24 *
25 * WCSLIB 7.6 - C routines that implement the FITS World Coordinate System
26 * (WCS) standard. Refer to the README file provided with WCSLIB for an
27 * overview of the library.
28 *
29 *
30 * Summary of the wcsfix routines
31 * ------------------------------
32 * Routines in this suite identify and translate various forms of construct
33 * known to occur in FITS headers that violate the FITS World Coordinate System
34 * (WCS) standard described in
35 *
36 = "Representations of world coordinates in FITS",
37 = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I)
38 =
39 = "Representations of celestial coordinates in FITS",
40 = Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (WCS Paper II)
41 =
42 = "Representations of spectral coordinates in FITS",
43 = Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
44 = 2006, A&A, 446, 747 (WCS Paper III)
45 =
46 = "Representations of time coordinates in FITS -
47 = Time and relative dimension in space",
48 = Rots, A.H., Bunclark, P.S., Calabretta, M.R., Allen, S.L.,
49 = Manchester, R.N., & Thompson, W.T. 2015, A&A, 574, A36 (WCS Paper VII)
50 *
51 * Repairs effected by these routines range from the translation of
52 * non-standard values for standard WCS keywords, to the repair of malformed
53 * coordinate representations. Some routines are also provided to check the
54 * consistency of pairs of keyvalues that define the same measure in two
55 * different ways, for example, as a date and an MJD.
56 *
57 * A separate routine, wcspcx(), "regularizes" the linear transformation matrix
58 * component (PCi_j) of the coordinate transformation to make it more human-
59 * readable. Where a coordinate description was constructed from CDi_j, it
60 * decomposes it into PCi_j + CDELTi in a meaningful way. Optionally, it can
61 * also diagonalize the PCi_j matrix (as far as possible), i.e. undo the
62 * transposition of axes in the intermediate pixel coordinate system.
63 *
64 * Non-standard keyvalues:
65 * -----------------------
66 * AIPS-convention celestial projection types, NCP and GLS, and spectral
67 * types, 'FREQ-LSR', 'FELO-HEL', etc., set in CTYPEia are translated
68 * on-the-fly by wcsset() but without modifying the relevant ctype[], pv[] or
69 * specsys members of the wcsprm struct. That is, only the information
70 * extracted from ctype[] is translated when wcsset() fills in wcsprm::cel
71 * (celprm struct) or wcsprm::spc (spcprm struct).
72 *
73 * On the other hand, these routines do change the values of wcsprm::ctype[],
74 * wcsprm::pv[], wcsprm::specsys and other wcsprm struct members as
75 * appropriate to produce the same result as if the FITS header itself had
76 * been translated.
77 *
78 * Auxiliary WCS header information not used directly by WCSLIB may also be
79 * translated. For example, the older DATE-OBS date format (wcsprm::dateobs)
80 * is recast to year-2000 standard form, and MJD-OBS (wcsprm::mjdobs) will be
81 * deduced from it if not already set.
82 *
83 * Certain combinations of keyvalues that result in malformed coordinate
84 * systems, as described in Sect. 7.3.4 of Paper I, may also be repaired.
85 * These are handled by cylfix().
86 *
87 * Non-standard keywords:
88 * ----------------------
89 * The AIPS-convention CROTAn keywords are recognized as quasi-standard
90 * and as such are accomodated by wcsprm::crota[] and translated to
91 * wcsprm::pc[][] by wcsset(). These are not dealt with here, nor are any
92 * other non-standard keywords since these routines work only on the contents
93 * of a wcsprm struct and do not deal with FITS headers per se. In
94 * particular, they do not identify or translate CD00i00j, PC00i00j, PROJPn,
95 * EPOCH, VELREF or VSOURCEa keywords; this may be done by the FITS WCS
96 * header parser supplied with WCSLIB, refer to wcshdr.h.
97 *
98 * wcsfix() and wcsfixi() apply all of the corrections handled by the following
99 * specific functions, which may also be invoked separately:
100 *
101 * - cdfix(): Sets the diagonal element of the CDi_ja matrix to 1.0 if all
102 * CDi_ja keywords associated with a particular axis are omitted.
103 *
104 * - datfix(): recast an older DATE-OBS date format in dateobs to year-2000
105 * standard form. Derive dateref from mjdref if not already set.
106 * Alternatively, if dateref is set and mjdref isn't, then derive mjdref
107 * from it. If both are set, then check consistency. Likewise for dateobs
108 * and mjdobs; datebeg and mjdbeg; dateavg and mjdavg; and dateend and
109 * mjdend.
110 *
111 * - obsfix(): if only one half of obsgeo[] is set, then derive the other
112 * half from it. If both halves are set, then check consistency.
113 *
114 * - unitfix(): translate some commonly used but non-standard unit strings in
115 * the CUNITia keyvalues, e.g. 'DEG' -> 'deg'.
116 *
117 * - spcfix(): translate AIPS-convention spectral types, 'FREQ-LSR',
118 * 'FELO-HEL', etc., in ctype[] as set from CTYPEia.
119 *
120 * - celfix(): translate AIPS-convention celestial projection types, NCP and
121 * GLS, in ctype[] as set from CTYPEia.
122 *
123 * - cylfix(): fixes WCS keyvalues for malformed cylindrical projections that
124 * suffer from the problem described in Sect. 7.3.4 of Paper I.
125 *
126 *
127 * wcsfix() - Translate a non-standard WCS struct
128 * ----------------------------------------------
129 * wcsfix() is identical to wcsfixi(), but lacks the info argument.
130 *
131 *
132 * wcsfixi() - Translate a non-standard WCS struct
133 * -----------------------------------------------
134 * wcsfixi() applies all of the corrections handled separately by cdfix(),
135 * datfix(), obsfix(), unitfix(), spcfix(), celfix(), and cylfix().
136 *
137 * Given:
138 * ctrl int Do potentially unsafe translations of non-standard
139 * unit strings as described in the usage notes to
140 * wcsutrn().
141 *
142 * naxis const int []
143 * Image axis lengths. If this array pointer is set to
144 * zero then cylfix() will not be invoked.
145 *
146 * Given and returned:
147 * wcs struct wcsprm*
148 * Coordinate transformation parameters.
149 *
150 * Returned:
151 * stat int [NWCSFIX]
152 * Status returns from each of the functions. Use the
153 * preprocessor macros NWCSFIX to dimension this vector
154 * and CDFIX, DATFIX, OBSFIX, UNITFIX, SPCFIX, CELFIX,
155 * and CYLFIX to access its elements. A status value
156 * of -2 is set for functions that were not invoked.
157 *
158 * info struct wcserr [NWCSFIX]
159 * Status messages from each of the functions. Use the
160 * preprocessor macros NWCSFIX to dimension this vector
161 * and CDFIX, DATFIX, OBSFIX, UNITFIX, SPCFIX, CELFIX,
162 * and CYLFIX to access its elements.
163 *
164 * Note that the memory allocated by wcsfixi() for the
165 * message in each wcserr struct (wcserr::msg, if
166 * non-zero) must be freed by the user. See
167 * wcsdealloc().
168 *
169 * Function return value:
170 * int Status return value:
171 * 0: Success.
172 * 1: One or more of the translation functions
173 * returned an error.
174 *
175 *
176 * cdfix() - Fix erroneously omitted CDi_ja keywords
177 * -------------------------------------------------
178 * cdfix() sets the diagonal element of the CDi_ja matrix to unity if all
179 * CDi_ja keywords associated with a given axis were omitted. According to WCS
180 * Paper I, if any CDi_ja keywords at all are given in a FITS header then those
181 * not given default to zero. This results in a singular matrix with an
182 * intersecting row and column of zeros.
183 *
184 * cdfix() is expected to be invoked before wcsset(), which will fail if these
185 * errors have not been corrected.
186 *
187 * Given and returned:
188 * wcs struct wcsprm*
189 * Coordinate transformation parameters.
190 *
191 * Function return value:
192 * int Status return value:
193 * -1: No change required (not an error).
194 * 0: Success.
195 * 1: Null wcsprm pointer passed.
196 *
197 *
198 * datfix() - Translate DATE-OBS and derive MJD-OBS or vice versa
199 * --------------------------------------------------------------
200 * datfix() translates the old DATE-OBS date format set in wcsprm::dateobs to
201 * year-2000 standard form (yyyy-mm-ddThh:mm:ss). It derives wcsprm::dateref
202 * from wcsprm::mjdref if not already set. Alternatively, if dateref is set
203 * and mjdref isn't, then it derives mjdref from it. If both are set but
204 * disagree by more than 0.001 day (86.4 seconds) then an error status is
205 * returned. Likewise for wcsprm::dateobs and wcsprm::mjdobs; wcsprm::datebeg
206 * and wcsprm::mjdbeg; wcsprm::dateavg and wcsprm::mjdavg; and wcsprm::dateend
207 * and wcsprm::mjdend.
208 *
209 * If neither dateobs nor mjdobs are set, but wcsprm::jepoch (primarily) or
210 * wcsprm::bepoch is, then both are derived from it. If jepoch and/or bepoch
211 * are set but disagree with dateobs or mjdobs by more than 0.000002 year
212 * (63.2 seconds), an informative message is produced.
213 *
214 * The translations done by datfix() do not affect and are not affected by
215 * wcsset().
216 *
217 * Given and returned:
218 * wcs struct wcsprm*
219 * Coordinate transformation parameters.
220 * wcsprm::dateref and/or wcsprm::mjdref may be changed.
221 * wcsprm::dateobs and/or wcsprm::mjdobs may be changed.
222 * wcsprm::datebeg and/or wcsprm::mjdbeg may be changed.
223 * wcsprm::dateavg and/or wcsprm::mjdavg may be changed.
224 * wcsprm::dateend and/or wcsprm::mjdend may be changed.
225 *
226 * Function return value:
227 * int Status return value:
228 * -1: No change required (not an error).
229 * 0: Success.
230 * 1: Null wcsprm pointer passed.
231 * 5: Invalid parameter value.
232 *
233 * For returns >= 0, a detailed message, whether
234 * informative or an error message, may be set in
235 * wcsprm::err if enabled, see wcserr_enable(), with
236 * wcsprm::err.status set to FIXERR_DATE_FIX.
237 *
238 * Notes:
239 * 1: The MJD algorithms used by datfix() are from D.A. Hatcher, 1984, QJRAS,
240 * 25, 53-55, as modified by P.T. Wallace for use in SLALIB subroutines
241 * CLDJ and DJCL.
242 *
243 *
244 * obsfix() - complete the OBSGEO-[XYZLBH] vector of observatory coordinates
245 * -------------------------------------------------------------------------
246 * obsfix() completes the wcsprm::obsgeo vector of observatory coordinates.
247 * That is, if only the (x,y,z) Cartesian coordinate triplet or the (l,b,h)
248 * geodetic coordinate triplet are set, then it derives the other triplet from
249 * it. If both triplets are set, then it checks for consistency at the level
250 * of 1 metre.
251 *
252 * The operations done by obsfix() do not affect and are not affected by
253 * wcsset().
254 *
255 * Given:
256 * ctrl int Flag that controls behaviour if one triplet is
257 * defined and the other is only partially defined:
258 * 0: Reset only the undefined elements of an
259 * incomplete coordinate triplet.
260 * 1: Reset all elements of an incomplete triplet.
261 * 2: Don't make any changes, check for consistency
262 * only. Returns an error if either of the two
263 * triplets is incomplete.
264 *
265 * Given and returned:
266 * wcs struct wcsprm*
267 * Coordinate transformation parameters.
268 * wcsprm::obsgeo may be changed.
269 *
270 * Function return value:
271 * int Status return value:
272 * -1: No change required (not an error).
273 * 0: Success.
274 * 1: Null wcsprm pointer passed.
275 * 5: Invalid parameter value.
276 *
277 * For returns >= 0, a detailed message, whether
278 * informative or an error message, may be set in
279 * wcsprm::err if enabled, see wcserr_enable(), with
280 * wcsprm::err.status set to FIXERR_OBS_FIX.
281 *
282 * Notes:
283 * 1: While the International Terrestrial Reference System (ITRS) is based
284 * solely on Cartesian coordinates, it recommends the use of the GRS80
285 * ellipsoid in converting to geodetic coordinates. However, while WCS
286 * Paper III recommends ITRS Cartesian coordinates, Paper VII prescribes
287 * the use of the IAU(1976) ellipsoid for geodetic coordinates, and
288 * consequently that is what is used here.
289 *
290 * 2: For reference, parameters of commonly used global reference ellipsoids:
291 *
292 = a (m) 1/f Standard
293 = --------- ------------- --------------------------------
294 = 6378140 298.2577 IAU(1976)
295 = 6378137 298.257222101 GRS80
296 = 6378137 298.257223563 WGS84
297 = 6378136 298.257 IERS(1989)
298 = 6378136.6 298.25642 IERS(2003,2010), IAU(2009/2012)
299 *
300 * where f = (a - b) / a is the flattening, and a and b are the semi-major
301 * and semi-minor radii in metres.
302 *
303 * 3: The transformation from geodetic (lng,lat,hgt) to Cartesian (x,y,z) is
304 *
305 = x = (n + hgt)*coslng*coslat,
306 = y = (n + hgt)*sinlng*coslat,
307 = z = (n*(1.0 - e^2) + hgt)*sinlat,
308 *
309 * where the "prime vertical radius", n, is a function of latitude
310 *
311 = n = a / sqrt(1 - (e*sinlat)^2),
312 *
313 * and a, the equatorial radius, and e^2 = (2 - f)*f, the (first)
314 * eccentricity of the ellipsoid, are constants. obsfix() inverts these
315 * iteratively by writing
316 *
317 = x = rho*coslng*coslat,
318 = y = rho*sinlng*coslat,
319 = zeta = rho*sinlat,
320 *
321 * where
322 *
323 = rho = n + hgt,
324 = = sqrt(x^2 + y^2 + zeta^2),
325 = zeta = z / (1 - n*e^2/rho),
326 *
327 * and iterating over the value of zeta. Since e is small, a good first
328 * approximation is given by zeta = z.
329 *
330 *
331 * unitfix() - Correct aberrant CUNITia keyvalues
332 * ----------------------------------------------
333 * unitfix() applies wcsutrn() to translate non-standard CUNITia keyvalues,
334 * e.g. 'DEG' -> 'deg', also stripping off unnecessary whitespace.
335 *
336 * unitfix() is expected to be invoked before wcsset(), which will fail if
337 * non-standard CUNITia keyvalues have not been translated.
338 *
339 * Given:
340 * ctrl int Do potentially unsafe translations described in the
341 * usage notes to wcsutrn().
342 *
343 * Given and returned:
344 * wcs struct wcsprm*
345 * Coordinate transformation parameters.
346 *
347 * Function return value:
348 * int Status return value:
349 * -1: No change required (not an error).
350 * 0: Success (an alias was applied).
351 * 1: Null wcsprm pointer passed.
352 *
353 * When units are translated (i.e. 0 is returned), an
354 * informative message is set in wcsprm::err if enabled,
355 * see wcserr_enable(), with wcsprm::err.status set to
356 * FIXERR_UNITS_ALIAS.
357 *
358 *
359 * spcfix() - Translate AIPS-convention spectral types
360 * ---------------------------------------------------
361 * spcfix() translates AIPS-convention spectral coordinate types,
362 * '{FREQ,FELO,VELO}-{LSR,HEL,OBS}' (e.g. 'FREQ-OBS', 'FELO-HEL', 'VELO-LSR')
363 * set in wcsprm::ctype[], subject to VELREF set in wcsprm::velref.
364 *
365 * Note that if wcs::specsys is already set then it will not be overridden.
366 *
367 * AIPS-convention spectral types set in CTYPEia are translated on-the-fly by
368 * wcsset() but without modifying wcsprm::ctype[] or wcsprm::specsys. That is,
369 * only the information extracted from wcsprm::ctype[] is translated when
370 * wcsset() fills in wcsprm::spc (spcprm struct). spcfix() modifies
371 * wcsprm::ctype[] so that if the header is subsequently written out, e.g. by
372 * wcshdo(), then it will contain translated CTYPEia keyvalues.
373 *
374 * The operations done by spcfix() do not affect and are not affected by
375 * wcsset().
376 *
377 * Given and returned:
378 * wcs struct wcsprm*
379 * Coordinate transformation parameters. wcsprm::ctype[]
380 * and/or wcsprm::specsys may be changed.
381 *
382 * Function return value:
383 * int Status return value:
384 * -1: No change required (not an error).
385 * 0: Success.
386 * 1: Null wcsprm pointer passed.
387 * 2: Memory allocation failed.
388 * 3: Linear transformation matrix is singular.
389 * 4: Inconsistent or unrecognized coordinate axis
390 * types.
391 * 5: Invalid parameter value.
392 * 6: Invalid coordinate transformation parameters.
393 * 7: Ill-conditioned coordinate transformation
394 * parameters.
395 *
396 * For returns >= 0, a detailed message, whether
397 * informative or an error message, may be set in
398 * wcsprm::err if enabled, see wcserr_enable(), with
399 * wcsprm::err.status set to FIXERR_SPC_UPDTE.
400 *
401 *
402 * celfix() - Translate AIPS-convention celestial projection types
403 * ---------------------------------------------------------------
404 * celfix() translates AIPS-convention celestial projection types, NCP and
405 * GLS, set in the ctype[] member of the wcsprm struct.
406 *
407 * Two additional pv[] keyvalues are created when translating NCP, and three
408 * are created when translating GLS with non-zero reference point. If the pv[]
409 * array was initially allocated by wcsini() then the array will be expanded if
410 * necessary. Otherwise, error 2 will be returned if sufficient empty slots
411 * are not already available for use.
412 *
413 * AIPS-convention celestial projection types set in CTYPEia are translated
414 * on-the-fly by wcsset() but without modifying wcsprm::ctype[], wcsprm::pv[],
415 * or wcsprm::npv. That is, only the information extracted from
416 * wcsprm::ctype[] is translated when wcsset() fills in wcsprm::cel (celprm
417 * struct). celfix() modifies wcsprm::ctype[], wcsprm::pv[], and wcsprm::npv
418 * so that if the header is subsequently written out, e.g. by wcshdo(), then it
419 * will contain translated CTYPEia keyvalues and the relevant PVi_ma.
420 *
421 * The operations done by celfix() do not affect and are not affected by
422 * wcsset(). However, it uses information in the wcsprm struct provided by
423 * wcsset(), and will invoke it if necessary.
424 *
425 * Given and returned:
426 * wcs struct wcsprm*
427 * Coordinate transformation parameters. wcsprm::ctype[]
428 * and/or wcsprm::pv[] may be changed.
429 *
430 * Function return value:
431 * int Status return value:
432 * -1: No change required (not an error).
433 * 0: Success.
434 * 1: Null wcsprm pointer passed.
435 * 2: Memory allocation failed.
436 * 3: Linear transformation matrix is singular.
437 * 4: Inconsistent or unrecognized coordinate axis
438 * types.
439 * 5: Invalid parameter value.
440 * 6: Invalid coordinate transformation parameters.
441 * 7: Ill-conditioned coordinate transformation
442 * parameters.
443 *
444 * For returns > 1, a detailed error message is set in
445 * wcsprm::err if enabled, see wcserr_enable().
446 *
447 *
448 * cylfix() - Fix malformed cylindrical projections
449 * ------------------------------------------------
450 * cylfix() fixes WCS keyvalues for malformed cylindrical projections that
451 * suffer from the problem described in Sect. 7.3.4 of Paper I.
452 *
453 * cylfix() requires the wcsprm struct to have been set up by wcsset(), and
454 * will invoke it if necessary. After modification, the struct is reset on
455 * return with an explicit call to wcsset().
456 *
457 * Given:
458 * naxis const int []
459 * Image axis lengths.
460 *
461 * Given and returned:
462 * wcs struct wcsprm*
463 * Coordinate transformation parameters.
464 *
465 * Function return value:
466 * int Status return value:
467 * -1: No change required (not an error).
468 * 0: Success.
469 * 1: Null wcsprm pointer passed.
470 * 2: Memory allocation failed.
471 * 3: Linear transformation matrix is singular.
472 * 4: Inconsistent or unrecognized coordinate axis
473 * types.
474 * 5: Invalid parameter value.
475 * 6: Invalid coordinate transformation parameters.
476 * 7: Ill-conditioned coordinate transformation
477 * parameters.
478 * 8: All of the corner pixel coordinates are invalid.
479 * 9: Could not determine reference pixel coordinate.
480 * 10: Could not determine reference pixel value.
481 *
482 * For returns > 1, a detailed error message is set in
483 * wcsprm::err if enabled, see wcserr_enable().
484 *
485 *
486 * wcspcx() - regularize PCi_j
487 * ---------------------------
488 * wcspcx() "regularizes" the linear transformation matrix component of the
489 * coordinate transformation (PCi_ja) to make it more human-readable.
490 *
491 * Normally, upon encountering a FITS header containing a CDi_ja matrix,
492 * wcsset() simply treats it as PCi_ja and sets CDELTia to unity. However,
493 * wcspcx() decomposes CDi_ja into PCi_ja and CDELTia in such a way that
494 * CDELTia form meaningful scaling parameters. In practice, the residual
495 * PCi_ja matrix will often then be orthogonal, i.e. unity, or describing a
496 * pure rotation, axis permutation, or reflection, or a combination thereof.
497 *
498 * The decomposition is based on normalizing the length in the transformed
499 * system (i.e. intermediate pixel coordinates) of the orthonormal basis
500 * vectors of the pixel coordinate system. This deviates slightly from the
501 * prescription given by Eq. (4) of WCS Paper I, namely Sum(j=1,N)(PCi_ja)² = 1,
502 * in replacing the sum over j with the sum over i. Consequently, the columns
503 * of PCi_ja will consist of unit vectors. In practice, especially in cubes
504 * and higher dimensional images, at least some pairs of these unit vectors, if
505 * not all, will often be orthogonal or close to orthogonal.
506 *
507 * The sign of CDELTia is chosen to make the PCi_ja matrix as close to the,
508 * possibly permuted, unit matrix as possible, except that where the coordinate
509 * description contains a pair of celestial axes, the sign of CDELTia is set
510 * negative for the longitude axis and positive for the latitude axis.
511 *
512 * Optionally, rows of the PCi_ja matrix may also be permuted to diagonalize
513 * it as far as possible, thus undoing any transposition of axes in the
514 * intermdiate pixel coordinate system.
515 *
516 * If the coordinate description contains a celestial plane, then the angle of
517 * rotation of each of the basis vectors associated with the celestial axes is
518 * returned. For a pure rotation the two angles should be identical. Any
519 * difference between them is a measure of axis skewness.
520 *
521 * The decomposition is not performed for axes involving a sequent distortion
522 * function that is defined in terms of CDi_ja, such as TPV, TNX, or ZPX, which
523 * always are. The independent variables of the polynomial are therefore
524 * intermediate world coordinates rather than intermediate pixel coordinates.
525 * Because sequent distortions are always applied before CDELTia, if CDi_ja was
526 * translated to PCi_ja plus CDELTia, then the distortion would be altered
527 * unless the polynomial coefficients were also adjusted to account for the
528 * change of scale.
529 *
530 * wcspcx() requires the wcsprm struct to have been set up by wcsset(), and
531 * will invoke it if necessary. The wcsprm struct is reset on return with an
532 * explicit call to wcsset().
533 *
534 * Given and returned:
535 * wcs struct wcsprm*
536 * Coordinate transformation parameters.
537 *
538 * Given:
539 * dopc int If 1, then PCi_ja and CDELTia, as given, will be
540 * recomposed according to the above prescription. If 0,
541 * the operation is restricted to decomposing CDi_ja.
542 *
543 * permute int If 1, then after decomposition (or recomposition),
544 * permute rows of PCi_ja to make the axes of the
545 * intermediate pixel coordinate system match as closely
546 * as possible those of the pixel coordinates. That is,
547 * make it as close to a diagonal matrix as possible.
548 * However, celestial axes are special in always being
549 * paired, with the longitude axis preceding the latitude
550 * axis.
551 *
552 * All WCS entities indexed by i, such as CTYPEia,
553 * CRVALia, CDELTia, etc., including coordinate lookup
554 * tables, will also be permuted as necessary to account
555 * for the change to PCi_ja. This does not apply to
556 * CRPIXja, nor prior distortion functions. These
557 * operate on pixel coordinates, which are not affected
558 * by the permutation.
559 *
560 * Returned:
561 * rotn double[2] Rotation angle [deg] of each basis vector associated
562 * with the celestial axes. For a pure rotation the two
563 * angles should be identical. Any difference between
564 * them is a measure of axis skewness.
565 *
566 * May be set to the NULL pointer if this information is
567 * not required.
568 *
569 * Function return value:
570 * int Status return value:
571 * 0: Success.
572 * 1: Null wcsprm pointer passed.
573 * 2: Memory allocation failed.
574 * 5: CDi_j matrix not used.
575 * 6: Sequent distortion function present.
576 *
577 *
578 * Global variable: const char *wcsfix_errmsg[] - Status return messages
579 * ---------------------------------------------------------------------
580 * Error messages to match the status value returned from each function.
581 *
582 *===========================================================================*/
583 
584 #ifndef WCSLIB_WCSFIX
585 #define WCSLIB_WCSFIX
586 
587 #include "wcs.h"
588 #include "wcserr.h"
589 
590 #ifdef __cplusplus
591 extern "C" {
592 #endif
593 
594 #define CDFIX 0
595 #define DATFIX 1
596 #define OBSFIX 2
597 #define UNITFIX 3
598 #define SPCFIX 4
599 #define CELFIX 5
600 #define CYLFIX 6
601 #define NWCSFIX 7
602 
603 extern const char *wcsfix_errmsg[];
604 #define cylfix_errmsg wcsfix_errmsg
605 
607  FIXERR_OBSGEO_FIX = -5, // Observatory coordinates amended.
608  FIXERR_DATE_FIX = -4, // Date string reformatted.
609  FIXERR_SPC_UPDATE = -3, // Spectral axis type modified.
610  FIXERR_UNITS_ALIAS = -2, // Units alias translation.
611  FIXERR_NO_CHANGE = -1, // No change.
612  FIXERR_SUCCESS = 0, // Success.
613  FIXERR_NULL_POINTER = 1, // Null wcsprm pointer passed.
614  FIXERR_MEMORY = 2, // Memory allocation failed.
615  FIXERR_SINGULAR_MTX = 3, // Linear transformation matrix is singular.
616  FIXERR_BAD_CTYPE = 4, // Inconsistent or unrecognized coordinate
617  // axis types.
618  FIXERR_BAD_PARAM = 5, // Invalid parameter value.
619  FIXERR_BAD_COORD_TRANS = 6, // Invalid coordinate transformation
620  // parameters.
621  FIXERR_ILL_COORD_TRANS = 7, // Ill-conditioned coordinate transformation
622  // parameters.
623  FIXERR_BAD_CORNER_PIX = 8, // All of the corner pixel coordinates are
624  // invalid.
625  FIXERR_NO_REF_PIX_COORD = 9, // Could not determine reference pixel
626  // coordinate.
627  FIXERR_NO_REF_PIX_VAL = 10 // Could not determine reference pixel value.
628 };
629 
630 int wcsfix(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[]);
631 
632 int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[],
633  struct wcserr info[]);
634 
635 int cdfix(struct wcsprm *wcs);
636 
637 int datfix(struct wcsprm *wcs);
638 
639 int obsfix(int ctrl, struct wcsprm *wcs);
640 
641 int unitfix(int ctrl, struct wcsprm *wcs);
642 
643 int spcfix(struct wcsprm *wcs);
644 
645 int celfix(struct wcsprm *wcs);
646 
647 int cylfix(const int naxis[], struct wcsprm *wcs);
648 
649 int wcspcx(struct wcsprm *wcs, int dopc, int permute, double rotn[2]);
650 
651 
652 #ifdef __cplusplus
653 }
654 #endif
655 
656 #endif // WCSLIB_WCSFIX
Error message handling.
Definition: wcserr.h:243
Coordinate transformation parameters.
Definition: wcs.h:2044
wcsfix_errmsg_enum
Definition: wcsfix.h:606
@ FIXERR_NO_REF_PIX_VAL
Definition: wcsfix.h:627
@ FIXERR_UNITS_ALIAS
Definition: wcsfix.h:610
@ FIXERR_OBSGEO_FIX
Definition: wcsfix.h:607
@ FIXERR_MEMORY
Definition: wcsfix.h:614
@ FIXERR_DATE_FIX
Definition: wcsfix.h:608
@ FIXERR_BAD_PARAM
Definition: wcsfix.h:618
@ FIXERR_BAD_CORNER_PIX
Definition: wcsfix.h:623
@ FIXERR_BAD_CTYPE
Definition: wcsfix.h:616
@ FIXERR_BAD_COORD_TRANS
Definition: wcsfix.h:619
@ FIXERR_SPC_UPDATE
Definition: wcsfix.h:609
@ FIXERR_ILL_COORD_TRANS
Definition: wcsfix.h:621
@ FIXERR_SINGULAR_MTX
Definition: wcsfix.h:615
@ FIXERR_NO_REF_PIX_COORD
Definition: wcsfix.h:625
@ FIXERR_NO_CHANGE
Definition: wcsfix.h:611
@ FIXERR_SUCCESS
Definition: wcsfix.h:612
@ FIXERR_NULL_POINTER
Definition: wcsfix.h:613
int cylfix(const int naxis[], struct wcsprm *wcs)
Fix malformed cylindrical projections.
const char * wcsfix_errmsg[]
Status return messages.
int cdfix(struct wcsprm *wcs)
Fix erroneously omitted CDi_ja keywords.
int obsfix(int ctrl, struct wcsprm *wcs)
complete the OBSGEO-[XYZLBH] vector of observatory coordinates.
int wcsfixi(int ctrl, const int naxis[], struct wcsprm *wcs, int stat[], struct wcserr info[])
Translate a non-standard WCS struct.
int datfix(struct wcsprm *wcs)
Translate DATE-OBS and derive MJD-OBS or vice versa.
int wcspcx(struct wcsprm *wcs, int dopc, int permute, double rotn[2])
regularize PCi_j.
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.
int celfix(struct wcsprm *wcs)
Translate AIPS-convention celestial projection types.
int spcfix(struct wcsprm *wcs)
Translate AIPS-convention spectral types.