00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <jsoc_main.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <math.h>
00028 #include <sys/time.h>
00029 #include <sys/resource.h>
00030 #include "set_statistics.c"
00031
00032
00033 #include "heliographic_coords.c"
00034
00035
00036 #include "polar_remap.c"
00037
00038
00039 #include "fitimage.c"
00040
00041
00042
00043
00044 #define IMGDIM (600)
00045
00046 #define K_TRANS (1.21) // Scaling factor to be multiplied on low-lat field
00047
00048 #define SECSINDAY ((double)86400.0)
00049 #define SECSINYEAR ((double)31536000.)
00050 #define DTOR (M_PI / 180.)
00051 #define TWOPI (2 * M_PI)
00052 #define CARRLONINYEAR (4817.5) // 365./27.2753*360.
00053
00054 #define EPOCH_DIFF ((double)220924792.000)
00055
00056
00057
00058
00059 int currentYear(void)
00060 {
00061 time_t timeval;
00062 struct tm *tp;
00063 time (&timeval);
00064 tp = gmtime(&timeval);
00065 return (tp->tm_year + 1900);
00066 }
00067
00068
00069 int time2Year(TIME t)
00070 {
00071 time_t timeval = (time_t)(t + EPOCH_DIFF);
00072 struct tm *tp = gmtime(&timeval);
00073 return (tp->tm_year + 1900);
00074 }
00075
00076
00077
00078 #ifndef MIN
00079 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
00080 #endif
00081 #ifndef MAX
00082 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
00083 #endif
00084
00085 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
00086 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00087 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s (status=%d)\n", msg, status); return(status);}
00088
00089 #define FREE_ARR(arr) {if (arr) {free(arr);}}
00090
00091
00092
00093
00094 struct option {
00095 int method;
00096 double lat0, latfil, latfil1;
00097 int nflag, sflag;
00098 int order;
00099 int interpOnly;
00100 int amb;
00101 };
00102
00103
00104 struct attrib {
00105
00106 int n_year[2], s_year[2];
00107 int n_extrap, s_extrap;
00108 int sinlat;
00109 int carr;
00110 double carr_time;
00111 double *lons, *lats;
00112 int mapDims[2];
00113 };
00114
00115
00116
00117 char poldb_name[100];
00118
00119
00120
00121
00122 int getInputInfo(DRMS_Record_t *inRec, struct attrib *att, struct option *opt);
00123
00124
00125 int checkPoldb(struct attrib *att, struct option *opt);
00126
00127
00128 int findYearInPoldb(struct attrib *att, int y, TIME t, int ns);
00129
00130
00131 int temp_spat(float *outMap, struct attrib *att, struct option *opt);
00132
00133
00134 int spat_2d(float *outMap, struct attrib *att, struct option *opt);
00135
00136
00137 int interpPoldb(int ns, int rowfil, double *map, struct attrib *att, struct option *opt);
00138
00139
00140 int writeOutput(char *outQuery, DRMS_Record_t *inRec, float **outMap,
00141 struct attrib *att, struct option *opt);
00142
00143
00144
00145
00146
00147
00148
00149
00150 char *module_name = "polcorr";
00151
00152 ModuleArgs_t module_args[] =
00153 {
00154 {ARG_STRING, "in", NULL, "Input data series."},
00155 {ARG_STRING, "out", NULL, "Output data series, name only."},
00156 {ARG_STRING, "poldb", "hmi.polar_db", "Polar field database, name only."},
00157 {ARG_NUME, "method", "TEMP_SPAT", "Correction scheme.", "TEMP_SPAT, SPAT_2D"},
00158 {ARG_DOUBLE, "lat0", "60.", "Start latitude used for fitting."},
00159 {ARG_DOUBLE, "latfil", "75.", "Start latitude for filling in, no lower than 75."},
00160 {ARG_DOUBLE, "latfil1", "62.", "Start latitude for reduced noise."},
00161 {ARG_INT, "nflag", "1", "Filling for north pole: 1 for yes, 0 for no."},
00162 {ARG_INT, "sflag", "1", "Filling for south pole: 1 for yes, 0 for no."},
00163 {ARG_INT, "order", "5", "Highest power of polynomials."},
00164 {ARG_INT, "amb", "2", "disambiguation method, 0 for potential, 1 for random, 2 for radial acute"},
00165 {ARG_FLAG, "i", "", "Force to run in interpolation only mode."},
00166 {ARG_END}
00167 };
00168
00169 int DoIt(void)
00170 {
00171
00172 int status = DRMS_SUCCESS;
00173
00174 struct option opt;
00175 struct attrib att;
00176
00177
00178
00179 char *inQuery = (char *)params_get_str(&cmdparams, "in");
00180 char *outQuery = (char *)params_get_str(&cmdparams, "out");
00181 strcpy(poldb_name, (char *)params_get_str(&cmdparams, "poldb"));
00182
00183 opt.method = params_get_int(&cmdparams, "method");
00184 opt.lat0 = fabs(params_get_double(&cmdparams, "lat0"));
00185 opt.latfil = fabs(params_get_double(&cmdparams, "latfil"));
00186 opt.latfil1 = fabs(params_get_double(&cmdparams, "latfil1"));
00187 opt.nflag = params_get_int(&cmdparams, "nflag");
00188 opt.sflag = params_get_int(&cmdparams, "sflag");
00189 opt.order = params_get_int(&cmdparams, "order");
00190 opt.interpOnly = params_isflagset(&cmdparams, "i");
00191 opt.amb = params_get_int(&cmdparams, "amb");
00192
00193 if (opt.latfil < 75.) opt.latfil = 75.;
00194 if (opt.latfil1 < opt.lat0) opt.latfil1 = opt.lat0;
00195 if (opt.latfil1 > opt.latfil) opt.latfil1 = opt.latfil;
00196
00197
00198
00199
00200
00201 DRMS_RecordSet_t *inRS = drms_open_records(drms_env, inQuery, &status);
00202 if (status || inRS->n == 0) {
00203 DIE("No input data found.\n");
00204 }
00205 int nrecs = inRS->n;
00206
00207
00208
00209 for (int irec = 0; irec < nrecs; irec++) {
00210
00211 printf("Record %d of %d\n", irec + 1, nrecs);
00212
00213
00214
00215 DRMS_Record_t *inRec = inRS->records[irec];
00216
00217
00218
00219
00220 att.lons = NULL; att.lats = NULL;
00221 status = getInputInfo(inRec, &att, &opt);
00222 if (status) {
00223 SHOW("record skipped.\n");
00224 FREE_ARR(att.lons); FREE_ARR(att.lats);
00225 continue;
00226 }
00227
00228 printf(" N_Y0=%d, N_Y1=%d\n S_Y0=%d, S_Y1=%d\n",
00229 att.n_year[0], att.n_year[1], att.s_year[0], att.s_year[1]);
00230 printf(" sinlat=%d, carr=%d, carr_time=%f\n", att.sinlat, att.carr, att.carr_time);
00231
00232
00233
00234 DRMS_Segment_t *inSeg = drms_segment_lookupnum(inRec, 0);
00235 DRMS_Array_t *inArray = NULL;
00236 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00237 if (status) {
00238 SHOW(" Input data not found, record skipped.\n");
00239 if (!inArray) drms_free_array(inArray);
00240 continue;
00241 }
00242
00243 float *map = (float *) inArray->data;
00244 int nx = att.mapDims[0], ny = att.mapDims[1], nxny = nx * ny;
00245
00246
00247
00248 float *outMap = (float *) (malloc(nxny * sizeof(float)));
00249 for (int count = 0; count < nxny; count++) {
00250 outMap[count] = map[count];
00251 }
00252 drms_free_array(inArray);
00253
00254
00255
00256 switch (opt.method) {
00257 default:
00258 case (0):
00259 status = temp_spat(outMap, &att, &opt);
00260 break;
00261 case (1):
00262 status = spat_2d(outMap, &att, &opt);
00263 break;
00264 }
00265
00266 FREE_ARR(att.lons); FREE_ARR(att.lats);
00267 if (status) {
00268 SHOW(" Polar filling error, record skipped.\n");
00269 }
00270
00271
00272
00273
00274
00275 status = writeOutput(outQuery, inRec, &outMap, &att, &opt);
00276 if (status) {
00277 SHOW("record skipped.\n");
00278 FREE_ARR(outMap);
00279 continue;
00280 }
00281
00282 }
00283
00284 drms_close_records(inRS, DRMS_FREE_RECORD);
00285
00286
00287
00288 return DRMS_SUCCESS;
00289
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299 int getInputInfo(DRMS_Record_t *inRec, struct attrib *att, struct option *opt)
00300 {
00301 int status = 0;
00302
00303
00304
00305 char *ctype2 = drms_getkey_string(inRec, "CTYPE2", &status);
00306 if (strcmp(ctype2, "CRLT-CEA") == 0) {
00307 att->sinlat = 1;
00308 } else if (strcmp(ctype2, "CRLT-CAR") == 0) {
00309 att->sinlat = 0;
00310 } else {
00311 SHOW(" CTYPE2 unknown, ");
00312 return 1;
00313 }
00314
00315 att->carr = drms_getkey_int(inRec, "CAR_ROT", &status);
00316 att->carr_time = drms_getkey_double(inRec, "CRVAL1", &status);
00317 if (status) {
00318 SHOW(" CRVAL1 unknown, ");
00319 return status;
00320 }
00321
00322
00323
00324 DRMS_Segment_t *inSeg = drms_segment_lookupnum(inRec, 0);
00325 int xsz = inSeg->axis[0], ysz = inSeg->axis[1];
00326 att->mapDims[0] = xsz;
00327 att->mapDims[1] = ysz;
00328 att->lons = (double *) (malloc(xsz * sizeof(double)));
00329 att->lats = (double *) (malloc(ysz * sizeof(double)));
00330
00331 double cdelt1 = drms_getkey_double(inRec, "CDELT1", &status);
00332 double cdelt2 = drms_getkey_double(inRec, "CDELT2", &status);
00333 double xc = drms_getkey_double(inRec, "CRPIX1", &status);
00334 double yc = drms_getkey_double(inRec, "CRPIX2", &status);
00335 double xref = att->carr_time;
00336 double yref = drms_getkey_double(inRec, "CRVAL2", &status);
00337
00338 for (int col = 0; col < xsz; col++) {
00339 att->lons[col] = (col + 1) * fabs(cdelt1) * DTOR - M_PI;
00340 }
00341 double y;
00342 for (int row = 0; row < ysz; row++) {
00343 y = (row - (yc - 1.)) * (cdelt2) + yref;
00344 att->lats[row] = (att->sinlat) ? asin(y) : (y * DTOR);
00345 }
00346
00347
00348
00349 switch (opt->method) {
00350 default:
00351 case (0):
00352
00353 status = checkPoldb(att, opt);
00354 if (status) {
00355 SHOW(" Polar data not available, ");
00356 return status;
00357 }
00358 break;
00359 case (1):
00360 break;
00361 }
00362
00363
00364
00365 if (opt->interpOnly) {
00366
00367 int n = (opt->nflag && att->n_extrap);
00368 int s = (opt->sflag && att->s_extrap);
00369 if (n || s) {
00370 SHOW(" In interpolation only mode but data base not ready, ");
00371 return 1;
00372 }
00373 }
00374
00375
00376
00377 return 0;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386 int checkPoldb(struct attrib *att, struct option *opt)
00387 {
00388
00389 int status = 0;
00390 att->n_year[0] = att->n_year[1] = 0;
00391 att->s_year[0] = att->s_year[1] = 0;
00392 att->n_extrap = att->s_extrap = 0;
00393
00394 int carr = att->carr;
00395 double lonc = carr * 360. - att->carr_time;
00396 TIME t = HeliographicTime(carr, lonc);
00397 int y = time2Year(t);
00398
00399 printf("y=%d\n", y);
00400
00401
00402
00403 if (opt->nflag) {
00404 if (findYearInPoldb(att, y, t, 0)) return 1;
00405 }
00406
00407
00408
00409 if (opt->sflag) {
00410 if (findYearInPoldb(att, y, t, 1)) return 1;
00411 }
00412
00413
00414
00415 return 0;
00416
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426 int findYearInPoldb(struct attrib *att, int y, TIME t, int ns)
00427 {
00428
00429 int status = 0;
00430 if (ns != 0 && ns != 1) return 1;
00431
00432
00433
00434 int *year = (ns) ? att->s_year : att->n_year;
00435 int *extrap = (ns) ? &(att->s_extrap) : &(att->n_extrap);
00436
00437
00438
00439 char inQuery[100], inQuery_tmp[100];
00440 TIME t0, t1, t2, tt;
00441 int y0, y1, y2, yy;
00442
00443 snprintf(inQuery, 100, "%s[%4d-%4d][%d]", poldb_name, y - 1, y + 1, ns);
00444 DRMS_RecordSet_t *inRS = NULL;
00445 inRS = drms_open_records(drms_env, inQuery, &status);
00446 if (status || inRS->n == 0) {
00447 if (inRS) drms_close_records(inRS, DRMS_FREE_RECORD);
00448 return 1;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 t0 = drms_getkey_time(inRS->records[0], "T_OBS", &status);
00458 y0 = drms_getkey_int(inRS->records[0], "YEAR", &status);
00459 printf("inQuery=%s, n=%d\n", inQuery, inRS->n);
00460 switch (inRS->n) {
00461 case 1:
00462 if (t <= t0) {
00463
00464 snprintf(inQuery_tmp, 100, "%s[%4d][%d]", poldb_name, y0 + 1, ns);
00465 DRMS_RecordSet_t *inRS_tmp = NULL;
00466 inRS_tmp = drms_open_records(drms_env, inQuery_tmp, &status);
00467 if (status || inRS->n != 1) {
00468 if (inRS_tmp) drms_close_records(inRS_tmp, DRMS_FREE_RECORD);
00469 return 1;
00470 }
00471 drms_close_records(inRS_tmp, DRMS_FREE_RECORD);
00472
00473 year[0] = y0; year[1] = y0 + 1; *extrap = -1;
00474 }
00475 if (t > t0) {year[0] = y0; year[1] = y0; *extrap = 1;}
00476 break;
00477 case 2:
00478 t1 = drms_getkey_time(inRS->records[1], "T_OBS", &status);
00479 y1 = drms_getkey_int(inRS->records[1], "YEAR", &status);
00480 if (t1 < t0) {tt = t1; t1 = t0; t0 = tt; yy = y1; y1 = y0; y0 = yy;}
00481 if (fabs(t1 - t0) >= (2.1 * SECSINYEAR)) { status = 1; break; }
00482 if (t <= t0) {
00483 year[0] = y0; year[1] = y1; *extrap = -1;
00484 } else if (t >= t1) {
00485 year[0] = y1; year[1] = y1; *extrap = 1;
00486 } else {
00487 year[0] = y0; year[1] = y1; *extrap = 0;
00488 }
00489 break;
00490 case 3:
00491 t1 = drms_getkey_time(inRS->records[1], "T_OBS", &status);
00492 y1 = drms_getkey_int(inRS->records[1], "YEAR", &status);
00493 t2 = drms_getkey_time(inRS->records[2], "T_OBS", &status);
00494 y2 = drms_getkey_int(inRS->records[2], "YEAR", &status);
00495 if (t1 < t0) {tt = t1; t1 = t0; t0 = tt; yy = y1; y1 = y0; y0 = yy;}
00496 if (t2 < t1) {tt = t2; t2 = t1; t1 = tt; yy = y2; y2 = y1; y1 = yy;}
00497 if (t1 < t0) {tt = t1; t1 = t0; t0 = tt; yy = y1; y1 = y0; y0 = yy;}
00498 *extrap = 0;
00499 if (t < t1) {
00500 year[0] = y0; year[1] = y1;
00501 } else {
00502 year[0] = y1; year[1] = y2;
00503 }
00504 break;
00505 default:
00506 break;
00507 }
00508 drms_close_records(inRS, DRMS_FREE_RECORD);
00509
00510
00511
00512 return status;
00513 }
00514
00515
00516
00517
00518
00519 int temp_spat(float *outMap, struct attrib *att, struct option *opt)
00520 {
00521
00522
00523
00524 int xsz = att->mapDims[0], ysz = att->mapDims[1], xysz = xsz * ysz;
00525 double *map = (double *) (calloc(xysz, sizeof(double)));
00526 for (int count = 0; count < xysz; count++) {
00527 map[count] = outMap[count];
00528 }
00529
00530
00531
00532 int imgDims[2] = {IMGDIM, IMGDIM}, imgDim2 = imgDims[0] * imgDims[1];
00533 double *img_n = (double *) (calloc(imgDim2, sizeof(double)));
00534 double *img_s = (double *) (calloc(imgDim2, sizeof(double)));
00535
00536
00537
00538
00539 int rowfil = 0, rowfil1 = 0;
00540 while (rowfil < (ysz / 2)) {
00541 if (fabs(att->lats[rowfil++] / DTOR) < opt->latfil) break;
00542 }
00543 while (rowfil1 < (ysz / 2)) {
00544 if (fabs(att->lats[rowfil1++] / DTOR) < opt->latfil1) break;
00545 }
00546
00547 printf("rowfil=%d, rowfil1=%d\n", rowfil, rowfil1);
00548
00549 int nxny1 = xsz * rowfil1, nxny = xsz * rowfil;
00550 float *mask_n = (float *) (calloc(nxny1, sizeof(float)));
00551 float *mask_s = (float *) (calloc(nxny1, sizeof(float)));
00552
00553
00554
00555 for (int row = 0; row < rowfil; row++) {
00556 for (int col = 0; col < xsz; col++) {
00557 mask_s[row * xsz + col] = 1.0;
00558 mask_n[(rowfil1 - 1 - row) * xsz + col] = 1.0;
00559 }
00560 }
00561
00562
00563
00564 float d_row = 1.0 / (rowfil1 + 1.0 - rowfil);
00565 for (int row = rowfil; row < rowfil1; row++) {
00566 for (int col = 0; col < xsz; col++) {
00567 mask_s[row * xsz + col] = d_row * (rowfil1 - row);
00568 mask_n[(rowfil1 - 1 - row) * xsz + col] = d_row * (rowfil1 - row);
00569 }
00570 }
00571
00572
00573
00574
00575
00576 #ifndef DEVELOP
00577 if (opt->nflag) {
00578
00579
00580
00581
00582 if (interpPoldb(0, rowfil, map, att, opt)) {
00583 FREE_ARR(map);
00584 FREE_ARR(img_n); FREE_ARR(img_s);
00585 FREE_ARR(mask_n); FREE_ARR(mask_s);
00586 return 1;
00587 }
00588
00589
00590
00591 synop2pole(0, att->sinlat, img_n, imgDims, map, att->mapDims,
00592 att->lons, att->lats, (opt->lat0 * DTOR));
00593 fitimage(img_n, imgDims[0], imgDims[1], opt->order, 1);
00594 pole2synop(0, att->sinlat, img_n, imgDims, map, att->mapDims,
00595 att->lons, att->lats, (opt->lat0 * DTOR));
00596
00597
00598
00599 int count0 = xysz - nxny1, count1 = xysz;
00600 for (int count = count0; count < count1; count++) {
00601 if (isnan(outMap[count])) outMap[count] = 0;
00602 outMap[count] = map[count] * mask_n[count - count0] +
00603 outMap[count] * (1. - mask_n[count - count0]);
00604 }
00605
00606 }
00607
00608
00609
00610 if (opt->sflag) {
00611
00612
00613
00614 if (interpPoldb(1, rowfil, map, att, opt)) {
00615 FREE_ARR(map);
00616 FREE_ARR(img_n); FREE_ARR(img_s);
00617 FREE_ARR(mask_n); FREE_ARR(mask_s);
00618 return 1;
00619 }
00620
00621
00622
00623 synop2pole(1, att->sinlat, img_s, imgDims, map, att->mapDims,
00624 att->lons, att->lats, (opt->lat0 * DTOR));
00625 fitimage(img_s, imgDims[0], imgDims[1], opt->order, 1);
00626 pole2synop(1, att->sinlat, img_s, imgDims, map, att->mapDims,
00627 att->lons, att->lats, (opt->lat0 * DTOR));
00628
00629
00630
00631 int count0 = 0, count1 = nxny1;
00632 for (int count = count0; count < count1; count++) {
00633 if (isnan(outMap[count])) outMap[count] = 0;
00634 outMap[count] = map[count] * mask_s[count - count0] +
00635 outMap[count] * (1. - mask_s[count - count0]);
00636 }
00637
00638 }
00639 #endif
00640
00641
00642
00643 FREE_ARR(map);
00644 FREE_ARR(img_n); FREE_ARR(img_s);
00645 FREE_ARR(mask_n); FREE_ARR(mask_s);
00646
00647 return 0;
00648
00649 }
00650
00651
00652
00653
00654
00655 int spat_2d(float *outMap, struct attrib *att, struct option *opt)
00656 {
00657
00658
00659
00660 int xsz = att->mapDims[0], ysz = att->mapDims[1], xysz = xsz * ysz;
00661 double *map = (double *) (calloc(xysz, sizeof(double)));
00662 for (int count = 0; count < xysz; count++) {
00663 map[count] = outMap[count];
00664 }
00665
00666
00667
00668 int imgDims[2] = {IMGDIM, IMGDIM}, imgDim2 = imgDims[0] * imgDims[1];
00669 double *img_n = (double *) (calloc(imgDim2, sizeof(double)));
00670 double *img_s = (double *) (calloc(imgDim2, sizeof(double)));
00671
00672
00673
00674
00675 int rowfil = 0, rowfil1 = 0;
00676 while (rowfil < (ysz / 2)) {
00677 if (fabs(att->lats[rowfil++] / DTOR) < opt->latfil) break;
00678 }
00679 while (rowfil1 < (ysz / 2)) {
00680 if (fabs(att->lats[rowfil1++] / DTOR) < opt->latfil1) break;
00681 }
00682
00683 printf("rowfil=%d, rowfil1=%d\n", rowfil, rowfil1);
00684
00685 int nxny1 = xsz * rowfil1, nxny = xsz * rowfil;
00686 float *mask_n = (float *) (calloc(nxny1, sizeof(float)));
00687 float *mask_s = (float *) (calloc(nxny1, sizeof(float)));
00688
00689
00690
00691 for (int row = 0; row < rowfil; row++) {
00692 for (int col = 0; col < xsz; col++) {
00693 mask_s[row * xsz + col] = 1.0;
00694 mask_n[(rowfil1 - 1 - row) * xsz + col] = 1.0;
00695 }
00696 }
00697
00698
00699
00700 float d_row = 1.0 / (rowfil1 + 1.0 - rowfil);
00701 for (int row = rowfil; row < rowfil1; row++) {
00702
00703 for (int col = 0; col < xsz; col++) {
00704 mask_s[row * xsz + col] = d_row * (rowfil1 - row);
00705 mask_n[(rowfil1 - 1 - row) * xsz + col] = d_row * (rowfil1 - row);
00706 }
00707 }
00708
00709
00710
00711 #ifndef DEVELOP
00712 if (opt->nflag) {
00713
00714
00715 synop2pole(0, att->sinlat, img_n, imgDims, map, att->mapDims,
00716 att->lons, att->lats, (opt->lat0 * DTOR));
00717 fitimage(img_n, imgDims[0], imgDims[1], opt->order, 1);
00718 pole2synop(0, att->sinlat, img_n, imgDims, map, att->mapDims,
00719 att->lons, att->lats, (opt->lat0 * DTOR));
00720
00721
00722
00723 int count0 = xysz - nxny1, count1 = xysz;
00724 for (int count = count0; count < count1; count++) {
00725 if (isnan(outMap[count])) outMap[count] = 0;
00726 outMap[count] = map[count] * mask_n[count - count0] +
00727 outMap[count] * (1. - mask_n[count - count0]);
00728 }
00729
00730 }
00731
00732
00733
00734 if (opt->sflag) {
00735
00736
00737 synop2pole(1, att->sinlat, img_s, imgDims, map, att->mapDims,
00738 att->lons, att->lats, (opt->lat0 * DTOR));
00739 fitimage(img_s, imgDims[0], imgDims[1], opt->order, 1);
00740 pole2synop(1, att->sinlat, img_s, imgDims, map, att->mapDims,
00741 att->lons, att->lats, (opt->lat0 * DTOR));
00742
00743
00744
00745
00746
00747 int count0 = 0, count1 = nxny1;
00748 for (int count = count0; count < count1; count++) {
00749 if (isnan(outMap[count])) outMap[count] = 0;
00750 outMap[count] = map[count] * mask_s[count - count0] +
00751 outMap[count] * (1. - mask_s[count - count0]);
00752 }
00753
00754
00755
00756 }
00757 #endif
00758
00759
00760
00761 FREE_ARR(map);
00762 FREE_ARR(img_n); FREE_ARR(img_s);
00763
00764 return 0;
00765
00766 }
00767
00768
00769
00770
00771
00772 int interpPoldb(int ns, int rowfil, double *map, struct attrib *att, struct option *opt)
00773 {
00774
00775 int status = 0;
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 int *year = (ns) ? att->s_year : att->n_year;
00786 int extrap = (ns) ? att->s_extrap : att->n_extrap;
00787
00788
00789
00790
00791 char inQuery[100];
00792 DRMS_RecordSet_t *inRS0 = NULL, *inRS1 = NULL;
00793 DRMS_Record_t *inRec0 = NULL, *inRec1 = NULL;
00794 DRMS_Segment_t *inSeg0 = NULL, *inSeg1 = NULL;
00795 DRMS_Array_t *inArray0 = NULL, *inArray1 = NULL;
00796
00797 double crpix1, crval1, cdelt1, crpix2, crval2, cdelt2;
00798 int xsz0, ysz0, xsz1, ysz1;
00799 double x, y;
00800
00801 double carr_time0, carr_time1;
00802 double lonc0, lonc1;
00803 float scale0, scale1;
00804 double *data0, *data1;
00805 double *lons_p0 = NULL, *lats_p0 = NULL;
00806 double *lons_p1 = NULL, *lats_p1 = NULL;
00807
00808 snprintf(inQuery, 100, "%s[%4d][%d]", poldb_name, year[0], ns);
00809 inRS0 = drms_open_records(drms_env, inQuery, &status);
00810
00811 if (status || inRS0->n < 1) {
00812 SHOW(" Open polar record error, ");
00813 return 1;
00814 }
00815 inRec0 = inRS0->records[0];
00816
00817 crpix1 = drms_getkey_double(inRec0, "CRPIX1", &status);
00818 crval1 = drms_getkey_double(inRec0, "CRVAL1", &status);
00819 cdelt1 = drms_getkey_double(inRec0, "CDELT1", &status);
00820 crpix2 = drms_getkey_double(inRec0, "CRPIX2", &status);
00821 crval2 = drms_getkey_double(inRec0, "CRVAL2", &status);
00822 cdelt2 = drms_getkey_double(inRec0, "CDELT2", &status);
00823 carr_time0 = drms_getkey_double(inRec0, "CARRTIME", &status);
00824
00825 scale0 = drms_getkey_double(inRec0, "SCALE", &status);
00826 inSeg0 = drms_segment_lookup(inRec0, "data");
00827 xsz0 = inSeg0->axis[0]; ysz0 = inSeg0->axis[1];
00828 inArray0 = drms_segment_read(inSeg0, DRMS_TYPE_DOUBLE, &status);
00829 if (status) {
00830 SHOW(" Read polar data array error, ");
00831 return 1;
00832 }
00833 data0 = (double *) inArray0->data;
00834
00835 lons_p0 = (double *) (calloc(xsz0, sizeof(double)));
00836 lats_p0 = (double *) (calloc(ysz0, sizeof(double)));
00837 lonc0 = (ceil(carr_time0 / 360.) * 360. - carr_time0) * DTOR;
00838 for (int col = 0; col < xsz0; col++) {
00839 lons_p0[col] = (col + 1 - crpix1) * fabs(cdelt1) * DTOR + lonc0;
00840 }
00841 for (int row = 0; row < ysz0; row++) {
00842 y = (row - crpix2 + 1) * cdelt2 + crval2;
00843 lats_p0[row] = (att->sinlat) ? asin(y) : (y * DTOR);
00844 }
00845
00846 if (extrap != 1) {
00847 snprintf(inQuery, 100, "%s[%4d][%d]", poldb_name, year[1], ns);
00848 inRS1 = drms_open_records(drms_env, inQuery, &status);
00849 if (status) {
00850 SHOW(" Open polar record error, ");
00851 return 1;
00852 }
00853 inRec1 = inRS1->records[0];
00854
00855 crpix1 = drms_getkey_double(inRec1, "CRPIX1", &status);
00856 crval1 = drms_getkey_double(inRec1, "CRVAL1", &status);
00857 cdelt1 = drms_getkey_double(inRec1, "CDELT1", &status);
00858 crpix2 = drms_getkey_double(inRec1, "CRPIX2", &status);
00859 crval2 = drms_getkey_double(inRec1, "CRVAL2", &status);
00860 cdelt2 = drms_getkey_double(inRec1, "CDELT2", &status);
00861 carr_time1 = drms_getkey_double(inRec1, "CARRTIME", &status);
00862
00863 scale1 = drms_getkey_double(inRec1, "SCALE", &status);
00864 inSeg1 = drms_segment_lookup(inRec1, "data");
00865 xsz1 = inSeg1->axis[0]; ysz1 = inSeg1->axis[1];
00866 inArray1 = drms_segment_read(inSeg1, DRMS_TYPE_DOUBLE, &status);
00867 if (status) {
00868 SHOW(" Read polar data array error, ");
00869 if (inArray0) drms_free_array(inArray0);
00870 return 1;
00871 }
00872 data1 = (double *) inArray1->data;
00873
00874 lonc1 = (ceil(carr_time1 / 360.) * 360. - carr_time1) * DTOR;
00875 } else {
00876 float mean62 = drms_getkey_float(inRec0, "MEAN62", &status);
00877 float mean75 = drms_getkey_float(inRec0, "MEAN75", &status);
00878 scale1 = scale0 * (mean62 / mean75 * K_TRANS);
00879 data1 = data0;
00880 xsz1 = xsz0; ysz1 = ysz0;
00881 carr_time1 = carr_time0 + CARRLONINYEAR;
00882 lonc1 = lonc0;
00883 }
00884
00885
00886 lons_p1 = (double *) (calloc(xsz1, sizeof(double)));
00887 lats_p1 = (double *) (calloc(ysz1, sizeof(double)));
00888 for (int col = 0; col < xsz1; col++) {
00889 lons_p1[col] = (col + 1 - crpix1) * fabs(cdelt1) * DTOR + lonc1;
00890 }
00891 for (int row = 0; row < ysz1; row++) {
00892 y = (row - crpix2 + 1) * cdelt2 + crval2;
00893 lats_p1[row] = (att->sinlat) ? asin(y) : (y * DTOR);
00894 }
00895
00896
00897
00898 double b0, b1;
00899 printf("t=%f, t0=%f, t1=%f\n", att->carr_time, carr_time0, carr_time1);
00900 printf("scale0=%f, scale1=%f\n", scale0, scale1);
00901
00902 double kt = (att->carr_time - carr_time0) / (carr_time1 - carr_time0);
00903
00904 int row0, row1;
00905 if (ns) {
00906 row0 = 0; row1 = rowfil;
00907 } else {
00908 row0 = att->mapDims[1] - rowfil; row1 = att->mapDims[1];
00909 }
00910
00911 printf("kt=%f\n", kt);
00912
00913 double x0, x1, y0, y1;
00914 double lon;
00915 for (int row = row0; row < row1; row++) {
00916 y0 = get_index(att->sinlat, ysz0, lats_p0, att->lats[row]);
00917 y1 = get_index(att->sinlat, ysz1, lats_p1, att->lats[row]);
00918 for (int col = 0; col < att->mapDims[0]; col++) {
00919
00920 lon = att->lons[col];
00921 while (lon < lons_p0[0]) {lon += TWOPI;}
00922 while (lon >= (lons_p0[0] + TWOPI)) {lon -= TWOPI;}
00923 x0 = get_index(0, xsz0, lons_p0, lon);
00924
00925 lon = att->lons[col];
00926 while (lon < lons_p1[0]) {lon += TWOPI;}
00927 while (lon >= (lons_p1[0] + TWOPI)) {lon -= TWOPI;}
00928 x1 = get_index(0, xsz1, lons_p1, lon);
00929
00930
00931
00932 b0 = linintd(data0, xsz0, ysz0, x0, y0) * scale0;
00933 b1 = linintd(data1, xsz1, ysz1, x1, y1) * scale1;
00934
00935 map[row * att->mapDims[0] + col] = b0 * (1. - kt) + b1 * kt;
00936 }
00937 }
00938
00939
00940
00941 drms_free_array(inArray0);
00942 drms_close_records(inRS0, DRMS_FREE_RECORD);
00943 if (extrap != 1) {
00944 drms_free_array(inArray1);
00945 drms_close_records(inRS1, DRMS_FREE_RECORD);
00946 }
00947
00948 FREE_ARR(lons_p0); FREE_ARR(lats_p0);
00949 FREE_ARR(lons_p1); FREE_ARR(lats_p1);
00950
00951 return 0;
00952
00953 }
00954
00955
00956
00957
00958
00959 int writeOutput(char *outQuery, DRMS_Record_t *inRec, float **outMap,
00960 struct attrib *att, struct option *opt)
00961 {
00962 int status = 0;
00963
00964 DRMS_Record_t *outRec = drms_create_record(drms_env, outQuery, DRMS_PERMANENT, &status);
00965 if (status) {
00966 SHOW(" Output record not created, record skipped.\n");
00967 return 1;
00968 }
00969
00970 DRMS_Segment_t *outSeg = drms_segment_lookupnum(outRec, 0);
00971 DRMS_Array_t *outArray = NULL;
00972 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, att->mapDims, (*outMap), &status);
00973 if (status) {
00974 SHOW(" Creating output array failed, ");
00975 if (!outArray) {
00976 drms_free_array(outArray);
00977 *outMap = NULL;
00978 }
00979 drms_close_record(outRec, DRMS_FREE_RECORD);
00980 return 1;
00981 }
00982
00983 outSeg->axis[0] = outArray->axis[0];
00984 outSeg->axis[1] = outArray->axis[1];
00985 outArray->israw = 0;
00986 outArray->bzero = outSeg->bzero;
00987 outArray->bscale = outSeg->bscale;
00988
00989 status = drms_segment_write(outSeg, outArray, 0);
00990 if (status) {
00991 SHOW(" Writing output array failed, ");
00992 if (!outArray) drms_free_array(outArray);
00993 *outMap = NULL;
00994 drms_close_record(outRec, DRMS_FREE_RECORD);
00995 return 1;
00996 }
00997
00998
00999
01000 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
01001
01002 drms_copykey(outRec, inRec, "CAR_ROT");
01003 drms_copykey(outRec, inRec, "T_OBS");
01004 drms_copykey(outRec, inRec, "T_REC");
01005 drms_setkey_int(outRec, "AMB", opt->amb);
01006
01007 set_statistics(outSeg, outArray, 1);
01008
01009 switch (opt->method) {
01010 default:
01011 case (0):
01012 drms_setkey_string(outRec, "METHOD", "TEMP_SPAT");
01013 drms_setkey_int(outRec, "N_EXTRAP", att->n_extrap);
01014 drms_setkey_int(outRec, "S_EXTRAP", att->s_extrap);
01015 drms_setkey_double(outRec, "LAT0", opt->lat0);
01016 drms_setkey_double(outRec, "LATFIL", opt->latfil);
01017 drms_setkey_double(outRec, "LATFIL1", opt->latfil1);
01018 drms_setkey_int(outRec, "NMAX", opt->order);
01019 break;
01020 case (1):
01021 drms_setkey_string(outRec, "METHOD", "SPAT_2D");
01022 drms_setkey_int(outRec, "NMAX", opt->order);
01023 break;
01024 }
01025
01026 char timebuf[1024];
01027 double UNIX_epoch = -220924792.000;
01028 sprint_time(timebuf, (double)time(NULL) + UNIX_epoch, "ISO", 0);
01029 drms_setkey_string(outRec, "DATE", timebuf);
01030
01031
01032
01033 drms_free_array(outArray);
01034 drms_close_record(outRec, DRMS_INSERT_RECORD);
01035
01036 return 0;
01037
01038 }