1 |
#include "jsoc.h" |
2 |
#include "jsoc_main.h" |
3 |
|
4 |
char *module_name = "hmi_fixCROTA2"; |
5 |
|
6 |
/* |
7 |
* This program updates CROTA2 based on results of the 2012 transit of Venus. |
8 |
* CROTA2 is corrected by adding either CAM1_DELTA or CAM2_DELTA |
9 |
* hmi.lev1 products must have CALVER32 and other procusts must have CALVER64 keywords. |
10 |
* CALVER64 or CALVER32 will have the second nibble set to 1. |
11 |
* If INST_ROT is present it will be updated. |
12 |
* DATE is updated. |
13 |
* A HISTORY line is added. |
14 |
* |
15 |
* call with hmi_fixCROTA2 ds=<seriesname> first=<first_time> last=<last_time> |
16 |
* |
17 |
* The program will operate on blocks of about 100d, 10d, 1d, or 6h as appropriate for |
18 |
* less than 25000 records in a chunk. |
19 |
* |
20 |
* The program requires (for now) that the first primekey be a slotted TIME. |
21 |
* |
22 |
* No query arguments other than the time range for each chunk are used. |
23 |
* |
24 |
* If CALVER32 == -2^31 it will be set to 0xFFFFFFFF prior to other processing. |
25 |
* CALVER64 and CALVER32 bit assignments: |
26 |
* At present CALVER64 is a string of 16 Hex digits. It can be divided finer or coarser later as needed. |
27 |
* bits 00:03 == HFCORRVR from old lev1, limb height of formation code version number |
28 |
* bits 04:07 == CROTA2 version. Was version 0 since launch, now becomes version 1. |
29 |
* |
30 |
*/ |
31 |
|
32 |
#define DIE(msg) {fflush(stdout);fprintf(stderr,"%s, status=%d\n",msg,status); return(status);} |
33 |
|
34 |
#define NOTSPECIFIED "Not Specified" |
35 |
|
36 |
ModuleArgs_t module_args[] = |
37 |
{ |
38 |
{ARG_STRING, "ds", NOTSPECIFIED, "data series to process."}, |
39 |
{ARG_TIME, "first", NOTSPECIFIED, "first time to process."}, |
40 |
{ARG_TIME, "last", NOTSPECIFIED, "last time to process."}, |
41 |
{ARG_END} |
42 |
}; |
43 |
|
44 |
#define CAM1_DELTA (0.0135 - 0.082596) // i.e. change 180.082596 to 180.0135 by adding CAM1_DELTA to INST_ROT and CROTAT2 |
45 |
#define CAM2_DELTA (-0.0702) // i.e. change 180.0 to 179.9298 by adding CAM1_DELTA to INST_ROT and CROTAT2 |
46 |
#define BLOCKSIZE (4000) // approx number of records to process in one call, will be rounded down to nice time. |
47 |
#define HOUR (3600) |
48 |
#define DAY (86400) |
49 |
|
50 |
int DoIt(void) |
51 |
{ |
52 |
int status = DRMS_SUCCESS; |
53 |
DRMS_Record_t *inTemplate; |
54 |
DRMS_RecordSet_t *inRS, *outRS; |
55 |
DRMS_Keyword_t *pkey; |
56 |
int irec, nrecs, npkeys; |
57 |
const char *dsSeries = params_get_str(&cmdparams, "ds"); |
58 |
char dsQuery[DRMS_MAXQUERYLEN]; |
59 |
char *timekeyname; |
60 |
TIME t_first = params_get_time(&cmdparams, "first"); |
61 |
TIME t_last = params_get_time(&cmdparams, "last"); |
62 |
TIME t_step, t_epoch, t_block, t_start, t_stop; |
63 |
int hasCALVER64; |
64 |
int hasCALVER32; |
65 |
|
66 |
char history[4096]; |
67 |
|
68 |
// Now find the prime time keyword name |
69 |
inTemplate = drms_template_record(drms_env, dsSeries, &status); |
70 |
if (status || !inTemplate) DIE("series not found"); |
71 |
npkeys = inTemplate->seriesinfo->pidx_num; |
72 |
timekeyname = NULL; |
73 |
if (npkeys > 0) |
74 |
{ |
75 |
int i; |
76 |
for (i=0; i<npkeys; i++) |
77 |
{ |
78 |
pkey = inTemplate->seriesinfo->pidx_keywords[i]; |
79 |
if (pkey->info->recscope > 1) |
80 |
pkey = drms_keyword_slotfromindex(pkey); |
81 |
if (pkey->info->type != DRMS_TYPE_TIME) |
82 |
continue; |
83 |
if(i > 0) DIE("Input series must have TIME keyword first, for now..."); |
84 |
timekeyname = pkey->info->name; |
85 |
t_step = drms_keyword_getdouble(drms_keyword_stepfromslot(pkey), &status); |
86 |
if (status) DIE("problem getting t_step"); |
87 |
t_epoch = drms_keyword_getdouble(drms_keyword_epochfromslot(pkey), &status); |
88 |
if (status) DIE("problem getting t_epoch"); |
89 |
break; |
90 |
} |
91 |
} |
92 |
else |
93 |
DIE("Must have time prime key"); |
94 |
|
95 |
hasCALVER64 = drms_keyword_lookup(inTemplate, "CALVER64", 0) != NULL; |
96 |
hasCALVER32 = drms_keyword_lookup(inTemplate, "CALVER32", 0) != NULL; |
97 |
|
98 |
fprintf(stdout,"Series %s hasCALVER32=%d hasCALVER64=%d\n",dsSeries, hasCALVER32, hasCALVER64); |
99 |
fflush(stdout); |
100 |
|
101 |
if (strncmp(dsSeries, "hmi.lev1", 8) && !hasCALVER64) |
102 |
DIE("Must have non-linked CALVER64 keyword for products above lev1"); |
103 |
|
104 |
if (strncmp(dsSeries, "hmi.lev1", 8) == 0 && !hasCALVER32) |
105 |
DIE("Must have non-linked CALVER32 keyword for lev1 products"); |
106 |
|
107 |
t_block = t_step * BLOCKSIZE; |
108 |
if (t_block > 100*DAY) |
109 |
t_block = 100*DAY; |
110 |
else if (t_block > 10*DAY) |
111 |
t_block = 10*DAY; |
112 |
else if (t_block > DAY) |
113 |
t_block = DAY; |
114 |
else if (t_block > 6*HOUR) |
115 |
t_block = 6*3600; |
116 |
|
117 |
for (t_start = t_first; t_start <= t_last; t_start += t_block) |
118 |
{ |
119 |
char first[100], last[100]; |
120 |
t_stop = t_start + t_block - t_step; |
121 |
if (t_stop > t_last) |
122 |
t_stop = t_last; |
123 |
sprint_time(first, t_start, pkey->info->unit, 0); |
124 |
sprint_time(last, t_stop, pkey->info->unit, 0); |
125 |
|
126 |
sprintf(dsQuery, "%s[%s-%s]", dsSeries, first, last); |
127 |
fprintf(stdout,"Query %s ",dsQuery); |
128 |
fflush(stdout); |
129 |
|
130 |
inRS = drms_open_records(drms_env, dsQuery, &status); |
131 |
nrecs = inRS->n; |
132 |
if (status || nrecs == 0) |
133 |
{ |
134 |
fprintf(stdout, " status=%d, no records found, skip this block\n",status); |
135 |
fflush(stdout); |
136 |
continue; |
137 |
} |
138 |
|
139 |
outRS = drms_clone_records_nosums(inRS, DRMS_PERMANENT, DRMS_SHARE_SEGMENTS, &status); |
140 |
nrecs = outRS->n; |
141 |
if (status || nrecs == 0) |
142 |
DIE("No records cloned"); |
143 |
drms_close_records(inRS, DRMS_FREE_RECORD); |
144 |
|
145 |
for (irec=0; irec<nrecs; irec++) |
146 |
{ |
147 |
DRMS_Record_t *rec = outRS->records[irec]; |
148 |
double inst_rot, crota2; |
149 |
unsigned long long calver64 = 0; |
150 |
unsigned int calver32 = 0; |
151 |
int quality, camera, instrot_status; |
152 |
|
153 |
quality = drms_getkey_int(rec, "QUALITY", &status); |
154 |
// if (!status && quality < 0) |
155 |
// continue; |
156 |
|
157 |
if (hasCALVER64) |
158 |
{ |
159 |
calver64 = (unsigned long long)drms_getkey_longlong(rec, "CALVER64", NULL); |
160 |
if ((calver64 & 0xF0) != 0) |
161 |
{ |
162 |
fprintf(stdout, "Record previously processed, skip, first=%s, irec=%d\n", first, irec); |
163 |
fflush(stdout); |
164 |
continue; |
165 |
} |
166 |
} |
167 |
else if (hasCALVER32) |
168 |
{ |
169 |
calver32 = (unsigned int)drms_getkey_int(rec, "CALVER32", NULL); |
170 |
if ((calver32 & 0xF0) != 0) |
171 |
{ |
172 |
fprintf(stdout, "Record previously processed, skip, first=%s, irec=%d\n", first, irec); |
173 |
fflush(stdout); |
174 |
continue; |
175 |
} |
176 |
} |
177 |
|
178 |
inst_rot = drms_getkey_double(rec, "INST_ROT", &instrot_status); |
179 |
camera = drms_getkey_int(rec, "CAMERA", NULL); |
180 |
crota2 = drms_getkey_double(rec, "CROTA2", NULL); |
181 |
|
182 |
// The action is all between here and the end of the irec loop |
183 |
if (camera == 1) |
184 |
{ |
185 |
crota2 += CAM1_DELTA; |
186 |
inst_rot += CAM1_DELTA; |
187 |
sprintf(history, "CROTA2 corrected by adding %6.4f degrees", CAM1_DELTA); |
188 |
} |
189 |
else |
190 |
{ |
191 |
crota2 += CAM2_DELTA; |
192 |
inst_rot += CAM2_DELTA; |
193 |
sprintf(history, "CROTA2 corrected by adding %6.4f degrees", CAM2_DELTA); |
194 |
} |
195 |
|
196 |
if (hasCALVER64) |
197 |
{ |
198 |
calver64 &= 0xFFFFFFFFFFFFFF0F; |
199 |
calver64 |= 0x0000000000000010; |
200 |
drms_setkey_longlong(rec, "CALVER64", calver64); |
201 |
} |
202 |
if (hasCALVER32) |
203 |
{ |
204 |
if (calver32 == 0x80000000) |
205 |
calver32 = 0xFFFFFFFF; |
206 |
calver32 &= 0xFFFFFF0F; |
207 |
calver32 |= 0x00000010; |
208 |
drms_setkey_int(rec, "CALVER32", calver32); |
209 |
} |
210 |
|
211 |
if (!instrot_status) |
212 |
drms_setkey_double(rec, "INST_ROT", inst_rot); |
213 |
drms_setkey_double(rec, "CROTA2", crota2); |
214 |
drms_appendhistory(rec, history, 1); |
215 |
drms_setkey_time(rec, "DATE", CURRENT_SYSTEM_TIME); |
216 |
} //end of "irec" loop |
217 |
|
218 |
if (drms_close_records(outRS, DRMS_INSERT_RECORD)) |
219 |
fprintf(stderr, "drms_close_records failure for first=%s\n", first); |
220 |
|
221 |
fprintf(stdout, "%s CROTA2 fixed for %s through %s\n", dsSeries, first, last); |
222 |
fflush(stdout); |
223 |
} // end of time chunk loop |
224 |
|
225 |
return (DRMS_SUCCESS); |
226 |
} // end of DoIt |