00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "jsoc_main.h"
00050
00051 #include <stdio.h>
00052 #include <string.h>
00053 #include <stdlib.h>
00054 #include <stdarg.h>
00055 #include <math.h>
00056 #include <sys/time.h>
00057 #include <sys/resource.h>
00058
00059
00060 static int verbflag;
00061
00062
00063
00064
00065 #define DIE(msg) do { \
00066 fflush(stdout); \
00067 fprintf(stderr, "%s: FATAL: %s. (status=%d)\n", module_name, msg, status); \
00068 return(status ? status : 1); \
00069 } while (0)
00070
00071
00072 #define WARN(msg) do { \
00073 fflush(stdout); \
00074 fprintf(stderr, "%s: WARNING: %s. Continuing.\n", module_name, msg); \
00075 fflush(stderr); \
00076 } while (0)
00077
00078
00079
00080
00081
00082
00083
00084 void
00085 V_printf(int flag, char *first, char *format, ...) {
00086 va_list args;
00087 extern char *module_name;
00088 FILE *fp = (flag > 0) ? stdout : stderr;
00089
00090 va_start(args, format);
00091 if (flag != 0) {
00092
00093
00094 if (first)
00095 fprintf(fp, "%s%s: ", first, module_name);
00096 vfprintf(fp, format, args);
00097 fflush(fp);
00098 }
00099 va_end(args);
00100 }
00101
00102
00103 #define STR_MAX 256
00104
00105
00106 #define DTOR (M_PI / 180.)
00107 #define RAD2ARCSEC (648000. / M_PI)
00108
00109
00110
00111
00112
00113
00114
00115
00116 #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
00117 #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
00118 #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
00119 #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 typedef struct {
00131 int ok;
00132 char missing[32];
00133
00134 double rsun_ref;
00135 double dsun_obs;
00136 float cdelt1;
00137 float crval1;
00138 float crval2;
00139 float crpix1;
00140 float crpix2;
00141 float crota2;
00142 float crlt_obs;
00143 float crln_obs;
00144 } wcs_t;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 static double getwalltime(void)
00155 {
00156 struct timeval tv;
00157 gettimeofday(&tv, NULL);
00158 return tv.tv_sec * 1000.0 + tv.tv_usec/1000.0;
00159 }
00160
00161 static double getcputime(double *utime, double *stime)
00162 {
00163
00164 struct rusage ru;
00165 getrusage(RUSAGE_SELF, &ru);
00166 *utime = ru.ru_utime.tv_sec * 1000.0 + ru.ru_utime.tv_usec / 1000.0;
00167 *stime = ru.ru_stime.tv_sec * 1000.0 + ru.ru_stime.tv_usec / 1000.0;
00168 return *utime + *stime;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 #define max(a,b) (((a) > (b)) ? (a) : (b))
00179
00180 static
00181 double
00182 wcs_diff(wcs_t *wcs1, wcs_t *wcs2)
00183 {
00184 double top = 0;
00185
00186
00187 top = max(top, fabs(wcs1->cdelt1 - wcs2->cdelt1 ));
00188 top = max(top, fabs(wcs1->crval1 - wcs2->crval1 ));
00189 top = max(top, fabs(wcs1->crval2 - wcs2->crval2 ));
00190 top = max(top, fabs(wcs1->crpix1 - wcs2->crpix1 ));
00191 top = max(top, fabs(wcs1->crpix2 - wcs2->crpix2 ));
00192 top = max(top, fabs(wcs1->crota2 - wcs2->crota2 ));
00193 top = max(top, fabs(wcs1->crlt_obs - wcs2->crlt_obs));
00194
00195
00196 return top;
00197 }
00198
00199
00200 #undef max
00201
00202
00203
00204
00205
00206
00207
00208
00209 static
00210 int
00211 wcs_load(wcs_t *wcs, DRMS_Record_t *rec)
00212 {
00213 int status, retval;
00214 const size_t Nmiss = sizeof(wcs->missing);
00215
00216
00217 status = 0;
00218 wcs->rsun_ref = drms_getkey_double(rec, "RSUN_REF", &status);
00219 if (status) wcs->rsun_ref = 6.96e8;
00220 status = 0;
00221 wcs->dsun_obs = drms_getkey_double(rec, "DSUN_OBS", &status);
00222 wcs->cdelt1 = drms_getkey_float (rec, "CDELT1", &status);
00223 wcs->crval1 = drms_getkey_float (rec, "CRVAL1", &status);
00224 wcs->crval2 = drms_getkey_float (rec, "CRVAL2", &status);
00225 wcs->crpix1 = drms_getkey_float (rec, "CRPIX1", &status);
00226 wcs->crpix2 = drms_getkey_float (rec, "CRPIX2", &status);
00227 wcs->crota2 = drms_getkey_float (rec, "CROTA2", &status);
00228 wcs->crlt_obs = drms_getkey_float (rec, "CRLT_OBS", &status);
00229 wcs->crln_obs = drms_getkey_float (rec, "CRLN_OBS", &status);
00230
00231 strcpy(wcs->missing, "");
00232 retval = 0;
00233
00234 if (status != 0) {
00235 snprintf(wcs->missing, Nmiss, "Failed getkey()");
00236 retval = 1;
00237 } else {
00238 if (isnan(wcs->dsun_obs)) snprintf(wcs->missing, Nmiss, "NaN %s", "DSUN_OBS");
00239 if (isnan(wcs->cdelt1 )) snprintf(wcs->missing, Nmiss, "NaN %s", "CDELT1");
00240 if (isnan(wcs->crval1 )) snprintf(wcs->missing, Nmiss, "NaN %s", "CRVAL1");
00241 if (isnan(wcs->crval2 )) snprintf(wcs->missing, Nmiss, "NaN %s", "CRVAL2");
00242 if (isnan(wcs->crpix1 )) snprintf(wcs->missing, Nmiss, "NaN %s", "CRPIX1");
00243 if (isnan(wcs->crpix2 )) snprintf(wcs->missing, Nmiss, "NaN %s", "CRPIX2");
00244 if (isnan(wcs->crota2 )) snprintf(wcs->missing, Nmiss, "NaN %s", "CROTA2");
00245 if (isnan(wcs->crlt_obs)) snprintf(wcs->missing, Nmiss, "NaN %s", "CRLT_OBS");
00246 if (isnan(wcs->crln_obs)) snprintf(wcs->missing, Nmiss, "NaN %s", "CRLN_OBS");
00247
00248 if (strlen(wcs->missing) > 0)
00249 retval = 2;
00250 }
00251
00252 return retval;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 static
00292 char *
00293 load_drms_rec_seg(DRMS_RecordSet_t **recSetP,
00294 DRMS_Record_t **recP,
00295 DRMS_Array_t **dataP,
00296 wcs_t *wcs,
00297
00298 const char *query,
00299 const char *trec,
00300 const char *segname,
00301 DRMS_Type_t d_typ)
00302 {
00303 char rec_query[STR_MAX];
00304 char tag[STR_MAX];
00305 int status, return_code;
00306 DRMS_RecordSet_t *the_recSet;
00307 DRMS_Record_t *the_rec;
00308 DRMS_Array_t *the_data;
00309 DRMS_Segment_t *the_seg;
00310
00311
00312 if (!query || !trec)
00313 return "Illegal argument to load_drms_rec_seg: need query and trec";
00314 if (!recSetP && (recP || dataP))
00315 return "Illegal argument to load_drms_rec_seg: recSet required here";
00316 if (!segname && dataP)
00317 return "Illegal argument to load_drms_rec_seg: segname required for data";
00318
00319 if (recSetP) *recSetP = NULL;
00320 if (recP) *recP = NULL;
00321 if (dataP) *dataP = NULL;
00322 if (wcs) {wcs->ok = 0; strcpy(wcs->missing, ""); }
00323
00324 snprintf(tag, sizeof(tag), "%s %s",
00325 segname ? "and segment" : "(no segment)",
00326 dataP ? "and array" : "");
00327
00328 snprintf(rec_query, sizeof(rec_query), "%s[%s]", query, trec);
00329 V_printf(verbflag > 2, "\t\t", "Opening record %s %s\n", rec_query, tag);
00330 status = 0;
00331 the_recSet = drms_open_records(drms_env, rec_query, &status);
00332 if (status != 0) {
00333
00334 return "Could not open record at this T_REC";
00335 }
00336
00337 if (the_recSet->n != 1) {
00338 drms_close_records(the_recSet, DRMS_FREE_RECORD);
00339 return "Could not open single record at this T_REC";
00340 }
00341 the_rec = the_recSet->records[0];
00342
00343 int quality = drms_getkey_int(the_rec, "QUALITY", &status);
00344 if (status != 0 || (quality & 0x80000000)) {
00345 drms_close_records(the_recSet, DRMS_FREE_RECORD);
00346 return "Missing data at this T_REC (quality)";
00347 }
00348
00349 if (wcs) {
00350 return_code = wcs_load(wcs, the_rec);
00351 if (return_code != 0) {
00352 drms_close_records(the_recSet, DRMS_FREE_RECORD);
00353 return "Missing WCS at this T_REC";
00354 }
00355 }
00356
00357 if (segname) {
00358 the_seg = drms_segment_lookup(the_rec, segname);
00359 if (the_seg == NULL) {
00360 drms_close_records(the_recSet, DRMS_FREE_RECORD);
00361 return "Failed data segment lookup at this T_REC";
00362 }
00363 }
00364
00365 if (segname && dataP) {
00366
00367 the_data = drms_segment_read(the_seg, d_typ, &status);
00368 if (the_data == NULL || status != 0) {
00369 drms_close_records(the_recSet, DRMS_FREE_RECORD);
00370 return "Failed data segment read at this T_REC";
00371 }
00372 }
00373
00374 if (recSetP) *recSetP = the_recSet;
00375 if (recP) *recP = the_rec;
00376 if (dataP) *dataP = the_data;
00377
00378 if (!recSetP)
00379 drms_close_records(the_recSet, DRMS_FREE_RECORD);
00380 return NULL;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 #define kSeriesXM "xm"
00394 #define kSeriesXP "xp"
00395 #define kQueryMask "y"
00396 #define kThresh "thresh"
00397 #define kLevel "level"
00398 #define kVerb "VERB"
00399
00400 char *module_name = "track_hmi_check_masks";
00401
00402 ModuleArgs_t module_args[] =
00403 {
00404 {ARG_STRING, kSeriesXM, "", "M-gram data series."},
00405 {ARG_STRING, kSeriesXP, "", "P-gram data series."},
00406 {ARG_STRING, kQueryMask, "", "Mask recordset query."},
00407 {ARG_DOUBLE, kThresh, "0", "Threshold: count, or proportion in [0,1)"},
00408 {ARG_INT, kLevel, "1", "Check level (unused at present)"},
00409 {ARG_INT, kVerb, "1", "Verbosity: 0=errs only; 1, 2, 3 = more"},
00410 {ARG_END}
00411 };
00412
00413
00414
00415
00416
00417
00418
00419
00420 int DoIt(void)
00421 {
00422
00423 int status = DRMS_SUCCESS;
00424 CmdParams_t *params = &cmdparams;
00425 const char *xmSeries = params_get_str(params, kSeriesXM);
00426 const char *xpSeries = params_get_str(params, kSeriesXP);
00427 const char *maskQuery = params_get_str(params, kQueryMask);
00428 const double threshIn = params_get_double(params, kThresh);
00429 const int level = params_get_int(params, kLevel);
00430
00431 char *maskTrecTail;
00432 char maskSeries[STR_MAX];
00433 char magQuery[STR_MAX];
00434
00435 DRMS_RecordSet_t *xmRecSet;
00436
00437 int ds, Nds;
00438 int ds_ok_source, ds_ok_mask, ds_bad;
00439 int thresh;
00440
00441 wcs_t mag_wcs, pgram_wcs;
00442 TIME trec;
00443 char trecStr[64];
00444 char trec_save[64];
00445 char *err;
00446 char err_save[STR_MAX];
00447
00448 double wt0, wt1, wt;
00449 double ut0, ut1, ut;
00450 double st0, st1, st;
00451 double ct0, ct1, ct;
00452
00453
00454 verbflag = params_get_int(params, kVerb);
00455
00456 V_printf(verbflag, "", "Beginning.\n");
00457
00458 wt0 = getwalltime();
00459 ct0 = getcputime(&ut0, &st0);
00460
00461
00462 if (strchr(xmSeries, '[') != NULL)
00463 WARN("Got T_REC qualifier [...] in mag input series, probably an error");
00464 if (strchr(xpSeries, '[') != NULL)
00465 WARN("Got T_REC qualifier [...] in pgram input series, probably an error");
00466 if ((maskTrecTail = strchr(maskQuery, '[')) == NULL)
00467 DIE("Need T_REC qualifier [...] in y (mask) input record query");
00468
00469 snprintf(magQuery, sizeof(magQuery), "%s%s", xmSeries, maskTrecTail);
00470
00471 strncpy(maskSeries, "", sizeof(maskSeries));
00472 strncpy(maskSeries, maskQuery, maskTrecTail-maskQuery);
00473
00474
00475 xmRecSet = drms_open_records(drms_env, (char *) magQuery, &status);
00476 if (status) {
00477 V_printf(-1, "", "Fatal: could not open mags for masks (%s)\n", magQuery);
00478 DIE("No matching mgram input data found");
00479 }
00480 Nds = xmRecSet->n;
00481
00482
00483 if (threshIn >= 1.0) {
00484
00485 thresh = (int) threshIn;
00486 } else {
00487
00488 thresh = (int) (Nds * threshIn);
00489 }
00490
00491
00492 V_printf(verbflag, "", "Examining sources and masks at %d T_RECs.\n", Nds);
00493 ds_ok_source = ds_ok_mask = 0;
00494 for (ds = 0; ds < Nds; ds++) {
00495
00496 wt1 = getwalltime();
00497 ct1 = getcputime(&ut1, &st1);
00498
00499 status = 0;
00500 trec = drms_getkey_time(xmRecSet->records[ds], "T_REC", &status);
00501 if (status) {
00502 V_printf(-1, "", "No T_REC at record %d of %d, skipping.\n", ds, Nds);
00503 continue;
00504 }
00505 sprint_time(trecStr, trec, "TAI", 0);
00506 V_printf(verbflag > 1, "\t", "[%d/%d] %s\n", ds, Nds, trecStr);
00507
00508
00509 err = load_drms_rec_seg(NULL, NULL, NULL, &mag_wcs,
00510 xmSeries, trecStr, "magnetogram", DRMS_TYPE_RAW);
00511 V_printf(err && (verbflag > 1), "\t\t",
00512 "%s[%s]: %s %s-- mag missing is OK.\n", xmSeries, trecStr, err,
00513 mag_wcs.ok ? "" : mag_wcs.missing);
00514
00515 if (err) continue;
00516
00517
00518 err = load_drms_rec_seg(NULL, NULL, NULL, &pgram_wcs,
00519 xpSeries, trecStr, "continuum", DRMS_TYPE_RAW);
00520 V_printf(err && (verbflag > 1), "\t\t",
00521 "%s[%s]: %s %s-- pgram missing is OK.\n", xpSeries, trecStr, err,
00522 pgram_wcs.ok ? "" : pgram_wcs.missing);
00523
00524 if (err) continue;
00525
00526
00527
00528
00529 if (wcs_diff(&mag_wcs, &pgram_wcs) > 1e-4) {
00530 err = "WCS mismatch between pgram/mgram at same T_REC";
00531 V_printf(verbflag > 1, "\t",
00532 "%s[%s]: %s -- OK (but surprising).\n", xmSeries, trecStr, err);
00533 continue;
00534 }
00535
00536
00537 err = load_drms_rec_seg(NULL, NULL, NULL, NULL,
00538 maskSeries, trecStr, "mask", DRMS_TYPE_RAW);
00539
00540 V_printf(err && (verbflag > 0), "\t\t",
00541 "%s[%s]: %s -- Error: mask missing.\n", maskSeries, trecStr, err);
00542
00543
00544 ds_ok_source++;
00545
00546 if (!err) ds_ok_mask++;
00547
00548 if (err) {
00549 snprintf(err_save, sizeof(err_save), "%s", err);
00550 snprintf(trec_save, sizeof(trec_save), "%s", trecStr);
00551 }
00552
00553
00554 wt = getwalltime();
00555 ct = getcputime(&ut, &st);
00556 V_printf(verbflag > 2, "\t\t", "record %d time used: %.3f s wall, %.3f s cpu\n",
00557 ds+1, (wt - wt1)*1e-3, (ct - ct1)*1e-3);
00558 }
00559 V_printf(verbflag > 2, "", "close records (mgram)\n");
00560 drms_close_records(xmRecSet, DRMS_FREE_RECORD);
00561
00562
00563 ds_bad = ds_ok_source - ds_ok_mask;
00564 V_printf(verbflag, "", "Examined NT = %d T_RECs.\n", Nds);
00565 V_printf(verbflag, "", " Of NT, found %d valid (mag,pgram) pairs.\n", ds_ok_source);
00566 V_printf(verbflag, "", " Of NT, found %d valid masks.\n", ds_ok_mask);
00567 if (ds_bad > 0) {
00568
00569 V_printf(1, "", "Some masks (%d) were missing although sources were present.\n", ds_bad);
00570 V_printf(1, "", "\tExample: %s[%s] -- %s.\n", maskSeries, trec_save, err_save);
00571 } else {
00572 V_printf(1, "", "No unexplained absences of masks.\n");
00573 }
00574 if (ds_bad <= thresh) {
00575 V_printf(1, "", "Overall mask check passed: %d missing <= %d threshold.\n",
00576 ds_bad, thresh);
00577 } else {
00578 V_printf(1, "", "Mask check failed: %d missing > %d threshold\n",
00579 ds_bad, thresh);
00580 }
00581
00582
00583 wt = getwalltime();
00584 ct = getcputime(&ut, &st);
00585 V_printf(verbflag, "", "total time used: %.3f s wall, %.3f s cpu\n",
00586 (wt - wt0)*1e-3, (ct - ct0)*1e-3);
00587
00588 V_printf(verbflag, "", "Done.\n");
00589
00590 if (ds_bad <= thresh) {
00591 return DRMS_SUCCESS;
00592 } else {
00593
00594 return 1;
00595 }
00596 }
00597