00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 static
00018 void
00019 match_ar_print(FILE *fp, char *s, match_info_t *m)
00020 {
00021 const int human_friendly = 0;
00022 char trec_str[24];
00023
00024 if (human_friendly) {
00025 if (m->valid != Patch_Normal) {
00026 fprintf(fp, "%sMatch-Patch not valid\n", s);
00027 } else {
00028 sprint_time(trec_str, m->t, "TAI", 0);
00029 fprintf(fp,
00030 "%sID = %d (%s) @ (%.2f,%.2f) A = %.1f\t[%s/%s]\n",
00031 s, m->id, trec_str, m->lat, m->lon, m->area, m->class_mag, m->class_zur);
00032 }
00033 } else {
00034
00035
00036 fprintf(fp,
00037 "%d\t%d\t%.1f\t%.2f\t%.2f\t%.1f\t%.1f\n",
00038 m->id, m->valid, (double) m->t, m->lat, m->lon, m->lon_wid, m->area);
00039 }
00040 }
00041
00042
00043
00044
00045
00046
00047 static
00048 void
00049 match_ar_extrapolate(TIME t, match_info_t *m0, match_info_t *m)
00050 {
00051 double dt = t - m0->t;
00052 const double CARR_RATE = 360.0 / 27.2753;
00053 const int SECDAY = 3600*24;
00054
00055
00056
00057 double omega = (dt / SECDAY) * CARR_RATE;
00058
00059
00060
00061 memcpy(m, m0, sizeof(*m));
00062
00063 m->t = t;
00064
00065 m->lon_carr = m0->lon_carr + omega;
00066 return;
00067 }
00068
00069
00070
00071
00072
00073
00074 static
00075 void
00076 match_ar_interpolate(TIME t, match_info_t *m0, match_info_t *m1, match_info_t *m)
00077 {
00078 double dt0 = t - m0->t;
00079 double dt1 = m1->t - t;
00080 double wt0, wt1;
00081
00082
00083
00084 if (m0 == m1) {
00085 wt0 = 1;
00086 } else if (dt0 == 0) {
00087 wt0 = 1;
00088 } else if (dt1 == 0) {
00089 wt0 = 0;
00090 } else {
00091
00092 wt0 = dt1 / (dt0 + dt1);
00093 }
00094 wt1 = 1.0 - wt0;
00095
00096 if (wt0 >= 0.5) {
00097 memcpy(m, m0, sizeof(*m));
00098 } else {
00099 memcpy(m, m1, sizeof(*m));
00100 }
00101
00102 m->lat = wt0 * m0->lat + wt1 * m1->lat;
00103 m->lon = wt0 * m0->lon + wt1 * m1->lon;
00104 m->lon_carr = wt0 * m0->lon_carr + wt1 * m1->lon_carr;
00105 m->lon_wid = wt0 * m0->lon_wid + wt1 * m1->lon_wid;
00106 m->area = wt0 * m0->area + wt1 * m1->area;
00107
00108
00109 m->t = t;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 static
00121 int
00122 match_ar_resample(int id, TIME t, match_info_t *MI_raw, int Nraw, match_info_t *MI)
00123 {
00124 int i, iLO, iHI;
00125 double dt, dt0, dt1;
00126 const double TOO_FAR = 3600*24*5;
00127 const double CLOSE_ENOUGH = 3600*1;
00128
00129
00130 iLO = iHI = -1;
00131 dt0 = -HUGE_VAL;
00132 dt1 = HUGE_VAL;
00133 for (i = 0; i < Nraw; i++) {
00134 if (MI_raw[i].id != id) continue;
00135 dt = MI_raw[i].t - t;
00136 if ((dt < -TOO_FAR) || (dt > TOO_FAR))
00137 continue;
00138
00139 if (dt <= 0) {
00140
00141 if (dt > dt0) {
00142
00143
00144 dt0 = dt;
00145 iLO = i;
00146 }
00147 }
00148
00149 if (dt >= 0) {
00150
00151 if (dt < dt1) {
00152
00153
00154 dt1 = dt;
00155 iHI = i;
00156 }
00157 }
00158 }
00159
00160
00161 if ((iHI == -1) && (iLO >= 0 && fabs(dt0) < CLOSE_ENOUGH))
00162 iHI = iLO;
00163
00164 if ((iLO == -1) && (iHI >= 0 && fabs(dt1) < CLOSE_ENOUGH))
00165 iLO = iHI;
00166
00167
00168
00169 if (iLO < 0 || iHI < 0)
00170 return 1;
00171
00172 match_ar_interpolate(t, MI_raw+iLO, MI_raw+iHI, MI);
00173 return 0;
00174 }
00175
00176
00177
00178
00179
00180 static
00181 int
00182 match_get_single_info(int *id, match_info_t *mI, DRMS_Record_t *inRec)
00183 {
00184 char *str;
00185 int s1 = 0;
00186 int s = 0;
00187
00188 *id = drms_getkey_int(inRec, "RegionNumber", &s1); s |= s1;
00189 if (mI == NULL)
00190 return s;
00191
00192
00193
00194
00195 mI->valid = Patch_Normal;
00196 mI->id = *id;
00197 mI->t = drms_getkey_time(inRec, "ObservationTime", &s1); s |= s1;
00198 mI->lat = drms_getkey_int (inRec, "LatitudeHG", &s1); s |= s1;
00199 mI->lon = drms_getkey_int (inRec, "LongitudeCM", &s1); s |= s1;
00200 mI->lon_carr = drms_getkey_int (inRec, "LongitudeHG", &s1); s |= s1;
00201 mI->lon_wid = drms_getkey_int (inRec, "LongitudinalExtent", &s1); s |= s1;
00202 mI->area = drms_getkey_int (inRec, "Area", &s1); s |= s1;
00203 mI->spot = drms_getkey_int (inRec, "SpotCount", &s1); s |= s1;
00204
00205
00206
00207 str = drms_getkey_string(inRec, "MagneticType", &s1); s |= s1;
00208 if (str && (strcmp(str, "?") == 0))
00209 str = "Plage";
00210 snprintf(mI->class_mag, sizeof(mI->class_mag), "%s", str ? str : "");
00211
00212 str = drms_getkey_string(inRec, "ZurichClass", &s1); s |= s1;
00213 snprintf(mI->class_zur, sizeof(mI->class_zur), "%s", str ? str : "");
00214 return s;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 static
00225 int
00226 match_get_all_info(DRMS_RecordSet_t *rs,
00227 int *nMarp,
00228 marp_info_t **Marps_p,
00229 match_info_t *MInfo)
00230 {
00231 DRMS_Record_t *rec;
00232 marp_info_t *Marps;
00233 int MAXid = 32;
00234 int Nid = 0;
00235 int Nrec, i, j;
00236 int id1;
00237 int already_seen;
00238
00239
00240 *nMarp = 0;
00241 *Marps_p = NULL;
00242 if ((Marps = malloc(MAXid*sizeof(*Marps))) == NULL) {
00243 V_printf(-1, "", "Failed malloc for %d Marps\n", MAXid);
00244 return 1;
00245 }
00246
00247
00248
00249
00250 Nrec = rs->n;
00251 for (i = 0; i < Nrec; i++) {
00252 rec = rs->records[i];
00253 if (match_get_single_info(&id1, MInfo+i, rec) != 0) {
00254 V_printf(-1, "", "Could not get some attributes for Match AR %d\n", id1);
00255 continue;
00256 }
00257 for (already_seen = 0, j = 0; j < MAXid && Marps[j].id > 0; j++)
00258 if (Marps[j].id == id1) {
00259 already_seen = 1;
00260 break;
00261 }
00262
00263 if (!already_seen) {
00264
00265 if (Nid + 1 == MAXid) {
00266
00267 MAXid *= 4;
00268 Marps = realloc(Marps, MAXid*sizeof(*Marps));
00269 if (Marps == NULL) {
00270 V_printf(-1, "", "Failed re-alloc for %d Marps\n", MAXid);
00271 return 1;
00272 }
00273 }
00274
00275 Marps[Nid].id = id1;
00276 Marps[Nid].rec0 = Marps[Nid].rec1 = 0;
00277 Marps[Nid].n_match = 0;
00278 Nid += 1;
00279 }
00280 }
00281
00282 *nMarp = Nid;
00283 *Marps_p = Marps;
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 static
00299 int
00300 match_load_resample(int nRec_all,
00301 trec_info_t *tRec,
00302 int *nMarp_p,
00303 marp_info_t **marp_p,
00304 match_info_t **match_p)
00305 {
00306 const char *matchQueryRoot = "su_rsb.NOAA_ActiveRegions";
00307 const int SECDAY = 3600*24;
00308 DRMS_RecordSet_t *matchRS;
00309 int status;
00310 char t0_S[24], t1_S[24];
00311 char matchQuery[STR_MAX];
00312 marp_info_t *marpInfo;
00313 match_info_t *matchInfo_raw;
00314 match_info_t *matchInfo;
00315 int Nmatch_raw;
00316 int nMarp;
00317 int i, m, inx, id;
00318
00319
00320 *nMarp_p = 0;
00321 *marp_p = NULL;
00322 *match_p = NULL;
00323
00324
00325
00326
00327 if (nRec_all > 0) {
00328 TIME t0 = tRec[0 ].t - SECDAY;
00329 TIME t1 = tRec[nRec_all-1].t + SECDAY;
00330 sprint_time(t0_S, t0, "TAI", 0);
00331 sprint_time(t1_S, t1, "TAI", 0);
00332 } else {
00333 snprintf(t0_S, sizeof(t0_S), "%s", "2011.02.14_00:00:00_TAI");
00334 snprintf(t1_S, sizeof(t1_S), "%s", "2011.02.14_00:00:00_TAI");
00335 V_printf(verbflag > 0, "", "No HARPs, using nominal time range for matches.\n");
00336 }
00337 V_printf(verbflag > 0, "", "Match start = %s\n", t0_S);
00338 V_printf(verbflag > 0, "", "Match end = %s\n", t1_S);
00339 snprintf(matchQuery, sizeof(matchQuery), "%s[%s-%s]", matchQueryRoot, t0_S, t1_S);
00340
00341 status = 0;
00342 matchRS = drms_open_records(drms_env, matchQuery, &status);
00343 if (status != DRMS_SUCCESS) {
00344 V_printf(-1, "", "Could not get match AR records from DRMS (%s)\n", matchQuery);
00345 return 1;
00346 }
00347 Nmatch_raw = matchRS->n;
00348 V_printf(verbflag > 0, "", "Loading %s (%d records)\n", matchQuery, Nmatch_raw);
00349
00350 if ((matchInfo_raw = calloc(Nmatch_raw, sizeof(*matchInfo_raw))) == NULL) {
00351 V_printf(-1, "", "Could not allocate space for %d match records.\n", Nmatch_raw);
00352 drms_close_records(matchRS, DRMS_FREE_RECORD);
00353 return 1;
00354 }
00355
00356 status = match_get_all_info(matchRS, &nMarp, &marpInfo, matchInfo_raw);
00357 drms_close_records(matchRS, DRMS_FREE_RECORD);
00358 if (status != 0) {
00359 V_printf(-1, "", "Could not extract info from match AR records\n");
00360 return 1;
00361 }
00362 V_printf(verbflag > 1, "\t", "Found %d distinct match ARs\n", nMarp);
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 if ((matchInfo = calloc(nMarp*nRec_all, sizeof(*matchInfo))) == NULL) {
00374 free(matchInfo_raw);
00375 return 1;
00376 }
00377 for (m = 0; m < nMarp; m++) {
00378 id = marpInfo[m].id;
00379
00380 for (i = 0; i < nRec_all; i++) {
00381 inx = nRec_all * m + i;
00382
00383
00384 status = match_ar_resample(id, tRec[i].t, matchInfo_raw, Nmatch_raw, matchInfo+inx);
00385 if (status != 0) {
00386
00387
00388 } else {
00389
00390 }
00391 }
00392 }
00393 free(matchInfo_raw);
00394
00395 *nMarp_p = nMarp;
00396 *marp_p = marpInfo;
00397 *match_p = matchInfo;
00398 return 0;
00399 }
00400