1 | /*
|
---|
2 | *+
|
---|
3 | * Name:
|
---|
4 | * palDafin
|
---|
5 |
|
---|
6 | * Purpose:
|
---|
7 | * Sexagesimal character string to angle
|
---|
8 |
|
---|
9 | * Language:
|
---|
10 | * Starlink ANSI C
|
---|
11 |
|
---|
12 | * Type of Module:
|
---|
13 | * Library routine
|
---|
14 |
|
---|
15 | * Invocation:
|
---|
16 | * void palDafin ( const char *string, int *ipos, double *a, int *j );
|
---|
17 |
|
---|
18 | * Arguments:
|
---|
19 | * string = const char * (Given)
|
---|
20 | * String containing deg, arcmin, arcsec fields
|
---|
21 | * ipos = int * (Given & Returned)
|
---|
22 | * Position to start decoding "string". First character
|
---|
23 | * is position 1 for compatibility with SLA. After
|
---|
24 | * calling this routine "iptr" will be positioned after
|
---|
25 | * the sexagesimal string.
|
---|
26 | * a = double * (Returned)
|
---|
27 | * Angle in radians.
|
---|
28 | * j = int * (Returned)
|
---|
29 | * status: 0 = OK
|
---|
30 | * +1 = default, A unchanged
|
---|
31 | * -1 = bad degrees )
|
---|
32 | * -2 = bad arcminutes ) (note 3)
|
---|
33 | * -3 = bad arcseconds )
|
---|
34 |
|
---|
35 | * Description:
|
---|
36 | * Extracts an angle from a sexagesimal string with degrees, arcmin,
|
---|
37 | * arcsec fields using space or comma delimiters.
|
---|
38 |
|
---|
39 | * Authors:
|
---|
40 | * TIMJ: Tim Jenness (JAC, Hawaii)
|
---|
41 | * PTW: Patrick T. Wallace
|
---|
42 | * {enter_new_authors_here}
|
---|
43 |
|
---|
44 | * Example:
|
---|
45 | * argument before after
|
---|
46 | *
|
---|
47 | * STRING '-57 17 44.806 12 34 56.7' unchanged
|
---|
48 | * IPTR 1 16 (points to 12...)
|
---|
49 | * A ? -1.00000D0
|
---|
50 | * J ? 0
|
---|
51 |
|
---|
52 | * Notes:
|
---|
53 | * - The first three "fields" in STRING are degrees, arcminutes,
|
---|
54 | * arcseconds, separated by spaces or commas. The degrees field
|
---|
55 | * may be signed, but not the others. The decoding is carried
|
---|
56 | * out by the palDfltin routine and is free-format.
|
---|
57 | * - Successive fields may be absent, defaulting to zero. For
|
---|
58 | * zero status, the only combinations allowed are degrees alone,
|
---|
59 | * degrees and arcminutes, and all three fields present. If all
|
---|
60 | * three fields are omitted, a status of +1 is returned and A is
|
---|
61 | * unchanged. In all other cases A is changed.
|
---|
62 | * - Range checking:
|
---|
63 | *
|
---|
64 | * The degrees field is not range checked. However, it is
|
---|
65 | * expected to be integral unless the other two fields are absent.
|
---|
66 | *
|
---|
67 | * The arcminutes field is expected to be 0-59, and integral if
|
---|
68 | * the arcseconds field is present. If the arcseconds field
|
---|
69 | * is absent, the arcminutes is expected to be 0-59.9999...
|
---|
70 | *
|
---|
71 | * The arcseconds field is expected to be 0-59.9999...
|
---|
72 | *
|
---|
73 | * - Decoding continues even when a check has failed. Under these
|
---|
74 | * circumstances the field takes the supplied value, defaulting
|
---|
75 | * to zero, and the result A is computed and returned.
|
---|
76 | * - Further fields after the three expected ones are not treated
|
---|
77 | * as an error. The pointer IPOS is left in the correct state
|
---|
78 | * for further decoding with the present routine or with palDfltin
|
---|
79 | * etc. See the example, above.
|
---|
80 | * - If STRING contains hours, minutes, seconds instead of degrees
|
---|
81 | * etc, or if the required units are turns (or days) instead of
|
---|
82 | * radians, the result A should be multiplied as follows:
|
---|
83 | *
|
---|
84 | * for to obtain multiply
|
---|
85 | * STRING A in A by
|
---|
86 | *
|
---|
87 | * d ' " radians 1 = 1.0
|
---|
88 | * d ' " turns 1/2pi = 0.1591549430918953358
|
---|
89 | * h m s radians 15 = 15.0
|
---|
90 | * h m s days 15/2pi = 2.3873241463784300365
|
---|
91 |
|
---|
92 | * History:
|
---|
93 | * 2012-03-08 (TIMJ):
|
---|
94 | * Initial version from SLA/F using Fortran documentation
|
---|
95 | * Adapted with permission from the Fortran SLALIB library.
|
---|
96 | * 2012-10-17 (TIMJ):
|
---|
97 | * Fix range check on arcminute value.
|
---|
98 | * {enter_further_changes_here}
|
---|
99 |
|
---|
100 | * Copyright:
|
---|
101 | * Copyright (C) 1996 Rutherford Appleton Laboratory
|
---|
102 | * Copyright (C) 2012 Science and Technology Facilities Council.
|
---|
103 | * All Rights Reserved.
|
---|
104 |
|
---|
105 | * Licence:
|
---|
106 | * This program is free software; you can redistribute it and/or
|
---|
107 | * modify it under the terms of the GNU General Public License as
|
---|
108 | * published by the Free Software Foundation; either version 3 of
|
---|
109 | * the License, or (at your option) any later version.
|
---|
110 | *
|
---|
111 | * This program is distributed in the hope that it will be
|
---|
112 | * useful, but WITHOUT ANY WARRANTY; without even the implied
|
---|
113 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
---|
114 | * PURPOSE. See the GNU General Public License for more details.
|
---|
115 | *
|
---|
116 | * You should have received a copy of the GNU General Public License
|
---|
117 | * along with this program; if not, write to the Free Software
|
---|
118 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
---|
119 | * MA 02110-1301, USA.
|
---|
120 |
|
---|
121 | * Bugs:
|
---|
122 | * {note_any_bugs_here}
|
---|
123 | *-
|
---|
124 | */
|
---|
125 |
|
---|
126 | #include "pal.h"
|
---|
127 | #include "palmac.h"
|
---|
128 | #include "pal1sofa.h"
|
---|
129 |
|
---|
130 | #include <math.h>
|
---|
131 |
|
---|
132 | void palDafin ( const char *string, int *ipos, double *a, int *j ) {
|
---|
133 |
|
---|
134 | int jd = 0; /* Status for degree parsing */
|
---|
135 | int jm = 0; /* Status for arcmin parsing */
|
---|
136 | int js = 0; /* Status for arcsec parsing */
|
---|
137 | int jf = 0; /* Internal copy of status */
|
---|
138 | double deg = 0.0;
|
---|
139 | double arcmin = 0.0;
|
---|
140 | double arcsec = 0.0;
|
---|
141 |
|
---|
142 | /* Decode degrees, arcminutes, arcseconds */
|
---|
143 | palDfltin( string, ipos, °, &jd );
|
---|
144 | if (jd > 1) {
|
---|
145 | jf = -1;
|
---|
146 | } else {
|
---|
147 |
|
---|
148 | palDfltin( string, ipos, &arcmin, &jm );
|
---|
149 | if ( jm < 0 || jm > 1 ) {
|
---|
150 | jf = -2;
|
---|
151 | } else {
|
---|
152 |
|
---|
153 | palDfltin( string, ipos, &arcsec, &js );
|
---|
154 | if (js < 0 || js > 1) {
|
---|
155 | jf = -3;
|
---|
156 |
|
---|
157 | } else if (jd > 0) { /* See if combination of fields is credible */
|
---|
158 | /* No degrees: arcmin, arcsec ought also to be absent */
|
---|
159 | if (jm == 0) {
|
---|
160 | /* Suspect arcmin */
|
---|
161 | jf = -2;
|
---|
162 | } else if (js == 0) {
|
---|
163 | /* Suspect arcsec */
|
---|
164 | jf = -3;
|
---|
165 | } else {
|
---|
166 | /* All three fields absent */
|
---|
167 | jf = 1;
|
---|
168 | }
|
---|
169 |
|
---|
170 | } else if (jm != 0 && js == 0) { /* Deg present: if arcsec present should have arcmin */
|
---|
171 | jf = -3;
|
---|
172 |
|
---|
173 | /* Tests for range and integrality */
|
---|
174 | } else if (jm == 0 && DINT(deg) != deg) { /* Degrees */
|
---|
175 | jf = -1;
|
---|
176 |
|
---|
177 | } else if ( (js == 0 && DINT(arcmin) != arcmin) || arcmin >= 60.0 ) { /* Arcmin */
|
---|
178 | jf = -2;
|
---|
179 |
|
---|
180 | } else if (arcsec >= 60.0) { /* Arcsec */
|
---|
181 | jf = -3;
|
---|
182 | }
|
---|
183 | }
|
---|
184 | }
|
---|
185 |
|
---|
186 | /* Unless all three fields absent, compute angle value */
|
---|
187 | if (jf <= 0) {
|
---|
188 | *a = PAL__DAS2R * ( 60.0 * ( 60.0 * fabs(deg) + arcmin) + arcsec );
|
---|
189 | if ( jd < 0 ) *a *= -1.;
|
---|
190 | }
|
---|
191 |
|
---|
192 | *j = jf;
|
---|
193 |
|
---|
194 | }
|
---|