ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/lev0/apps/hmi_import_egse_lev0.c
Revision: 1.9
Committed: Mon Jun 1 19:37:12 2009 UTC (14 years, 3 months ago) by thailand
Content type: text/plain
Branch: MAIN
CVS Tags: Ver_6-0, Ver_6-1, Ver_6-2, Ver_6-3, Ver_6-4, Ver_9-1, Ver_5-14, Ver_5-13, Ver_5-12, Ver_5-11, Ver_5-10, Ver_LATEST, Ver_9-3, Ver_5-7, Ver_5-6, Ver_9-41, Ver_9-2, Ver_5-9, Ver_8-8, Ver_5-8, Ver_8-2, Ver_8-3, Ver_8-0, Ver_8-1, Ver_8-6, Ver_8-7, Ver_8-4, Ver_8-5, Ver_5-3, Ver_5-2, Ver_7-1, Ver_7-0, Ver_5-5, Ver_9-5, Ver_9-4, Ver_8-10, Ver_8-11, Ver_8-12, Ver_9-0, HEAD
Changes since 1.8: +5 -0 lines
Log Message:
Added check for config_rs to fail properly for missing config records

File Contents

# Content
1 //todo
2 // add flag to disable config
3
4 /* MODIFIED from original program to re-read older versions of DRMS lev0 code.
5 * the change is in reverting to original keywords values in the cases where they were munged.
6 * List of fixes:
7 * if -R flag is set then add 2 to HCAMID if exposure > 0
8 */
9
10 /* import_egse_lev0 - import lev0 fits files from prog:hmi_ground,level:lev0,series:hmi_egsefsfm[fsn] type files */
11 /* Expect input keywords to contain HSQFGSN and shutter time HOBITSEC or SHS from the image header time. */
12 /* Expect prime keys in out series to be "FSN" and "T_OBS" */
13
14 /* Expect the target dataseries to have the desired FITS keynames as the first token in each
15 keyword description.
16 Allow a mapping of names from the actual level0 FITS names to the target short names. These
17 mappings must be provided in a map file whose path is in the "keymap" parameter.
18 Format of keymap file is one line per target keyname, target keyname is first token on line
19 and aliases that may be found in the input file are subsequent tokens.
20 At most MAX_KEYMAPS tokens may be present on each line.
21 At most MAX_KEYS keywords will be considerend for remapping.
22 */
23
24 /* NOTE that this module uses the dr library cloned from the sds library !! */
25
26 /**
27 @defgroup hmi_import_egse_lev0 hmi_import_egse_lev0 - ingest pre-launch level-0 data files
28 @ingroup su_lev0
29
30 Import ground test level0 FITS files into DRMS.
31
32 This program is used only for processing of pre-launch data.
33
34 The program copies a lev0 FITS file into a matching DRMS record, setting the
35 DRMS keywords from the FITS file. Additional keywords are written into both
36 the DRMS and FITS headers so the lev0 data can be accessed as a stand-along FITS
37 file or via DRMS segment read calls.
38
39 The program can accept either RAL EGSE generated lev0 FITS files or
40 CIF/DCHRI HS-bus lev0 files produced from the telemetry via the SSIM.
41 The CIF or RAL mode is set in the CONFIG command line arg and saved in the keyword @c CONFIG.
42
43 @code
44 Outline of this program
45 Init:
46 Get command line flags and args
47 Create a new output record into DRMS struct
48 Read input lev0 FITS file into DR struct.
49 Set some keywords from command line info
50 Loop through output keywords
51 begin
52 Get DRMS name and FITS shortname from rec
53 if shortname in input file, use it
54 else if shortname in alias list
55 if one of aliases in input file, use it
56 else set default value in FITS file
57 if keyword is prime key T_OBS
58 if RAL mode
59 Use filename for T_OBS
60 else
61 look in keyword named in timekey command line arg
62 but if not found default to SHS keyword.
63 if keyword is prime key FSN
64 get FSN from possibly aliased keyword
65 if keyword is TELEM_T set telem time value from SHS
66 else
67 for all other keywords copy value from
68 FITS to DRMS if present, if not present
69 set FITS value from DRMS default values from JSD.
70 if RAL mode then fix the PCU position values.
71 End of loop
72 if CIF mode then
73 begin
74 get test config info from auxillary file
75 call external program (set_config_by_time.csh) to update config info in
76 an ancillary dataseries. Pass the FSN and T_OBS to this program.
77 Then open the newly made record in the ancillar series and copy
78 the configuration keywords into both DRMS and FITS headers.
79 set mechanism values via index keywords using tables.
80 end of CIF special code
81 Save new FITS file with all keywords in segment with original filename
82 Close DRMS record
83 Done
84 @endcode
85
86 @par Synopsis:
87 @code
88 import_egse_lev0 [-RhrvDRIVER_FLAGS] in=<lev0_FITS_file>] [out=<lev0_DRMS_series>]
89 [fsn_key=<fsn_keyword>] [time_key=<obs_time_keyword>]
90 [keymap=<alias_table>] [dsds=<egse_lev0_DSDS_name>]
91 @endcode
92
93 @par Flags:
94 @c -R: Add 2 to HCAMID if exposure > 0.
95 @par
96 @c -h: Print usage message and quit.
97 @par
98 @c -r: RAL EGSE data expected.
99 @par
100 @c -v: Verbose - noisy.
101
102 @par Driver flags:
103 @ref jsoc_main
104
105 @param in
106 Specifies the EGSE produced level0 FITS file. If it was produced by the
107 RAL Camera EGSE the @a -r flag should also be specified.
108
109 @param out
110 This is the destination dataseries for the level 0 data. For HMI is will be
111 @a hmi_ground.lev0. It must have both @a FSN and @a T_OBS as prime keys and
112 of type ::DRMS_TYPE_INT and ::DRMS_TYPE_TIME respectively. No record filter
113 should be specified.
114 The keywords description is used for the shortname that will be used for the
115 FITS keyword name. Thus each keyword must have at least the shortname as the
116 first word in the description in the JSD file. For convenience the keymap
117 entries are also present as comments.
118
119 @param fsn_key
120 The name of the keyword in the input FITS file that should be used for the Filtergram
121 Sequence Number, FSN. The default is @c FSN for CIF mode and @c HSQFGSN for RAL mode.
122
123 @param time_key
124 The name of the keyword to be used for the observation time @a T_OBS target keyword.
125 The default is @c HOBITSEC. If the time_key defined keyword is not present,
126 then @c SHS will be used. At least one must be present.
127
128 @param keymap
129 The optional name of an alias file. The alias file should contain one line for each
130 target shortname that may have an alternate in the input lev0 file. Up to
131 9 aliases may be provided. The first word (white space delimited) on the line is
132 the target. Subsequent words are possible aliases. A maximum of 256 alias
133 lines are allowed.
134
135 @param dsds
136 If present the value of this keyword is stored in the @c DSDS_SRC keyword to record
137 the source of the input data. It can be a "prog:level:series" name or simply
138 the filename of the input data.
139 */
140 /* @{ */
141 /* Defined constants */
142 #define MAX_KEYMAPS 10
143 #define MAX_KEYS 256
144
145 #define FSN_CAM_ID_FIXED 50630 /* FSN before this number will have 1 added to HCAMID to fix bug */
146 #define FSN_HSHIEXP_FIXED 163852 /* FSN before this need to have exposures looked up. Probably could be a lot earlier */
147 #define FSN_TAI_FIXED 1000000 /* FSN before this number will have 33 secs added to OBT to fix to TAI */
148
149 /* Table directory for mech values when in CIF mode */
150 #define TABLE_PATH "proj/lev0/apps/data/"
151
152 /* Program to call to update the config dataseries, takes 3 args: T_OBS, FSN, DRMSSESSION */
153 #define UPDATE_CONFIG_PROG "proj/lev0/scripts/hmi_ground/set_config_by_time.csh"
154
155 /* Ancillary series with test config data, prime key FSN */
156 #define CONFIG_SERIES "hmi_ground.lev0_config"
157
158 /* Includes for DRMS */
159 #include "jsoc_main.h"
160 #include "drms.h"
161 #include "drms_names.h"
162
163 /* includes code for sds clone library of fits reading, called DR instead of SDS */
164 /* #include "dr_lib.c" - code in the dr library now */
165 #include "dr.h"
166
167 /* Includes for standard libs */
168 #include <string.h>
169 #include <stdlib.h>
170
171 #define NOT_SPECIFIED "***Not Specified***"
172 #define DIE(msg) {fprintf(stderr,"$$$$ %s: %s\n",module_name,msg); return 1;}
173
174 /* Global variables for JSOC running environment */
175
176 ModuleArgs_t module_args[] =
177 {
178 {ARG_STRING, "in", NOT_SPECIFIED, "Path to DSDS hmi_ground lev0 file"},
179 {ARG_STRING, "out", NOT_SPECIFIED, "drms series for lev0 data"},
180 {ARG_STRING, "fsn_key", "HSQFGSN", "Filtergram number keyword name"},
181 {ARG_STRING, "time_key", "HOBITSEC", "Filtergram time keyword name"},
182 {ARG_STRING, "t_obs", NOT_SPECIFIED, "Filtergram time override"},
183 {ARG_STRING, "keymap", NOT_SPECIFIED, "Keyword mapping table"},
184 {ARG_STRING, "dsds", NOT_SPECIFIED, "DSDS source dataset name"},
185 {ARG_FLAG, "r", "0", "RAL EGSE data expected"},
186 {ARG_FLAG, "R", "0", "Re-ingest from DRMS lev0 file"},
187 {ARG_FLAG, "h", "0", "Print usage message and quit"},
188 {ARG_FLAG, "v", "0", "verbose flag"},
189 {ARG_END}
190 };
191
192 char *module_name = "import_egse_lev0";
193 /* @} */
194
195 /* Support functions */
196
197 int verbose = 0;
198 int nice_intro(int help)
199 {
200 int usage = cmdparams_get_int(&cmdparams, "h", NULL) != 0;
201 verbose = cmdparams_get_int(&cmdparams, "v", NULL) != 0;
202 if (usage || help)
203 {
204 printf("import_egse_lev0 in='fits file' out='jsoc series' {keymap='keymap file'} {dsds='dsds dataset'} {-h} {-r} {-v} "
205 " -h: print this message\n"
206 " -r: RAL data input, no external config info needed\n"
207 " -R: Re-ingest mode, fixes HCAMID back to egse version\n"
208 " -v: verbose\n"
209 "keymap=<key map file> - optional\n"
210 "t_obs=<time over-ride value\n"
211 "dsds=<dsds dataset name for source file\n"
212 "in=<lev0 fits file> - required\n"
213 "out=<drms lev0 series> - required\n");
214 return(1);
215 }
216 return(0);
217 }
218
219 /* Functions defined at end of this file */
220
221 TIME SDO_to_DRMS_time(int sdo_s, int sdo_ss);
222 int set_mech_values(DRMS_Record_t *rec, DR *dr, int fsn);
223 int init_keymaps(char *keymaps[MAX_KEYS][MAX_KEYMAPS], int *nkeys, char *key_map_file);
224 void sprint_time_ISO (char *tstring, TIME t);
225
226 /* Module main function. */
227
228 int DoIt(void)
229 {
230 int status = 0;
231 int RALmode = 0;
232 int fsn;
233 TIME t_obs, t_obs_force;
234 char *t_obs_override;
235 char *in, *out;
236 char *in_filename;
237 char tmpfile[1024];
238 char tmpdir[1024];
239 char *dsdsname;
240 char *keymap;
241 DRMS_Record_t *rec;
242 DRMS_RecordSet_t *rs;
243 HIterator_t key_hit;
244 DRMS_Keyword_t *key;
245 DR *lev0, *tmpdr;
246 char *keymaps[MAX_KEYS][MAX_KEYMAPS];
247 int keytarg, keytargs, newkey;
248 ATTRIBUTES *fits_attr;
249 TIME TIME2006Jan = sscan_time("2006.01.01_00:00:00");
250 int re_ingest_from_drms;
251
252 if (nice_intro(0))
253 return(0);
254
255 printf("Import ground test lev0 data:\n");
256
257 /* Get command line arguments */
258 in = strdup(cmdparams_get_str(&cmdparams, "in", NULL));
259 if (strcmp(in,NOT_SPECIFIED)==0)
260 DIE("in argument is required");
261 printf(" in=%s\n", in);
262
263 out = strdup(cmdparams_get_str(&cmdparams, "out", NULL));
264 if (strcmp(out,NOT_SPECIFIED)==0)
265 DIE("out argument is required");
266 printf(" out=%s\n", out);
267
268 dsdsname = cmdparams_get_str(&cmdparams, "dsds", NULL);
269 if (strcmp(dsdsname,NOT_SPECIFIED)==0)
270 dsdsname = "n.a.";
271 printf(" dsds=%s\n", dsdsname);
272
273 keymap = cmdparams_get_str(&cmdparams, "keymap", NULL);
274 if (strcmp(keymap,NOT_SPECIFIED)==0)
275 printf(" keymap not used\n");
276 else
277 printf(" keymap=%s\n", keymap);
278 if (init_keymaps(keymaps, &keytargs, keymap))
279 DIE("Key Mapping File not found");
280 printf(" keymap count=%d\n",keytargs);
281
282 RALmode = cmdparams_get_int(&cmdparams, "r", NULL);
283 printf(" %s\n", (RALmode ? "RAL mode" : "DCHRI mode"));
284
285 re_ingest_from_drms = cmdparams_get_int(&cmdparams, "R", NULL) != 0;
286 if (re_ingest_from_drms)
287 printf(" Re-ingest from previous DRMS lev0 file.\n");
288
289 t_obs_override = cmdparams_get_str(&cmdparams, "t_obs", NULL);
290 if (strcmp(t_obs_override,NOT_SPECIFIED)==0)
291 t_obs_force = 0.0;
292 else
293 {
294 char t_obs_str[1024];
295 t_obs_force = sscan_time(t_obs_override);
296 sprint_ut(t_obs_str, t_obs_force);
297 printf(" ** WARNING ** T_OBS over-ride from command line is %s\n", t_obs_str);
298 }
299
300 /* Create new record to contain the lev0 image */
301
302 rs = drms_create_records(drms_env, 1, out, DRMS_PERMANENT, &status);
303 if (status)
304 DIE("cant create records in output series");
305 rec = rs->records[0];
306
307 /* Get input file fits header */
308
309 lev0 = dr_get_fits(in);
310 if (!lev0)
311 DIE("Failed to read fits header");
312 tmpdr = lev0;
313
314 /* Set some keywords not from input files */
315
316 drms_setkey_string(rec, "DSDS_SRC", dsdsname);
317 dr_setkey_str(tmpdr, "DSDS_SRC", dsdsname);
318 drms_setkey_string(rec, "CONFIG", (RALmode ? "RAL" : "CIF"));
319 dr_setkey_str(tmpdr, "CONFIG", (RALmode ? "RAL" : "CIF"));
320
321 /* Look for all the drms keywords in the input lev0 and copy to output */
322
323 hiter_new(&key_hit, &rec->keywords);
324 while( (key = (DRMS_Keyword_t *)hiter_getnext(&key_hit)) )
325 {
326 char describe[DRMS_MAXCOMMENTLEN];
327 char *shortname;
328 char *usename;
329 char *keyname = key->info->name;
330 strcpy(describe, key->info->description);
331 shortname = strtok(describe," \t,:");
332 if (!shortname)
333 shortname = keyname;
334 if (strlen(shortname) > 8)
335 DIE("shortname too long\n");
336 // fprintf(stderr,"longname=%s shortname=%s",keyname,shortname);
337 if (dr_search_attr(lev0, shortname) != NULL)
338 {
339 usename = shortname;
340 // fprintf(stderr,": found in lev0\n");
341 }
342 else
343 { /* name not found, so lookup shortname in keymap to see if alternate expected */
344 usename = shortname;
345 // fprintf(stderr,": NOT found in lev0\n");
346
347 for (keytarg = 0; keytarg < keytargs; keytarg++)
348 {
349 if (strcmp(shortname, keymaps[keytarg][0]) == 0)
350 { /* found shortname in key mapping list, now look for each of the aliases, take the first one found. */
351 int trykey;
352 // fprintf(stderr, " Found shortname in keymap.\n");
353 for (trykey=1; trykey < MAX_KEYMAPS && keymaps[keytarg][trykey] != NULL; trykey++)
354 if (fits_attr = dr_search_attr(lev0, keymaps[keytarg][trykey]))
355 { /* found substitute keyword in the input FITS file */
356 usename = keymaps[keytarg][trykey];
357 // fprintf(stderr, " new name is %s\n",usename);
358 break;
359 }
360 break;
361 }
362 }
363 // fprintf(stderr, " none of newnames found.\n");
364 } /* usename now contains shortname or a keyword present in the input FITS file */
365
366 if (strcmp(keyname, "T_OBS") == 0) /* must have t_obs from somewhere */
367 { /* this keyword is prime key T_OBS, make sure it gets set */
368 char t_obs_str[40];
369 int t_obs_s;
370 char *time_key = strdup(cmdparams_get_str(&cmdparams, "time_key", NULL));
371 if (t_obs_force > 0.0)
372 t_obs = t_obs_force;
373 else if (RALmode)
374 {
375 char *filename = DR_getkey_str(lev0, "FILENAME");
376 int y,M,d,h,m,s;
377 sscanf(filename, "i_%2d%2d%2d_%2d%2d%2d", &y, &M, &d, &h, &m, &s);
378 sprintf(t_obs_str, "20%02d.%02d.%02d_%02d:%02d:%02d_UTC", y, M, d, h, m, s);
379 t_obs = sscan_time(t_obs_str);
380 }
381 else
382 {
383 t_obs_s = dr_getkey_int(lev0, time_key);
384 if (is_I_MISSING(t_obs_s) || t_obs_s < TIME2006Jan )
385 {
386 t_obs_s = dr_getkey_int(lev0, "SHS"); /* no T_OBS so try SHS */
387 if (is_I_MISSING(t_obs_s))
388 DIE("Failed to find either time keyword");
389 }
390 t_obs = SDO_to_DRMS_time(t_obs_s, 0);
391 }
392 drms_setkey_double(rec, "T_OBS", t_obs);
393 dr_setkey_time(tmpdr, "T_OBS", t_obs);
394 sprint_ut(t_obs_str, t_obs);
395 printf(" T_OBS=%s\n", t_obs_str);
396 }
397 else if (strcmp(keyname, "FSN")==0) /* get FSN, use alternate if given */
398 { /* this keyword is prime key T_OBS, make sure it gets set */
399 char *fsn_key = strdup(cmdparams_get_str(&cmdparams, "fsn_key", NULL));
400 fsn = dr_getkey_int(lev0, fsn_key);
401 if (is_I_MISSING(fsn))
402 DIE("Failed to find FSN keyword");
403 drms_setkey_int(rec, "FSN", fsn);
404 dr_setkey_int(tmpdr, "FSN", fsn);
405 printf(" FSN=%d\n", fsn);
406 }
407 if (strcmp(keyname, "TELEM_T") == 0) /* Get telemetry time from SHS, SHSS keywords */
408 /* but note that TELEM_T is no longer a keyword in the .jsd file so this code will not be used... */
409 { /* set keyword for telemetry time, this could be omitted */
410 int t = dr_getkey_int(lev0, "SHS");
411 int tf = dr_getkey_int(lev0, "SHSS");
412 if (!is_I_MISSING(t) && !is_I_MISSING(tf))
413 {
414 TIME telem_t = SDO_to_DRMS_time(t, tf);
415 drms_setkey_double(rec, keyname, telem_t);
416 dr_setkey_time(tmpdr, shortname, telem_t);
417 }
418 }
419 else if (usename) /* simply copy other keywords that are found */
420 { /* all other keywords, copy values from FITS to DRMS */
421 if (fits_attr = dr_search_attr(lev0, usename))
422 {
423 char *fits_val_str = dr_attrvalue_str(fits_attr);
424 // fprintf(stderr, " Found usename=%s value=%s\n",usename,fits_val_str);
425 /* emergency patch to shutter times */
426 /* problem starts at version 435
427 P% show_keys "ds=hmi_ground.lev0[628720-628730]" key=FSN,PACKET_VERSION_NUMBER,HMI_SHM_IMG_CLOSE_BOTTOM,DATEORIG
428 FSN PACKET_VERSION_NUMBER HMI_SHM_IMG_CLOSE_BOTTOM DATEORIG
429 0628720 424 3782456 2007-10-04 13:26:55
430 0628721 424 3777470 2007-10-04 13:26:52
431 0628722 424 0 2007-10-04 13:26:57
432 0628723 424 0 2007-10-04 13:26:59
433 0628724 435 0 2007-10-04 23:00:40
434 0628725 435 0 2007-10-04 23:01:09
435 0628726 435 0 2007-10-04 23:01:49
436 0628727 435 3 2007-10-04 23:02:39
437 0628728 435 0 2007-10-04 23:03:29
438 */
439
440 int fixversion = dr_getkey_int(tmpdr, "HVN00F");
441 int newfixversion = dr_getkey_int(tmpdr, "HVNISP");
442 if ((newfixversion >= 435 || fixversion >= 435) &&
443 (strcmp(usename,"HSHMICLB") == 0 ||
444 strcmp(usename,"HSHMICLM") == 0 ||
445 strcmp(usename,"HSHMICLT") == 0 ||
446 strcmp(usename,"HSHMIOPB") == 0 ||
447 strcmp(usename,"HSHMIOPM") == 0 ||
448 strcmp(usename,"HSHMIOPT") == 0 ))
449 {
450 double dv = atof(fits_val_str);
451 int iv = 1000*dv;
452 printf("XXX fix version = %d, in string = %s\n", fixversion, fits_val_str);
453 printf("XXX iv = %d\n", iv);
454 drms_setkey_int(rec, keyname, iv);
455 dr_setkey_int(tmpdr, usename, iv);
456 }
457 else
458 /* end of shutter patch */
459 drms_setkey_string(rec, keyname, fits_val_str);
460 if (strcmp(usename, shortname) != 0)
461 {
462 free(fits_attr->name);
463 fits_attr->name = strdup(shortname);
464 }
465 if (RALmode)
466 {
467 if (!strcmp(shortname,"HPCUPOLR") ||
468 !strcmp(shortname,"HPCUPOLM") ||
469 !strcmp(shortname,"HPCURETR") ||
470 !strcmp(shortname,"HPCURETM") )
471 dr_setkey_double(tmpdr, shortname, strtod(fits_val_str, NULL));
472 }
473 free(fits_val_str);
474 }
475 else
476 {
477 /* set the dr key to the drms default value */
478 fprintf(stderr, " using default value for %s\n", shortname);
479 dr_setkey_drmstype(tmpdr, shortname, key);
480 }
481 }
482 }
483
484 /* Now try for config info */
485 if (!RALmode)
486 {
487 char cmdline[1024], t_obs_str[1024];
488 int status;
489 char config_ds[1024];
490 DRMS_Record_t *config_rec;
491 DRMS_RecordSet_t *config_rs;
492 HIterator_t config_key_hit;
493 DRMS_Keyword_t *config_key;
494 /* Correct T_OBS for TAI error on SSIM prior to FSN_TAI_FIXED */
495 if (fsn < FSN_TAI_FIXED)
496 {
497 t_obs += 33.0;
498 drms_setkey_double(rec, "T_OBS", t_obs);
499 dr_setkey_time(tmpdr, "T_OBS", t_obs);
500 sprint_ut(t_obs_str, t_obs);
501 printf(" CORRECTED T_OBS=%s\n", t_obs_str);
502 }
503 /* call external program to update config info */
504 sprint_time(t_obs_str, t_obs, "UTC", 0);
505 sprintf(cmdline, "%s/%s '%s' %d %s", cmdparams_get_str(&cmdparams, "JSOCROOT", NULL),
506 UPDATE_CONFIG_PROG, t_obs_str, fsn, cmdparams_get_str(&cmdparams, "DRMSSESSION", NULL));
507 status = system(cmdline);
508 if (status)
509 {
510 fprintf(stderr, "Failed to execute %s\n", cmdline);
511 DIE("Failed to get config info\n");
512 }
513 /* Now get record with config info for this fsn and copy keywords */
514 sprintf(config_ds, "%s[%d]", CONFIG_SERIES, fsn);
515 config_rs = drms_open_records(drms_env, config_ds, &status);
516 if (status == 0)
517 {
518 if (config_rs->n < 1)
519 {
520 fprintf(stderr, "Failed to get config record for fsn '%d'.\n", fsn);
521 DIE("Quitting now.");
522 }
523 config_rec = config_rs->records[0];
524 hiter_new(&config_key_hit, &config_rec->keywords);
525 while( (config_key = (DRMS_Keyword_t *)hiter_getnext(&config_key_hit)) )
526 {
527 int stat = drms_setkey(rec, config_key->info->name, config_key->info->type, &config_key->value);
528 /* note for these params the DRMS name is an OK FITS name */
529 dr_setkey_drmstype(tmpdr, config_key->info->name, config_key);
530 }
531 drms_close_records(config_rs, DRMS_FREE_RECORD);
532 }
533 else
534 fprintf(stderr,"cant open config records for %s\n",config_ds);
535
536 /* do mech table lookups */
537 status = set_mech_values(rec, tmpdr, fsn);
538 if (status)
539 DIE("Mech table failure");
540 }
541
542 /* set curent time in DATE kwyword. Note EGSE DATE keyword will have been copied into DATEORIG above */
543 {
544 char tmpstr[100];
545 sprint_time_ISO(tmpstr,CURRENT_SYSTEM_TIME);
546 drms_setkey_string(rec, "DATE", tmpstr);
547 dr_setkey_str(tmpdr, "DATE", tmpstr);
548 }
549
550 /* Save new FITS file with all keywords in segment with original filename */
551 if (in_filename = strrchr(in,'/'))
552 in_filename++;
553 else
554 in_filename = in;
555 status = dr_write_fits_to_drms_segment(tmpdr, in_filename, rec, 0);
556 if (status)
557 DIE("FITS save in segment failure");
558 dr_free(&lev0);
559 status = drms_close_records(rs, DRMS_INSERT_RECORD);
560 if (status)
561 DIE("close failure");
562 return 0;
563 }
564
565 /*
566 * TIME SDO_to_DRMS_time(int sdo_s, int sdo_ss);
567 * Note on time codes.
568 * SDO/HMI,AIA keeps time in a 48-bit counter in units of 1/(2^16) seconds. Thus
569 * the top 32 bits is a seconds counter and the bottom 16 bits is a sub-seconds
570 * counter (left adjusted in a 32-bit field). The epoch is 1958.01.01_00:00:00.
571 * Thus to convert HMI,AIA instrument time in two variables, e.g. SHS and SHSS to
572 * a DRMS time the conversion is: t_drms = SDO_EPOCH + SHS + (SHSS>>16)/65536.0
573 * where SDO_EPOCH = sscan_time("1958.01.01_00:00:00");
574 * TAI and UTC are same at 1 Jan 1958.
575 */
576 TIME SDO_to_DRMS_time(int sdo_s, int sdo_ss)
577 {
578 static int firstcall = 1;
579 static TIME sdo_epoch;
580 if (firstcall)
581 { /* time_1958 - time_1977_TAI, to be added to SDO time to get DRMS time */
582 firstcall = 0;
583 sdo_epoch = sscan_time("1958.01.01_00:00:00_TAI");
584 }
585 return(sdo_epoch + (TIME)sdo_s + ((TIME)sdo_ss)/65536.0);
586 }
587
588 /* Function to set HMI mechanism position keywords */
589
590 int set_mech_values(DRMS_Record_t *rec, DR *lev0, int fsn)
591 {
592 static int called = 0;
593
594 #define MAXROWS 10000
595 static int pol[MAXROWS*4];
596 static int tuning[MAXROWS*5];
597 static int focus[MAXROWS*3];
598 static int expose[MAXROWS*3];
599
600 static char *pol_keys[] = {"HPL1POS", "HPL2POS", "HPL3POS"};
601 static char *pol_longkeys[] = {"HPL1POS", "HPL2POS", "HPL3POS"};
602 static char *tuning_keys[] = {"HWL1POS", "HWL2POS", "HWL3POS", "HWL4POS"};
603 static char *tuning_longkeys[] = {"HWL1POS", "HWL2POS", "HWL3POS", "HWL4POS"};
604 static char *focus_keys[] = {"HCF1POS", "HCF2POS"};
605 static char *focus_longkeys[] = {"HCF1POS", "HCF2POS"};
606 static char *expose_keys[] = {"HSHIEXP", "HSHIEXP"};
607 static char *expose_longkeys[] = {"HMI_FSW_IMG_CMDED_EXPOSURE", "HMI_FSW_IMG_CMDED_EXPOSURE"};
608
609 static char *camkey = "HCAMID";
610 static char *camkey_longname = "HMI_SEQ_ID_EXP_PATH";
611
612 typedef struct tabinf
613 {
614 char *filename;
615 char *index;
616 char **keys;
617 char **longkeys;
618 int *table;
619 int cols;
620 char *longname;
621 } TABINFO;
622 static TABINFO tabinfo[] = {"in_air_cal3.p", "HPLTID", pol_keys, pol_longkeys, pol, 3,"HMI_SEQ_ID_PST",
623 "in_air_cal3.w", "HWLTID", tuning_keys, tuning_longkeys, tuning, 4,"HMI_SEQ_ID_WLT",
624 "in_air_cal.c", "HCFTID", focus_keys, focus_longkeys, focus, 2,"HMI_SEQ_ID_FOCUS",
625 "in_air_cal.e", "HSQEIDX", expose_keys, expose_longkeys, expose, 2,"HMI_SEQ_EXPOSURE_INDX"};
626 int tab;
627 int status;
628 int camera = dr_getkey_int(lev0, camkey);
629 int re_ingest_from_drms = cmdparams_get_int(&cmdparams, "R", NULL) != 0;
630
631 if (camera < 0 || camera > 3)
632 {
633 fprintf(stderr,"XX camera=%d outside range, use camera 1 exposures\n",camera);
634 camera=1;
635 }
636
637 if (re_ingest_from_drms)
638 {
639 int exposure = dr_getkey_int(lev0, expose_keys[0]);
640 if (exposure > 0)
641 camera += 2;
642 }
643
644 if (!called)
645 {
646 called = 1;
647 for (tab=0; tab<4; tab++)
648 {
649 char tablepath[1024];
650 int idx, *res, val, vals;
651 FILE *fp;
652 char line[1024];
653 strcpy(tablepath, cmdparams_get_str(&cmdparams, "JSOCROOT", NULL));
654 strcat(tablepath, "/");
655 strcat(tablepath, TABLE_PATH);
656 strcat(tablepath, tabinfo[tab].filename);
657 fp = fopen(tablepath, "r");
658 if (!fp)
659 {
660 fprintf(stderr,"Failed to open mech table %s, die.\n",tablepath);
661 return(1);
662 }
663 res = tabinfo[tab].table;
664 vals = tabinfo[tab].cols;
665 for (idx=0; idx<MAXROWS; idx++)
666 for (val=0; val<vals+1; val++)
667 res[val + (vals+1)*idx] = -1;
668 for (idx=0; fgets(line,1024,fp); )
669 {
670 if (*line != '#')
671 {
672 char *e, *p=line;
673 int d;
674 for (val=0; val<vals+1; val++)
675 {
676 d = strtod(p, &e);
677 if (e == p)
678 break;
679 else
680 {
681 p = e;
682 res[val + (vals+1)*idx] = d;
683 }
684 }
685 if (res[(vals+1)*idx] >= 0)
686 idx++;
687 }
688 }
689 fclose(fp);
690 }
691 }
692
693 for (tab=0; tab<4; tab++)
694 {
695 int found_index;
696 int row, index;
697 int status;
698 int val, vals = tabinfo[tab].cols;
699 int *res = tabinfo[tab].table;
700 char **keys = tabinfo[tab].keys;
701 char **longkeys = tabinfo[tab].longkeys;
702 found_index = 0;
703 index = dr_getkey_int(lev0, tabinfo[tab].index);
704 if (tab == 3) /* Fix index value for exposures */
705 {
706 if (fsn < FSN_CAM_ID_FIXED)
707 index += 1; /* e.g. 39 goes to 40. Ask Jesper. */
708 dr_setkey_int(lev0, tabinfo[tab].index, index);
709 drms_setkey_int(rec, tabinfo[tab].longname, index);
710 }
711 if (is_I_MISSING(index))
712 {
713 fprintf(stderr,"Mech Index %s not found.\n",tabinfo[tab].index);
714 continue;
715 }
716 for (row=0; row<MAXROWS; row++)
717 if (index == res[(vals+1)*row])
718 { /* found proper row for this image */
719 found_index = 1;
720 if (tab<3) /* set positiion values for motors */
721 {
722 for (val=0; val<vals; val++)
723 {
724 drms_setkey_int(rec, longkeys[val], res[val+1+(vals+1)*row]);
725 dr_setkey_int(lev0, keys[val], res[val+1+(vals+1)*row]);
726 }
727 break;
728 }
729 else /* exposure handled differently */
730 {
731 int exposure;
732 if (camera <= 1)
733 exposure = 0;
734 else
735 {
736 camera -= 2;
737 if (fsn <= FSN_HSHIEXP_FIXED) /* use lookup table for old ones, use EGSE keyword for later */
738 exposure = res[camera+1+(vals+1)*row];
739 else
740 exposure = dr_getkey_int(lev0, "HSHIEXP");
741 }
742 drms_setkey_int(rec, longkeys[0], exposure);
743 dr_setkey_int(lev0, keys[0], exposure);
744 drms_setkey_int(rec, camkey_longname, camera);
745 dr_setkey_int(lev0, camkey, camera);
746 break;
747 }
748 }
749 if (!found_index)
750 {
751 fprintf(stderr,"Mech Index %d not found in mech table %s.\n",index,tabinfo[tab].filename);
752 if (index > 0)
753 return(1);
754 }
755 }
756 return(0);
757 }
758
759 /* function to read keyword aliases */
760
761 int init_keymaps(char *keymaps[MAX_KEYS][MAX_KEYMAPS], int *nkeys, char *key_map_file)
762 {
763 int key, map;
764 for (key=0; key<MAX_KEYS; key++)
765 for (map=0; map<MAX_KEYMAPS; map++)
766 keymaps[key][map] = NULL;
767 key = 0;
768 if (strcmp(key_map_file, NOT_SPECIFIED) != 0)
769 {
770 FILE *km = fopen(key_map_file,"r");
771 char line[1024];
772 if (!km)
773 return(1);
774 key=0;
775 while (fgets(line, 1024, km))
776 {
777 char *tok;
778 for (map=0, tok = strtok(line, " \t,:\n"); map<MAX_KEYMAPS && tok; map++, tok=strtok(NULL, " \t,\n"))
779 {
780 keymaps[key][map] = strdup(tok);
781 }
782 key++;
783 }
784 }
785 *nkeys = key;
786 return(0);
787 }
788
789 void sprint_time_ISO (char *tstring, TIME t)
790 {
791 sprint_at(tstring,t);
792 tstring[4] = tstring[7] = '-';
793 tstring[10] = 'T';
794 tstring[19] = '\0';
795 }