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
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <jsoc_main.h>
00060
00061 char *module_name = "maicalc";
00062 char *module_desc = "integration of mapped and tracked magnetogram data";
00063 char *version_id = "1.1";
00064
00065 #define RSUNM (6.96e8)
00066
00067 ModuleArgs_t module_args[] = {
00068 {ARG_STRING, "ds", "", "input data series or dataset"},
00069 {ARG_INT, "cr", "Not Specified", "Carrington Rotation (default: current)"},
00070 {ARG_FLOAT, "cl", "Not Specified",
00071 "Carrington longitude of central meridian (default: current or 180"},
00072 {ARG_FLOAT, "interval", "", "length of sampling interval, Carr. deg",
00073 "(0.0,)"},
00074 {ARG_INT, "qmask", "0x80000000", "quality bit mask for image rejection"},
00075 {ARG_STRING, "reject", "Not Specified", "file containing rejection list"},
00076 {ARG_INT, "rec_step", "", "sampling step, record steps", "[1,)"},
00077 {ARG_FLOAT, "max_reach", "0.5", "maximum reach to acceptable record",
00078 "[0.0,1.0]"},
00079 {ARG_FLOAT, "scale", "",
00080 "integrating map scale for interpolation [deg/pixel]", "(0.0,)"},
00081 {ARG_FLOAT, "extent", "", "extent of integrating maps [degrees]"},
00082 {ARG_FLOATS, "lat", "[0.0]",
00083 "heliographic latitude(s) of tracking center(s) [deg]"},
00084 {ARG_FLOATS, "lon", "[0.0]",
00085 "heliographic longitude(s) of tracking center(s) [deg]"},
00086 {ARG_FLOAT, "mask_in", "0.9765625", "inner edge of 1 - r^2 apodization",
00087 "[0.0,)"},
00088 {ARG_FLOAT, "mask_ex", "1.0", "outer edge of 1 - r^2 apodization", "[0.0,)"},
00089 {ARG_FLOAT, "floor", "50.0", "noise floor (gauss)", "[0.0,)"},
00090 {ARG_STRING, "file", "Not Specified", "output file name for diagnostics"},
00091 {ARG_STRING, "qual_key", "Quality", "keyname for 32-bit image quality field"},
00092 {ARG_STRING, "clon_key", "CRLN_OBS", "keyname for image central longitude"},
00093 {ARG_STRING, "clat_key", "CRLT_OBS", "keyname for image central latitude"},
00094 {ARG_STRING, "crot_key", "CAR_ROT", "keyname for image Carrington rotation"},
00095 {ARG_STRING, "rsun_key", "R_SUN", "keyname for image semi-diameter (pixel)"},
00096 {ARG_STRING, "apsd_key", "RSUN_OBS",
00097 "keyname for apparent solar semi-diameter (arcsec)"},
00098 {ARG_STRING, "dsun_key", "DSUN_OBS", "keyname for observer distance"},
00099 {ARG_FLAG, "n", "", "turns off tracking; target cl only determines time"},
00100 {ARG_FLAG, "r", "", "turns off apodization"},
00101 {ARG_FLAG, "t", "", "turns on time range checks"},
00102 {ARG_FLAG, "v", "", "runs in verbose mode"},
00103 {}
00104 };
00105
00106 #include "selstuff.c"
00107 #include "solephem.c"
00108 #include "cartography.c"
00109 #include "imginfo.c"
00110
00111 #define OUTLIER_RATIO (6.0)
00112 #define OUTLIER_BASE (400.0)
00113
00114
00115 float missing_val;
00116
00117
00118
00119
00120
00121 int fgetline (FILE *in, char *line, int max) {
00122 if (fgets (line, max, in) == NULL) return 0;
00123 else return (strlen (line));
00124 }
00125
00126 int read_reject_list (FILE *file, int **list) {
00127 int ds, sn, rec, last_rec;
00128 int allocd = 1024, ct = 0, gap = 0;
00129 char line[1024], t_str[64], estr[16];
00130
00131 *list = (int *)malloc (allocd * sizeof (int));
00132 while (fgetline (file, line, 1024)) {
00133 if (strlen (line) == 1) continue;
00134 if (line[0] == '#') continue;
00135 if (sscanf (line, "%d %d %d %s", &ds, &sn, &rec, t_str) != 4) {
00136 if (sscanf (line, "%d %s", &rec, t_str) != 2) {
00137 sscanf (line, "%s", estr);
00138 if (strcmp (estr, "...")) continue;
00139 gap = 1;
00140 last_rec = rec;
00141 continue;
00142 }
00143 }
00144 if (gap) {
00145 while (rec > last_rec) {
00146 last_rec++;
00147 (*list)[ct++] = last_rec;
00148 if (ct >= allocd) {
00149 allocd += 1024;
00150 *list = (int *)realloc (*list, allocd * sizeof (int));
00151 }
00152 }
00153 gap = 0;
00154 continue;
00155 }
00156 (*list)[ct++] = rec;
00157 if (ct >= allocd) {
00158 allocd += 1024;
00159 *list = (int *)realloc (*list, allocd * sizeof (int));
00160 }
00161 }
00162 return ct;
00163 }
00164
00165 double apodization (double x, double y, double inner, double outer) {
00166 double f, r = hypot (x, y), r2;
00167
00168 if (inner >= outer) r = (r < outer) ? 0.0 : 1.0;
00169 else r = (r - inner) / (outer - inner);
00170 r2 = 1.0 - r * r;
00171 f = (r >= 1.0) ? 0.0 : (r <= 0.0) ? 1.0 : r2 * r2;
00172 return f;
00173 }
00174
00175 int eliminate_outliers (DRMS_Array_t *img, double accept, double baseval) {
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 double s, w;
00186 double amn, amx;
00187 float *z;
00188 float v, blank = 0.0/ 0.0;
00189 arraylen_t n;
00190 int cl[8];
00191 int col, cols, row, rows, i;
00192 int count = 0;
00193 if (accept <= 0.0) return -1;
00194 if (accept < 1.0) accept = 1.0 / accept;
00195 amx = accept;
00196 amn = 1.0 / accept;
00197
00198
00199
00200 cols = drms_array_nth_axis (img, 0);
00201 rows = drms_array_nth_axis (img, 1);
00202 cl[0] = -cols - 1;
00203 cl[1] = -cols;
00204 cl[2] = -cols + 1;
00205 cl[3] = -1;
00206 cl[4] = 1;
00207 cl[5] = cols - 1;
00208 cl[6] = cols;
00209 cl[7] = cols + 1;
00210
00211 z = (float *)img->data;
00212
00213
00214 n = drms_array_count (img) - 1;
00215 n -= cols;
00216 for (row = rows - 2; row; row--) {
00217 for (col = cols - 2; col; col--, n--) {
00218 v = z[n];
00219 if (isnan (v)) continue;
00220 if (v == 0.0) continue;
00221 s = w = 0.0;
00222 for (i = 0; i < 8; i++) {
00223 v = z[n + cl[i]];
00224 if (isnan (v)) continue;
00225 w += 1.0;
00226 s += v;
00227 }
00228 if (w != 0.0) {
00229 v = fabs (z[n]);
00230 s /= w;
00231 s = fabs (s);
00232 if ((v > amx * s) && (v > baseval)) {
00233
00234
00235
00236
00237
00238 z[n] = blank;
00239 count++;
00240 } else if ((s > baseval) && (v < amn * s)) {
00241
00242
00243
00244
00245
00246 z[n] = blank;
00247 count++;
00248 }
00249 }
00250 }
00251 n -= 2;
00252 }
00253 return count;
00254 }
00255
00256 int truncate_noise (DRMS_Array_t *img, double accept) {
00257 arraylen_t n = drms_array_count (img);
00258 float *z;
00259 int count = 0;
00260
00261 z = (float *)img->data;
00262 while (n--) {
00263 if (fabs (*z) < accept) {
00264 *z = 0.0;
00265 count++;
00266 }
00267 z++;
00268 }
00269 return count;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 static void ccker (double *u, double s) {
00292 double s2, s3;
00293
00294 s2= s * s;
00295 s3= s2 * s;
00296 u[0] = s2 - 0.5 * (s3 + s);
00297 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
00298 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
00299 u[3] = 0.5 * (s3 - s2);
00300 }
00301
00302 float ccint2 (float *f, int nx, int ny, double x, double y) {
00303 double ux[4], uy[4];
00304 double sum;
00305 int ix, iy, ix1, iy1, i, j;
00306
00307 if (x < 1.0 || x >= (float)(nx-2) || y < 1.0 || y >= (float)(ny-2))
00308 return missing_val;
00309
00310 ix = (int)x;
00311 ccker (ux, x - (double)ix);
00312 iy = (int)y;
00313 ccker (uy, y - (double)iy);
00314
00315 ix1 = ix - 1;
00316 iy1 = iy - 1;
00317 sum = 0.;
00318 for (i = 0; i < 4; i++)
00319 for (j = 0; j < 4; j++)
00320 sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00321 return (float)sum;
00322 }
00323
00324 float nearest_val (float *f, int cols, int rows, double x, double y) {
00325 int col, row;
00326 if (x < -0.5 || x >= (cols - 0.5) || y < -0.5 || y >= (rows - 0.5))
00327 return missing_val;
00328 col = x + 0.5;
00329 row = y + 0.5;
00330 return f[col + row * cols];
00331 }
00332
00333 #define INTERP_NEAREST_NEIGHBOR (1)
00334
00335 float array_imaginterp (DRMS_Array_t *img, double x, double y, int schema) {
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 double xs, ys;
00361 int cols, rows, mdim;
00362
00363 cols = img->axis[0];
00364 rows = img->axis[1];
00365 mdim = (cols > rows) ? cols : rows;
00366 xs = 0.5 * (x + 1.0) * mdim - 0.5;
00367 ys = 0.5 * (y + 1.0) * mdim - 0.5;
00368 if (schema == INTERP_NEAREST_NEIGHBOR)
00369 return nearest_val (img->data, cols, rows, xs, ys);
00370 else return ccint2 (img->data, cols, rows, xs, ys);
00371 }
00372
00373
00374 #define CARRINGTON_EPOCH ("1853.11.09_12:00")
00375 #define CARR_ROT_SYNODIC (27.275311 * 86400.0)
00376
00377
00378 double carrington_rots (TIME obs_time) {
00379 TIME upd;
00380 double ephem[EPHEM_SIZE];
00381 double car_rot, clong, clest;
00382 double r, lat, lon, vr, vn, vw;
00383 int carr_ct;
00384
00385 car_rot = 1.0 + (obs_time - sscan_time (CARRINGTON_EPOCH)) / CARR_ROT_SYNODIC;
00386 carr_ct = car_rot;
00387 clest = car_rot - carr_ct;
00388 calc_sun_ephemeris (obs_time, ephem, 0.0, 0.0);
00389 lon = 360.0 - fmod (ephem[EPHEM_L0], 360.0);
00390 clong = 1.0 - lon / 360.0;
00391 if ((clong - clest) > 0.5) carr_ct--;
00392 if ((clest - clong) > 0.5) carr_ct++;
00393 return (carr_ct + clong);
00394 }
00395
00396
00397
00398
00399
00400
00401
00402 int good_record (DRMS_RecordSet_t *ds, int nrt, int rstp, float max_reach,
00403 TIME t0, TIME t1, int time_check, char *qual_key, unsigned int qmask,
00404 int *rejects, int *reject_list, int *shift) {
00405 DRMS_Record_t *rec;
00406 TIME t, tobs;
00407 unsigned int quality;
00408 int idrec, match;
00409 int n, nr, nrr, nrmn, nrmx, offset, status;
00410
00411 static int qcheck = 1;
00412 int found = 1;
00413 static unsigned char *ok = NULL;
00414
00415 rec = ds->records[nrt];
00416 if (time_check) {
00417 tobs = drms_getkey_time (rec, "T_OBS", &status);
00418 t = tobs - MISSION_EPOCH;
00419 if (t < t0 || t > t1 || status) found = 0;
00420 }
00421 if (qcheck) {
00422
00423 quality = drms_getkey_int (rec, qual_key, &status);
00424 if (status) qcheck = 0;
00425 else if (quality & qmask) found = 0;
00426 }
00427 if (*rejects) {
00428 idrec = drms_getkey_int (rec, "T_REC_index", &status);
00429 match = 0;
00430 if (status) {
00431 fprintf (stderr, "Warning: \"T_REC_index\" keyword not found\n");
00432 fprintf (stderr, " up to %d bad images could be processed\n",
00433 *rejects);
00434 *rejects = 0;
00435 }
00436 for (n = 0; n < *rejects; n++) {
00437 if (idrec == reject_list[n]) {
00438 match = 1;
00439 break;
00440 }
00441 }
00442 if (match) found = 0;
00443 }
00444 if (found) {
00445 *shift = 0;
00446 return nrt;
00447 }
00448
00449 nrr = -1;
00450 *shift = offset = max_reach * rstp;
00451 if (!offset) return nrr;
00452 nrmx = nrt + offset;
00453 nrmn = nrt - offset;
00454 ok = (unsigned char *)realloc (ok, ds->n * sizeof (char));
00455 if (nrmx >= ds->n) nrmx = ds->n - 1;
00456 if (nrmn < 0) nrmn = 0;
00457 for (nr = nrmn; nr <= nrmx; nr++) {
00458 rec = ds->records[nr];
00459 tobs = drms_getkey_time (rec, "T_OBS", &status);
00460 t = tobs - MISSION_EPOCH;
00461 if (t < t0 || t > t1 || status) {
00462 ok[nr] = 0;
00463 continue;
00464 }
00465 if (qcheck) {
00466
00467 quality = drms_getkey_int (rec, qual_key, &status);
00468 if (status) qcheck = 0;
00469 else if (quality & qmask) {
00470 ok[nr] = 0;
00471 continue;
00472 }
00473 }
00474 if (*rejects) {
00475
00476 idrec = drms_getkey_int (rec, "T_REC_index", &status);
00477 match = 0;
00478 for (n = 0; n < *rejects; n++) {
00479 if (idrec == reject_list[n]) {
00480 match = 1;
00481 break;
00482 }
00483 }
00484 if (match) {
00485 ok[nr] = 0;
00486 continue;
00487 }
00488 }
00489 ok[nr] = 1;
00490 }
00491 for (nr = nrmn; nr <= nrmx; nr++) {
00492
00493 if (ok[nr] && (abs (nr - nrt) < *shift)) {
00494 nrr = nr;
00495 *shift = abs (nr - nrt);
00496 }
00497 }
00498 return nrr;
00499 }
00500
00501
00502
00503 int DoIt (void) {
00504 CmdParams_t *params = &cmdparams;
00505 DRMS_RecordSet_t *ds;
00506 DRMS_Record_t *rec;
00507 DRMS_Segment_t *seg;
00508 DRMS_Array_t *mgram;
00509 struct maploc {
00510 double lat;
00511 double lon;
00512 double wt;
00513 } *mloc;
00514 FILE *out;
00515 TIME t, t0, t1, tcm;
00516 double *sum, *suma, *sb, *sbt, *sf, *sft, *s1, *st, *st2, *det;
00517 double img_radius, ellipse_e, ellipse_pa;
00518 double x, y, x0, y0, xstp, ystp, mscale;
00519 double xc, yc, xscale, yscale, imgscale, latc, lonc, peff;
00520 double lat, lon;
00521 double twt, tfac, wtfac, img_weight;
00522 double f0, f1;
00523 float *clat, *clon;
00524 float b;
00525 int *reject_list = NULL;
00526 int nrec, recct, use, valct;
00527 int mcol, mcols, mrow, mrows, map, maps, n, ntot, s, size;
00528 int plate_cols, plate_rows, plate_width;
00529 int x_invrt, y_invrt;
00530 int need_ephem;
00531 int rank, off, count;
00532 int badqual, rejects, shifted, shiftct;
00533 char *dpc_str;
00534 char module_ident[64], time_str[64], key[64];
00535
00536 double raddeg = M_PI / 180.0;
00537 double degrad = 1.0 / raddeg;
00538 int projection = LAMBERT;
00539 int status = 0;
00540 missing_val = 0.0 / 0.0;
00541
00542 char *inset = strdup (params_get_str (params, "ds"));
00543 char *filename = strdup (params_get_str (params, "file"));
00544 int cr = params_get_int (params, "cr");
00545 float cl = params_get_float (params, "cl");
00546 unsigned int qmask = cmdparams_get_int64 (params, "qmask", &status);
00547 int latct = params_get_int (params, "lat_nvals");
00548 int lonct = params_get_int (params, "lon_nvals");
00549 float map_scale = params_get_float (params, "scale");
00550 float map_size = params_get_float (params, "extent");
00551 double apode_inner = params_get_double (params, "mask_in");
00552 double apode_outer = params_get_double (params, "mask_ex");
00553 double noise_floor = params_get_double (params, "floor");
00554 double interval = params_get_double (params, "interval");
00555 int rec_step = params_get_int (params, "rec_step");
00556 float max_reach = params_get_float (params, "max_reach");
00557 char *rejectfile = strdup (params_get_str (params, "reject"));
00558 char *qual_key = strdup (params_get_str (params, "qual_key"));
00559 char *clon_key = strdup (params_get_str (params, "clon_key"));
00560 char *clat_key = strdup (params_get_str (params, "clat_key"));
00561 char *crot_key = strdup (params_get_str (params, "crot_key"));
00562 char *rsun_key = strdup (params_get_str (params, "rsun_key"));
00563 char *apsd_key = strdup (params_get_str (params, "apsd_key"));
00564 char *dsun_key = strdup (params_get_str (params, "dsun_key"));
00565
00566 int no_track = params_isflagset (params, "n");
00567 int no_apode = params_isflagset (params, "r");
00568 int time_check = params_isflagset (params, "t");
00569 int verbose = params_isflagset (params, "v");
00570 int filereq = strcasecmp (filename, "Not Specified");
00571
00572 snprintf (module_ident, 64, "%s v %s", module_name, version_id);
00573 if (verbose) fprintf (stderr, "%s: JSOC version %s\n", module_ident, jsoc_version);
00574
00575 if (cr < 0) {
00576
00577 double rsun, lat, lon, vr, vn, vw;
00578 tcm = CURRENT_SYSTEM_TIME;
00579 earth_ephemeris (tcm, &rsun, &lat, &lon, &vr, &vn, &vw);
00580 cr = carrington_rots (tcm);
00581 cr--;
00582 if (isnan (cl)) cl = lon;
00583 } else if (isnan (cl)) cl = 0.0;
00584
00585 if (key_params_from_dspec (inset)) {
00586 fprintf (stderr, "Error: data set specification not supported\n");
00587 fprintf (stderr, " use data series and params cr, cl, and length\n");
00588 return 0;
00589 } else {
00590
00591
00592 char ttarget[64];
00593 sprintf (ttarget, "%d:%06.2f", cr, cl);
00594
00595
00596 if (!(ds = select_dataset_from_time_interval (inset, ttarget, interval)))
00597
00598
00599
00600 return 1;
00601 if ((recct = ds->n) < 2) {
00602 printf ("<2 records in selected input set\n");
00603 drms_close_records (ds, DRMS_FREE_RECORD);
00604 return 1;
00605 }
00606 }
00607
00608 rejects = 0;
00609 if (strcmp (rejectfile, "Not Specified")) {
00610 FILE *rejectfp = fopen (rejectfile, "r");
00611 if (rejectfp) rejects = read_reject_list (rejectfp, &reject_list);
00612 else fprintf (stderr,
00613 "Warning: could not open rejection list %s; ignored\n", rejectfile);
00614 }
00615
00616 maps = (latct > lonct) ? latct : lonct;
00617 clat = (float *)malloc (maps * sizeof (float));
00618 clon = (float *)malloc (maps * sizeof (float));
00619 for (map = 0; map < latct; map++) {
00620 snprintf (key, 64, "lat_%d_value", map);
00621 clat[map] = params_get_float (params, key) * raddeg;
00622 }
00623 for (map = 0; map < lonct; map++) {
00624 snprintf (key, 64, "lon_%d_value", map);
00625 clon[map] = params_get_float (params, key) * raddeg;
00626 }
00627 for (map = latct; map < maps; map++) clat[map] = clat[map-1];
00628 for (map = lonct; map < maps; map++) clon[map] = clon[map-1];
00629
00630 if (filereq) {
00631 if (!(out = fopen (filename, "w"))) {
00632 fprintf (stderr, "Error - unable to open file %s for table output\n", filename);
00633 return 1;
00634 }
00635 if (verbose) fprintf (out, "CR %d:%03.0f\n", cr, cl);
00636 } else verbose = 0;
00637
00638
00639
00640
00641 tcm = earth_meridian_crossing (cl, cr);
00642 tcm -= MISSION_EPOCH;
00643
00644
00645 interval *= 1440 / 13.2;
00646 t0 = tcm - interval * 30.0;
00647 t1 = tcm + interval * 30.0;
00648 tfac = 2.0 / (t1 - t0);
00649
00650 mcols = mrows = map_size / map_scale + 0.5;
00651 size = mcols * mrows;
00652 xstp = ystp = map_scale * raddeg;
00653 x0 = 0.5 * (1.0 - mcols) * xstp;
00654 y0 = 0.5 * (1.0 - mrows) * ystp;
00655 mscale = (map_size > map_scale) ?
00656 2.0 / (map_size - map_scale) / raddeg : 0.0;
00657
00658
00659
00660
00661 ntot = 0;
00662 for (mrow=0, y=y0; mrow<mrows; mrow++, y+=ystp) {
00663 for (mcol=0, x=x0; mcol<mcols; mcol++, x+=xstp, ntot++) ;
00664 }
00665 ntot *= maps;
00666 mloc = (struct maploc *)malloc (ntot * sizeof (struct maploc));
00667 sum = (double *)malloc (maps * sizeof (double));
00668 suma = (double *)malloc (maps * sizeof (double));
00669 det = (double *)malloc (maps * sizeof (double));
00670 s1 = (double *)calloc (maps, sizeof (double));
00671 st = (double *)calloc (maps, sizeof (double));
00672 st2 = (double *)calloc (maps, sizeof (double));
00673 sb = (double *)calloc (maps, sizeof (double));
00674 sbt = (double *)calloc (maps, sizeof (double));
00675 sf = (double *)calloc (maps, sizeof (double));
00676 sft = (double *)calloc (maps, sizeof (double));
00677
00678 for (n = 0, map = 0; map < maps; map++) {
00679 sum[map] = 0.0;
00680 for (mrow = 0, y = y0; mrow < mrows; mrow++, y += ystp) {
00681 for (mcol = 0, x = x0; mcol < mcols; mcol++, x += xstp, n++) {
00682 off = plane2sphere (x, y, clat[map], clon[map], &lat, &lon, projection);
00683 mloc[n].lat = lat;
00684 mloc[n].lon = lon;
00685 mloc[n].wt = (off) ? 0.0 : (no_apode) ? 1.0 :
00686 apodization (x * mscale, y * mscale, apode_inner, apode_outer);
00687 sum[map] += mloc[n].wt;
00688 }
00689 }
00690 }
00691 for (map = 0, n = 0; map < maps; map++) {
00692 if (sum[map] != 0.0) {
00693 wtfac = 1.0 / sum[map];
00694 for (s = 0; s < size; s++, n++)
00695 mloc[n].wt *= wtfac;
00696 } else n += size;
00697 }
00698 valct = 0;
00699
00700 badqual = shiftct = shifted = 0;
00701 for (nrec = 0; nrec < recct; nrec += rec_step) {
00702 float bmax = -HUGE_VAL, bmin = HUGE_VAL;
00703 double lonmax, lonmin, latmax, latmin;
00704
00705
00706
00707 use = good_record (ds, nrec, rec_step, max_reach, t0, t1, time_check,
00708 qual_key, qmask, &rejects, reject_list, &shifted);
00709 if (use < 0) {
00710
00711
00712
00713
00714 if (shifted) badqual++;
00715 continue;
00716 }
00717 if (shifted) shiftct++;
00718 rec = ds->records[use];
00719 t = drms_getkey_time (rec, "T_OBS", &status) - MISSION_EPOCH;
00720 seg = drms_segment_lookupnum (rec, 0);
00721 mgram = drms_segment_read (seg, DRMS_TYPE_FLOAT, &status);
00722 if (!mgram || status) {
00723
00724
00725
00726
00727 if (mgram) drms_free_array (mgram);
00728 continue;
00729 }
00730 if ((rank = drms_array_naxis (mgram)) != 2) {
00731 fprintf (stderr, "improper format for record %d: rank = %d\n", nrec,
00732 rank);
00733 drms_free_array (mgram);
00734 continue;
00735 }
00736 plate_cols = drms_array_nth_axis (mgram, 0);
00737 plate_rows = drms_array_nth_axis (mgram, 1);
00738 twt = tfac * (t - tcm);
00739 count = drms_getkey_int (rec, "DATAVALS", &status);
00740 if (status) count = plate_cols * plate_rows;
00741
00742 status = solar_image_info (rec, &xscale, &yscale, &xc, &yc,
00743 &img_radius, rsun_key, apsd_key, &peff, &ellipse_e, &ellipse_pa,
00744 &x_invrt, &y_invrt, &need_ephem, 0);
00745 if (status & NO_SEMIDIAMETER) {
00746 int keystat = 0;
00747 double dsun_obs = drms_getkey_double (rec, dsun_key, &keystat);
00748 if (keystat) {
00749 fprintf (stderr,
00750 "Error: one or more essential keywords or values missing; skipped\n");
00751 fprintf (stderr, "solar_image_info() returned %08x\n", status);
00752 continue;
00753 }
00754
00755 img_radius = asin (RSUNM / dsun_obs);
00756 img_radius *= 3600.0 * degrad;
00757 img_radius /= (xscale <= yscale) ? xscale : yscale;
00758 status &= ~NO_SEMIDIAMETER;
00759 }
00760 if (status) {
00761 fprintf (stderr,
00762 "Error: one or more essential keywords or values missing; skipped\n");
00763 fprintf (stderr, "solar_image_info() returned %08x\n", status);
00764 continue;
00765 }
00766 lonc = drms_getkey_double (rec, clon_key, &status) * raddeg;
00767 latc = drms_getkey_double (rec, clat_key, &status) * raddeg;
00768 if (no_track) lonc = cl * raddeg;
00769
00770 imgscale = (xscale > yscale) ? xscale : yscale;
00771 if (verbose && filereq) {
00772 sprint_time (time_str, t + MISSION_EPOCH, "UT", -1);
00773 dpc_str = drms_getkey_string (rec, "DPC", &status);
00774 if (!status)
00775 fprintf (out, "%.16s : %08lx\n", time_str, strtol (dpc_str, NULL, 16));
00776 else fprintf (out, "%.16s\n", time_str);
00777 }
00778
00779 status = truncate_noise (mgram, noise_floor);
00780
00781 if (verbose && filereq) fprintf (out,
00782 " zeroed %d (of %d) values within limits +/- %.1f\n",
00783 status, count, noise_floor);
00784
00785 count -= status;
00786
00787 status = eliminate_outliers (mgram, OUTLIER_RATIO, OUTLIER_BASE);
00788 if (status && verbose && filereq)
00789 fprintf (out, " removed %d (of %d) outlier(s)\n", status, count);
00790
00791
00792
00793
00794 status = 0;
00795 plate_width = (plate_cols > plate_rows) ? plate_cols : plate_rows;
00796 xc -= 0.5 * (plate_cols - 1);
00797 yc -= 0.5 * (plate_rows - 1);
00798 xc *= 2.0 / plate_width;
00799 yc *= 2.0 / plate_width;
00800 img_radius *= 2.0 / plate_width;
00801
00802 for (map = 0, n = 0; map < maps; map++) {
00803 sum[map] = suma[map] = 0.0;
00804 ntot = 0;
00805 img_weight = 1.0;
00806 for (s = 0; s < size; s++, n++) {
00807 if (mloc[n].wt == 0.0) continue;
00808 if (sphere2img (mloc[n].lat, mloc[n].lon, latc, lonc, &x, &y, xc, yc,
00809 img_radius, peff, 0.0, 0.0, 0, 0)) {
00810 img_weight -= mloc[n].wt;
00811 continue;
00812 }
00813 b = array_imaginterp (mgram, x, y, 0);
00814 if (isnan (b)) {
00815 img_weight -= mloc[n].wt;
00816 continue;
00817 }
00818 if (b > bmax) {
00819 bmax = b;
00820 lonmax = mloc[n].lon;
00821 latmax = mloc[n].lat;
00822 }
00823 if (b < bmin) {
00824 bmin = b;
00825 lonmin = mloc[n].lon;
00826 latmin = mloc[n].lat;
00827 }
00828 sum[map] += b * mloc[n].wt;
00829 suma[map] += fabs (b) * mloc[n].wt;
00830 ntot++;
00831 }
00832 if (img_weight < 1.0) {
00833 sum[map] *= img_weight;
00834 suma[map] *= img_weight;
00835 }
00836 s1[map] += img_weight;
00837 st[map] += img_weight * twt;
00838 st2[map] += img_weight * twt * twt;
00839 sb[map] += sum[map];
00840 sbt[map] += twt * sum[map];
00841 sf[map] += suma[map];
00842 sft[map] += twt * suma[map];
00843 }
00844
00845 if (verbose && filereq) {
00846 fprintf (out, " min = %7.1f at [%6.2f, %6.2f] ", bmin,
00847 lonmin/raddeg, latmin/raddeg);
00848 fprintf (out, " max = %7.1f at [%6.2f, %6.2f]\n", bmax,
00849 lonmax/raddeg, latmax/raddeg);
00850 }
00851 drms_free_array (mgram);
00852 valct++;
00853 }
00854 drms_close_records (ds, DRMS_FREE_RECORD);
00855 if (valct < 2) {
00856 fprintf (stderr, "Error: <2 usable magnetograms in interval\n");
00857 if (filereq) fclose (out);
00858 return 1;
00859 }
00860 if (verbose && filereq) fprintf (out, "\n");
00861
00862 for (map = 0; map < maps; map++)
00863 det[map] = 1.0 / (s1[map] * st2[map] - st[map] * st[map]);
00864 if (filereq) fprintf (out, " Lon Lat |Bz| d|Bz|/dt Bz dBz/dt [Gauss(/sec)]:\n");
00865
00866 for (map = 0; map < maps; map++) {
00867 f0 = det[map] * (st2[map] * sf[map] - st[map] * sft[map]);
00868 printf ("%8.3f", f0);
00869 if (filereq) {
00870 double fs0 = det[map] * (st2[map] * sb[map] - st[map] * sbt[map]);
00871 double fs1 = det[map] * tfac * (s1[map] * sbt[map] - st[map] * sb[map]);
00872 f1 = det[map] * tfac * (s1[map] * sft[map] - st[map] * sf[map]);
00873 fprintf (out, "%05.1f %+05.1f : %8.3f %8.3f %8.3f %8.3f\n",
00874 clon[map] / raddeg, clat[map] / raddeg, f0, 1.0e6 * f1, fs0,
00875 1.0e6 * fs1);
00876 }
00877 }
00878 printf ("\n");
00879 if (filereq) fclose (out);
00880 if (verbose && badqual) fprintf (stderr,
00881 " %d of %d records rejected for quality matching %08x\n",
00882 badqual, valct, qmask);
00883 if (verbose && shiftct) fprintf (stderr,
00884 "%d records shifted from targets for quality issues\n", shiftct);
00885
00886 return status;
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944