00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <jsoc_main.h>
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <math.h>
00015 #include <sys/time.h>
00016 #include <sys/resource.h>
00017
00018 #define DIE(msg) {fflush(stdout); fprintf(stderr, "%s, status=%d\n", msg, status); return(status);}
00019
00020
00021 #define STR_MAX 200
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 typedef enum {
00033 Patch_Invalid = 0,
00034 Patch_Normal,
00035 Patch_Padding,
00036 } patch_status_t;
00037
00038
00039
00040
00041 typedef struct {
00042 TIME t;
00043 char str[24];
00044 int nharp;
00045 } trec_info_t;
00046
00047
00048
00049
00050 typedef struct {
00051 int id;
00052 int rec0, rec1;
00053 } marp_info_t;
00054
00055
00056
00057
00058 typedef struct {
00059 patch_status_t valid;
00060 int id;
00061 TIME t;
00062 float lat, lon;
00063 float lon_carr;
00064 float lon_wid;
00065 float area;
00066 int spot;
00067 char class_mag[STR_MAX];
00068 char class_zur[4];
00069 } match_info_t;
00070
00071
00072
00073
00074
00075
00076
00077
00078 static
00079 void
00080 match_ar_print(char *s, match_info_t *m)
00081 {
00082 char trec_str[24];
00083 if (m->valid != Patch_Normal) {
00084 printf("%sMatch-Patch not valid\n", s);
00085 } else {
00086 sprint_time(trec_str, m->t, "TAI", 0);
00087 printf("%sID = %d (%s) @ (%.2f,%.2f) A = %.1f\t[%s/%s]\n",
00088 s, m->id, trec_str, m->lat, m->lon, m->area, m->class_mag, m->class_zur);
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097 static
00098 void
00099 match_ar_interpolate(TIME t, match_info_t *m0, match_info_t *m1, match_info_t *m)
00100 {
00101 double dt0 = t - m0->t;
00102 double dt1 = m1->t - t;
00103 double wt0, wt1;
00104
00105
00106
00107 if (m0 == m1) {
00108 wt0 = 1;
00109 } else if (dt0 == 0) {
00110 wt0 = 1;
00111 } else if (dt1 == 0) {
00112 wt0 = 0;
00113 } else {
00114
00115 wt0 = dt1 / (dt0 + dt1);
00116 }
00117 wt1 = 1.0 - wt0;
00118
00119 if (wt0 >= 0.5) {
00120 memcpy(m, m0, sizeof(*m));
00121 } else {
00122 memcpy(m, m1, sizeof(*m));
00123 }
00124
00125 m->lat = wt0 * m0->lat + wt1 * m1->lat;
00126 m->lon = wt0 * m0->lon + wt1 * m1->lon;
00127 m->lon_carr = wt0 * m0->lon_carr + wt1 * m1->lon_carr;
00128 m->lon_wid = wt0 * m0->lon_wid + wt1 * m1->lon_wid;
00129 m->area = wt0 * m0->area + wt1 * m1->area;
00130
00131
00132 m->t = t;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 static
00144 int
00145 match_ar_resample(int id, TIME t, match_info_t *MI_raw, int Nraw, match_info_t *MI)
00146 {
00147 int i, iLO, iHI;
00148 double dt, dt0, dt1;
00149 const double TOO_FAR = 3600*24*5;
00150 const double CLOSE_ENOUGH = 3600*1;
00151
00152
00153 iLO = iHI = -1;
00154 dt0 = -HUGE_VAL;
00155 dt1 = HUGE_VAL;
00156 for (i = 0; i < Nraw; i++) {
00157 if (MI_raw[i].id != id) continue;
00158 dt = MI_raw[i].t - t;
00159 if ((dt < -TOO_FAR) || (dt > TOO_FAR))
00160 continue;
00161
00162 if (dt <= 0) {
00163
00164 if (dt > dt0) {
00165
00166
00167 dt0 = dt;
00168 iLO = i;
00169 }
00170 }
00171
00172 if (dt >= 0) {
00173
00174 if (dt < dt1) {
00175
00176
00177 dt1 = dt;
00178 iHI = i;
00179 }
00180 }
00181 }
00182
00183
00184 if ((iHI == -1) && (iLO >= 0 && fabs(dt0) < CLOSE_ENOUGH))
00185 iHI = iLO;
00186
00187 if ((iLO == -1) && (iHI >= 0 && fabs(dt1) < CLOSE_ENOUGH))
00188 iLO = iHI;
00189
00190
00191
00192 if (iLO < 0 || iHI < 0)
00193 return 1;
00194
00195 match_ar_interpolate(t, MI_raw+iLO, MI_raw+iHI, MI);
00196 return 0;
00197 }
00198
00199
00200
00201
00202
00203 static
00204 int
00205 match_get_single_info(int *id, match_info_t *mI, DRMS_Record_t *inRec)
00206 {
00207 char *str;
00208 int s1 = 0;
00209 int s = 0;
00210
00211 *id = drms_getkey_int(inRec, "RegionNumber", &s1); s |= s1;
00212 if (mI == NULL)
00213 return s;
00214
00215
00216
00217
00218 mI->valid = Patch_Normal;
00219 mI->id = *id;
00220 mI->t = drms_getkey_time(inRec, "ObservationTime", &s1); s |= s1;
00221 mI->lat = drms_getkey_int (inRec, "LatitudeHG", &s1); s |= s1;
00222 mI->lon = drms_getkey_int (inRec, "LongitudeCM", &s1); s |= s1;
00223 mI->lon_carr = drms_getkey_int (inRec, "LongitudeHG", &s1); s |= s1;
00224 mI->lon_wid = drms_getkey_int (inRec, "LongitudinalExtent", &s1); s |= s1;
00225 mI->area = drms_getkey_int (inRec, "Area", &s1); s |= s1;
00226 mI->spot = drms_getkey_int (inRec, "SpotCount", &s1); s |= s1;
00227
00228
00229
00230 str = drms_getkey_string(inRec, "MagneticType", &s1); s |= s1;
00231 if (str && (strcmp(str, "?") == 0))
00232 str = "Plage";
00233 snprintf(mI->class_mag, sizeof(mI->class_mag), "%s", str ? str : "");
00234
00235 str = drms_getkey_string(inRec, "ZurichClass", &s1); s |= s1;
00236 snprintf(mI->class_zur, sizeof(mI->class_zur), "%s", str ? str : "");
00237 return s;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 static
00248 int
00249 match_get_all_info(DRMS_RecordSet_t *rs,
00250 int *nMarp,
00251 marp_info_t **Marps_p,
00252 match_info_t *MInfo)
00253 {
00254 DRMS_Record_t *rec;
00255 marp_info_t *Marps;
00256 int MAXid = 32;
00257 int Nid = 0;
00258 int Nrec, i, j;
00259 int id1;
00260 int already_seen;
00261
00262
00263 *nMarp = 0;
00264 *Marps_p = NULL;
00265 if ((Marps = malloc(MAXid*sizeof(*Marps))) == NULL) {
00266 printf("Failed malloc for %d Marps\n", MAXid);
00267 return 1;
00268 }
00269
00270
00271
00272
00273 Nrec = rs->n;
00274 for (i = 0; i < Nrec; i++) {
00275 rec = rs->records[i];
00276 if (match_get_single_info(&id1, MInfo+i, rec) != 0) {
00277 fprintf(stderr, "Could not get some attributes for Match AR %d\n", id1);
00278 continue;
00279 }
00280 for (already_seen = 0, j = 0; j < MAXid && Marps[j].id > 0; j++)
00281 if (Marps[j].id == id1) {
00282 already_seen = 1;
00283 break;
00284 }
00285
00286 if (!already_seen) {
00287
00288 if (Nid + 1 == MAXid) {
00289
00290 MAXid *= 4;
00291 Marps = realloc(Marps, MAXid*sizeof(*Marps));
00292 if (Marps == NULL) {
00293 printf("Failed re-alloc for %d Marps\n", MAXid);
00294 return 1;
00295 }
00296 }
00297 Marps[Nid++].id = id1;
00298 }
00299 }
00300
00301 *nMarp = Nid;
00302 *Marps_p = Marps;
00303 return 0;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 static
00318 int
00319 match_load_resample(int nRec_all,
00320 trec_info_t *tRec,
00321 int *nMarp_p,
00322 marp_info_t **marp_p,
00323 match_info_t **match_p)
00324 {
00325 const char *matchQueryRoot = "su_rsb.NOAA_ActiveRegions";
00326 const int SECDAY = 3600*24;
00327 DRMS_RecordSet_t *matchRS;
00328 int status;
00329 TIME t0, t1;
00330 char t0_S[24], t1_S[24];
00331 char matchQuery[STR_MAX];
00332 marp_info_t *marpInfo;
00333 match_info_t *matchInfo_raw;
00334 match_info_t *matchInfo;
00335 int Nmatch_raw;
00336 int nMarp;
00337 int i, m, inx, id;
00338
00339
00340 *nMarp_p = 0;
00341 *marp_p = NULL;
00342 *match_p = NULL;
00343
00344
00345
00346
00347 t0 = tRec[0 ].t - SECDAY;
00348 t1 = tRec[nRec_all-1].t + SECDAY;
00349 sprint_time(t0_S, t0, "TAI", 0);
00350 sprint_time(t1_S, t1, "TAI", 0);
00351 printf("Match start = %s\nMatch end = %s\n", t0_S, t1_S);
00352 snprintf(matchQuery, sizeof(matchQuery), "%s[%s-%s]", matchQueryRoot, t0_S, t1_S);
00353
00354 status = 0;
00355 matchRS = drms_open_records(drms_env, matchQuery, &status);
00356 if (status != DRMS_SUCCESS) {
00357 printf("Could not get match AR records from DRMS (%s)\n", matchQuery);
00358 return 1;
00359 }
00360 Nmatch_raw = matchRS->n;
00361 printf("Matching against %s with %d records\n", matchQuery, Nmatch_raw);
00362
00363 if ((matchInfo_raw = calloc(Nmatch_raw, sizeof(*matchInfo_raw))) == NULL) {
00364 printf("Could not allocate space for %d match records.\n", Nmatch_raw);
00365 drms_close_records(matchRS, DRMS_FREE_RECORD);
00366 return 1;
00367 }
00368
00369 status = match_get_all_info(matchRS, &nMarp, &marpInfo, matchInfo_raw);
00370 drms_close_records(matchRS, DRMS_FREE_RECORD);
00371 if (status != 0) {
00372 printf("Could not extract info from match AR records\n");
00373 return 1;
00374 }
00375 printf("Found %d distinct ARs\n", nMarp);
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 if ((matchInfo = calloc(nMarp*nRec_all, sizeof(*matchInfo))) == NULL) {
00387 free(matchInfo_raw);
00388 return 1;
00389 }
00390 for (m = 0; m < nMarp; m++) {
00391 id = marpInfo[m].id;
00392
00393 for (i = 0; i < nRec_all; i++) {
00394 inx = nRec_all * m + i;
00395
00396
00397 status = match_ar_resample(id, tRec[i].t, matchInfo_raw, Nmatch_raw, matchInfo+inx);
00398 if (status != 0) {
00399
00400
00401 } else {
00402
00403 }
00404 }
00405 }
00406 free(matchInfo_raw);
00407
00408 *nMarp_p = nMarp;
00409 *marp_p = marpInfo;
00410 *match_p = matchInfo;
00411 return 0;
00412 }
00413
00414
00415 char *module_name = "noaa_loop";
00416
00417 ModuleArgs_t module_args[] =
00418 {
00419 {ARG_STRING, "ref", NULL, "Input time reference series name."},
00420 {ARG_INT, "noaa", "0", "Queried NOAA number (0 for all)."},
00421 {ARG_END}
00422 };
00423
00424
00425 int DoIt(void)
00426 {
00427 int status = DRMS_SUCCESS;
00428 int status1;
00429 char *refQuery;
00430 DRMS_RecordSet_t *refRS;
00431 DRMS_Record_t *refRec;
00432 int noaa, id;
00433 marp_info_t *marpInfo;
00434 match_info_t *matchInfo;
00435 int i, m, inx;
00436 TIME trec;
00437 char trec_str[40];
00438 int nMarp, nRec_all;
00439
00440
00441 refQuery = (char *)params_get_str(&cmdparams, "ref");
00442 noaa = params_get_int(&cmdparams, "noaa");
00443
00444
00445 refRS = drms_open_records(drms_env, refQuery, &status);
00446
00447 if (status || refRS->n == 0) DIE("No input data found");
00448 nRec_all = refRS->n;
00449
00450
00451 printf("Reference has %d records\n", nRec_all);
00452 trec_info_t tRec[nRec_all];
00453 for (i = 0; i < nRec_all; i++) {
00454 refRec = refRS->records[i];
00455 tRec[i].t = drms_getkey_time(refRec, "T_REC", &status);
00456 sprint_time(tRec[i].str, tRec[i].t, "TAI", 0);
00457
00458 }
00459 drms_close_records(refRS, DRMS_FREE_RECORD);
00460 printf("Reference T_REC range:\n\tt0 = %s\n\tt1 = %s\n",
00461 tRec[0].str, tRec[nRec_all-1].str);
00462
00463
00464 if (match_load_resample(nRec_all, tRec, &nMarp, &marpInfo, &matchInfo) != 0) {
00465 printf("Could not load and resample Match-AR metadata.\n");
00466 } else {
00467
00468 printf("\n\n=================================================\n\n\n");
00469 for (m = 0; m < nMarp; m++) {
00470 id = marpInfo[m].id;
00471 if (noaa > 0 && noaa != id) continue;
00472 for (i = 0; i < nRec_all; i++) {
00473 inx = nRec_all * m + i;
00474 if (matchInfo[inx].valid == Patch_Normal)
00475 match_ar_print("", matchInfo+inx);
00476 }
00477 }
00478 }
00479 free(marpInfo);
00480 free(matchInfo);
00481
00482 printf("done.\n");
00483
00484 return 0;
00485 }
00486