1 |
/* |
2 |
* keystuff.c (linked from) ~rick/src/util |
3 |
* |
4 |
* library of miscellaneous utility functions for dealing with DRMS record keys |
5 |
* |
6 |
* append_args_tokey () |
7 |
* append_keyval_to_primekeyval () |
8 |
* check_and_copy_key () |
9 |
* check_and_setkey_TYPE () |
10 |
* copy_prime_keys () |
11 |
* create_primekey_from_keylist () |
12 |
* drms_appendstr_tokey () |
13 |
* drms_wcs_timestep () |
14 |
* propagate_keys () |
15 |
* |
16 |
* Bugs: |
17 |
* Commented out warnings of type mis-matches in check_and_copy_key |
18 |
* There is evidently a bug in append_keyval_to_primekeyval() in keystuff.c, |
19 |
* as the ingest_track module was generating a seg fault in |
20 |
* drms_setkey_string() with values of the PrimeKeyString like |
21 |
* 1987:000.0|22.5|-52.5|2002.03.30_00:44:30_TAI|1664|16.0|16.0|0.100000|0.000000|Postels|0.12500|0.00000|prog:mdi,level:lev1.5,series:fd_V_01h[80986-81014],sel:[53-36] |
22 |
* I was only able to work around this by changing the initial value of |
23 |
* buflen in append_keyval_to_primekeyval() from 128 to 256 |
24 |
* Many combinations of legitimate prefixes and unit strings for WCS time |
25 |
* descriptions are not yet supported |
26 |
* Consistency of floating-point key values in check_and_setkey_XXX is |
27 |
* only guaranteed to within the recommended format precision; this is |
28 |
* by design |
29 |
* check_and_setkey unimplemented for keys of type char and long long |
30 |
* |
31 |
* Revision history is at end of file |
32 |
*/ |
33 |
|
34 |
int check_and_set_key_short (DRMS_Record_t *new, const char *key, short val) { |
35 |
DRMS_Keyword_t *keywd; |
36 |
short vreq; |
37 |
int status; |
38 |
|
39 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
40 |
if (keywd->info->recscope != 1) { |
41 |
/* it's not a constant, so don't worry, just set it */ |
42 |
drms_setkey_short (new, key, val); |
43 |
return 0; |
44 |
} |
45 |
vreq = drms_getkey_short (new, key, &status); |
46 |
if (status) { |
47 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
48 |
return 1; |
49 |
} |
50 |
if (vreq != val) { |
51 |
char format[256]; |
52 |
sprintf (format, |
53 |
"Error: parameter value %s for keyword %%s\n differs from required value %s\n", |
54 |
keywd->info->format, keywd->info->format); |
55 |
fprintf (stderr, format, val, key, vreq); |
56 |
return 1; |
57 |
} |
58 |
return 0; |
59 |
} |
60 |
|
61 |
int check_and_set_key_int (DRMS_Record_t *new, const char *key, int val) { |
62 |
DRMS_Keyword_t *keywd; |
63 |
int vreq; |
64 |
int status; |
65 |
|
66 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
67 |
if (keywd->info->recscope != 1) { |
68 |
/* it's not a constant, so don't worry, just set it */ |
69 |
drms_setkey_int (new, key, val); |
70 |
return 0; |
71 |
} |
72 |
vreq = drms_getkey_int (new, key, &status); |
73 |
if (status) { |
74 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
75 |
return 1; |
76 |
} |
77 |
if (vreq != val) { |
78 |
char format[256]; |
79 |
sprintf (format, |
80 |
"Error: parameter value %s for keyword %%s\n differs from required value %s\n", |
81 |
keywd->info->format, keywd->info->format); |
82 |
fprintf (stderr, format, val, key, vreq); |
83 |
return 1; |
84 |
} |
85 |
return 0; |
86 |
} |
87 |
|
88 |
int check_and_set_key_longlong (DRMS_Record_t *new, const char *key, |
89 |
long long val) { |
90 |
DRMS_Keyword_t *keywd; |
91 |
long long vreq; |
92 |
int status; |
93 |
|
94 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
95 |
if (keywd->info->recscope != 1) { |
96 |
/* it's not a constant, so don't worry, just set it */ |
97 |
drms_setkey_longlong (new, key, val); |
98 |
return 0; |
99 |
} |
100 |
vreq = drms_getkey_longlong (new, key, &status); |
101 |
if (status) { |
102 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
103 |
return 1; |
104 |
} |
105 |
if (vreq != val) { |
106 |
char format[256]; |
107 |
sprintf (format, |
108 |
"Error: parameter value %s for keyword %%s\n differs from required value %s\n", |
109 |
keywd->info->format, keywd->info->format); |
110 |
fprintf (stderr, format, val, key, vreq); |
111 |
return 1; |
112 |
} |
113 |
return 0; |
114 |
} |
115 |
|
116 |
int check_and_set_key_float (DRMS_Record_t *new, const char *key, float val) { |
117 |
DRMS_Keyword_t *keywd; |
118 |
float vreq; |
119 |
int status; |
120 |
char sreq[128], sval[128]; |
121 |
|
122 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
123 |
if (keywd->info->recscope != 1) { |
124 |
/* it's not a constant, so don't worry, just set it */ |
125 |
drms_setkey_float (new, key, val); |
126 |
return 0; |
127 |
} |
128 |
vreq = drms_getkey_float (new, key, &status); |
129 |
if (status) { |
130 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
131 |
return 1; |
132 |
} |
133 |
sprintf (sreq, keywd->info->format, vreq); |
134 |
sprintf (sval, keywd->info->format, val); |
135 |
if (strcmp (sreq, sval)) { |
136 |
char format[256]; |
137 |
sprintf (format, |
138 |
"Error: parameter value %s for keyword %%s\n differs from required value %s\n", |
139 |
keywd->info->format, keywd->info->format); |
140 |
fprintf (stderr, format, val, key, vreq); |
141 |
return 1; |
142 |
} |
143 |
return 0; |
144 |
} |
145 |
|
146 |
int check_and_set_key_double (DRMS_Record_t *new, const char *key, double val) { |
147 |
DRMS_Keyword_t *keywd; |
148 |
double vreq; |
149 |
int status; |
150 |
char sreq[128], sval[128]; |
151 |
|
152 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
153 |
if (keywd->info->recscope != 1) { |
154 |
/* it's not a constant, so don't worry, just set it */ |
155 |
drms_setkey_double (new, key, val); |
156 |
return 0; |
157 |
} |
158 |
vreq = drms_getkey_double (new, key, &status); |
159 |
if (status) { |
160 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
161 |
return 1; |
162 |
} |
163 |
sprintf (sreq, keywd->info->format, vreq); |
164 |
sprintf (sval, keywd->info->format, val); |
165 |
if (strcmp (sreq, sval)) { |
166 |
char format[256]; |
167 |
sprintf (format, |
168 |
"Error: parameter value %s for keyword %%s\n differs from required value %s\n", |
169 |
keywd->info->format, keywd->info->format); |
170 |
fprintf (stderr, format, val, key, vreq); |
171 |
return 1; |
172 |
} |
173 |
return 0; |
174 |
} |
175 |
|
176 |
int check_and_set_key_str (DRMS_Record_t *new, const char *key, char *val) { |
177 |
DRMS_Keyword_t *keywd; |
178 |
char *vreq; |
179 |
int status; |
180 |
|
181 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
182 |
if (keywd->info->recscope != 1) { |
183 |
/* it's not a constant, so don't worry, just set it */ |
184 |
drms_setkey_string (new, key, val); |
185 |
return 0; |
186 |
} |
187 |
vreq = drms_getkey_string (new, key, &status); |
188 |
if (status) { |
189 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
190 |
return 1; |
191 |
} |
192 |
if (strcmp (vreq, val)) { |
193 |
char format[256]; |
194 |
sprintf (format, |
195 |
"Error: parameter value \"%s\" for keyword %%s\n differs from required value \"%s\"\n", |
196 |
keywd->info->format, keywd->info->format); |
197 |
fprintf (stderr, format, val, key, vreq); |
198 |
return 1; |
199 |
} |
200 |
return 0; |
201 |
} |
202 |
|
203 |
int check_and_set_key_time (DRMS_Record_t *new, const char *key, TIME tval) { |
204 |
DRMS_Keyword_t *keywd; |
205 |
TIME treq; |
206 |
int status; |
207 |
char sreq[64], sval[64]; |
208 |
|
209 |
if (!(keywd = drms_keyword_lookup (new, key, 1))) return 0; |
210 |
if (keywd->info->recscope != 1) { |
211 |
/* it's not a constant, so don't worry, just set it */ |
212 |
drms_setkey_time (new, key, tval); |
213 |
return 0; |
214 |
} |
215 |
treq = drms_getkey_time (new, key, &status); |
216 |
if (status) { |
217 |
fprintf (stderr, "Error retrieving value for constant keyword %s\n", key); |
218 |
return 1; |
219 |
} |
220 |
sprint_time (sreq, treq, keywd->info->unit, atoi (keywd->info->format)); |
221 |
sprint_time (sval, tval, keywd->info->unit, atoi (keywd->info->format)); |
222 |
if (strcmp (sval, sreq)) { |
223 |
fprintf (stderr, "Error: parameter value %s for keyword %s\n", sval, key); |
224 |
fprintf (stderr, " differs from required value %s\n", sreq); |
225 |
return 1; |
226 |
} |
227 |
return 0; |
228 |
} |
229 |
|
230 |
int check_and_copy_key (DRMS_Record_t *new, DRMS_Record_t *old, |
231 |
const char *key) { |
232 |
DRMS_Keyword_t *oldkey, *newkey, *pkey; |
233 |
DRMS_Type_t *type; |
234 |
DRMS_Type_Value_t *value; |
235 |
int n, status; |
236 |
|
237 |
if (!(oldkey = drms_keyword_lookup (old, key, 1))) return 0; |
238 |
if (newkey = drms_keyword_lookup (new, key, 0)) { |
239 |
/* is it a link? */ |
240 |
if (newkey->info->islink) { |
241 |
int pkeyct = old->seriesinfo->pidx_num; |
242 |
type = (DRMS_Type_t *)malloc (pkeyct * sizeof (DRMS_Type_t)); |
243 |
value = (DRMS_Type_Value_t *)malloc (pkeyct * sizeof (DRMS_Type_Value_t)); |
244 |
for (n = 0; n < pkeyct; n++) { |
245 |
pkey = old->seriesinfo->pidx_keywords[n]; |
246 |
value[n] = drms_getkey (old, pkey->info->name, &type[n], NULL); |
247 |
} |
248 |
/* types and values refer to the prime keys specifying record old */ |
249 |
drms_setlink_dynamic (new, newkey->info->linkname, type, value); |
250 |
free (type); |
251 |
free (value); |
252 |
return 0; |
253 |
} |
254 |
} else { |
255 |
return 0; |
256 |
} |
257 |
/* check that key types agree (this could be relaxed) */ |
258 |
if (oldkey->info->type != newkey->info->type) { |
259 |
/* |
260 |
fprintf (stderr, "Warning: type for keyword %s differs in input and output\n", |
261 |
key); |
262 |
*/ |
263 |
; |
264 |
/* |
265 |
return 1; |
266 |
*/ |
267 |
} |
268 |
if (newkey->info->recscope != 1) { |
269 |
/* it's not a constant, so don't worry, just copy it */ |
270 |
/* but what if it is a link? */ |
271 |
drms_copykey (new, old, key); |
272 |
return 0; |
273 |
} |
274 |
switch (newkey->info->type) { |
275 |
/* |
276 |
case DRMS_TYPE_CHAR: |
277 |
return check_and_set_key_char (new, key, |
278 |
drms_getkey_char (old, key, &status)); |
279 |
*/ |
280 |
case DRMS_TYPE_SHORT: |
281 |
return check_and_set_key_short (new, key, |
282 |
drms_getkey_short (old, key, &status)); |
283 |
case DRMS_TYPE_INT: |
284 |
return check_and_set_key_int (new, key, |
285 |
drms_getkey_int (old, key, &status)); |
286 |
/* |
287 |
case DRMS_TYPE_LONGLONG: |
288 |
return check_and_set_key_longlong (new, key, |
289 |
drms_getkey_longlong (old, key, &status)); |
290 |
*/ |
291 |
case DRMS_TYPE_FLOAT: |
292 |
return check_and_set_key_float (new, key, |
293 |
drms_getkey_float (old, key, &status)); |
294 |
case DRMS_TYPE_DOUBLE: |
295 |
return check_and_set_key_double (new, key, |
296 |
drms_getkey_double (old, key, &status)); |
297 |
case DRMS_TYPE_TIME: |
298 |
return check_and_set_key_time (new, key, |
299 |
drms_getkey_time (old, key, &status)); |
300 |
case DRMS_TYPE_STRING: |
301 |
return check_and_set_key_str (new, key, |
302 |
drms_getkey_string (old, key, &status)); |
303 |
default: |
304 |
fprintf (stderr, |
305 |
"Error in check_and_copy_key(): Unknown type %s for keyword %s\n", |
306 |
drms_type2str (newkey->info->type), key); |
307 |
return 1; |
308 |
} |
309 |
} |
310 |
|
311 |
int drms_appendstr_tokey (DRMS_Record_t *rec, const char *key, const char *str, |
312 |
int addline) { |
313 |
/* |
314 |
* This is just a private, slightly simplified version of the static function |
315 |
* AppendStrKeyInternal() in $DRMS/base/drms/libs/api/drms_keyword.c |
316 |
*/ |
317 |
DRMS_Keyword_t *keyword = NULL; |
318 |
int rv; |
319 |
|
320 |
if (!rec || !str) return DRMS_ERROR_INVALIDDATA; |
321 |
if (!strlen (str)) return 0; |
322 |
keyword = drms_keyword_lookup (rec, key, 0); |
323 |
if (!keyword) return DRMS_ERROR_UNKNOWNKEYWORD; |
324 |
if (keyword->info->islink || drms_keyword_isconstant (keyword) || |
325 |
drms_keyword_isslotted (keyword)) |
326 |
return DRMS_ERROR_KEYWORDREADONLY; |
327 |
if (keyword->info->type != DRMS_TYPE_STRING) return DRMS_ERROR_INVALIDDATA; |
328 |
/* append to old string, if it exists, otherwise just assign */ |
329 |
if (keyword->value.string_val) { |
330 |
char *tmp = NULL; |
331 |
if (strlen (keyword->value.string_val)) { |
332 |
size_t strsz = strlen (keyword->value.string_val) + strlen (str) + 2; |
333 |
tmp = malloc(strsz); |
334 |
if (addline) |
335 |
snprintf (tmp, strsz, "%s\n%s", keyword->value.string_val, str); |
336 |
else |
337 |
snprintf (tmp, strsz, "%s%s", keyword->value.string_val, str); |
338 |
} else tmp = strdup (str); |
339 |
free (keyword->value.string_val); |
340 |
keyword->value.string_val = tmp; |
341 |
} else keyword->value.string_val = strdup (str); |
342 |
return 0; |
343 |
} |
344 |
|
345 |
void append_args_tokey (DRMS_Record_t *rec, const char *key) { |
346 |
/* |
347 |
* Appends a list of all calling argument values to the designated |
348 |
* key (presumably HISTORY or COMMENT) |
349 |
*/ |
350 |
ModuleArgs_t *arg = gModArgs; |
351 |
CmdParams_t *params = &cmdparams; |
352 |
int flagct = 0; |
353 |
char *strval; |
354 |
char flaglist[72]; |
355 |
|
356 |
drms_appendstr_tokey (rec, key, "Module called with following arguments:", 1); |
357 |
while (arg->type != ARG_END) { |
358 |
if (arg->type == ARG_FLAG) { |
359 |
if (params_isflagset (params, arg->name)) { |
360 |
if (!flagct) sprintf (flaglist, "with flags -"); |
361 |
strcat (flaglist, arg->name); |
362 |
flagct++; |
363 |
} |
364 |
} else { |
365 |
drms_appendstr_tokey (rec, key, arg->name, 1); |
366 |
drms_appendstr_tokey (rec, key, "= ", 0); |
367 |
strval = strdup (params_get_str (params, arg->name)); |
368 |
drms_appendstr_tokey (rec, key, strval, 0); |
369 |
} |
370 |
arg++; |
371 |
} |
372 |
if (flagct) drms_appendstr_tokey (rec, key, flaglist, 1); |
373 |
return; |
374 |
} |
375 |
|
376 |
/* |
377 |
* Parse a token separated list of character strings into an array of |
378 |
* character strings and return the number of such strings, plus the |
379 |
* array itself in the argument list |
380 |
* |
381 |
* Bugs: |
382 |
* There is no way of including the token in the parsed strings |
383 |
*/ |
384 |
int construct_stringlist (const char *request, char token, char ***stringlist) { |
385 |
int keyct = 1; |
386 |
int m, n; |
387 |
char *req, *req0 = strdup (request); |
388 |
char c; |
389 |
/* count the number of separators */ |
390 |
req = req0; |
391 |
while (c = *req) { |
392 |
if (c == token) { |
393 |
*req = '\0'; |
394 |
keyct++; |
395 |
} |
396 |
req++; |
397 |
} |
398 |
*stringlist = (char **)malloc (keyct * sizeof (char **)); |
399 |
req = req0; |
400 |
for (n = 0; n < keyct; n++) { |
401 |
(*stringlist)[n] = strdup (req); |
402 |
req += strlen (req) + 1; |
403 |
} |
404 |
for (n = 0; n < keyct; n++) { |
405 |
char *subs = (*stringlist)[n]; |
406 |
/* remove leading white space */ |
407 |
while (isspace (c = *subs)) subs++; |
408 |
(*stringlist)[n] = subs; |
409 |
/* remove trailing white space */ |
410 |
if (strlen (subs)) { |
411 |
subs += strlen (subs) - 1; |
412 |
while (isspace (c = *subs)) { |
413 |
*subs = '\0'; |
414 |
subs--; |
415 |
} |
416 |
} |
417 |
} |
418 |
/* remove empty strings from list */ |
419 |
for (n = 0; n < keyct; n++) { |
420 |
if (!strlen ((*stringlist)[n])) { |
421 |
for (m = n; m < keyct - 1; m++) |
422 |
(*stringlist)[m] = (*stringlist)[m + 1]; |
423 |
keyct--; |
424 |
} |
425 |
} |
426 |
free (req0); |
427 |
return keyct; |
428 |
} |
429 |
|
430 |
int copy_prime_keys (DRMS_Record_t *new, DRMS_Record_t *old) { |
431 |
/* |
432 |
* Copy the prime keys of new from old if possible |
433 |
* For slotted prime keys, it is copy the key value rather than its index |
434 |
*/ |
435 |
DRMS_Keyword_t *pkey; |
436 |
int n, kstat = 0; |
437 |
char *key, *pkeyindex; |
438 |
int pkeyct = new->seriesinfo->pidx_num; |
439 |
|
440 |
for (n = 0; n < pkeyct; n++) { |
441 |
pkey = new->seriesinfo->pidx_keywords[n]; |
442 |
key = strdup (pkey->info->name); |
443 |
|
444 |
if (pkeyindex = strstr (key, "_index")) *pkeyindex = '\0'; |
445 |
if (!drms_keyword_lookup (old, key, 1)) continue; |
446 |
kstat += check_and_copy_key (new, old, key); |
447 |
} |
448 |
return kstat; |
449 |
} |
450 |
|
451 |
void string_insert_escape_char (char **str, const char esc) { |
452 |
int i, n, ct = 0, len; |
453 |
|
454 |
len = strlen (*str); |
455 |
for (n = 0; n < len; n++) if ((*str)[n] == esc) ct++; |
456 |
if (ct) { |
457 |
*str = realloc (*str, 2*len); |
458 |
for (n = len; n < 2*len; n++) (*str)[n] = '\0'; |
459 |
} |
460 |
for (n = 0; n < len; n++) { |
461 |
if ((*str)[n] == esc) { |
462 |
for (i = len; i > n; i--) (*str)[i] = (*str)[i-1]; |
463 |
(*str)[n] = '\\'; |
464 |
len++; |
465 |
n++; |
466 |
} |
467 |
} |
468 |
} |
469 |
|
470 |
int append_keyval_to_primekeyval (char **pkey, DRMS_Record_t *rec, |
471 |
const char *key) { |
472 |
DRMS_Keyword_t *keywd; |
473 |
int size; |
474 |
static int curlen; |
475 |
char **buf; |
476 |
int buflen = 256; |
477 |
|
478 |
if (!*pkey) { |
479 |
*pkey = calloc (buflen, sizeof (char)); |
480 |
curlen = buflen; |
481 |
} |
482 |
size = strlen (*pkey); |
483 |
if (size) { |
484 |
/* after first key, append separator */ |
485 |
size++; |
486 |
if (size >= curlen) { |
487 |
char *tmp = calloc (curlen, sizeof (char)); |
488 |
strcpy (tmp, *pkey); |
489 |
curlen += buflen; |
490 |
*pkey = realloc (*pkey, curlen); |
491 |
bzero (*pkey, curlen); |
492 |
strcpy (*pkey, tmp); |
493 |
free (tmp); |
494 |
} |
495 |
strcat (*pkey, "|"); |
496 |
} |
497 |
if (!(keywd = drms_keyword_lookup (rec, key, 1))) { |
498 |
fprintf (stderr, "create_primekey_from_keylist(): %s not found\n", key); |
499 |
if (*pkey) free (*pkey); |
500 |
*pkey = NULL; |
501 |
return 1; |
502 |
} |
503 |
buf = malloc (sizeof (char **)); |
504 |
*buf = malloc (DRMS_DEFVAL_MAXLEN * sizeof (char *)); |
505 |
drms_keyword_snprintfval (keywd, *buf, DRMS_DEFVAL_MAXLEN); |
506 |
if (keywd->info->type == DRMS_TYPE_STRING || |
507 |
keywd->info->type == DRMS_TYPE_TIME) { |
508 |
string_insert_escape_char (buf, '|'); |
509 |
} |
510 |
size += strlen (*buf); |
511 |
if (size >= curlen) { |
512 |
curlen += buflen; |
513 |
*pkey = realloc (*pkey, curlen); |
514 |
} |
515 |
strncat (*pkey, *buf, strlen (*buf)); |
516 |
free (*buf); |
517 |
free (buf); |
518 |
return 0; |
519 |
} |
520 |
|
521 |
char *create_primekey_from_keylist (DRMS_Record_t *rec, char **keylist, |
522 |
int keyct) { |
523 |
char *pkey = NULL; |
524 |
int n; |
525 |
for (n = 0; n < keyct; n++) |
526 |
if (append_keyval_to_primekeyval (&pkey, rec, keylist[n])) break; |
527 |
|
528 |
return pkey; |
529 |
} |
530 |
|
531 |
int propagate_keys (DRMS_Record_t *to, DRMS_Record_t *from, char **keylist, |
532 |
int keyct) { |
533 |
int n, status = 0; |
534 |
for (n = 0; n < keyct; n++) |
535 |
status += check_and_copy_key (to, from, keylist[n]); |
536 |
return status; |
537 |
} |
538 |
|
539 |
char *iau_units_parse_unit (char *unit, double *scale) { |
540 |
char prefix = unit[0]; |
541 |
|
542 |
*scale = 1.0; |
543 |
switch (prefix) { |
544 |
case ('y'): |
545 |
if (strcmp (unit, "yr")) { |
546 |
*scale = 1.0e24; |
547 |
return &unit[1]; |
548 |
} else return unit; |
549 |
case ('z'): *scale = 1.0e21; return &unit[1]; |
550 |
case ('a'): |
551 |
if (strlen (unit) == 1) return unit; |
552 |
if (strcmp (unit, "arcmin") && strcmp (unit, "arcsec") && |
553 |
strcmp (unit, "adu")) { |
554 |
*scale = 1.0e18; |
555 |
return &unit[1]; |
556 |
} else return unit; |
557 |
case ('f'): *scale = 1.0e15; return &unit[1]; |
558 |
case ('p'): |
559 |
if (strcmp (unit, "pc") && strcmp (unit, "ph") && strcmp (unit, "photon") |
560 |
&& strcmp (unit, "pix") && strcmp (unit, "pixel") ) { |
561 |
*scale = 1.0e12; |
562 |
return &unit[1]; |
563 |
} else return unit; |
564 |
case ('n'): *scale = 1.0e9; return &unit[1]; |
565 |
case ('u'): *scale = 1.0e6; return &unit[1]; |
566 |
case ('m'): |
567 |
if (strlen (unit) == 1) return unit; |
568 |
if (strcmp (unit, "mol") && strcmp (unit, "mas") && strcmp (unit, "min") |
569 |
&& strcmp (unit, "mag")) { |
570 |
*scale = 1.0e3; |
571 |
return &unit[1]; |
572 |
} else return unit; |
573 |
case ('c'): |
574 |
if (strcmp (unit, "cd") && strcmp (unit, "count") && strcmp (unit, "ct") |
575 |
&& strcmp (unit, "chan")) { |
576 |
*scale = 1.0e2; |
577 |
return &unit[1]; |
578 |
} else return unit; |
579 |
case ('d'): |
580 |
if (strlen (unit) == 1) return unit; |
581 |
if (strcmp (unit, "deg")) { |
582 |
*scale = 1.0e1; |
583 |
return &unit[1]; |
584 |
} else return unit; |
585 |
case ('h'): |
586 |
if (strlen (unit) == 1) return unit; |
587 |
else { |
588 |
*scale = 1.0e-2; |
589 |
return &unit[1]; |
590 |
} |
591 |
case ('k'): |
592 |
if (strcmp (unit, "kg") && strcmp (unit, "count") && strcmp (unit, "ct") |
593 |
&& strcmp (unit, "chan")) { |
594 |
*scale = 1.0e-3; |
595 |
return &unit[1]; |
596 |
} else return unit; |
597 |
case ('M'): *scale = 1.0e-6; return &unit[1]; |
598 |
case ('G'): |
599 |
if (strlen (unit) == 1) return unit; |
600 |
else { |
601 |
*scale = 1.0e-9; |
602 |
return &unit[1]; |
603 |
} |
604 |
case ('T'): |
605 |
if (strlen (unit) == 1) return unit; |
606 |
else { |
607 |
*scale = 1.0e-12; |
608 |
return &unit[1]; |
609 |
} |
610 |
case ('P'): |
611 |
if (strcmp (unit, "PA")) { |
612 |
*scale = 1.0e-15; |
613 |
return &unit[1]; |
614 |
} else return unit; |
615 |
case ('E'): *scale = 1.0e-18; return &unit[1]; |
616 |
case ('Z'): *scale = 1.0e-21; return &unit[1]; |
617 |
case ('Y'): *scale = 1.0e-24; return &unit[1]; |
618 |
default: return unit; |
619 |
} |
620 |
} |
621 |
|
622 |
int drms_iau_units_scale (char *unit, double *scale) { |
623 |
if (!(strcmp (unit, "rad"))) *scale = 1.0; |
624 |
else return -1; |
625 |
return 0; |
626 |
} |
627 |
|
628 |
int drms_wcs_timestep (DRMS_Record_t *rec, int axis, double *tstep) { |
629 |
double dval; |
630 |
int status; |
631 |
char *sval; |
632 |
char delta[9], unit[9]; |
633 |
|
634 |
*tstep = 1.0 / 0.0; |
635 |
sprintf (delta, "CDELT%d", axis); |
636 |
sprintf (unit, "CUNIT%d", axis); |
637 |
dval = drms_getkey_double (rec, delta, &status); |
638 |
if (status || isnan (dval)) return 1; |
639 |
*tstep = dval; |
640 |
sval = drms_getkey_string (rec, unit, &status); |
641 |
|
642 |
if (status || !sval) { |
643 |
fprintf (stderr, "Warning: no keyword %s: \"s\" assumed\n", unit); |
644 |
return 0; |
645 |
} |
646 |
if (!strcmp (sval, "s")) return 0; |
647 |
if (!strcmp (sval, "min")) { |
648 |
*tstep *= 60.0; |
649 |
return 0; |
650 |
} |
651 |
if (!strcmp (sval, "h")) { |
652 |
*tstep *= 3600.0; |
653 |
return 0; |
654 |
} |
655 |
if (!strcmp (sval, "d")) { |
656 |
*tstep *= 86400.0; |
657 |
return 0; |
658 |
} |
659 |
if (!strcmp (sval, "a") || !strcmp (sval, "yr")) { |
660 |
*tstep *= 31557600.0; |
661 |
return 0; |
662 |
} |
663 |
|
664 |
if (!strcmp (sval, "ns")) { |
665 |
*tstep *= 1.0e-9; |
666 |
return 0; |
667 |
} |
668 |
if (!strcmp (sval, "us")) { |
669 |
*tstep *= 1.0e-6; |
670 |
return 0; |
671 |
} |
672 |
if (!strcmp (sval, "ms")) { |
673 |
*tstep *= 0.001; |
674 |
return 0; |
675 |
} |
676 |
if (!strcmp (sval, "cs")) { |
677 |
*tstep *= 0.01; |
678 |
return 0; |
679 |
} |
680 |
if (!strcmp (sval, "ds")) { |
681 |
*tstep *= 0.1; |
682 |
return 0; |
683 |
} |
684 |
if (!strcmp (sval, "das")) { |
685 |
*tstep *= 10.0; |
686 |
return 0; |
687 |
} |
688 |
if (!strcmp (sval, "hs")) { |
689 |
*tstep *= 100.0; |
690 |
return 0; |
691 |
} |
692 |
if (!strcmp (sval, "ks")) { |
693 |
*tstep *= 1000.0; |
694 |
return 0; |
695 |
} |
696 |
if (!strcmp (sval, "Ms")) { |
697 |
*tstep *= 1.0e6; |
698 |
return 0; |
699 |
} |
700 |
if (!strcmp (sval, "gs")) { |
701 |
*tstep *= 1.0e9; |
702 |
return 0; |
703 |
} |
704 |
|
705 |
if (!strcmp (sval, "nmin")) { |
706 |
*tstep *= 6.0e-8; |
707 |
return 0; |
708 |
} |
709 |
if (!strcmp (sval, "umin")) { |
710 |
*tstep *= 6.0e-5; |
711 |
return 0; |
712 |
} |
713 |
if (!strcmp (sval, "mmin")) { |
714 |
*tstep *= 0.06; |
715 |
return 0; |
716 |
} |
717 |
if (!strcmp (sval, "cmin")) { |
718 |
*tstep *= 0.6; |
719 |
return 0; |
720 |
} |
721 |
if (!strcmp (sval, "dmin")) { |
722 |
*tstep *= 6.0; |
723 |
return 0; |
724 |
} |
725 |
if (!strcmp (sval, "damin")) { |
726 |
*tstep *= 600.0; |
727 |
return 0; |
728 |
} |
729 |
if (!strcmp (sval, "hmin")) { |
730 |
*tstep *= 6000.0; |
731 |
return 0; |
732 |
} |
733 |
if (!strcmp (sval, "kmin")) { |
734 |
*tstep *= 60000.0; |
735 |
return 0; |
736 |
} |
737 |
if (!strcmp (sval, "Mmin")) { |
738 |
*tstep *= 6.0e7; |
739 |
return 0; |
740 |
} |
741 |
if (!strcmp (sval, "gmin")) { |
742 |
*tstep *= 6.0e10; |
743 |
return 0; |
744 |
} |
745 |
|
746 |
if (!strcmp (sval, "nh")) { |
747 |
*tstep *= 3.6e-6; |
748 |
return 0; |
749 |
} |
750 |
if (!strcmp (sval, "uh")) { |
751 |
*tstep *= 3.6e-3; |
752 |
return 0; |
753 |
} |
754 |
if (!strcmp (sval, "mh")) { |
755 |
*tstep *= 0.36; |
756 |
return 0; |
757 |
} |
758 |
if (!strcmp (sval, "ch")) { |
759 |
*tstep *= 3.6; |
760 |
return 0; |
761 |
} |
762 |
if (!strcmp (sval, "dh")) { |
763 |
*tstep *= 360.0; |
764 |
return 0; |
765 |
} |
766 |
if (!strcmp (sval, "dah")) { |
767 |
*tstep *= 3.6e4; |
768 |
return 0; |
769 |
} |
770 |
if (!strcmp (sval, "hh")) { |
771 |
*tstep *= 3.6e5; |
772 |
return 0; |
773 |
} |
774 |
if (!strcmp (sval, "kh")) { |
775 |
*tstep *= 3.6e6; |
776 |
return 0; |
777 |
} |
778 |
if (!strcmp (sval, "Mh")) { |
779 |
*tstep *= 3.6e9; |
780 |
return 0; |
781 |
} |
782 |
if (!strcmp (sval, "gh")) { |
783 |
*tstep *= 3.6e12; |
784 |
return 0; |
785 |
} |
786 |
|
787 |
if (!strcmp (sval, "nd")) { |
788 |
*tstep *= 8.64e-5; |
789 |
return 0; |
790 |
} |
791 |
if (!strcmp (sval, "ud")) { |
792 |
*tstep *= 8.64-2; |
793 |
return 0; |
794 |
} |
795 |
if (!strcmp (sval, "md")) { |
796 |
*tstep *= 86.4; |
797 |
return 0; |
798 |
} |
799 |
if (!strcmp (sval, "cd")) { |
800 |
*tstep *= 864.0; |
801 |
return 0; |
802 |
} |
803 |
if (!strcmp (sval, "dd")) { |
804 |
*tstep *= 8640.0; |
805 |
return 0; |
806 |
} |
807 |
if (!strcmp (sval, "dad")) { |
808 |
*tstep *= 8.64e5; |
809 |
return 0; |
810 |
} |
811 |
if (!strcmp (sval, "hd")) { |
812 |
*tstep *= 8.64e6; |
813 |
return 0; |
814 |
} |
815 |
if (!strcmp (sval, "kd")) { |
816 |
*tstep *= 8.64e7; |
817 |
return 0; |
818 |
} |
819 |
if (!strcmp (sval, "Md")) { |
820 |
*tstep *= 8.64e10; |
821 |
return 0; |
822 |
} |
823 |
if (!strcmp (sval, "gd")) { |
824 |
*tstep *= 8.64e13; |
825 |
return 0; |
826 |
} |
827 |
|
828 |
fprintf (stderr, "Error: %s type of %s unrecognized by drms_wcs_timestep()\n", |
829 |
unit, sval); |
830 |
return 1; |
831 |
} |
832 |
|
833 |
/* |
834 |
* Revision History (all mods by Rick Bogart unless otherwise noted) |
835 |
* |
836 |
* 09.04.27 or earlier created file |
837 |
* 09.05.16 added functions for creating prime key string |
838 |
* 09.11.06 added WCS parsing function |
839 |
* 09.11.09 modified check_and_set_key_* to only require matching |
840 |
* to precision of keyword format for float, double, & time |
841 |
* 09.12.02 fixed two icc11 compiler warnings and one error |
842 |
* 10.01.07 added support in check_and_copy_key for keywords that |
843 |
* are dynamic links (in which case checking is irrelevant) |
844 |
* 10.02.03 relaxed check in check_and_copy_key (too much) |
845 |
* 10.04.24 added copy_prime_keys() |
846 |
* 10.06.11 added construct_stringlist() (orig in drms_rebin) |
847 |
* 12.03.21 added check_and_set_key_longlong() |
848 |
*/ |