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
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 #include <jsoc_main.h>
00221
00222
00223 char *module_name = "mtrack";
00224 char *module_desc = "track multiple regions from solar image sequences";
00225 char *version_id = "2.0";
00226
00227 #define CARR_RATE (2.86532908457)
00228 #define RSUNM (6.96e8)
00229 #define INTERP_NEAREST_NEIGHBOR (1)
00230 #define INTERP_BILINEAR (2)
00231 #define FILL_BY_INTERP (0)
00232 #define FILL_WITH_ZERO (1)
00233 #define FILL_WITH_NAN (2)
00234
00235 ModuleArgs_t module_args[] = {
00236 {ARG_STRING, "in", "", "input data series or dataset"},
00237 {ARG_STRING, "segment", "Not Specified",
00238 "input data series segment; ignored if series only has one segment"},
00239 {ARG_STRING, "out", "", "output data series"},
00240 {ARG_STRING, "bckgn", "Not Specified",
00241 "background record-segment image to be subtracted from input data"},
00242 {ARG_STRING, "reject", "Not Specified", "file containing rejection list"},
00243 {ARG_INT, "qmask", "0x80000000", "quality bit mask for image rejection"},
00244 {ARG_INT, "max_miss", "All",
00245 "missing values threshold for image rejection"},
00246 {ARG_STRING, "tmid", "Not Specified", "midpoint of tracking interval"},
00247 {ARG_INT, "length", "0",
00248 "target length of tracking interval [in units of input cadence]"},
00249
00250 {ARG_TIME, "tstart", "JD_0", "start of tracking interval"},
00251 {ARG_TIME, "tstop", "JD_0", "end of tracking interval"},
00252 {ARG_FLOAT, "tstep", "Not specified", "temporal cadence for output"},
00253 {ARG_FLOATS, "lat", "[0.0]",
00254 "heliographic latitude(s) of tracking center(s) [deg]"},
00255 {ARG_FLOATS, "lon", "[0.0]",
00256 "heliographic longitude(s) of tracking center(s) [deg]"},
00257 {ARG_NUME, "map", "Postel", "map projection",
00258 "carree, Cassini, Mercator, cyleqa, sineqa, gnomonic, Postel, stereographic, orthographic, Lambert"},
00259 {ARG_NUME, "interp", "cubiconv", "interpolation option",
00260 "cubiconv, nearest, bilinear"},
00261 {ARG_NUME, "fillopt", "interp", "missing frame fill option",
00262 "interp, zero, nan"},
00263 {ARG_FLOAT, "scale", "Not specified", "map scale at center [deg/pxl]"},
00264 {ARG_INT, "cols", "0", "columns in output map(s)"},
00265 {ARG_INT, "rows", "0", "rows in output map(s)"},
00266 {ARG_FLOATS, "map_pa", "0.0", "position angle(s) of north on output map"},
00267 {ARG_FLOAT, "a0", "-0.02893",
00268 "equatorial rotation - Carrington rate [urad/sec]"},
00269 {ARG_FLOAT, "a2", "-0.3441", "solar rotation parameter A2 [urad/sec]"},
00270 {ARG_FLOAT, "a4", "-0.5037", "solar rotation parameter A4 [urad/sec]"},
00271 {ARG_FLOAT, "merid_v", "0.0",
00272 "solar meridional velocity [urad/sec]; 0.0014368 * rate in m/s"},
00273 {ARG_FLOAT, "bscale", "Segment Default", "output scaling factor"},
00274 {ARG_FLOAT, "bzero", "Segment Default", "output offset"},
00275 {ARG_STRING, "trec_key", "T_REC", "keyname of (slotted) prime key"},
00276 {ARG_STRING, "tobs_key", "T_OBS", "keyname for image observation time"},
00277 {ARG_STRING, "tstp_key", "CADENCE", "keyname for image observation time"},
00278 {ARG_STRING, "qual_key", "Quality", "keyname for 32-bit image quality field"},
00279 {ARG_STRING, "clon_key", "CRLN_OBS", "keyname for image central longitude"},
00280 {ARG_STRING, "clat_key", "CRLT_OBS", "keyname for image central latitude"},
00281 {ARG_STRING, "crot_key", "CAR_ROT", "keyname for image Carrington rotation"},
00282 {ARG_STRING, "rsun_key", "R_SUN", "keyname for image semi-diameter (pixel)"},
00283 {ARG_STRING, "apsd_key", "RSUN_OBS", "keyname for apparent solar semi-diameter (arcsec)"},
00284 {ARG_STRING, "dsun_key", "DSUN_OBS", "keyname for observer distance"},
00285 {ARG_STRING, "cvkey", "CalVer64", "keyname for Calibration Version key"},
00286 {ARG_STRING, "cvok", "any", "Acceptable value of cvkey"},
00287 {ARG_STRING, "cvno", "none", "Unacceptable value of cvkey"},
00288 {ARG_FLOATS, "mai", "NaN", "Magnetic Activity Indices"},
00289 {ARG_STRING, "ident", "Not Specified", "identifier"},
00290 {ARG_FLAG, "c", "", "track at Carrington rate"},
00291 {ARG_FLAG, "n", "", "turn off tracking"},
00292 {ARG_FLAG, "o", "",
00293 "remove line-of-sight component of observer velocity"},
00294 {ARG_FLAG, "r", "",
00295 "remove line-of-sight component of solar rotation"},
00296 {ARG_FLAG, "v", "", "verbose mode"},
00297 {ARG_FLAG, "w", "", "experimental mode (do not save output nor process images)"},
00298 {ARG_FLAG, "x", "", "experimental mode (do not save output)"},
00299 {ARG_FLAG, "M", "",
00300 "use MDI keywords for input and correct for MDI distortion"},
00301 {ARG_FLAG, "Z", "", "log times in UTC rather than TAI"},
00302 {}
00303 };
00304
00305 char *propagate[] = {"CONTENT"};
00306
00307 #include "keystuff.c"
00308 #include "earth_ephem.c"
00309 #include "soho_ephem.c"
00310 #include "cartography.c"
00311 #include "imginfo.c"
00312 #include "mdistuff.c"
00313
00314 typedef enum {LOC_UNKNOWN, LOC_GEOC, LOC_MWO, LOC_GONG_MR, LOC_GONG_LE,
00315 LOC_GONG_UD, LOC_GONG_TD, LOC_GONG_CT, LOC_GONG_TC, LOC_GONG_BB,
00316 LOC_GONG_ML, LOC_SOHO, LOC_SDO} platloc;
00317
00318 char *prime_keylist[] = {"CarrRot", "CMLon", "LonHG", "LatHG", "Duration",
00319 "Width", "Height", "Source", "ZonalTrk", "MeridTrk", "MapProj", "MapScale"};
00320
00321 char *create_prime_key (DRMS_Record_t *rec) {
00322 int pct = sizeof (prime_keylist) / sizeof (char *);
00323
00324 return create_primekey_from_keylist (rec, prime_keylist, pct);
00325 }
00326
00327 long long params_get_mask (CmdParams_t *params, char *arg,
00328 long long defval) {
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 long long retval;
00339 const char *str = params_get_str (params, arg);
00340 char *ext;
00341
00342 retval = strtoull (str, &ext, 16);
00343 if (strlen (ext)) retval = defval;
00344 return retval;
00345 }
00346
00347
00348
00349
00350
00351
00352 int fgetline (FILE *in, char *line, int max) {
00353 if (fgets (line, max, in) == NULL) return 0;
00354 else return (strlen (line));
00355 }
00356
00357 int read_reject_list (FILE *file, int **list) {
00358 int ds, sn, rec, last_rec;
00359 int allocd = 1024, ct = 0, gap = 0;
00360 char line[1024], t_str[64], estr[16];
00361
00362 *list = (int *)malloc (allocd * sizeof (int));
00363 while (fgetline (file, line, 1024)) {
00364 if (strlen (line) == 1) continue;
00365 if (line[0] == '#') continue;
00366 if (sscanf (line, "%d %d %d %s", &ds, &sn, &rec, t_str) != 4) {
00367 if (sscanf (line, "%d %s", &rec, t_str) != 2) {
00368 sscanf (line, "%s", estr);
00369 if (strcmp (estr, "...")) continue;
00370 gap = 1;
00371 last_rec = rec;
00372 continue;
00373 }
00374 }
00375 if (gap) {
00376 while (rec > last_rec) {
00377 last_rec++;
00378 (*list)[ct++] = last_rec;
00379 if (ct >= allocd) {
00380 allocd += 1024;
00381 *list = (int *)realloc (*list, allocd * sizeof (int));
00382 }
00383 }
00384 gap = 0;
00385 continue;
00386 }
00387 (*list)[ct++] = rec;
00388 if (ct >= allocd) {
00389 allocd += 1024;
00390 *list = (int *)realloc (*list, allocd * sizeof (int));
00391 }
00392 }
00393 return ct;
00394 }
00395
00396 int drms_key_is_slotted (DRMS_Env_t *drms_env, const char *keyname,
00397 const char *dsname) {
00398 DRMS_Record_t *rec;
00399 DRMS_Keyword_t *key;
00400 int status;
00401
00402 rec = drms_template_record (drms_env, dsname, &status);
00403 if (status) return 0;
00404 key = drms_keyword_lookup (rec, keyname, 1);
00405 if (!key) return 0;
00406 status = (key->info->recscope > 1);
00407 drms_free_keyword_struct (key);
00408 drms_free_record (rec);
00409 return status;
00410 }
00411
00412 int key_params_from_dspec (const char *dspec) {
00413
00414
00415
00416
00417
00418
00419 int n, nt = strlen (dspec);
00420
00421 for (n = 0; n < nt; n++) if (dspec[n] == '[') return 1;
00422 return 0;
00423 }
00424
00425 int *ndimsegments (DRMS_Record_t *rec, int ndim, int *ct) {
00426
00427
00428
00429
00430
00431 DRMS_Record_t *temprec;
00432 DRMS_Segment_t *seg;
00433 static int *seglist = NULL;
00434 int found, n, segct, status;
00435
00436 temprec = drms_template_record (drms_env, rec->seriesinfo->seriesname, &status);
00437 segct = drms_record_numsegments (temprec);
00438 if (!seglist) seglist = (int *)realloc (seglist, segct * sizeof (int));
00439 found = 0;
00440 for (n = 0; n < segct; n++) {
00441 seg = drms_segment_lookupnum (rec, n);
00442 if (!(seg = drms_segment_lookupnum (rec, n))) continue;
00443 if (seg->info->naxis == ndim) seglist[found++] = n;
00444 }
00445 *ct = found;
00446 return seglist;
00447 }
00448
00449
00450 float missing_val;
00451
00452 int ephemeris_params (DRMS_Record_t *img, double *vr, double *vw, double *vn) {
00453 int status, kstat = 0;
00454
00455 *vr = drms_getkey_double (img, "OBS_VR", &status);
00456 kstat += status;
00457 *vw = drms_getkey_double (img, "OBS_VW", &status);
00458 kstat += status;
00459 *vn = drms_getkey_double (img, "OBS_VN", &status);
00460 kstat += status;
00461 if (kstat) *vr = *vw = *vn = 0.0;
00462 return kstat;
00463 }
00464
00465
00466
00467
00468
00469 void adjust_for_observer_velocity (float *map, int mapct, float *mapclat,
00470 float *mapclon, int pixct, double latc, double lonc, double orbvr,
00471 double orbvw, double orbvn, double semidiam, int radial_only) {
00472
00473
00474
00475 double vobs;
00476 double chi, clon, coslat, sig, x, y;
00477 double coslatc = cos (latc), sinlatc = sin (latc);
00478 int m, n, mset = 0;
00479
00480 double tanang_r = tan (semidiam);
00481
00482 for (m = 0; m < mapct; m++) {
00483 coslat = cos (mapclat[m]);
00484 clon = mapclon[m] - lonc;
00485 x = coslat * sin (clon);
00486 y = sin (mapclat[m]) * coslatc - sinlatc * coslat * cos (clon);
00487 chi = atan2 (x, y);
00488 sig = atan (hypot (x, y) * tanang_r);
00489 vobs = orbvr * cos (sig);
00490 if (!radial_only) {
00491 vobs -= orbvw * sin (sig) * sin (chi);
00492 vobs -= orbvn * sin (sig) * cos (chi);
00493 }
00494 for (n = 0; n < pixct; n++) map[n + mset] -= vobs;
00495 mset += pixct;
00496 }
00497 }
00498
00499
00500
00501
00502
00503 static void adjust_for_solar_rotation (float *map, int mapct, float *mapclat,
00504 float *mapclon, int pixct, double latc, double lonc) {
00505 static double a0 = -0.02893, a2 = -0.3441, a4 = -0.5037;
00506 static double RSunMm = 1.0e-6 * RSUNM;
00507 double vrot, uonlos;
00508 double chi, clon, coslat, sinlat, sin2lat, sinth, x, y;
00509 double coslatc = cos (latc), sinlatc = sin (latc);
00510 int m, n, mset = 0;
00511
00512 for (m = 0; m < mapct; m++) {
00513 coslat = cos (mapclat[m]);
00514 sinlat = sin (mapclat[m]);
00515 sin2lat = sinlat * sinlat;
00516 clon = mapclon[m] - lonc;
00517 x = coslat * sin (clon);
00518 y = sin (mapclat[m]) * coslatc - sinlatc * coslat * cos (clon);
00519 chi = atan2 (x, y);
00520 sinth = hypot (x, y);
00521
00522 uonlos = (coslat > 1.e-8) ? sinth * coslatc * sin (chi) / coslat : 0.0;
00523 vrot = (a0 + CARR_RATE) * RSunMm * coslat * uonlos;
00524 vrot += a2 * RSunMm * coslat * uonlos * sin2lat;
00525 vrot += a4 * RSunMm * coslat * uonlos * sin2lat * sin2lat;
00526
00527 for (n = 0; n < pixct; n++) map[n + mset] -= vrot;
00528 mset += pixct;
00529 }
00530 return;
00531 }
00532
00533 int set_stat_keys (DRMS_Record_t *rec, long long ntot, long long valid,
00534 double vmn, double vmx, double sum, double sum2, double sum3, double sum4) {
00535 double scal, avg, var, skew, kurt;
00536 int kstat = 0;
00537
00538 kstat += check_and_set_key_longlong (rec, "DATAVALS", valid);
00539 kstat += check_and_set_key_longlong (rec, "MISSVALS", ntot - valid);
00540 if (valid <= 0) return kstat;
00541
00542 kstat += check_and_set_key_double (rec, "DATAMIN", vmn);
00543 kstat += check_and_set_key_double (rec, "DATAMAX", vmx);
00544
00545 scal = 1.0 / valid;
00546 avg = scal * sum;
00547 var = scal * sum2 - avg * avg;
00548 skew = scal * sum3 - 3 * var * avg - avg * avg * avg;
00549 kurt = scal * sum4 - 4 * skew * avg - 6 * avg * avg * var -
00550 avg * avg * avg * avg;
00551 kstat += check_and_set_key_double (rec, "DATAMEAN", avg);
00552 if (var < 0.0) return kstat;
00553 kstat += check_and_set_key_double (rec, "DATARMS", sqrt (var));
00554 if (var == 0.0) return kstat;
00555 skew /= var * sqrt (var);
00556 kurt /= var * var;
00557 kurt -= 3.0;
00558 kstat += check_and_set_key_double (rec, "DATASKEW", skew);
00559 kstat += check_and_set_key_double (rec, "DATAKURT", kurt);
00560
00561 return kstat;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 static void ccker (double *u, double s) {
00584 double s2, s3;
00585
00586 s2= s * s;
00587 s3= s2 * s;
00588 u[0] = s2 - 0.5 * (s3 + s);
00589 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
00590 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
00591 u[3] = 0.5 * (s3 - s2);
00592 }
00593
00594 float ccint2 (float *f, int nx, int ny, double x, double y) {
00595 double ux[4], uy[4];
00596 double sum;
00597 int ix, iy, ix1, iy1, i, j;
00598
00599 if (x < 1.0 || x >= (float)(nx-2) || y < 1.0 || y >= (float)(ny-2))
00600 return missing_val;
00601
00602 ix = (int)x;
00603 ccker (ux, x - (double)ix);
00604 iy = (int)y;
00605 ccker (uy, y - (double)iy);
00606
00607 ix1 = ix - 1;
00608 iy1 = iy - 1;
00609 sum = 0.;
00610 for (i = 0; i < 4; i++)
00611 for (j = 0; j < 4; j++)
00612 sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00613 return (float)sum;
00614 }
00615
00616 float linint2 (float *f, int cols, int rows, double x, double y) {
00617 double p, q, val;
00618 int col = (int)x, row = (int)y;
00619 int onerow = cols * row;
00620 int colp1 = col + 1, onerowp1 = onerow + cols;
00621
00622
00623
00624 if (x < 0.0 || x > cols - 1.0 || y < 0.0 || y > rows - 1.0)
00625 return missing_val;
00626 p = x - col;
00627 q = y - row;
00628 val = (1 - p) * (1 - q) * f[col + onerow]
00629 + p * (1 - q) * f[colp1 + onerow]
00630 + (1 - p) * q * f[col + onerowp1]
00631 + p * q * f[colp1 + onerowp1];
00632 return val;
00633 }
00634
00635 float nearest_val (float *f, int cols, int rows, double x, double y) {
00636 int col, row;
00637 if (x < -0.5 || x >= (cols - 0.5) || y < -0.5 || y >= (rows - 0.5))
00638 return missing_val;
00639 col = x + 0.5;
00640 row = y + 0.5;
00641 return f[col + row * cols];
00642 }
00643
00644
00645 float array_imaginterp (DRMS_Array_t *img, double x, double y, int schema) {
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 double xs, ys;
00671 int cols, rows, mdim;
00672
00673 cols = img->axis[0];
00674 rows = img->axis[1];
00675 mdim = (cols > rows) ? cols : rows;
00676 xs = 0.5 * (x + 1.0) * mdim - 0.5;
00677 ys = 0.5 * (y + 1.0) * mdim - 0.5;
00678 if (schema == INTERP_NEAREST_NEIGHBOR)
00679 return nearest_val (img->data, cols, rows, xs, ys);
00680 else if (schema == INTERP_BILINEAR)
00681 return linint2 (img->data, cols, rows, xs, ys);
00682 else return ccint2 (img->data, cols, rows, xs, ys);
00683 }
00684
00685 static int fsphere2img (double sin_lat, double cos_lat, double lon,
00686 double latc, double lonc, double *x, double *y,
00687 double xcenter, double ycenter, double rsun,
00688 double cospa, double sinpa, double ecc, double chi, int ellipse,
00689 int xinvrt, int yinvrt) {
00690
00691
00692
00693
00694 static double sin_asd = 0.004660, cos_asd = 0.99998914;
00695
00696 static double last_latc = 0.0, cos_latc = 1.0, sin_latc = 0.0;
00697 double r, cos_cang, xr, yr;
00698 double cos_lat_lon;
00699 double squash, cchi, schi, c2chi, s2chi, xp, yp;
00700 int hemisphere;
00701
00702 if (latc != last_latc) {
00703 sin_latc = sin (latc);
00704 cos_latc = cos (latc);
00705 last_latc = latc;
00706 }
00707 cos_lat_lon = cos_lat * cos (lon - lonc);
00708
00709 cos_cang = sin_lat * sin_latc + cos_latc * cos_lat_lon;
00710 hemisphere = (cos_cang < 0.0) ? 1 : 0;
00711 r = rsun * cos_asd / (1.0 - cos_cang * sin_asd);
00712 xr = r * cos_lat * sin (lon - lonc);
00713 yr = r * (sin_lat * cos_latc - sin_latc * cos_lat_lon);
00714
00715 if (xinvrt) xr *= -1.0;
00716 if (yinvrt) yr *= -1.0;
00717
00718 if (ellipse) {
00719 squash = sqrt (1.0 - ecc * ecc);
00720 cchi = cos (chi);
00721 schi = sin (chi);
00722 s2chi = schi * schi;
00723 c2chi = 1.0 - s2chi;
00724 xp = xr * (s2chi + squash * c2chi) - yr * (1.0 - squash) * schi * cchi;
00725 yp = yr * (c2chi + squash * s2chi) - xr * (1.0 - squash) * schi * cchi;
00726 xr = xp;
00727 yr = yp;
00728 }
00729 *x = xr * cospa - yr * sinpa;
00730 *y = xr * sinpa + yr * cospa;
00731
00732 *y += ycenter;
00733 *x += xcenter;
00734 return (hemisphere);
00735 }
00736
00737 static void perform_mappings (DRMS_Array_t *img, float *maps, double *delta_rot,
00738 int mapct, double *maplat, double *maplon,
00739 double *map_coslat, double *map_sinlat, int pixct,
00740 double delta_time, unsigned char *offsun,
00741 double latc, double lonc, double xc, double yc,
00742 double a0, double a2, double a4, double merid_v, double radius, double pa,
00743 double ellipse_e, double ellipse_pa, int x_invrt, int y_invrt,
00744 int interpolator, int MDI_correct_distort) {
00745
00746
00747
00748
00749
00750
00751
00752 static double sin_asd = 0.004660, cos_asd = 0.99998914;
00753
00754 double lat, lon, cos_lat, sin_lat;
00755 double xx, yy;
00756 float interpval;
00757 int m, n, mset;
00758
00759 double delta_lat = merid_v * delta_time;
00760 int plate_cols = img->axis[0];
00761 int plate_rows = img->axis[1];
00762 double plate_width = (plate_cols > plate_rows) ? plate_cols : plate_rows;
00763 int no_merid_v = (merid_v == 0.0);
00764 double cos_pa = cos (pa);
00765 double sin_pa = sin (pa);
00766 int fit_ellipse = (ellipse_e > 0.0 && ellipse_e < 1.0);
00767
00768 mset = 0;
00769 xc *= 2.0 / plate_width;
00770 yc *= 2.0 / plate_width;
00771 radius *= 2.0 / plate_width;
00772
00773 if (no_merid_v) {
00774 if (x_invrt || y_invrt || fit_ellipse) {
00775 for (m = 0; m < mapct; m++) {
00776 double delta_lon = delta_rot[m] * delta_time;
00777 for (n = 0; n < pixct; n++) {
00778 if (offsun[n + mset]) {
00779 maps[n + mset] = missing_val;
00780 continue;
00781 }
00782
00783 sin_lat = map_sinlat[n + mset];
00784 cos_lat = map_coslat[n + mset];
00785 lon = maplon[n + mset] + delta_lon;
00786
00787 if (fsphere2img (sin_lat, cos_lat, lon, latc, lonc, &xx, &yy, xc, yc,
00788 radius, cos_pa, sin_pa, ellipse_e, ellipse_pa, fit_ellipse,
00789 x_invrt, y_invrt)) {
00790 maps[n + mset] = missing_val;
00791 continue;
00792 }
00793 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00794 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00795
00796
00797 if (MDI_correct_distort) {
00798 mtrack_MDI_image_tip (&xx, &yy, 1, 1);
00799 mtrack_MDI_image_stretch (&xx, &yy, 1, 1);
00800 }
00801 interpval = array_imaginterp (img, xx, yy, interpolator);
00802 maps[n + mset] = (isnan (interpval)) ? missing_val : interpval;
00803 }
00804 mset += pixct;
00805 }
00806 } else {
00807 double r, cos_cang, xr, yr, cos_lat_lon;
00808 double cos_latc = cos (latc);
00809 double sin_latc = sin (latc);
00810 for (m = 0; m < mapct; m++) {
00811 double delta_lon = delta_rot[m] * delta_time;
00812 for (n = 0; n < pixct; n++) {
00813 if (offsun[n + mset]) {
00814 maps[n + mset] = missing_val;
00815 continue;
00816 }
00817
00818 sin_lat = map_sinlat[n + mset];
00819 cos_lat = map_coslat[n + mset];
00820 lon = maplon[n + mset] + delta_lon;
00821 cos_lat_lon = cos_lat * cos (lon - lonc);
00822 cos_cang = sin_lat * sin_latc + cos_latc * cos_lat_lon;
00823 if (cos_cang < 0.0) {
00824 maps[n + mset] = missing_val;
00825 continue;
00826 }
00827 r = radius * cos_asd / (1.0 - cos_cang * sin_asd);
00828 xr = r * cos_lat * sin (lon - lonc);
00829 yr = r * (sin_lat * cos_latc - sin_latc * cos_lat_lon);
00830 xx = xr * cos_pa - yr * sin_pa;
00831 yy = xr * sin_pa + yr * cos_pa;
00832 yy += yc;
00833 xx += xc;
00834
00835 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00836 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00837
00838
00839 if (MDI_correct_distort) {
00840 mtrack_MDI_image_tip (&xx, &yy, 1, 1);
00841 mtrack_MDI_image_stretch (&xx, &yy, 1, 1);
00842 }
00843 interpval = array_imaginterp (img, xx, yy, interpolator);
00844 maps[n + mset] = (isnan (interpval)) ? missing_val : interpval;
00845 }
00846 mset += pixct;
00847 }
00848 }
00849 return;
00850 }
00851
00852
00853
00854 for (m = 0; m < mapct; m++) {
00855 double delta_lon = delta_rot[m] * delta_time;
00856 for (n = 0; n < pixct; n++) {
00857 if (offsun[n + mset]) {
00858 maps[n + mset] = missing_val;
00859 continue;
00860 }
00861
00862 lat = maplat[n + mset] + delta_lat;
00863 lon = maplon[n + mset] + delta_lon;
00864
00865 if (sphere2img (lat, lon, latc, lonc, &xx, &yy, xc, yc, radius, pa,
00866 ellipse_e, ellipse_pa, x_invrt, y_invrt)) {
00867 maps[n + mset] = missing_val;
00868 continue;
00869 }
00870 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00871 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00872
00873 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00874 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00875
00876 if (MDI_correct_distort) {
00877 mtrack_MDI_image_tip (&xx, &yy, 1, 1);
00878 mtrack_MDI_image_stretch (&xx, &yy, 1, 1);
00879 }
00880 interpval = array_imaginterp (img, xx, yy, interpolator);
00881 maps[n + mset] = (isnan (interpval)) ? missing_val : interpval;
00882 }
00883 mset += pixct;
00884 }
00885 }
00886
00887 void calc_limb_distance (double *delta_rot, int mapct, double *maplat,
00888 double *maplon, double delta_time, double merid_v,unsigned char *offsun,
00889 double latc, double lonc, double *mu, double *ctrx, double *ctry) {
00890
00891
00892
00893
00894
00895 static double degrad = 180.0 / M_PI;
00896 double lat, lon, cos_lat, cos_lon, cos_lat_lon;
00897 double cos_cang;
00898 int m;
00899
00900 double cos_latc = cos (latc);
00901 double sin_latc = sin (latc);
00902 double delta_lat = merid_v * delta_time;
00903 double missing_val = 0.0 / 0.0;
00904
00905 for (m = 0; m < mapct; m++) {
00906 mu[m] = missing_val;
00907 double delta_lon = delta_rot[m] * delta_time;
00908 if (offsun[m]) continue;
00909 lat = maplat[m] + delta_lat;
00910 lon = maplon[m] + delta_lon;
00911 cos_lat = cos (lat);
00912 cos_lon = cos (lon - lonc);
00913 cos_lat_lon = cos_lat * cos_lon;
00914 cos_cang = sin (lat) * sin_latc + cos_latc * cos_lat_lon;
00915 if (cos_cang < 0.0) continue;
00916 mu[m] = cos_cang;
00917 ctrx[m] = cos_lat * sin (lon - lonc);
00918 ctry[m] = sin (lat) * cos_latc - sin_latc * cos_lat * cos_lon;
00919 }
00920 }
00921
00922 TIME time_from_crcl (int cr, double cl, int from_soho) {
00923 if (from_soho)
00924 return SOHO_meridian_crossing (cl, cr);
00925 else
00926 return earth_meridian_crossing (cl, cr);
00927 }
00928
00929 int getctrloc_from_time (TIME t, double *img_lat, double *cm_lon, int *cr,
00930 platloc platform) {
00931
00932
00933
00934
00935
00936
00937
00938 double rsun, vr, vn, vw;
00939 TIME table_mod_time;
00940
00941 if (platform == LOC_SOHO)
00942 soho_ephemeris (t, &rsun, img_lat, cm_lon, &vr, &vn, &vw, &table_mod_time);
00943 else if (platform == LOC_UNKNOWN) return 1;
00944 else earth_ephemeris (t, &rsun, img_lat, cm_lon, &vr, &vn, &vw);
00945 *cr = carrington_rots (t, 1);
00946 return 0;
00947 }
00948
00949 int verify_keys (DRMS_Record_t *rec, const char *clon,
00950 const char *clat, double *keyscale) {
00951 DRMS_Keyword_t *keywd;
00952
00953 keywd = drms_keyword_lookup (rec, clon, 1);
00954 if (!keywd) {
00955 fprintf (stderr,
00956 "Error: Keyword \"%s\" for Carrington longitude of observer not found\n",
00957 clon);
00958 fprintf (stderr, " Must supply an appropriate value for clon_key\n");
00959 fprintf (stderr, " (Carrington longitude of disc center in deg)\n");
00960 return -1;
00961 }
00962 if (keywd->info->type == DRMS_TYPE_TIME ||
00963 keywd->info->type == DRMS_TYPE_STRING ||
00964 keywd->info->type == DRMS_TYPE_RAW) {
00965 fprintf (stderr,
00966 "Error: Keyword \"%s\" for observer Carrington longitude is of wrong type\n",
00967 clon);
00968 fprintf (stderr, " Must supply an appropriate value for clon_key\n");
00969 fprintf (stderr, " (Carrington longitude of disc centre in deg)\n");
00970 return -1;
00971 }
00972 if (strncasecmp (keywd->info->unit, "deg", 3)) {
00973 fprintf (stderr,
00974 "Warning: Keyword \"%s\" for observer Carrington longitude has unit of \"%s\"\n",
00975 clon, keywd->info->unit);
00976 fprintf (stderr, " ignored, \"deg\" assumed\n");
00977 }
00978
00979 keywd = drms_keyword_lookup (rec, clat, 1);
00980 if (!keywd) {
00981 fprintf (stderr,
00982 "Error: Keyword \"%s\" for observer heliographic latitude not found\n",
00983 clat);
00984 fprintf (stderr, " Must supply an appropriate value for clat_key\n");
00985 fprintf (stderr, " (heliographic latitude of disc centre in deg)\n");
00986 return -1;
00987 }
00988 if (keywd->info->type == DRMS_TYPE_TIME ||
00989 keywd->info->type == DRMS_TYPE_STRING ||
00990 keywd->info->type == DRMS_TYPE_RAW) {
00991 fprintf (stderr,
00992 "Error: Keyword \"%s\" for observer heliographic latitude is of wrong type\n",
00993 clat);
00994 fprintf (stderr, " Must supply an appropriate value for clat_key\n");
00995 fprintf (stderr, " (heliographic latitude of disc centre in deg)\n");
00996 return -1;
00997 }
00998 if (strncasecmp (keywd->info->unit, "deg", 3)) {
00999 fprintf (stderr,
01000 "Warning: Keyword \"%s\" for observer heliographic latitude has unit of \"%s\"\n",
01001 clat, keywd->info->unit);
01002 fprintf (stderr, " ignored, \"deg\" assumed\n");
01003 }
01004
01005 return 0;
01006 }
01007
01008 int get_cadence (DRMS_Record_t *rec, const char *source, const char *tstp_key,
01009 const char *trec_key, double *tstep, double *cadence) {
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 DRMS_Keyword_t *keywd;
01020 int status;
01021
01022 if ((keywd = drms_keyword_lookup (rec, tstp_key, 1))) {
01023
01024 *cadence = drms_getkey_double (rec, tstp_key, &status);
01025 if (keywd->info->recscope != 1) {
01026 fprintf (stderr, "Warning: %s is variable in input series %s\n",
01027 tstp_key, source);
01028 drms_free_keyword_struct (keywd);
01029 if ((keywd = drms_keyword_lookup (rec, trec_key, 1))) {
01030 if (drms_key_is_slotted (drms_env, trec_key, source)) {
01031 char *stepkey = malloc (strlen (trec_key) + 8);
01032 sprintf (stepkey, "%s_step", trec_key);
01033 *cadence = drms_getkey_double (rec, stepkey, &status);
01034 free (stepkey);
01035 } else {
01036 fprintf (stderr, " and %s is not slotted\n", trec_key);
01037 fprintf (stderr, " output cadence will be %f\n", *tstep);
01038 *cadence = *tstep;
01039 }
01040 drms_free_keyword_struct (keywd);
01041 } else {
01042 fprintf (stderr, " and %s is not present\n", trec_key);
01043 fprintf (stderr, " output cadence will be %f\n", *tstep);
01044 *cadence = *tstep;
01045 }
01046 }
01047 } else {
01048
01049 drms_free_keyword_struct (keywd);
01050 if ((keywd = drms_keyword_lookup (rec, trec_key, 1))) {
01051 if (drms_key_is_slotted (drms_env, trec_key, source)) {
01052 char *stepkey = malloc (strlen (trec_key) + 8);
01053 sprintf (stepkey, "%s_step", trec_key);
01054 *cadence = drms_getkey_double (rec, stepkey, &status);
01055 free (stepkey);
01056 } else if (isnan (*tstep)) {
01057 fprintf (stderr,
01058 "Error: data cadence keyword %s not in input series %s\n",
01059 tstp_key, source);
01060 fprintf (stderr, " and %s is not slotted\n", trec_key);
01061 fprintf (stderr, " Specify desired output cadence as tstep\n");
01062 return 1;
01063 }
01064 drms_free_keyword_struct (keywd);
01065 } else if (isnan (*tstep)) {
01066
01067 fprintf (stderr,
01068 "Error: data cadence keyword %s not in input series %s\n",
01069 tstp_key, source);
01070 fprintf (stderr, " and %s is not present\n", trec_key);
01071 fprintf (stderr, " Specify desired output cadence as tstep\n");
01072 return 1;
01073 } else *cadence = *tstep;
01074 }
01075
01076 if (isnan (*tstep)) *tstep = *cadence;
01077 return 0;
01078 }
01079
01080 static int cleanup (int error, DRMS_RecordSet_t *ids, DRMS_RecordSet_t *ods,
01081 DRMS_Array_t *data, DRMS_Array_t *map) {
01082 if (data) drms_free_array (data);
01083 if (map) drms_free_array (map);
01084 if (ids) drms_close_records (ids, DRMS_FREE_RECORD);
01085 if (ods) {
01086 if (error) drms_close_records (ods, DRMS_FREE_RECORD);
01087 else drms_close_records (ods, DRMS_INSERT_RECORD);
01088 }
01089 return error;
01090 }
01091
01092 static void free_all (float *clat, float *clon, float *mai, double *delta_rot,
01093 float *maps, float *last, double *maplat, double *maplon, double *mapsinlat,
01094 unsigned char *offsun, DRMS_Record_t **orecs, FILE **log, int *rejects) {
01095 free (clat);
01096 free (clon);
01097 free (mai);
01098 free (delta_rot);
01099 free (maps);
01100 free (last);
01101 free (maplat);
01102 free (maplon);
01103 free (mapsinlat);
01104 free (offsun);
01105 free (orecs);
01106 free (log);
01107 free (rejects);
01108 }
01109
01110
01111
01112
01113 int DoIt (void) {
01114 CmdParams_t *params = &cmdparams;
01115 DRMS_RecordSet_t *ids = NULL, *ods = NULL, *bckgds = NULL;
01116 DRMS_Record_t **orecs;
01117 DRMS_Record_t *irec, *orec;
01118 DRMS_Segment_t *record_segment, *oseg, *logseg;
01119 DRMS_Array_t *data_array = NULL, *map_array = NULL, *bckg_array;
01120 DRMS_Keyword_t *keywd;
01121 FILE **log;
01122 TIME trec, tobs, tmid, tbase, tfirst, tlast, ttrgt;
01123 double *maplat, *maplon, *map_coslat, *map_sinlat = NULL;
01124 double *cmaplat, *cmaplon, *ctrmu, *ctrx, *ctry, *muavg, *xavg, *yavg, *latavg;
01125 double *delta_rot, *map_pa;
01126 double *minval, *maxval, *datamean, *datarms, *dataskew, *datakurt;
01127 double min_scaled, max_scaled;
01128 double carr_lon, cm_lon_start, cm_lon_stop, lon_span;
01129 double cm_lon_first, cm_lon_last;
01130 double data_cadence, coverage, t_eps, phase;
01131 double lat, lon, img_lat, img_lon;
01132 double t_cl, tmid_cl, lon_cm;
01133 double x, y, x0, y0, xstp, ystp;
01134 double *cos_phi, *sin_phi;
01135 double img_xc, img_yc, img_xscl, img_yscl, img_radius, img_pa;
01136 double ellipse_e, ellipse_pa;
01137 double kscale;
01138 float *maps = NULL, *last = NULL;
01139 float *data, *clat, *clon, *mai, *bck = NULL, *zero;
01140 platloc platform = LOC_UNKNOWN;
01141 long long *datavalid, *origvalid;
01142 long long *cvgolist, *cvnolist, *cvlist;
01143 long long nn, nntot, calver;
01144 unsigned int quality;
01145 int *mnlatct, *muct, *cvfound;
01146 int *reject_list = NULL;
01147 int axes[3], slice_start[3], slice_end[3];
01148 int recct, rgn, rgnct, segct, valid, cvct, cvgoct, cvnoct, cvused, cvmaxct;
01149 int t_cr, tmid_cr, cr_start, cr_stop;
01150 int cr_first, cr_last;
01151 int found_first, found_mid, found_last;
01152 int col, row, pixct, dxy, i, found, n, nr, or;
01153 int blankvals, no_merid_v, rejects, status, verbose_logs, setmais;
01154 int x_invrt, y_invrt;
01155 int need_ephem, need_limb_dist, need_stats;
01156 int MDI_correct, MDI_correct_distort;
01157 int bscale_override, bzero_override, data_scaled;
01158 int badpkey, badqual, badfill, badtime, badcv, blacklist, qualcheck;
01159 unsigned char *offsun, *ctroffsun;
01160 char *input, *source_series, *eoser, *segspec, *osegname, *pkeyval;
01161 char logfilename[DRMS_MAXPATHLEN], ctimefmt[DRMS_MAXFORMATLEN];
01162 char rec_query[256];
01163 char module_ident[64], key[64], tbuf[64], ptbuf[64], ctime_str[16];
01164
01165 double raddeg = M_PI / 180.0;
01166 double degrad = 1.0 / raddeg;
01167 int *seglist;
01168 int need_crcl = 1;
01169 int check_platform = 0;
01170 int segnum = 0;
01171 int extrapolate = 1;
01172 char *mapname[] = {"PlateCarree", "Cassini-Soldner", "Mercator",
01173 "LambertCylindrical", "Sanson-Flamsteed", "gnomonic", "Postel",
01174 "stereographic", "orthographic", "LambertAzimuthal"};
01175 char *interpname[] = {"Cubic Convolution", "Nearest Neighbor", "Bilinear"};
01176 char *wcscode[] = {"CAR", "CAS", "MER", "CEA", "GLS", "TAN", "ARC", "STG",
01177 "SIN", "ZEA"};
01178 missing_val = 0.0 / 0.0;
01179
01180 char *inset = strdup (params_get_str (params, "in"));
01181 char *outser = strdup (params_get_str (params, "out"));
01182 char *bckgn = strdup (params_get_str (params, "bckgn"));
01183 char *rejectfile = strdup (params_get_str (params, "reject"));
01184 char *seg_name = strdup (params_get_str (params, "segment"));
01185 unsigned int qmask = cmdparams_get_int64 (params, "qmask", &status);
01186 long long cvaccept = params_get_mask (params, "cvok", -1);
01187 long long cvreject = params_get_mask (params, "cvno", 0);
01188 char *calverkey = strdup (params_get_str (params, "cvkey"));
01189 int max_miss = params_get_int (params, "max_miss");
01190 char *tmid_str = strdup (params_get_str (params, "tmid"));
01191 char *tstrt_str = strdup (params_get_str (params, "tstart"));
01192 char *tstop_str = strdup (params_get_str (params, "tstop"));
01193 TIME tstrt = params_get_time (params, "tstart");
01194 TIME tstop = params_get_time (params, "tstop");
01195 int length = params_get_int (params, "length");
01196 double tstep = params_get_double (params, "tstep");
01197 int latct = params_get_int (params, "lat_nvals");
01198 int lonct = params_get_int (params, "lon_nvals");
01199 int maict = params_get_int (params, "mai_nvals");
01200 int pact = params_get_int (params, "map_pa_nvals");
01201 int proj = params_get_int (params, "map");
01202 int intrpopt = params_get_int (params, "interp");
01203 int fillopt = params_get_int (params, "fillopt");
01204 double map_scale = params_get_double (params, "scale");
01205 int map_cols = params_get_int (params, "cols");
01206 int map_rows = params_get_int (params, "rows");
01207 double a0 = params_get_double (params, "a0");
01208 double a2 = params_get_double (params, "a2");
01209 double a4 = params_get_double (params, "a4");
01210 double merid_v = params_get_double (params, "merid_v");
01211 double bscale = params_get_double (params, "bscale");
01212 double bzero = params_get_double (params, "bzero");
01213 char *identifier = strdup (params_get_str (params, "ident"));
01214
01215 char *trec_key = strdup (params_get_str (params, "trec_key"));
01216 char *tobs_key = strdup (params_get_str (params, "tobs_key"));
01217 char *tstp_key = strdup (params_get_str (params, "tstp_key"));
01218 char *qual_key = strdup (params_get_str (params, "qual_key"));
01219 char *clon_key = strdup (params_get_str (params, "clon_key"));
01220 char *clat_key = strdup (params_get_str (params, "clat_key"));
01221 char *crot_key = strdup (params_get_str (params, "crot_key"));
01222 char *rsun_key = strdup (params_get_str (params, "rsun_key"));
01223 char *apsd_key = strdup (params_get_str (params, "apsd_key"));
01224 char *dsun_key = strdup (params_get_str (params, "dsun_key"));
01225
01226 int carr_track = params_isflagset (params, "c");
01227 int no_track = params_isflagset (params, "n");
01228 int remove_obsvel = params_isflagset (params, "o");
01229 int remove_rotation = params_isflagset (params, "r");
01230 int verbose = params_isflagset (params, "v");
01231 int no_proc = params_isflagset (params, "w");
01232 int dispose = (no_proc | params_isflagset (params, "x")) ? DRMS_FREE_RECORD :
01233 DRMS_INSERT_RECORD;
01234 int geo_times = params_isflagset (params, "G");
01235 int MDI_proc = params_isflagset (params, "M");
01236 int ut_times = params_isflagset (params, "Z");
01237 int filt_on_calver = (cvreject || ~cvaccept);
01238
01239 need_limb_dist = 1;
01240
01241 snprintf (module_ident, 64, "%s v %s", module_name, version_id);
01242 if (verbose) printf ("%s: JSOC version %s\n", module_ident, jsoc_version);
01243 verbose_logs = (dispose == DRMS_INSERT_RECORD) ? verbose : 0;
01244
01245 cvused = 0;
01246 cvmaxct = 64;
01247 cvfound = (int *)malloc (cvmaxct * sizeof (int));
01248 cvlist = (long long *)malloc (cvmaxct * sizeof (long long));
01249 if (filt_on_calver) {
01250 cvgoct = 1;
01251 cvgolist = (long long *)malloc (cvgoct * sizeof (long long));
01252 cvgolist[0] = cvaccept;
01253 cvnoct = 1;
01254 cvnolist = (long long *)malloc (cvnoct * sizeof (long long));
01255 cvnolist[0] = cvreject;
01256 if (~cvaccept) cvgoct = 0;
01257 if (!cvreject) cvnoct = 0;
01258 }
01259
01260 rgnct = (latct > lonct) ? latct : lonct;
01261 if (rgnct > 300) {
01262 fprintf (stderr,
01263 "Error: requested number of regions (%d) exceeds cfitsio limit\n", rgnct);
01264 fprintf (stderr, " of 300 open file pointers.\n");
01265 return 1;
01266 }
01267 setmais = (maict == rgnct);
01268 if (isnan (map_scale) || map_scale == 0.0) {
01269 fprintf (stderr,
01270 "Error: auto scaling from image resolution not implemented;\n");
01271 fprintf (stderr, " scale parameter must be set.\n");
01272 return 1;
01273 }
01274
01275 if (no_track) {
01276 a0 = -(CARR_RATE);
01277 a2 = a4 = merid_v = 0.0;
01278 if (carr_track) {
01279 fprintf (stderr, "Error: inconsistent flags -c and -n\n");
01280 return 1;
01281 }
01282 }
01283 if (carr_track) a0 = a2 = a4 = merid_v = 0.0;
01284
01285 a0 *= 1.0e-6;
01286 a2 *= 1.0e-6;
01287 a4 *= 1.0e-6;
01288 merid_v *= 1.0e-6;
01289 no_merid_v = (merid_v == 0.0);
01290 if (map_cols < 1) map_cols = map_rows;
01291 if (map_rows < 1) map_rows = map_cols;
01292 if (map_rows < 1) {
01293 fprintf (stderr, "Error: at least one of \"cols\" or \"rows\" must be set\n");
01294 return 1;
01295 }
01296 MDI_correct = MDI_correct_distort = MDI_proc;
01297 pixct = map_rows * map_cols;
01298 xstp = ystp = map_scale * raddeg;
01299 x0 = 0.5 * (1.0 - map_cols) * xstp;
01300 y0 = 0.5 * (1.0 - map_rows) * ystp;
01301
01302 if (!(ods = drms_create_records (drms_env, rgnct, outser, DRMS_PERMANENT,
01303 &status))) {
01304 fprintf (stderr, "Error: unable to create %d records in series %s\n",
01305 rgnct, outser);
01306 fprintf (stderr, " drms_create_records() returned status %d\n", status);
01307 return 1;
01308 }
01309 if (verbose) printf ("creating %d record(s) in series %s\n", rgnct, outser);
01310 if (verbose && dispose == DRMS_FREE_RECORD)
01311 printf ("experimental run, output records will not be saved\n");
01312
01313 orec = drms_recordset_getrec (ods, 0);
01314 if (!orec) {
01315 fprintf (stderr, "Error accessing record %d in series %s\n", 0, outser);
01316 drms_close_records (ods, DRMS_FREE_RECORD);
01317 return 1;
01318 }
01319 segct = drms_record_numsegments (orec);
01320 found = 0;
01321 for (n = 0; n < segct; n++) {
01322 record_segment = drms_segment_lookupnum (orec, n);
01323 if (record_segment->info->naxis != 3) continue;
01324 if (record_segment->info->scope == DRMS_CONSTANT) continue;
01325 if (record_segment->info->scope == DRMS_VARIABLE) {
01326 if (record_segment->axis[0] != map_cols ||
01327 record_segment->axis[1] != map_rows ||
01328 record_segment->axis[2] != length) continue;
01329 }
01330 if (!found) osegname = strdup (record_segment->info->name);
01331 found++;
01332 }
01333 if (found < 1) {
01334 fprintf (stderr,
01335 "Error: no data segment of dimension 3 and appropriate size in output series %s\n", outser);
01336 drms_close_records (ods, DRMS_FREE_RECORD);
01337 return 1;
01338 }
01339 record_segment = drms_segment_lookup (orec, osegname);
01340 if (found > 1) {
01341 fprintf (stderr,
01342 "Warning: multiple data segments of dimension 3 and appropriate size in output series %s\n", outser);
01343 fprintf (stderr, " using \"%s\"\n", osegname);
01344 }
01345
01346 bscale_override = 1;
01347 if (isnan (bscale) || bscale == 0.0) {
01348 bscale = record_segment->bscale;
01349 bscale_override = 0;
01350 }
01351 bzero_override = 1;
01352 if (isnan (bzero)) {
01353 bzero = record_segment->bzero;
01354 bzero_override = 0;
01355 }
01356
01357 logseg = drms_segment_lookup (orec, "Log");
01358 if (logseg) drms_segment_filename (logseg, logfilename);
01359 else if (verbose) {
01360 fprintf (stderr,
01361 "Warning: segment \"Log\" not present in output series %s\n", outser);
01362 fprintf (stderr, " verbose logging turned off\n");
01363 verbose_logs = 0;
01364 }
01365 if ((keywd = drms_keyword_lookup (orec, "CMLon", 1)))
01366 sprintf (ctimefmt, "%%d:%s", keywd->info->format);
01367 else sprintf (ctimefmt, "%%d:%%07.3f");
01368
01369 need_stats = (drms_keyword_lookup (orec, "DATAMIN", 1) ||
01370 drms_keyword_lookup (orec, "DATAMAX", 1) ||
01371 drms_keyword_lookup (orec, "DATAMEAN", 1) ||
01372 drms_keyword_lookup (orec, "DATARMS", 1) ||
01373 drms_keyword_lookup (orec, "DATASKEW", 1) ||
01374 drms_keyword_lookup (orec, "DATAKURT", 1) ||
01375 drms_keyword_lookup (orec, "DATAVALS", 1) ||
01376 drms_keyword_lookup (orec, "MISSVALS", 1));
01377 data_scaled = ((record_segment->info->type == DRMS_TYPE_CHAR) ||
01378 (record_segment->info->type == DRMS_TYPE_SHORT) ||
01379 (record_segment->info->type == DRMS_TYPE_INT) ||
01380 (record_segment->info->type == DRMS_TYPE_LONGLONG));
01381 need_stats |= data_scaled;
01382 if (data_scaled) {
01383 max_scaled = (record_segment->info->type == DRMS_TYPE_CHAR) ?
01384 SCHAR_MAX : (record_segment->info->type == DRMS_TYPE_SHORT) ?
01385 SHRT_MAX : (record_segment->info->type == DRMS_TYPE_INT) ?
01386 INT_MAX : LLONG_MAX;
01387 min_scaled = - max_scaled;
01388 max_scaled *= bscale;
01389 min_scaled *= bscale;
01390 max_scaled += bzero;
01391 min_scaled += bzero;
01392 }
01393
01394 input = strdup (inset);
01395 source_series = strdup (inset);
01396 segspec = strstr (input, "{");
01397 eoser = strchr (source_series, '[');
01398 if (eoser) *eoser = '\0';
01399 eoser = strchr (source_series, '{');
01400 if (eoser) *eoser = '\0';
01401
01402 if (key_params_from_dspec (inset)) {
01403
01404 if (!time_is_invalid (tstrt) || !time_is_invalid (tstop) ||
01405 strcmp (tmid_str, "Not Specified") || (length > 0)) {
01406 fprintf (stderr, "Warning: input record set explicitly specified:\n");
01407 fprintf (stderr,
01408 " tstart, tstop, tmid and length values ignored\n");
01409 }
01410 if (!(ids = drms_open_records (drms_env, inset, &status))) {
01411 fprintf (stderr, "Error: (%s) unable to open input data set \"%s\"\n",
01412 module_ident, inset);
01413 fprintf (stderr, " status = %d\n", status);
01414 return 1;
01415 }
01416 if ((recct = ids->n) < 2) {
01417 fprintf (stderr, "Error: (%s) <2 records in selected input set\n",
01418 module_ident);
01419 fprintf (stderr, " %s\n", inset);
01420 drms_close_records (ids, DRMS_FREE_RECORD);
01421 return 1;
01422 }
01423 irec = ids->records[0];
01424
01425 if (filt_on_calver) {
01426 keywd = drms_keyword_lookup (irec, calverkey, 1);
01427 if (!keywd) {
01428 fprintf (stderr, "Warning: required keyword %s not found\n", calverkey);
01429 fprintf (stderr, " no calibration version filtering applied\n");
01430 filt_on_calver = 0;
01431 }
01432 }
01433 status = verify_keys (irec, clon_key, clat_key, &kscale);
01434 if (status) {
01435 drms_close_records (ids, DRMS_FREE_RECORD);
01436 return 1;
01437 }
01438 tstrt = drms_getkey_time (irec, trec_key, &status);
01439 tstop = drms_getkey_time (ids->records[recct - 1], trec_key, &status);
01440 length = (tstop - tstrt + 1.01 * tstep) / tstep;
01441 tmid = 0.5 * (tstrt + tstop);
01442
01443
01444
01445 seglist = ndimsegments (irec, 2, &segct);
01446 if (get_cadence (irec, source_series, tstp_key, trec_key, &tstep, &data_cadence)) {
01447 drms_close_records (ids, DRMS_FREE_RECORD);
01448 return 1;
01449 }
01450
01451
01452
01453 } else {
01454
01455
01456 if (!strcmp (tmid_str, "Not Specified") &&
01457 (time_is_invalid (tstrt) || time_is_invalid (tstop))) {
01458 fprintf (stderr,
01459 "Error: either a specific data record set must be selected as input\n");
01460 fprintf (stderr, " or (tmid and length) or (tstart and tstop) must be\n");
01461 fprintf (stderr, " specified\n");
01462 return 1;
01463 }
01464
01465
01466 snprintf (rec_query, 256, "%s[:#^]", source_series);
01467 if (segspec) strcat (rec_query, segspec);
01468 if (!(ids = drms_open_records (drms_env, rec_query, &status))) {
01469 fprintf (stderr, "Error: unable to open input data set \"%s\"\n", inset);
01470 fprintf (stderr, " status = %d\n", status);
01471 return 1;
01472 }
01473 irec = ids->records[0];
01474 status = verify_keys (irec, clon_key, clat_key, &kscale);
01475 if (status) {
01476 drms_close_records (ids, DRMS_FREE_RECORD);
01477 return 1;
01478 }
01479 if (get_cadence (irec, source_series, tstp_key, trec_key, &tstep,
01480 &data_cadence)) {
01481 drms_close_records (ids, DRMS_FREE_RECORD);
01482 return 1;
01483 }
01484 t_eps = 0.5 * data_cadence;
01485
01486 if ((keywd = drms_keyword_lookup (irec, "TELESCOP", 1))) {
01487
01488 if (keywd->info->recscope != 1)
01489 fprintf (stderr, "Warning: TELESCOP is variable in input series %s\n",
01490 source_series);
01491 if (!strcmp (drms_getkey_string (irec, "TELESCOP", &status), "SDO/HMI"))
01492 platform = LOC_SDO;
01493 else if (!strcmp (drms_getkey_string (irec, "TELESCOP", &status), "SOHO"))
01494 platform = LOC_SOHO;
01495 else if (!strcmp (drms_getkey_string (irec, "TELESCOP", &status),
01496 "NSO-GONG")) {
01497 if ((keywd = drms_keyword_lookup (irec, "SITE", 1))) {
01498 if (!strcmp (drms_getkey_string (irec, "SITE", &status), "MR"))
01499 platform = LOC_GONG_MR;
01500 else if (!strcmp (drms_getkey_string (irec, "SITE", &status), "LE"))
01501 platform = LOC_GONG_LE;
01502 else if (!strcmp (drms_getkey_string (irec, "SITE", &status), "UD"))
01503 platform = LOC_GONG_UD;
01504 else if (!strcmp (drms_getkey_string (irec, "SITE", &status), "TD"))
01505 platform = LOC_GONG_TD;
01506 else if (!strcmp (drms_getkey_string (irec, "SITE", &status), "CT"))
01507 platform = LOC_GONG_CT;
01508 else if (!strcmp (drms_getkey_string (irec, "SITE", &status), "BB"))
01509 platform = LOC_GONG_BB;
01510 else if (!strcmp (drms_getkey_string (irec, "SITE", &status), "ML"))
01511 platform = LOC_GONG_ML;
01512 else {
01513 platform = LOC_GONG_MR;
01514 }
01515 } else {
01516 fprintf (stderr, "Warning: unspecified GONG site: MR assumed\n");
01517 platform = LOC_GONG_MR;
01518 }
01519 }
01520 }
01521 if (platform == LOC_UNKNOWN) fprintf (stderr,
01522 "Warning: observing location unknown, assumed geocenter\n");
01523
01524
01525
01526 seglist = ndimsegments (irec, 2, &segct);
01527
01528 if (strcmp (tmid_str, "Not Specified")) {
01529
01530
01531 if (sscanf (tmid_str, "%d:%lf", &tmid_cr, &tmid_cl) == 2) {
01532
01533 need_crcl = 0;
01534 tmid = (geo_times) ?
01535 time_from_crcl (tmid_cr, tmid_cl, 0) :
01536 time_from_crcl (tmid_cr, tmid_cl, platform == LOC_SOHO);
01537 if (ut_times) sprint_time (ptbuf, tmid, "UTC", 0);
01538 else sprint_time (ptbuf, tmid, "TAI", 0);
01539
01540 tbase = drms_getkey_time (irec, trec_key, &status);
01541 phase = fmod ((tmid - tbase), data_cadence);
01542 tmid -= phase;
01543 if (phase > 0.5 * data_cadence) tmid += data_cadence;
01544 if (verbose) {
01545 if (ut_times) sprint_time (tbuf, tmid, "UTC", 0);
01546 else sprint_time (tbuf, tmid, "TAI", 0);
01547 printf ("Target time %d:%05.1f = %s adjusted to\n\t%s\n",
01548 tmid_cr, tmid_cl, ptbuf, tbuf);
01549 }
01550 } else
01551 tmid = sscan_time (tmid_str);
01552 tbase = drms_getkey_time (irec, trec_key, &status);
01553 phase = fmod ((tmid - tbase), data_cadence);
01554 tstrt = tmid - 0.5 * length * tstep;
01555 tstop = tstrt + (length - 1) * tstep;
01556 if (tstop <= tstrt) {
01557 sprint_time (ptbuf, tstop, "", 0);
01558 fprintf (stderr,
01559 "Error: requested end time %s before or at\n start time ",
01560 ptbuf);
01561 sprint_time (ptbuf, tstrt, "", 0);
01562 fprintf (stderr, "%s for length = %d, tstep = %.2f\n", ptbuf, length,
01563 tstep);
01564 drms_close_records (ids, DRMS_FREE_RECORD);
01565 return 1;
01566 }
01567
01568 if ((fabs (phase) < 0.001 * t_eps) && length % 2)
01569 tstop += tstep;
01570 if ((fabs (phase - t_eps) < 0.001 * t_eps) && (length % 2 == 0))
01571 tstop += tstep;
01572 } else {
01573
01574 if (sscanf (tstrt_str, "%d:%lf", &t_cr, &t_cl) == 2) {
01575 tstrt = (geo_times) ?
01576 time_from_crcl (t_cr, t_cl, 0) :
01577 time_from_crcl (t_cr, t_cl, platform == LOC_SOHO);
01578 if (ut_times) sprint_time (ptbuf, tstrt, "UTC", 0);
01579 else sprint_time (ptbuf, tstrt, "TAI", 0);
01580
01581 tbase = drms_getkey_time (irec, trec_key, &status);
01582 phase = fmod ((tstrt - tbase), data_cadence);
01583 tstrt -= phase;
01584 if (phase > 0.5 * data_cadence) tstrt += data_cadence;
01585 if (verbose) {
01586 if (ut_times) sprint_time (tbuf, tstrt, "UTC", 0);
01587 else sprint_time (tbuf, tstrt, "TAI", 0);
01588 printf ("Start time %d:%05.1f = %s adjusted to\n\t%s\n",
01589 t_cr, t_cl, ptbuf, tbuf);
01590 }
01591 }
01592 if (sscanf (tstop_str, "%d:%lf", &t_cr, &t_cl) == 2) {
01593 tstop = (geo_times) ?
01594 time_from_crcl (t_cr, t_cl, 0) :
01595 time_from_crcl (t_cr, t_cl, platform == LOC_SOHO);
01596 if (ut_times) sprint_time (ptbuf, tstop, "UTC", 0);
01597 else sprint_time (ptbuf, tstop, "TAI", 0);
01598
01599 tbase = drms_getkey_time (irec, trec_key, &status);
01600 phase = fmod ((tstop - tbase), data_cadence);
01601 tstop -= phase;
01602 if (phase > 0.5 * data_cadence) tstop += data_cadence;
01603 if (verbose) {
01604 if (ut_times) sprint_time (tbuf, tstop, "UTC", 0);
01605 else sprint_time (tbuf, tstop, "TAI", 0);
01606 printf ("Stop time %d:%05.1f = %s adjusted to\n\t%s\n",
01607 t_cr, t_cl, ptbuf, tbuf);
01608 }
01609 }
01610
01611 tmid = 0.5 * (tstrt + tstop);
01612 length = (tstop - tstrt + 1.01 * tstep) / tstep;
01613 }
01614 drms_close_records (ids, DRMS_FREE_RECORD);
01615 if (drms_key_is_slotted (drms_env, trec_key, source_series)) {
01616
01617 DRMS_Record_t *rec = drms_template_record (drms_env, source_series,
01618 &status);
01619 TIME pkeybase;
01620 double pkeystep;
01621 int tstrt_ind, tstop_ind;
01622 char *pkindx = malloc (strlen (trec_key) + 8);
01623 char *pkbase = malloc (strlen (trec_key) + 8);
01624 char *pkstep = malloc (strlen (trec_key) + 8);
01625
01626 sprintf (pkindx, "%s_index", trec_key);
01627 sprintf (pkbase, "%s_epoch", trec_key);
01628 sprintf (pkstep, "%s_step", trec_key);
01629 pkeybase = drms_getkey_time (rec, pkbase, &status);
01630 pkeystep = drms_getkey_double (rec, pkstep, &status);
01631 tstrt_ind = (tstrt - pkeybase) / pkeystep;
01632 tstop_ind = (tstop - pkeybase) / pkeystep;
01633 snprintf (rec_query, 256, "%s[?%s between %d and %d?]", source_series,
01634 pkindx, tstrt_ind, tstop_ind);
01635
01636 free (pkindx);
01637 free (pkbase);
01638 free (pkstep);
01639 drms_free_record (rec);
01640 } else snprintf (rec_query, 256, "%s[?%s between %23.16e and %23.16e?]",
01641 source_series, trec_key, tstrt - t_eps, tstop + t_eps);
01642 if (segspec) strcat (rec_query, segspec);
01643 if (!(ids = drms_open_records (drms_env, rec_query, &status))) {
01644 fprintf (stderr, "Error: unable to open input data set \"%s\\n", rec_query);
01645 fprintf (stderr, " status = %d\n", status);
01646 drms_close_records (ids, DRMS_FREE_RECORD);
01647 return 1;
01648 }
01649 if ((recct = ids->n) < 2) {
01650 fprintf (stderr, "Error: (%s) <2 records in selected input set\n",
01651 module_ident);
01652 fprintf (stderr, " %s with selection\n", inset);
01653 fprintf (stderr, " %s\n", rec_query);
01654 drms_close_records (ids, DRMS_FREE_RECORD);
01655 return 1;
01656 }
01657
01658 input = strdup (rec_query);
01659
01660 }
01661
01662 if (verbose) {
01663 sprint_time (ptbuf, tstrt, "", 0);
01664 sprint_time (tbuf, tstop, "", 0);
01665 printf ("tracking data from %s - %s at cadence of %.1f s\n", ptbuf, tbuf,
01666 tstep);
01667 }
01668
01669
01670
01671
01672 irec = ids->records[0];
01673 if (segct == 1) {
01674 segnum = seglist[0];
01675 record_segment = drms_segment_lookupnum (irec, segnum);
01676 } else if (segct > 1) {
01677 if (strcmp (seg_name, "Not Specified")) {
01678 int n;
01679 segnum = -1;
01680 for (n = 0; n < segct; n++) {
01681 record_segment = drms_segment_lookupnum (irec, seglist[n]);
01682 if (!strcmp (record_segment->info->name, seg_name)) {
01683 segnum = n;
01684 break;
01685 }
01686 }
01687 if (segnum < 0) {
01688 fprintf (stderr,
01689 "Error: requested segment %s not found in input series\n",
01690 seg_name);
01691 drms_close_records (ids, DRMS_FREE_RECORD);
01692 return 1;
01693 }
01694 } else {
01695 fprintf (stderr,
01696 "Error: input data set contains multiple 2-d segments\n");
01697 fprintf (stderr,
01698 " segment must be named explicitly as segment parameter\n");
01699 fprintf (stderr, " or in dataset specification (within braces)\n");
01700 drms_close_records (ids, DRMS_FREE_RECORD);
01701 return 1;
01702 }
01703 } else {
01704 fprintf (stderr, "Error: input data set contains no 2-d segments\n");
01705 drms_close_records (ids, DRMS_FREE_RECORD);
01706 return 1;
01707 }
01708
01709 found_first = found_mid = found_last = 0;
01710 tobs = drms_getkey_time (ids->records[0], tobs_key, &status);
01711 if (fabs (tobs - tstrt) < data_cadence) {
01712 tfirst = tobs;
01713 irec = ids->records[0];
01714 cm_lon_first = cm_lon_start = drms_getkey_double (irec, clon_key, &status);
01715 cr_first = cr_start = drms_getkey_int (irec, crot_key, &status);
01716 if (isnan (cm_lon_first) || cr_first < 0) {
01717 if (geo_times)
01718 getctrloc_from_time (tobs, &img_lat, &cm_lon_first, &cr_first, LOC_GEOC);
01719 else
01720 getctrloc_from_time (tobs, &img_lat, &cm_lon_first, &cr_first, platform);
01721 }
01722 else found_first = 1;
01723 }
01724
01725 tobs = drms_getkey_time (ids->records[recct - 1], tobs_key, &status);
01726 if (fabs (tobs - tstop) < data_cadence) {
01727 tlast = tobs;
01728 irec = ids->records[recct - 1];
01729 cm_lon_last = cm_lon_stop = drms_getkey_double (irec, clon_key, &status);
01730 cr_last = cr_stop = drms_getkey_int (irec, crot_key, &status);
01731 if (isnan (cm_lon_last) || cr_last < 0) {
01732 if (geo_times)
01733 getctrloc_from_time (tobs, &img_lat, &cm_lon_last, &cr_last, LOC_GEOC);
01734 else
01735 getctrloc_from_time (tobs, &img_lat, &cm_lon_last, &cr_last, platform);
01736 }
01737 else found_last = 1;
01738 }
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780 if (!found_first) {
01781 for (nr = 0; nr < recct; nr++) {
01782 tobs = drms_getkey_time (ids->records[nr], tobs_key, &status);
01783 if (time_is_invalid (tobs)) continue;
01784 irec = ids->records[nr];
01785 cm_lon_first = drms_getkey_double (irec, clon_key, &status);
01786 cr_first = drms_getkey_int (irec, crot_key, &status);
01787 tfirst = tobs;
01788 if (isnan (cm_lon_first) || cr_first < 0) {
01789 if (geo_times)
01790 getctrloc_from_time (tobs, &img_lat, &cm_lon_first, &cr_first, LOC_GEOC);
01791 else
01792 getctrloc_from_time (tobs, &img_lat, &cm_lon_first, &cr_first, platform);
01793 } else {
01794 found_first = 1;
01795 break;
01796 }
01797 }
01798 }
01799 if (need_crcl) {
01800 double timediff = fabs (tstop - tstrt);
01801 for (nr = 0; nr < recct; nr++) {
01802 tobs = drms_getkey_time (ids->records[nr], tobs_key, &status);
01803 if (time_is_invalid (tobs)) continue;
01804 if (fabs (tobs - tmid) > data_cadence) continue;
01805 if (fabs (tobs - tmid) > timediff) continue;
01806 timediff = fabs (tobs - tmid);
01807 irec = ids->records[nr];
01808 tmid_cl = drms_getkey_double (irec, clon_key, &status);
01809 tmid_cr = drms_getkey_int (irec, crot_key, &status);
01810 if (isnan (tmid_cl) || tmid_cr < 0) {
01811 if (geo_times)
01812 getctrloc_from_time (tobs, &img_lat, &cm_lon_first, &cr_first, LOC_GEOC);
01813 else
01814 getctrloc_from_time (tobs, &img_lat, &cm_lon_first, &cr_first, platform);
01815 }
01816 }
01817 }
01818 if (!found_last) {
01819 for (nr = recct - 1; nr; nr--) {
01820 tobs = drms_getkey_time (ids->records[nr], tobs_key, &status);
01821 if (time_is_invalid (tobs)) continue;
01822 irec = ids->records[nr];
01823 cm_lon_last = drms_getkey_double (irec, clon_key, &status);
01824 cr_last = drms_getkey_int (irec, crot_key, &status);
01825 tlast = tobs;
01826 if (isnan (cm_lon_last) || cr_last < 0) {
01827 if (geo_times)
01828 getctrloc_from_time (tobs, &img_lat, &cm_lon_last, &cr_last, LOC_GEOC);
01829 else
01830 getctrloc_from_time (tobs, &img_lat, &cm_lon_last, &cr_last, platform);
01831 } else {
01832 found_last = 1;
01833 break;
01834 }
01835 }
01836 }
01837 if (!found_first) {
01838 fprintf (stderr, "Error: No valid observation times in input data set\n");
01839 drms_close_records (ids, DRMS_FREE_RECORD);
01840 return 1;
01841 }
01842
01843 axes[0] = map_cols;
01844 axes[1] = map_rows;
01845 axes[2] = 1;
01846 slice_start[0] = slice_start[1] = 0;
01847 slice_end[0] = axes[0] - 1;
01848 slice_end[1] = axes[1] - 1;
01849 if (geo_times) {
01850 getctrloc_from_time (tstrt, &img_lat, &cm_lon_start, &cr_start, LOC_GEOC);
01851 getctrloc_from_time (tstop, &img_lat, &cm_lon_stop, &cr_stop, LOC_GEOC);
01852 } else {
01853 getctrloc_from_time (tstrt, &img_lat, &cm_lon_start, &cr_start, platform);
01854 getctrloc_from_time (tstop, &img_lat, &cm_lon_stop, &cr_stop, platform);
01855 }
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886 lon_span = cm_lon_start - cm_lon_stop;
01887 while (cr_start < cr_stop) {
01888 cr_start++;
01889 lon_span += 360.0;
01890 }
01891 nntot = (long long)recct * pixct;
01892
01893 clat = (float *)malloc (rgnct * sizeof (float));
01894 clon = (float *)malloc (rgnct * sizeof (float));
01895 mai = (float *)malloc (rgnct * sizeof (float));
01896 map_pa = (double *)malloc (rgnct * sizeof (double));
01897 cos_phi = (double *)malloc (rgnct * sizeof (double));
01898 sin_phi = (double *)malloc (rgnct * sizeof (double));
01899 delta_rot = (double *)malloc (rgnct * sizeof (double));
01900 for (i = 0; i < latct; i++) {
01901 snprintf (key, 64, "lat_%d_value", i);
01902 clat[i] = params_get_float (params, key) * raddeg;
01903 }
01904 for (i = 0; i < lonct; i++) {
01905 snprintf (key, 64, "lon_%d_value", i);
01906 clon[i] = params_get_float (params, key) * raddeg;
01907 }
01908 for (i = latct; i < rgnct; i++) clat[i] = clat[i-1];
01909 for (i = lonct; i < rgnct; i++) clon[i] = clon[i-1];
01910 for (i = 0; i < pact; i++) {
01911 snprintf (key, 64, "map_pa_%d_value", i);
01912 map_pa[i] = params_get_double (params, key) * raddeg;
01913 cos_phi[i] = cos (map_pa[i]);
01914 sin_phi[i] = sin (map_pa[i]);
01915 }
01916 for (; i < rgnct; i++) {
01917 map_pa[i] = map_pa[i-1];
01918 cos_phi[i] = cos_phi[i-1];
01919 sin_phi[i] = sin_phi[i-1];
01920 }
01921 if (setmais) {
01922 for (i = 0; i < rgnct; i++) {
01923 snprintf (key, 64, "mai_%d_value", i);
01924 mai[i] = params_get_float (params, key);
01925 }
01926 }
01927 for (rgn = 0; rgn < rgnct; rgn++) {
01928 double sin_lat = sin (clat[rgn]);
01929 sin_lat *= sin_lat;
01930 delta_rot[rgn] = a0 + sin_lat * (a2 + a4 * sin_lat);
01931 }
01932 log = (FILE **)malloc (rgnct * sizeof (FILE *));
01933
01934
01935 orecs = (DRMS_Record_t **)malloc (rgnct * sizeof (DRMS_Record_t *));
01936 if (need_stats) {
01937 minval = (double *)malloc (rgnct * sizeof (double));
01938 maxval = (double *)malloc (rgnct * sizeof (double));
01939 datamean = (double *)calloc (rgnct, sizeof (double));
01940 datarms = (double *)calloc (rgnct, sizeof (double));
01941 dataskew = (double *)calloc (rgnct, sizeof (double));
01942 datakurt = (double *)calloc (rgnct, sizeof (double));
01943 datavalid = (long long *)calloc (rgnct, sizeof (long long));
01944 origvalid = (long long *)calloc (rgnct, sizeof (long long));
01945 }
01946 maps = (float *)malloc (pixct * rgnct * sizeof (float));
01947 last = (float *)malloc (pixct * rgnct * sizeof (float));
01948
01949 maplat = (double *)malloc (pixct * rgnct * sizeof (double));
01950 maplon = (double *)malloc (pixct * rgnct * sizeof (double));
01951 if (no_merid_v) {
01952 map_coslat = maplat;
01953 map_sinlat = (double *)malloc (pixct * rgnct * sizeof (double));
01954 }
01955 offsun = (unsigned char *)malloc (pixct * rgnct * sizeof (char));
01956 latavg = (double *)calloc (rgnct, sizeof (double));
01957 mnlatct = (int *)calloc (rgnct, sizeof (int));
01958 if (need_limb_dist) {
01959 cmaplat = (double *)malloc (rgnct * sizeof (double));
01960 cmaplon = (double *)malloc (rgnct * sizeof (double));
01961 ctrmu = (double *)malloc (rgnct * sizeof (double));
01962 ctrx = (double *)malloc (rgnct * sizeof (double));
01963 ctry = (double *)malloc (rgnct * sizeof (double));
01964 muavg = (double *)calloc (rgnct, sizeof (double));
01965 muct = (int *)calloc (rgnct, sizeof (int));
01966 xavg = (double *)calloc (rgnct, sizeof (double));
01967 yavg = (double *)calloc (rgnct, sizeof (double));
01968 ctroffsun = (unsigned char *)malloc (rgnct * sizeof (char));
01969 }
01970
01971 n = 0;
01972 for (rgn = 0; rgn < rgnct; rgn++) {
01973 double xrot, yrot;
01974 for (row=0, y=y0; row < map_rows; row++, y +=ystp) {
01975 for (col=0, x=x0; col < map_cols; col++, x +=xstp, n++) {
01976 xrot = x * cos_phi[rgn] - y * sin_phi[rgn];
01977 yrot = y * cos_phi[rgn] + x * sin_phi[rgn];
01978 offsun[n] = plane2sphere (xrot, yrot, clat[rgn], clon[rgn], &lat, &lon,
01979 proj);
01980 maplat[n] = lat;
01981 maplon[n] = lon;
01982 if (no_merid_v) {
01983 map_coslat[n] = cos (lat);
01984 map_sinlat[n] = sin (lat);
01985 }
01986 if (!offsun[n]) {
01987 mnlatct[rgn]++;
01988 latavg[rgn] += lat;
01989 }
01990 }
01991 }
01992 if (mnlatct[rgn]) latavg[rgn] /= mnlatct[rgn];
01993 if (need_stats) {
01994 minval[rgn] = 1./ 0.;
01995 maxval[rgn] = -minval[rgn];
01996 datavalid[rgn] = nntot;
01997 origvalid[rgn] = nntot;
01998 }
01999 if (need_limb_dist) {
02000 ctroffsun[rgn] = plane2sphere (0.0, 0.0, clat[rgn], clon[rgn], &lat, &lon,
02001 proj);
02002 cmaplat[rgn] = lat;
02003 cmaplon[rgn] = lon;
02004 }
02005 }
02006
02007 zero = (float *)calloc (pixct, sizeof (float));
02008 map_array = drms_array_create (DRMS_TYPE_FLOAT, 3, axes, (void *)zero, &status);
02009 map_array->bscale = bscale;
02010 map_array->bzero = bzero;
02011
02012 dxy = 0;
02013 if (strcmp (bckgn, "Not Specified")) {
02014
02015 if (bckgds = drms_open_records (drms_env, bckgn, &status)) {
02016 if (bckgds->n == 1) {
02017 DRMS_Record_t *bckrec = bckgds->records[0];
02018 segct = drms_record_numsegments (bckrec);
02019 if (segct) {
02020 for (segnum = 0; segnum < segct; segnum++) {
02021 DRMS_Segment_t *recseg = drms_segment_lookupnum (bckrec, segnum);
02022 if (recseg) {
02023 bckg_array = drms_segment_read (recseg, DRMS_TYPE_FLOAT, &status);
02024 if (bckg_array) {
02025 if (bckg_array->naxis) dxy = 1;
02026 for (n = 0; n < bckg_array->naxis; n++)
02027 dxy *= bckg_array->axis[n];
02028 bck = (float *)bckg_array->data;
02029 if (segct > 1)
02030 fprintf (stderr, "using background segment %d (%s)\n",
02031 segnum, recseg->info->name);
02032 break;
02033 } else continue;
02034 }
02035 }
02036 if (segnum >= segct) {
02037 fprintf (stderr,
02038 "Error: unable to open background record segment \"%s\"\n", bckgn);
02039 drms_close_records (bckgds, DRMS_FREE_RECORD);
02040 drms_close_records (ids, DRMS_FREE_RECORD);
02041 drms_close_records (ods, DRMS_FREE_RECORD);
02042 return 1;
02043 }
02044 } else {
02045 fprintf (stderr, "Warning: background data record %s\n", bckgn);
02046 fprintf (stderr, " contains %d segments; ignored\n", segct);
02047 }
02048 } else {
02049 fprintf (stderr, "Warning: background data set %s\n", bckgn);
02050 fprintf (stderr, " contains %d records; ignored\n", bckgds->n);
02051 }
02052 drms_close_records (bckgds, DRMS_FREE_RECORD);
02053 } else {
02054 fprintf (stderr, "Warning: unable to open background data set \"%s\"\n",
02055 bckgn);
02056 fprintf (stderr, " drms_open_records() returned %d; ignored\n",
02057 status);
02058 }
02059 }
02060
02061 rejects = 0;
02062 if (strcmp (rejectfile, "Not Specified")) {
02063 FILE *rejectfp = fopen (rejectfile, "r");
02064 if (rejectfp) rejects = read_reject_list (rejectfp, &reject_list);
02065 else fprintf (stderr,
02066 "Warning: could not open rejection list %s; ignored\n", rejectfile);
02067 }
02068
02069 found = 0;
02070 for (rgn = 0; rgn < rgnct; rgn++) {
02071 orec = orecs[rgn] = drms_recordset_getrec (ods, rgn);
02072 if (!orec) {
02073 fprintf (stderr, "Error accessing record %d in series %s\n", rgn, outser);
02074 drms_close_records (ids, DRMS_FREE_RECORD);
02075 drms_close_records (ods, DRMS_FREE_RECORD);
02076 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02077 map_sinlat, offsun, orecs, log, reject_list);
02078 if (bck) free (bck);
02079 return 1;
02080 }
02081 if (verbose_logs) {
02082 logseg = drms_segment_lookup (orec, "Log");
02083 if (logseg) drms_segment_filename (logseg, logfilename);
02084 log[rgn] = fopen (logfilename, "w");
02085 if (!log[rgn]) {
02086 fprintf (stderr, "Error: unable to open log file \"%s\"\n", logfilename);
02087 drms_close_records (ids, DRMS_FREE_RECORD);
02088 drms_close_records (ods, DRMS_FREE_RECORD);
02089 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02090 map_sinlat, offsun, orecs, log, reject_list);
02091 if (bck) free (bck);
02092 return 1;
02093 }
02094 }
02095
02096 oseg = drms_segment_lookup (orec, osegname);
02097 if (oseg->info->scope == DRMS_VARDIM) {
02098 oseg->axis[0] = map_cols;
02099 oseg->axis[1] = map_rows;
02100 oseg->axis[2] = length;
02101 }
02102 if (bscale_override) oseg->bscale = bscale;
02103 if (bzero_override) oseg->bzero = bzero;
02104 }
02105
02106 valid = 0;
02107 ttrgt = tstrt;
02108 or = 0;
02109 badpkey = badqual = badfill = badtime = badcv = blacklist = 0;
02110 if (verbose) fflush (stdout);
02111 for (nr = 0; nr < recct; nr++) {
02112 irec = ids->records[nr];
02113 tobs = drms_getkey_time (irec, tobs_key, &status);
02114 if (time_is_invalid (tobs)) {
02115
02116 badpkey++;
02117 continue;
02118 }
02119 quality = drms_getkey_int (irec, qual_key, &status);
02120 if (status) qualcheck = 0;
02121 else if (quality & qmask) {
02122
02123 badqual++;
02124 continue;
02125 } else qualcheck = 1;
02126 blankvals = drms_getkey_int (irec, "MISSVALS", &status);
02127 if ((max_miss >= 0) && (blankvals > max_miss) && !status) {
02128
02129 badfill++;
02130 continue;
02131 }
02132 if (tobs == tlast) {
02133
02134 badtime++;
02135 continue;
02136 }
02137
02138 img_lon = raddeg * drms_getkey_double (irec, clon_key, &status);
02139 img_lat = raddeg * drms_getkey_double (irec, clat_key, &status);
02140
02141 if (rejects) {
02142 int idrec = drms_getkey_int (irec, "T_REC_index", &status);
02143 int match = 0;
02144 if (status) {
02145 fprintf (stderr, "Warning: \"T_REC_index\" keyword not found\n");
02146 fprintf (stderr, " up to %d bad images could be processed\n",
02147 rejects);
02148 rejects = 0;
02149 }
02150 for (n = 0; n < rejects; n++) {
02151 if (idrec == reject_list[n]) {
02152 match = 1;
02153 break;
02154 }
02155 }
02156 if (match) {
02157 blacklist++;
02158 continue;
02159 }
02160 }
02161
02162 calver = drms_getkey_longlong (irec, calverkey, &status);
02163 if (filt_on_calver) {
02164 if (status) {
02165
02166 badcv++;
02167 continue;
02168 }
02169 for (cvct = 0; cvct < cvgoct; cvct++)
02170 if (calver == cvgolist[cvct]) break;
02171 if (cvct >= cvgoct) {
02172 badcv++;
02173 continue;
02174 }
02175 for (cvct = 0; cvct < cvnoct; cvct++) {
02176 if (calver == cvnolist[cvct]) {
02177 badcv++;
02178 continue;
02179 }
02180 }
02181 for (cvct = 0; cvct < cvnoct; cvct++) {
02182 if (calver == cvnolist[cvct]) {
02183 badcv++;
02184 continue;
02185 }
02186 }
02187 }
02188 for (cvct = 0; cvct < cvused; cvct++) {
02189 if (calver == cvlist[cvct]) {
02190 cvfound[cvct]++;
02191 break;
02192 }
02193 }
02194 if (cvct == cvused) {
02195 if (cvused < cvmaxct) {
02196 cvlist[cvct] = calver;
02197 cvfound[cvct] = 1;
02198 cvused++;
02199 }
02200 }
02201
02202 status = solar_image_info (irec, &img_xscl, &img_yscl, &img_xc, &img_yc,
02203 &img_radius, rsun_key, apsd_key, &img_pa, &ellipse_e, &ellipse_pa,
02204 &x_invrt, &y_invrt, &need_ephem, 0);
02205 if (status & NO_SEMIDIAMETER) {
02206 int keystat = 0;
02207 double dsun_obs = drms_getkey_double (irec, dsun_key, &keystat);
02208 if (keystat) {
02209 fprintf (stderr, "Error: one or more essential keywords or values missing; skipped\n");
02210 fprintf (stderr, "solar_image_info() returned %08x\n", status);
02211 continue;
02212 }
02213
02214 img_radius = asin (RSUNM / dsun_obs);
02215 img_radius *= 3600.0 * degrad;
02216 img_radius /= (img_xscl <= img_yscl) ? img_xscl : img_yscl;
02217 status &= ~NO_SEMIDIAMETER;
02218 }
02219 if (status) {
02220 fprintf (stderr, "Error: one or more essential keywords or values missing; skipped\n");
02221 fprintf (stderr, "solar_image_info() returned %08x\n", status);
02222 continue;
02223 }
02224 if (MDI_correct) {
02225 mtrack_MDI_correct_imgctr (&img_xc, &img_yc, img_radius);
02226 mtrack_MDI_correct_pa (&img_pa);
02227 }
02228 if (ut_times) sprint_time (tbuf, tobs, "UTC", 0);
02229 else sprint_time (tbuf, tobs, "TAI", 0);
02230 tbuf[strlen (tbuf) - 4] = '\0';
02231 record_segment = drms_segment_lookupnum (irec, segnum);
02232 if (!no_proc) {
02233
02234 data_array = drms_segment_read (record_segment, DRMS_TYPE_FLOAT, &status);
02235 if (status) {
02236 if (ut_times) sprint_time (tbuf, tobs, "UTC", 0);
02237 else sprint_time (tbuf, tobs, "TAI", 0);
02238 fprintf (stderr, "Error: segment read failed for record %s\n", tbuf);
02239 if (qualcheck) {
02240 if (data_array) drms_free_array (data_array);
02241 drms_free_array (map_array);
02242 drms_close_records (ods, DRMS_FREE_RECORD);
02243 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02244 map_sinlat, offsun, orecs, log, reject_list);
02245 return 1;
02246 } else continue;
02247 }
02248 data = (float *)data_array->data;
02249
02250 if (dxy) {
02251 for (nn = 0; nn < dxy; nn++) {
02252 if (isnan (data[nn])) continue;
02253 data[nn] -= bck[nn];
02254 }
02255 }
02256 img_xc -= 0.5 * (data_array->axis[0] - 1);
02257 img_yc -= 0.5 * (data_array->axis[1] - 1);
02258
02259 if (!extrapolate)
02260 memcpy (last, maps, rgnct * pixct * sizeof (float));
02261
02262 perform_mappings (data_array, maps, delta_rot, rgnct, maplat,
02263 maplon, map_coslat, map_sinlat, pixct, tobs - tmid, offsun,
02264 img_lat, img_lon, img_xc, img_yc, a0, a2, a4, merid_v, img_radius,
02265 img_pa, ellipse_e, ellipse_pa, x_invrt, y_invrt, intrpopt,
02266 MDI_correct_distort);
02267 if (need_limb_dist) {
02268 calc_limb_distance (delta_rot, rgnct, cmaplat, cmaplon, tobs - tmid,
02269 merid_v, ctroffsun, img_lat, img_lon, ctrmu, ctrx, ctry);
02270 for (rgn = 0; rgn < rgnct; rgn++) {
02271 if (isfinite (ctrmu[rgn])) {
02272 muct[rgn]++;
02273 muavg[rgn] += ctrmu[rgn];
02274 xavg[rgn] += ctrx[rgn];
02275 yavg[rgn] += ctry[rgn];
02276 }
02277 }
02278 }
02279 if (need_stats) {
02280 double v, v2;
02281 if (data_scaled) {
02282 for (rgn = 0; rgn < rgnct; rgn++) {
02283 nn = rgn * pixct;
02284 for (n = 0; n < pixct; n++) {
02285 v = maps[n + nn];
02286 if (!isfinite (v)) {
02287 origvalid[rgn]--;
02288 datavalid[rgn]--;
02289 } else if (v < min_scaled || v > max_scaled) {
02290 datavalid[rgn]--;
02291 } else {
02292 if (v > maxval[rgn]) maxval[rgn] = v;
02293 if (v < minval[rgn]) minval[rgn] = v;
02294 datamean[rgn] += v;
02295 v2 = v * v;
02296 datarms[rgn] += v2;
02297 dataskew[rgn] += v2 * v;
02298 datakurt[rgn] += v2 * v2;
02299 }
02300 }
02301 }
02302 } else {
02303 for (rgn = 0; rgn < rgnct; rgn++) {
02304 nn = rgn * pixct;
02305 for (n = 0; n < pixct; n++) {
02306 v = maps[n + nn];
02307 if (!isfinite (v)) {
02308 origvalid[rgn]--;
02309 datavalid[rgn]--;
02310 } else {
02311 if (v > maxval[rgn]) maxval[rgn] = v;
02312 if (v < minval[rgn]) minval[rgn] = v;
02313 datamean[rgn] += v;
02314 v2 = v * v;
02315 datarms[rgn] += v2;
02316 dataskew[rgn] += v2 * v;
02317 datakurt[rgn] += v2 * v2;
02318 }
02319 }
02320 }
02321 }
02322 }
02323 }
02324
02325 if (extrapolate) {
02326 int ntot = rgnct * pixct;
02327 int fillunset = 1;
02328 float *val = (float *)malloc (ntot * sizeof (float));
02329
02330 while (ttrgt < tobs) {
02331 if (fillopt == FILL_BY_INTERP) {
02332 if (fillunset)
02333 for (n = 0; n < ntot; n++) val[n] = maps[n];
02334 fillunset = 0;
02335 if (verbose) printf ("step %d extrapolated from image %s\n", or, tbuf);
02336 } else if (fillopt == FILL_WITH_ZERO) {
02337 if (fillunset)
02338 for (n = 0; n < ntot; n++) val[n] = (isfinite (maps[n])) ? 0.0 :
02339 missing_val;
02340 fillunset = 0;
02341 if (verbose) printf ("step %d zero filled\n", or);
02342 } else if (fillopt == FILL_WITH_NAN) {
02343 if (fillunset)
02344 for (n = 0; n < ntot; n++) val[n] = missing_val;
02345 fillunset = 0;
02346 if (verbose) printf ("step %d blank filled\n", or);
02347 }
02348 if (verbose && !(or % 64)) fflush (stdout);
02349 if (!no_proc) {
02350 for (rgn = 0; rgn < rgnct; rgn++) {
02351 orec = orecs[rgn];
02352 oseg = drms_segment_lookup (orec, osegname);
02353 memcpy (map_array->data, &val[rgn*pixct], pixct * sizeof (float));
02354 slice_start[2] = slice_end[2] = or;
02355 status = drms_segment_writeslice (oseg, map_array, slice_start,
02356 slice_end, 0);
02357 if (status) {
02358 fprintf (stderr, "Error writing data to record %d in series %s\n",
02359 rgn, outser);
02360 fprintf (stderr, " series may not have appropriate structure\n");
02361 drms_free_array (map_array);
02362 drms_close_records (ods, DRMS_FREE_RECORD);
02363 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02364 map_sinlat, offsun, orecs, log, reject_list);
02365 return 1;
02366 }
02367 if (verbose_logs) fprintf (log[rgn],
02368 "step %d extrapolated from image %s\n", or, tbuf);
02369 }
02370 }
02371 or++;
02372 if (or >= length) {
02373 fprintf (stderr, "Error: reached output length limit\n");
02374 drms_close_records (ids, DRMS_FREE_RECORD);
02375 drms_close_records (ods, DRMS_FREE_RECORD);
02376 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02377 map_sinlat, offsun, orecs, log, reject_list);
02378 if (bck) free (bck);
02379 return 1;
02380 }
02381 ttrgt += tstep;
02382 }
02383 extrapolate = 0;
02384 free (val);
02385 }
02386 if (remove_obsvel) {
02387 double obsvr, obsvw, obsvn, apsd;
02388 if (ephemeris_params (irec, &obsvr, &obsvw, &obsvn)) {
02389 obsvr = obsvw = obsvn = 0.0;
02390 remove_obsvel = 0;
02391 fprintf (stderr, "Warning: expected keywords not found;\n");
02392 fprintf (stderr, " no correction will be made for orbital velocity.\n");
02393 }
02394 apsd = img_xscl * img_radius * raddeg / 3600.0;
02395 adjust_for_observer_velocity (maps, rgnct, clat, clon, pixct,
02396 img_lat, img_lon, obsvr, obsvw, obsvn, apsd, 0);
02397 }
02398
02399 if (remove_rotation) adjust_for_solar_rotation (maps, rgnct, clat, clon,
02400 pixct, img_lat, img_lon);
02401
02402 if (ttrgt < tobs) {
02403
02404
02405 double f, g;
02406 int ntot = rgnct * pixct;
02407 float *val = (float *)malloc (ntot * sizeof (float));
02408 char *skip = (char *)malloc (ntot * sizeof (char));
02409
02410 for (n = 0; n < ntot; n++) {
02411 skip[n] = (isnan (last[n]) || isnan (maps[n]));
02412 val[n] = missing_val;
02413 }
02414 while (ttrgt < tobs) {
02415 if (no_proc) {
02416 if (verbose) {
02417 if (fillopt == FILL_BY_INTERP || fabs (ttrgt - tlast) <= tstep) {
02418 printf ("step %d not interpolated from images %s and %s\n", or, ptbuf,
02419 tbuf);
02420 } else if (fillopt == FILL_WITH_ZERO)
02421 printf ("step %d zero filled\n", or);
02422 else if (fillopt == FILL_WITH_NAN)
02423 printf ("step %d blank filled\n", or);
02424 if (!(or % 64)) fflush (stdout);
02425 }
02426 } else {
02427 if (fillopt == FILL_BY_INTERP || fabs (ttrgt - tlast) <= tstep) {
02428 f = (ttrgt - tlast) / (tobs - tlast);
02429 g = 1.0 - f;
02430 for (n = 0; n < ntot; n++)
02431 if (!skip[n]) val[n] = g * last[n] + f * maps[n];
02432 if (verbose) {
02433 printf ("step %d interpolated from images %s and %s\n", or, ptbuf,
02434 tbuf);
02435 if (!(or % 64)) fflush (stdout);
02436 }
02437 } else if (fillopt == FILL_WITH_ZERO) {
02438 for (n = 0; n < ntot; n++) if (isfinite (val[n])) val[n] = 0.0;
02439 if (verbose) printf ("step %d zero filled\n", or);
02440 } else if (fillopt == FILL_WITH_NAN) {
02441 for (n = 0; n < ntot; n++) val[n] = missing_val;
02442 if (verbose) printf ("step %d blank filled\n", or);
02443 }
02444 for (rgn = 0; rgn < rgnct; rgn++) {
02445 orec = orecs[rgn];
02446 oseg = drms_segment_lookup (orec, osegname);
02447 memcpy (map_array->data, &val[rgn*pixct], pixct * sizeof (float));
02448 slice_start[2] = slice_end[2] = or;
02449 status = drms_segment_writeslice (oseg, map_array, slice_start,
02450 slice_end, 0);
02451 if (status) {
02452 fprintf (stderr, "Error writing data to record %d in series %s\n",
02453 rgn, outser);
02454 fprintf (stderr,
02455 " series may not have appropriate structure\n");
02456 drms_free_array (map_array);
02457 drms_close_records (ods, DRMS_FREE_RECORD);
02458 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02459 map_sinlat, offsun, orecs, log, reject_list);
02460 return 1;
02461 }
02462 if (verbose_logs) fprintf (log[rgn],
02463 "step %d interpolated from images %s and %s\n", or, ptbuf, tbuf);
02464 }
02465 }
02466 or++;
02467 if (or >= length) {
02468 if (nr < recct - 1) fprintf (stderr,
02469 "Warning: reached output limit before last input record processed\n");
02470 ttrgt = tstop;
02471 }
02472 ttrgt += tstep;
02473 }
02474 free (val);
02475 free (skip);
02476 }
02477
02478 if (ttrgt == tobs) {
02479 if (no_proc) {
02480 if (verbose) {
02481 printf ("step %d not mapped from image %s [#%lld]\n", or, tbuf,
02482 irec->recnum);
02483 if (!(or % 64)) fflush (stdout);
02484 }
02485 } else {
02486 if (verbose) {
02487 printf ("step %d mapped from image %s [#%lld]\n", or, tbuf,
02488 irec->recnum);
02489 if (!(or % 64)) fflush (stdout);
02490 }
02491 for (rgn = 0; rgn < rgnct; rgn++) {
02492
02493
02494
02495 orec = orecs[rgn];
02496 oseg = drms_segment_lookup (orec, osegname);
02497 memcpy (map_array->data, &maps[rgn*pixct], pixct * sizeof (float));
02498 slice_start[2] = slice_end[2] = or;
02499 status = drms_segment_writeslice (oseg, map_array, slice_start,
02500 slice_end, 0);
02501 if (status) {
02502 fprintf (stderr, "Error writing data to record %d in series %s\n",
02503 rgn, outser);
02504 fprintf (stderr, " series may not have appropriate structure\n");
02505 drms_free_array (map_array);
02506 drms_close_records (ods, DRMS_FREE_RECORD);
02507 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02508 map_sinlat, offsun, orecs, log, reject_list);
02509 return 1;
02510 }
02511 if (verbose_logs)
02512 fprintf (log[rgn], "step %d mapped from image %s [#%lld]\n", or,
02513 tbuf, irec->recnum);
02514 }
02515 }
02516 or++;
02517 ttrgt += tstep;
02518 }
02519 tlast = tobs;
02520 strcpy (ptbuf, tbuf);
02521 drms_free_array (data_array);
02522 data_array = NULL;
02523 valid++;
02524 }
02525 if (bck) free (bck);
02526 for (rgn = 0; rgn < rgnct; rgn++) {
02527
02528 int kstat = 0;
02529 int keyct = sizeof (propagate) / sizeof (char *);
02530 orec = orecs[rgn];
02531 kstat += propagate_keys (orec, irec, propagate, keyct);
02532 if (kstat) {
02533 fprintf (stderr, "Error writing key value(s) to record %d in series %s\n",
02534 rgn, outser);
02535 fprintf (stderr, " series may not have appropriate structure\n");
02536 drms_free_array (map_array);
02537 drms_close_records (ids, DRMS_FREE_RECORD);
02538 drms_close_records (ods, DRMS_FREE_RECORD);
02539 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02540 map_sinlat, offsun, orecs, log, reject_list);
02541 return 1;
02542 }
02543 if ((keywd = drms_keyword_lookup (orec, "COMMENT", 1)))
02544 append_args_tokey (orec, "COMMENT");
02545 else if ((keywd = drms_keyword_lookup (orec, "HISTORY", 1)))
02546 append_args_tokey (orec, "HISTORY");
02547 }
02548 drms_close_records (ids, DRMS_FREE_RECORD);
02549
02550 if (!valid) {
02551 fprintf (stderr, "Error: no valid records in input dataset %s\n", input);
02552 if (badpkey) fprintf (stderr,
02553 " %d of %d records rejected for invalid values of %s\n",
02554 badpkey, recct, trec_key);
02555 if (badqual) fprintf (stderr,
02556 " %d of %d records rejected for quality matching %08x\n",
02557 badqual, recct, qmask);
02558 if (badfill) fprintf (stderr,
02559 " %d of %d records rejected for missing values exceeding %d\n",
02560 badfill, recct, max_miss);
02561 if (badtime) fprintf (stderr,
02562 " %d of %d records rejected for duplicate values of %s\n",
02563 badtime, recct, trec_key);
02564 if (badcv) fprintf (stderr,
02565 " %d of %d records rejected for unacceptabel values of %s\n",
02566 badcv, recct, calverkey);
02567 drms_close_records (ods, DRMS_FREE_RECORD);
02568 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02569 map_sinlat, offsun, orecs, log, reject_list);
02570 return 1;
02571 }
02572 if (or < length) {
02573 int fillunset = 1;
02574 int ntot = rgnct * pixct;
02575 float *val = (float *)malloc (ntot * sizeof (float));
02576
02577 while (ttrgt <= tstop && or < length) {
02578 if (fillopt == FILL_BY_INTERP) {
02579 if (fillunset)
02580 for (n = 0; n < ntot; n++) val[n] = last[n];
02581 fillunset = 0;
02582 if (verbose) printf ("step %d extrapolated from image %s\n", or, tbuf);
02583 } else if (fillopt == FILL_WITH_ZERO) {
02584 if (fillunset)
02585 for (n = 0; n < ntot; n++) if (isfinite (val[n])) val[n] = 0.0;
02586 fillunset = 0;
02587 if (verbose) printf ("step %d zero filled\n", or);
02588 } else if (fillopt == FILL_WITH_NAN) {
02589 if (fillunset)
02590 for (n = 0; n < ntot; n++) val[n] = missing_val;
02591 fillunset = 0;
02592 if (verbose) printf ("step %d blank filled\n", or);
02593 }
02594 if (verbose && !(or % 64)) fflush (stdout);
02595 for (rgn = 0; rgn < rgnct; rgn++) {
02596 orec = orecs[rgn];
02597 oseg = drms_segment_lookup (orec, osegname);
02598 memcpy (map_array->data, &val[rgn*pixct], pixct * sizeof (float));
02599 slice_start[2] = slice_end[2] = or;
02600 status = drms_segment_writeslice (oseg, map_array, slice_start,
02601 slice_end, 0);
02602 if (status) {
02603 fprintf (stderr, "Error writing data to record %d in series %s\n",
02604 rgn, outser);
02605 fprintf (stderr, " series may not have appropriate structure\n");
02606 drms_free_array (map_array);
02607 drms_close_records (ods, DRMS_FREE_RECORD);
02608 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02609 map_sinlat, offsun, orecs, log, reject_list);
02610 return 1;
02611 }
02612 if (verbose_logs) {
02613 if (fillopt == FILL_BY_INTERP)
02614 fprintf (log[rgn], "step %d extrapolated from image %s\n", or, tbuf);
02615 else if (fillopt == FILL_WITH_ZERO)
02616 fprintf (log[rgn], "step %d zero filled\n", or);
02617 else if (fillopt == FILL_WITH_NAN)
02618 fprintf (log[rgn], "step %d blank filled\n", or);
02619 }
02620 }
02621 ttrgt += tstep;
02622 or++;
02623 }
02624 free (val);
02625 }
02626
02627 coverage = (double)valid / (double)length;
02628 if (verbose) {
02629 printf ("End tracking: %d of %d possible input records accepted\n",
02630 valid, recct);
02631 printf (" effective coverage = %.3f\n", coverage);
02632 if (badpkey) printf
02633 (" %d input records rejected for invalid values of %s\n",
02634 badpkey, trec_key);
02635 if (badqual) printf
02636 (" %d input records rejected for quality matching %08x\n",
02637 badqual, qmask);
02638 if (blacklist) printf
02639 (" %d input records rejected from rejection list\n", blacklist);
02640 if (badfill) printf
02641 (" %d input records rejected for missing values exceeding %d\n",
02642 badfill, max_miss);
02643 if (badtime) printf
02644 (" %d input records rejected for duplicate values of %s\n",
02645 badtime, trec_key);
02646 if (badcv) printf
02647 (" %d input records rejected for unacceptable values of %s\n",
02648 badcv, calverkey);
02649 }
02650
02651 if (data_scaled) {
02652 long long totor = 0;
02653 int orrgn = 0;
02654 for (rgn = 0; rgn < rgnct; rgn++) {
02655 totor += origvalid[rgn] - datavalid[rgn];
02656 orrgn++;
02657 }
02658 if (totor) {
02659 fprintf (stderr,
02660 "Warning: %lld valid values scaled out of representable range in %d records\n",
02661 totor, orrgn);
02662 for (rgn = 0; rgn < rgnct; rgn++) {
02663 if (origvalid[rgn] != datavalid[rgn]) {
02664 if (verbose_logs) fprintf (log[rgn],
02665 " %lld valid values scaled out of representable range\n",
02666 origvalid[rgn] - datavalid[rgn]);
02667 if (verbose)
02668 printf (" %lld valid values scaled out of representable range in region #%d\n",
02669 origvalid[rgn] - datavalid[rgn], rgn);
02670 }
02671 }
02672 }
02673 }
02674
02675 if (tmid_cl <= 0.0) {
02676 tmid_cl += 360.0;
02677 tmid_cr++;
02678 }
02679 orec = orecs[0];
02680 if ((keywd = drms_keyword_lookup (orec, "CMLon", 1))) {
02681 if (keywd->info->recscope > 1) {
02682 double kstep;
02683 sprintf (key, "CMLon_step");
02684 kstep = fabs (drms_getkey_double (orec, key, &status));
02685 if (tmid_cl <= 0.5 * kstep) {
02686 tmid_cl += 360.0;
02687 tmid_cr++;
02688 }
02689 }
02690 }
02691 for (rgn = 0; rgn < rgnct; rgn++) {
02692
02693 int kstat = 0;
02694 orec = orecs[rgn];
02695 kstat += check_and_set_key_str (orec, "WCSNAME", "Carrington Heliographic/Time");
02696 kstat += check_and_set_key_int (orec, "WCSAXES", 3);
02697 snprintf (key, 64, "CRLN-%s", wcscode[proj]);
02698 kstat += check_and_set_key_str (orec, "CTYPE1", key);
02699 snprintf (key, 64, "CRLT-%s", wcscode[proj]);
02700 kstat += check_and_set_key_str (orec, "CTYPE2", key);
02701 kstat += check_and_set_key_str (orec, "CTYPE3", "TIME");
02702 kstat += check_and_set_key_str (orec, "CUNIT1", "deg");
02703 kstat += check_and_set_key_str (orec, "CUNIT2", "deg");
02704 kstat += check_and_set_key_str (orec, "CUNIT3", "s");
02705 kstat += check_and_set_key_float (orec, "CRPIX1", 0.5 * map_cols + 0.5);
02706 kstat += check_and_set_key_float (orec, "CRPIX2", 0.5 * map_rows + 0.5);
02707 kstat += check_and_set_key_float (orec, "CRPIX3", 0.5 * length + 0.5);
02708 kstat += check_and_set_key_float (orec, "CRVAL1", clon[rgn] * degrad);
02709 kstat += check_and_set_key_float (orec, "CRVAL2", clat[rgn] * degrad);
02710 kstat += check_and_set_key_double(orec, "CRVAL3", tmid);
02711 kstat += check_and_set_key_float (orec, "CDELT1", map_scale);
02712 kstat += check_and_set_key_float (orec, "CDELT2", map_scale);
02713 kstat += check_and_set_key_float (orec, "CDELT3", tstep);
02714 kstat += check_and_set_key_float (orec, "LonHG", clon[rgn] * degrad);
02715 kstat += check_and_set_key_float (orec, "LatHG", clat[rgn] * degrad);
02716 kstat += check_and_set_key_str (orec, "MapProj", mapname[proj]);
02717 kstat += check_and_set_key_str (orec, "Interp", interpname[intrpopt]);
02718 kstat += check_and_set_key_time (orec, "MidTime", tmid);
02719 snprintf (ctime_str, 16, ctimefmt, tmid_cr, tmid_cl);
02720 kstat += check_and_set_key_str (orec, "CarrTime", ctime_str);
02721 kstat += check_and_set_key_int (orec, "CarrRot", tmid_cr);
02722 kstat += check_and_set_key_float (orec, "CMLon", tmid_cl);
02723 carr_lon = (360.0 * tmid_cr) + 360.0 - tmid_cl;
02724 kstat += check_and_set_key_double(orec, "CarrLon", carr_lon);
02725 lon_cm = clon[rgn] * degrad - tmid_cl;
02726 while (lon_cm < -180.0) lon_cm += 360.0;
02727 while (lon_cm > 180.0) lon_cm -= 360.0;
02728 kstat += check_and_set_key_float (orec, "LonCM", lon_cm);
02729 kstat += check_and_set_key_time (orec, "T_START", tstrt);
02730 kstat += check_and_set_key_time (orec, "T_STOP", tstop);
02731 kstat += check_and_set_key_float (orec, "LonSpan", lon_span);
02732 kstat += check_and_set_key_float (orec, "Coverage", coverage);
02733 kstat += check_and_set_key_float (orec, "ZonalTrk", delta_rot[rgn] * 1.0e6);
02734 kstat += check_and_set_key_float (orec, "ZonalVel",
02735 (delta_rot[rgn] + CARR_RATE * 1.0e-6) * RSUNM * cos (clat[rgn]));
02736 kstat += check_and_set_key_float (orec, "LonDrift",
02737 delta_rot[rgn] * degrad * length * tstep);
02738 kstat += check_and_set_key_float (orec, "MeridTrk", merid_v * 1.0e6);
02739 kstat += check_and_set_key_float (orec, "MeridVel", merid_v * RSUNM);
02740 kstat += check_and_set_key_float (orec, "LatDrift",
02741 merid_v * degrad * length * tstep);
02742 kstat += check_and_set_key_str (orec, "Module", module_ident);
02743 kstat += check_and_set_key_str (orec, "BLD_VERS", jsoc_version);
02744 kstat += check_and_set_key_str (orec, "Source", source_series);
02745 kstat += check_and_set_key_str (orec, "Input", input);
02746 kstat += check_and_set_key_time (orec, "Created", CURRENT_SYSTEM_TIME);
02747 if (strcmp (bckgn, "Not Specified"))
02748 kstat += check_and_set_key_str (orec, "Backgrnd", bckgn);
02749 if (strcmp (rejectfile, "Not Specified"))
02750 kstat += check_and_set_key_str (orec, "RejectList", rejectfile);
02751 kstat += check_and_set_key_float (orec, "MapScale", map_scale);
02752 kstat += check_and_set_key_float (orec, "Cadence", tstep);
02753 kstat += check_and_set_key_float (orec, "Duration", length * tstep);
02754 kstat += check_and_set_key_float (orec, "Width", map_cols * map_scale);
02755 kstat += check_and_set_key_float (orec, "Height", map_rows * map_scale);
02756 kstat += check_and_set_key_float (orec, "Size", sqrt (map_rows * map_cols) * map_scale);
02757 kstat += check_and_set_key_float (orec, "Map_PA", map_pa[rgn] / raddeg);
02758 kstat += check_and_set_key_float (orec, "RSunRef", 1.0e-6 * RSUNM);
02759 if (setmais && isfinite (mai[rgn]))
02760 kstat += check_and_set_key_float (orec, "MAI", mai[rgn]);
02761 if (bscale_override) {
02762 sprintf (key, "%s_bscale", osegname);
02763 kstat += check_and_set_key_double (orec, key, bscale);
02764 }
02765 if (bzero_override) {
02766 sprintf (key, "%s_bzero", osegname);
02767 kstat += check_and_set_key_double (orec, key, bzero);
02768 }
02769 if (MDI_correct)
02770 kstat += check_and_set_key_float (orec, "MDI_PA_Corr", MDI_IMG_SOHO_PA);
02771 if (pkeyval = create_prime_key (orec))
02772 kstat += check_and_set_key_str (orec, "PrimeKeyString", pkeyval);
02773 if (strcmp (identifier, "Not Specified"))
02774 kstat += check_and_set_key_str (orec, "Ident", identifier);
02775 if (need_stats) kstat += set_stat_keys (orec, nntot, datavalid[rgn],
02776 minval[rgn], maxval[rgn], datamean[rgn], datarms[rgn], dataskew[rgn],
02777 datakurt[rgn]);
02778 if (need_limb_dist) {
02779 if (muct[rgn]) {
02780 kstat +=
02781 check_and_set_key_float (orec, "MeanMU", muavg[rgn] / muct[rgn]);
02782 xavg[rgn] /= muct[rgn];
02783 yavg[rgn] /= muct[rgn];
02784 kstat += check_and_set_key_float (orec, "MeanPA",
02785 degrad * atan2 (xavg[rgn], yavg[rgn]));
02786 }
02787 }
02788 if (mnlatct[rgn])
02789 kstat += check_and_set_key_float (orec, "MeanLat", latavg[rgn] * degrad);
02790 if (kstat) {
02791 fprintf (stderr, "Error writing key value(s) to record %d in series %s\n",
02792 rgn, outser);
02793 fprintf (stderr, " series may not have appropriate structure\n");
02794 drms_free_array (map_array);
02795 drms_close_records (ods, DRMS_FREE_RECORD);
02796 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon,
02797 map_sinlat, offsun, orecs, log, reject_list);
02798 return 1;
02799 }
02800 if (verbose_logs) {
02801 if (badqual) fprintf (log[rgn],
02802 " %d input records rejected for quality matching %08x\n",
02803 badqual, qmask);
02804 if (blacklist) fprintf (log[rgn],
02805 " %d input records rejected from rejection list\n", blacklist);
02806 if (badfill) fprintf (log[rgn],
02807 " %d of %d records rejected for missing values exceeding %d\n",
02808 badfill, recct, max_miss);
02809 if (badtime) fprintf (log[rgn],
02810 " %d of %d records rejected for duplicate values of %s\n",
02811 badtime, recct, trec_key);
02812 if (badcv) {
02813 fprintf (log[rgn],
02814 " %d input records rejected for calib version matching %016llx\n",
02815 badcv, cvreject);
02816 fprintf (log[rgn],
02817 " or failing to match %016llx\n", cvaccept);
02818 }
02819 fprintf (log[rgn], "%s values used:", calverkey);
02820 for (cvct = 0; cvct < cvused; cvct++) {
02821 if (cvct) fprintf (log[rgn], ",");
02822 fprintf (log[rgn], " %016llx (%d)", cvlist[cvct], cvfound[cvct]);
02823 }
02824 fprintf (log[rgn], "\n");
02825 fclose (log[rgn]);
02826 }
02827 }
02828 drms_close_records (ods, dispose);
02829 drms_free_array (map_array);
02830 free_all (clat, clon, mai, delta_rot, maps, last, maplat, maplon, map_sinlat,
02831 offsun, orecs, log, reject_list);
02832 return 0;
02833 }
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995