00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <string.h>
00010 #include "jsoc_main.h"
00011 #include "drms.h"
00012 #include "drms_names.h"
00013
00014 #define NOT_SPECIFIED "***Not Specified***"
00015 #define DIE(msg) {fprintf(stderr,"$$$$ %s: %s\n", module_name, msg); return 1;}
00016
00017 #define NBINS 1048576
00018 static int hist[NBINS];
00019
00020 int image_magrotate(void *, int nin, int min, int data_type_input, float theta, float mag,
00021 float dx, float dy, void **outarray, int *nx, int *ny, int regridtype_input, int stretch_lines);
00022
00023 int drms_appendcomment(DRMS_Record_t *rec, const char *comment, int nl);
00024
00025 ModuleArgs_t module_args[] =
00026 {
00027 {ARG_STRING, "in", NOT_SPECIFIED, "Input series query"},
00028 {ARG_STRING, "out", NOT_SPECIFIED, "Output series"},
00029
00030 {ARG_INT, "rescale", "0", "rescale to fixed plate scale"},
00031 {ARG_INT, "regrid", "1", "regrid type 0: nearest neighbor, 1: bicubic"},
00032 {ARG_INT, "center_to", "0", "center to 0: Sun center, 1: First image, 2: No change"},
00033 {ARG_DOUBLE, "scale_to", "0.6", "rescale to new CDELT scale"},
00034 {ARG_STRING, "do_stretchmarks", "0", "replicate pixels created else use missing value"},
00035 {ARG_STRING, "requestid", NOT_SPECIFIED, "RequestID if used for export"},
00036 {ARG_FLAG, "c", "0", "crop image to RSUN_OBS-1/4 pixel"},
00037 {ARG_FLAG, "h", "0", "Print usage message and quit"},
00038 {ARG_FLAG, "v", "0", "verbose flag"},
00039 {ARG_END}
00040 };
00041
00042 char *module_name = "jsoc_resize";
00043
00044
00045
00046
00047
00048 #define Deg2Rad (M_PI/180.0)
00049 #define Rad2arcsec (3600.0/Deg2Rad)
00050 #define arcsec2Rad (Deg2Rad/3600.0)
00051 #define Rad2Deg (180.0/M_PI)
00052
00053 struct ObsInfo_struct
00054 {
00055
00056 TIME t_obs;
00057 double rsun_obs, obs_vr, obs_vw, obs_vn;
00058 double crpix1, crpix2, cdelt1, cdelt2, crota2;
00059 double crval1, crval2;
00060 double cosa, sina;
00061 double obs_b0;
00062
00063 int i,j;
00064
00065 double x,y,r;
00066 double rho;
00067 double lon;
00068 double lat;
00069 double sinlat, coslat;
00070 double sig;
00071 double mu;
00072 double chi;
00073 double obs_v;
00074 };
00075
00076 typedef struct ObsInfo_struct ObsInfo_t;
00077
00078 void rebinArraySF(DRMS_Array_t *out, DRMS_Array_t *in);
00079 int upNcenter(DRMS_Array_t *arr, ObsInfo_t *ObsLoc);
00080 int crop_image(DRMS_Array_t *arr, ObsInfo_t *ObsLoc);
00081 const char *get_input_recset(DRMS_Env_t *drms_env, const char *in, DRMS_Record_t **template);
00082
00083 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus);
00084
00085
00086
00087 int verbose;
00088
00089 int nice_intro(int help)
00090 {
00091 int usage = cmdparams_get_int(&cmdparams, "h", NULL) != 0;
00092 verbose = cmdparams_get_int(&cmdparams, "v", NULL) != 0;
00093 if (usage || help) {
00094 printf("jsoc_resize {-h} {-v} dsinp=series_record_spec dsout=output_series\n"
00095 " -h: print this message\n"
00096 " -v: verbose\n"
00097
00098 "rescale=0, do not rescale to fixed plate scale, default=0\n"
00099 "regrid=0, nearest neighbor, default=1, bicubic\n"
00100 "center_to=0, centering target, 0=Sun, 1=First_image, 2=no change; default=0\n"
00101 "scale_to=0.6, rescale to fixed plate scale, default=0.6 arcsec/pixel\n"
00102 "do_stretchmarks=0, fill in empty pixels created, default=0\n"
00103 "in=<recordset query> as <series>{[record specifier]} - required\n"
00104 "out=<series> - required\n");
00105 return(1);
00106 }
00107 return(0);
00108 }
00109
00110 int set_statistics(DRMS_Segment_t *seg, DRMS_Array_t *arr, int mode);
00111
00112 int DoIt ()
00113 {
00114 if (nice_intro(0)) return(0);
00115
00116 int irec, iseg, nrecs, nsegs, status, is_aia=0;
00117 char now_str[100];
00118 float crpix1, crpix2, cdelt1, cdelt2, crota2, x0, y0;
00119 float mag = 1.0, dx, dy;
00120 DRMS_Record_t *inprec, *outrec;
00121 DRMS_Record_t *template = NULL;
00122 DRMS_RecordSet_t *inprs;
00123 DRMS_Keyword_t *inpkey = NULL, *outkey = NULL;
00124 DRMS_Array_t *inparr=NULL, *outarr=NULL;
00125 DRMS_Segment_t *inpseg, *outseg;
00126 const char *inQuery;
00127
00128 const char *requestid = cmdparams_get_str(&cmdparams, "requestid", NULL);
00129 char *dsinp = strdup(cmdparams_get_str(&cmdparams, "in", NULL));
00130 const char *dsout = cmdparams_get_str(&cmdparams, "out", NULL);
00131 if (strcmp(dsinp, NOT_SPECIFIED)==0) DIE("\"in\" argument is required");
00132 if (strcmp(dsout, NOT_SPECIFIED)==0)
00133 {
00134 char newout[DRMS_MAXNAMELEN];
00135 char *inp, inseries[DRMS_MAXNAMELEN];
00136 strncpy(inseries, dsinp, DRMS_MAXNAMELEN);
00137 inp = index(inseries, '[');
00138 if (inp)
00139 *inp = '\0';
00140 strncpy(newout, inseries, DRMS_MAXNAMELEN);
00141 strncat(newout, "_resized", DRMS_MAXNAMELEN);
00142 dsout = strdup(newout);
00143 }
00144 else
00145 dsout = strdup(dsout);
00146 inQuery = get_input_recset(drms_env, dsinp, &template);
00147
00148 int rescale = cmdparams_get_int(&cmdparams, "rescale", NULL);
00149 double scale_to = cmdparams_get_double(&cmdparams, "scale_to", NULL);
00150 int regridtype = cmdparams_get_int(&cmdparams, "regrid", NULL);
00151 int center_to = cmdparams_get_int(&cmdparams, "center_to", NULL);
00152 int do_stretchmarks = cmdparams_get_int(&cmdparams, "do_stretchmarks", NULL);
00153 int do_crop = cmdparams_get_int(&cmdparams, "c", NULL) != 0;
00154
00155 double scale_by;
00156 char comment[4096];
00157
00158 if (strstr(dsinp, "aia")) is_aia = 1;
00159 inprs = drms_open_records(drms_env, inQuery, &status);
00160 if (status) DIE("cant open recordset query");
00161 if (dsinp != inQuery && *inQuery == '@')
00162 unlink(inQuery+1);
00163 drms_stage_records(inprs, 1, 0);
00164 nrecs = inprs->n;
00165 printf("%d records\n", nrecs);
00166 float usedx = 0;
00167 float usedy = 0;
00168 float usemag = 1.0;
00169
00170 int iSet;
00171 int iSubRec;
00172 int nSubRecs = 0;
00173
00174
00175
00176 for (iSet = 0, irec = 0; iSet < inprs->ss_n; iSet++)
00177 {
00178 int hasSeglist = 0;
00179
00180
00181
00182
00183 if (strchr(inprs->ss_queries[iSet], '{'))
00184 {
00185 hasSeglist = 1;
00186 }
00187
00188 nSubRecs = drms_recordset_getssnrecs(inprs, iSet, &status);
00189
00190 for (iSubRec = 0; iSubRec < nSubRecs; iSubRec++, irec++)
00191 {
00192 int quality;
00193 TIME t_rec, t_obs;
00194 ObsInfo_t *ObsLoc;
00195 char inQuery[DRMS_MAXQUERYLEN];
00196
00197 inprec = inprs->records[(inprs->ss_starts)[iSet] + iSubRec];
00198
00199 t_obs = drms_getkey_time(inprec, "T_OBS", &status); if (status) DIE("T_OBS not found!");
00200 if (t_obs < 0)
00201 continue;
00202 if (is_aia)
00203 {
00204 int qualmask = 0x800100f0;
00205 int quallev0;
00206 quallev0 = drms_getkey_int(inprec, "QUALLEV0", &status); if (status) DIE("QUALLEV0 not found!");
00207 if (quallev0 & qualmask)
00208 continue;
00209 }
00210 quality = drms_getkey_int(inprec, "QUALITY", &status);
00211 if (verbose)
00212 fprintf(stderr,"rec %d of %d, quality=%X\n",irec,nrecs,quality);
00213 if (quality < 0)
00214 continue;
00215
00216 outrec = drms_create_record(drms_env, (char*)dsout, DRMS_PERMANENT, &status);
00217 if (status) DIE("cant create recordset");
00218 status = drms_copykeys(outrec, inprec, 0, kDRMS_KeyClass_Explicit);
00219 if (status) DIE("Error in drms_copykeys()");
00220 if (strcmp(requestid, NOT_SPECIFIED) != 0)
00221 drms_setkey_string(outrec, "requestid", requestid);
00222 drms_setkey_time(outrec, "DATE", CURRENT_SYSTEM_TIME);
00223 drms_sprint_rec_query(inQuery, inprec);
00224 drms_setkey_string(outrec, "SOURCE", inQuery);
00225
00226 if (is_aia)
00227 {
00228 if (!drms_keyword_lookup(inprec, "T_REC", 1) && drms_keyword_lookup(outrec, "T_REC", 1))
00229 {
00230 double tr_step;
00231 long long tr_index;
00232 TIME tr_epoch;
00233 if ( 0 == drms_setkey_time(outrec, "T_REC", t_obs))
00234 {
00235 tr_index = drms_getkey_longlong(outrec, "T_REC_index", &status); if (status) DIE("T_REC_index not found!");
00236 tr_step = drms_getkey_double(outrec, "T_REC_step", &status); if (status) DIE("T_REC_step not found!");
00237 tr_epoch = drms_getkey_time(outrec, "T_REC_epoch", &status); if (status) DIE("T_REC_epoch not found!");
00238 t_rec = tr_epoch + tr_index*tr_step;
00239 drms_setkey_time(outrec, "T_REC", t_rec);
00240 }
00241 }
00242 if (!drms_keyword_lookup(inprec, "GAEX_OBS", 1))
00243 drms_setkey_double(outrec, "GAEX_OBS", drms_getkey_double(inprec, "GCIEC_X", NULL));
00244 if (!drms_keyword_lookup(inprec, "GAEY_OBS", 1))
00245 drms_setkey_double(outrec, "GAEY_OBS", drms_getkey_double(inprec, "GCIEC_Y", NULL));
00246 if (!drms_keyword_lookup(inprec, "GAEZ_OBS", 1))
00247 drms_setkey_double(outrec, "GAEZ_OBS", drms_getkey_double(inprec, "GCIEC_Z", NULL));
00248 if (!drms_keyword_lookup(inprec, "HAEX_OBS", 1))
00249 drms_setkey_double(outrec, "HAEX_OBS", drms_getkey_double(inprec, "HCIEC_X", NULL));
00250 if (!drms_keyword_lookup(inprec, "HAEY_OBS", 1))
00251 drms_setkey_double(outrec, "HAEY_OBS", drms_getkey_double(inprec, "HCIEC_Y", NULL));
00252 if (!drms_keyword_lookup(inprec, "HAEZ_OBS", 1))
00253 drms_setkey_double(outrec, "HAEZ_OBS", drms_getkey_double(inprec, "HCIEC_Z", NULL));
00254 }
00255
00256 crpix1 = drms_getkey_double(inprec, "CRPIX1", &status); if (status) DIE("CRPIX1 not found!");
00257 crpix2 = drms_getkey_double(inprec, "CRPIX2", &status); if (status) DIE("CRPIX2 not found!");
00258 cdelt1 = drms_getkey_double(inprec, "CDELT1", &status); if (status) DIE("CDELT1 not found!");
00259 if (rescale)
00260 {
00261 mag = fabs(cdelt1 / scale_to);
00262 cdelt1 /= mag;
00263 }
00264 crota2 = drms_getkey_double(inprec, "CROTA2", &status); if (status) crota2 = 0.0;
00265
00266
00267 HIterator_t *segIter = NULL;
00268 DRMS_Segment_t *orig = NULL;
00269
00270
00271
00272
00273 while ((inpseg = drms_record_nextseg2(inprec, &segIter, 1, &orig)) != NULL)
00274 {
00275
00276
00277
00278
00279 void *output_array = NULL;
00280 int i, ix, iy, n, m, dtyp, nx, ny, npix;
00281
00282 {
00283 inparr = drms_segment_read(inpseg, DRMS_TYPE_FLOAT, &status); if (status) DIE("drms_segment_read failed!");
00284
00285
00286
00287
00288
00289
00290
00291
00292 outseg = drms_segment_lookupnum(outrec, orig->info->segnum);
00293
00294 if (!outseg)
00295 {
00296 DIE("Cant get output segment");
00297 }
00298
00299 int outdims[2];
00300 dtyp = 3;
00301 n = inparr->axis[0];
00302 m = inparr->axis[1];
00303
00304 if (is_aia)
00305 {
00306 float *fval;
00307 fval = inparr->data;
00308 for (ix = 0; ix<n; ix++)
00309 {
00310 fval[ix] = 0.0;
00311 fval[(m - 1)*n + ix] = 0.0;
00312 }
00313 for (iy = 0; iy<m; iy++)
00314 {
00315 fval[iy*n] = 0.0;
00316 fval[iy*n + n - 1] = 0.0;
00317 }
00318 }
00319 else
00320 {
00321 ObsLoc = GetObsInfo(inpseg, NULL, &status);
00322 upNcenter(inparr, ObsLoc);
00323 if (do_crop)
00324 crop_image(inparr, ObsLoc);
00325 crota2 = ObsLoc->crota2;
00326 crpix1 = ObsLoc->crpix1;
00327 crpix2 = ObsLoc->crpix2;
00328 }
00329
00330 if (center_to == 0)
00331 {
00332 usedx = (n + 1.0)/2.0;
00333 usedy = (m + 1.0)/2.0;
00334 }
00335 else
00336 {
00337 if (irec == 0 || center_to == 2)
00338 {
00339 usedx = crpix1;
00340 usedy = crpix2;
00341 usemag = cdelt1;
00342 }
00343 mag = cdelt1/usemag;
00344 cdelt1 = usemag;
00345 }
00346
00347
00348 dx = usedx - crpix1;
00349 dy = usedy - crpix2;
00350 status = image_magrotate( (float *)inparr->data, n, m, dtyp, crota2,
00351 mag, dx, dy, &output_array, &nx, &ny, regridtype, do_stretchmarks);
00352 if (verbose)
00353 {
00354 fprintf(stderr,"image_magrotate called with: "
00355 "data=%p, n=%d, m=%d, dtyp=%d, crota2=%f, mag=%f, dx=%f, dy=%f, regridtype=%d, do_stretch=%d\n",
00356 (float *)inparr->data, n, m, dtyp, crota2, mag, dx, dy,regridtype, do_stretchmarks);
00357 fprintf(stderr,"image_magrotate returned: "
00358 "into out=%p, nx=%d, ny=%d, status=%d\n", output_array, nx, ny, status);
00359 }
00360 sprintf(comment,"resize: scale_to=%f, mag=%f, dx=%f, dy=%f, regridtype=%d, do_stretch=%d, center_to=%s",
00361 scale_to, mag, dx, dy,regridtype, do_stretchmarks,
00362 (center_to==0 ? "solar disk" : (center_to==1 ? "First frame" : "No change")));
00363 drms_appendcomment(outrec, comment, 0);
00364 if (status) DIE("image_magrotate failed!");
00365 outdims[0] = nx;
00366 outdims[1] = ny;
00367 outarr = drms_array_create(inparr->type, 2, outdims, output_array, &status);
00368 if (status) DIE("drms_array_create failed!");
00369
00370 drms_setkey_float(outrec, "CROTA2", 0.0);
00371 drms_setkey_float(outrec, "CRPIX1", (nx + 1.0)*0.5);
00372 drms_setkey_float(outrec, "CRPIX2", (ny + 1.0)*0.5);
00373 drms_setkey_float(outrec, "CDELT1", cdelt1);
00374 drms_setkey_float(outrec, "CDELT2", cdelt1);
00375 set_statistics(outseg, outarr, 1);
00376
00377 outarr->bzero = outseg->bzero;
00378 outarr->bscale = outseg->bscale;
00379 if (requestid == NOT_SPECIFIED)
00380 drms_segment_write(outseg, outarr, 0);
00381 else
00382 drms_segment_writewithkeys(outseg, outarr, 0);
00383 if (inparr) drms_free_array(inparr);
00384 if (outarr) drms_free_array(outarr);
00385 }
00386
00387
00388
00389 if (drms_record_numsegments(inprec) == drms_record_numsegments(template) && !hasSeglist)
00390 {
00391 break;
00392 }
00393 }
00394
00395 if (segIter)
00396 {
00397 hiter_destroy(&segIter);
00398 }
00399
00400 drms_close_record(outrec, DRMS_INSERT_RECORD);
00401 }
00402 }
00403 return 0;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 int upNcenter(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00417 {
00418 int nx, ny, ix, iy, i, j, xoff, yoff, max_off;
00419 double rot, x0, y0, midx, midy;
00420 float *data;
00421 float *data2;
00422 if (!arr || !ObsLoc)
00423 return(1);
00424 data = arr->data;
00425 nx = arr->axis[0];
00426 ny = arr->axis[1];
00427 x0 = ObsLoc->crpix1 - 1;
00428 y0 = ObsLoc->crpix2 - 1;
00429 midx = (nx-1.0)/2.0;
00430 midy = (ny-1.0)/2.0;
00431 if ((rot = fabs(ObsLoc->crota2)) > 179 && rot < 181)
00432 {
00433
00434 float val;
00435 int half = ny / 2;
00436 int odd = ny & 1;
00437 for (iy=0; iy<half; iy++)
00438 {
00439 for (ix=0; ix<nx; ix++)
00440 {
00441 i = iy*nx + ix;
00442 j = (ny - 1 - iy)*nx + (nx - 1 - ix);
00443 val = data[i];
00444 data[i] = data[j];
00445 data[j] = val;
00446 }
00447 }
00448
00449 if (odd) {
00450 for (ix=0; ix<nx/2; ++ix) {
00451 i = nx*half + ix;
00452 j = nx*half + nx - ix - 1;
00453 val = data[i];
00454 data[i] = data[j];
00455 data[j] = val;
00456 }
00457 }
00458 x0 = nx - 1 - x0;
00459 y0 = ny - 1 - y0;
00460 rot = ObsLoc->crota2 - 180.0;
00461 if (rot < -90.0) rot += 360.0;
00462 ObsLoc->crota2 = rot;
00463 }
00464
00465 xoff = round(x0 - midx);
00466 yoff = round(y0 - midy);
00467 max_off = 20.0 / ObsLoc->cdelt1;
00468 if (arr->parent_segment &&
00469 arr->parent_segment->record &&
00470 arr->parent_segment->record->seriesinfo &&
00471 arr->parent_segment->record->seriesinfo->seriesname &&
00472 strncasecmp(arr->parent_segment->record->seriesinfo->seriesname, "aia", 3) &&
00473 abs(xoff) < max_off && abs(yoff) < max_off)
00474 {
00475 if (abs(xoff) >= 1 || abs(yoff) >= 1)
00476 {
00477 data2 = malloc(4*nx*ny);
00478 for (iy=0; iy<ny; iy++)
00479 {
00480 int jy = iy + yoff;
00481 for (ix=0; ix<nx; ix++)
00482 {
00483 int jx = ix + xoff;
00484 int idx = jy*nx + jx;
00485 int idx2 = iy*nx + ix;
00486 if (jx<0 || jx>=nx || jy<0 || jy>=ny)
00487 data2[idx2] = DRMS_MISSING_FLOAT;
00488 else
00489 data2[idx2] = data[idx];
00490 }
00491 }
00492 x0 -= xoff;
00493 y0 -= yoff;
00494 free(data);
00495 arr->data = data2;
00496 }
00497 }
00498
00499 ObsLoc->crpix1 = x0 + 1;
00500 ObsLoc->crpix2 = y0 + 1;
00501 return(0);
00502 }
00503
00504
00505
00506 int crop_image(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00507 {
00508 int nx, ny, ix, iy, i, j, xoff, yoff;
00509 double x0, y0;
00510 double rsun = ObsLoc->rsun_obs/ObsLoc->cdelt1;
00511 double scale, crop_limit2;
00512 float *data;
00513 if (!arr || !ObsLoc)
00514 return(1);
00515 data = arr->data;
00516 nx = arr->axis[0];
00517 ny = arr->axis[1];
00518 x0 = ObsLoc->crpix1 - 1;
00519 y0 = ObsLoc->crpix2 - 1;
00520 scale = 1.0/rsun;
00521
00522 crop_limit2 = 0.99950;
00523 for (iy=0; iy<ny; iy++)
00524 for (ix=0; ix<nx; ix++)
00525 {
00526 double x, y, R2;
00527 float *Ip = data + iy*nx + ix;
00528 if (drms_ismissing_float(*Ip))
00529 continue;
00530 x = ((double)ix - x0) * scale;
00531 y = ((double)iy - y0) * scale;
00532 R2 = x*x + y*y;
00533 if (R2 > crop_limit2)
00534 *Ip = DRMS_MISSING_FLOAT;
00535 }
00536 return(0);
00537 }
00538
00539
00540
00541 #define CHECK(keyname) {if (status) {fprintf(stderr,"Keyword failure to find: %s, status=%d\n",keyname,status); *rstatus=status; return(NULL);}}
00542
00543 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus)
00544 {
00545 TIME t_prev;
00546 DRMS_Record_t *rec;
00547 TIME t_obs;
00548 double dv;
00549 ObsInfo_t *ObsLoc;
00550 int status;
00551
00552 if (!seg || !(rec = seg->record))
00553 { *rstatus = 1; return(NULL); }
00554
00555 ObsLoc = (pObsLoc ? pObsLoc : (ObsInfo_t *)malloc(sizeof(ObsInfo_t)));
00556 if (!pObsLoc)
00557 memset(ObsLoc, 0, sizeof(ObsInfo_t));
00558
00559 t_prev = ObsLoc->t_obs;
00560 t_obs = drms_getkey_time(rec, "T_OBS", &status); CHECK("T_OBS");
00561
00562 if (t_obs <= 0.0)
00563 { *rstatus = 2; return(NULL); }
00564
00565 if (t_obs != t_prev)
00566 {
00567 ObsLoc->crpix1 = drms_getkey_double(rec, "CRPIX1", &status); CHECK("CRPIX1");
00568 ObsLoc->crpix2 = drms_getkey_double(rec, "CRPIX2", &status); CHECK("CRPIX2");
00569 ObsLoc->crval1 = drms_getkey_double(rec, "CRVAL1", &status); CHECK("CRVAL1");
00570 ObsLoc->crval2 = drms_getkey_double(rec, "CRVAL2", &status); CHECK("CRVAL2");
00571 ObsLoc->cdelt1 = drms_getkey_double(rec, "CDELT1", &status); CHECK("CDELT1");
00572 ObsLoc->cdelt2 = drms_getkey_double(rec, "CDELT2", &status); CHECK("CDELT1");
00573 ObsLoc->crota2 = drms_getkey_double(rec, "CROTA2", &status); if (status) ObsLoc->crota2 = 0.0;
00574 ObsLoc->sina = sin(ObsLoc->crota2*Deg2Rad);
00575 ObsLoc->cosa = sqrt (1.0 - ObsLoc->sina*ObsLoc->sina);
00576 ObsLoc->rsun_obs = drms_getkey_double(rec, "RSUN_OBS", &status);
00577 if (status)
00578 {
00579 double dsun_obs = drms_getkey_double(rec, "DSUN_OBS", &status); CHECK("DSUN_OBS");
00580 ObsLoc->rsun_obs = asin(696000000.0/dsun_obs)/arcsec2Rad;
00581 }
00582 ObsLoc->obs_vr = drms_getkey_double(rec, "OBS_VR", &status); CHECK("OBS_VR");
00583 ObsLoc->obs_vw = drms_getkey_double(rec, "OBS_VW", &status); CHECK("OBS_VW");
00584 ObsLoc->obs_vn = drms_getkey_double(rec, "OBS_VN", &status); CHECK("OBS_VN");
00585 ObsLoc->obs_b0 = drms_getkey_double(rec, "CRLT_OBS", &status); CHECK("CRLT_OBS");
00586 ObsLoc->t_obs = t_obs;
00587 }
00588 *rstatus = 0;
00589 return(ObsLoc);
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 #define DIE_get_recset(msg) {fprintf(stderr,"$$$$ %s: %s\n", module_name, msg); return NULL;}
00607 const char *get_input_recset(DRMS_Env_t *drms_env, const char *inQuery, DRMS_Record_t **template)
00608 {
00609 static char newInQuery[DRMS_MAXSERIESNAMELEN+2];
00610 int epoch_given = cmdparams_exists(&cmdparams, "epoch");
00611 TIME epoch, t_epoch;
00612 DRMS_Array_t *data;
00613 DRMS_Record_t *inTemplate;
00614 TIME t_start, t_stop, t_now, t_want, t_diff, this_t_diff;
00615 int status = 1;
00616 int nrecs, irec;
00617 int nslots, islot;
00618 long long *recnums;
00619 TIME *t_this, half;
00620 TIME cadence;
00621 double *drecnum, *dquality;
00622 int quality;
00623 long long recnum;
00624 char keylist[DRMS_MAXQUERYLEN];
00625 char filename[DRMS_MAXSERIESNAMELEN];
00626 char *tmpdir;
00627 FILE *tmpfile;
00628 char newIn[DRMS_MAXQUERYLEN];
00629 char seriesname[DRMS_MAXQUERYLEN];
00630 char *lbracket;
00631 char *at = index(inQuery, '@');
00632 int npkeys;
00633 char *timekeyname;
00634 double t_step;
00635
00636 strcpy(seriesname, inQuery);
00637 lbracket = index(seriesname,'[');
00638 if (lbracket) *lbracket = '\0';
00639 inTemplate = drms_template_record(drms_env, seriesname, &status);
00640 if (template)
00641 {
00642 *template = inTemplate;
00643 }
00644 if (status || !inTemplate) DIE_get_recset("Input series can not be found");
00645
00646
00647 npkeys = inTemplate->seriesinfo->pidx_num;
00648 timekeyname = NULL;
00649 if (npkeys > 0)
00650 {
00651 int i;
00652 for (i=0; i<npkeys; i++)
00653 {
00654 DRMS_Keyword_t *pkey, *skey;
00655 pkey = inTemplate->seriesinfo->pidx_keywords[i];
00656 if (pkey->info->recscope > 1)
00657 pkey = drms_keyword_slotfromindex(pkey);
00658 if (pkey->info->type != DRMS_TYPE_TIME)
00659 continue;
00660 if(i > 0) DIE_get_recset("Input series must have TIME keyword first, for now...");
00661 timekeyname = pkey->info->name;
00662 t_step = drms_keyword_getdouble(drms_keyword_stepfromslot(pkey), &status);
00663 if (status) DIE_get_recset("problem getting t_step");
00664 t_epoch = drms_keyword_getdouble(drms_keyword_epochfromslot(pkey), &status);
00665 if (status) DIE_get_recset("problem getting t_epoch");
00666 }
00667 }
00668 else
00669 DIE_get_recset("Must have time prime key");
00670 epoch = epoch_given ? params_get_time(&cmdparams, "epoch") : t_epoch;
00671
00672 if (at && *at && ((strncmp(inQuery,"aia.lev1[", 9)==0 ||
00673 strncmp(inQuery,"hmi.lev1[", 9)==0 ||
00674 strncmp(inQuery,"aia.lev1_nrt2[",14)==0 ||
00675 strncmp(inQuery,"hmi.lev1_nrt[", 13)==0 ) ||
00676 epoch_given))
00677 {
00678 char *ip=(char *)inQuery, *op=newIn, *p;
00679 long n, mul;
00680 while ( *ip && ip<at )
00681 *op++ = *ip++;
00682 ip++;
00683 n = strtol(ip, &p, 10);
00684 if (*p == 's') mul = 1;
00685 else if (*p == 'm') mul = 60;
00686 else if (*p == 'h') mul = 3600;
00687 else if (*p == 'd') mul = 86400;
00688 else
00689 DIE_get_recset("cant make sense of @xx cadence spec");
00690 cadence = n * mul;
00691 ip = ++p;
00692 while ( *ip )
00693 *op++ = *ip++;
00694 *op = '\0';
00695 half = cadence/2.0;
00696 sprintf(keylist, "%s,QUALITY,recnum", timekeyname);
00697 data = drms_record_getvector(drms_env, newIn, keylist, DRMS_TYPE_DOUBLE, 0, &status);
00698 if (!data || status)
00699 {
00700 fprintf(stderr, "status=%d\n", status);
00701 DIE_get_recset("getkey_vector failed\n");
00702 }
00703 nrecs = data->axis[1];
00704 irec = 0;
00705 t_this = (TIME *)data->data;
00706 dquality = (double *)data->data + 1*nrecs;
00707 drecnum = (double *)data->data + 2*nrecs;
00708 if (epoch_given)
00709 {
00710 int s0 = (t_this[0] - epoch)/cadence;
00711 TIME t0 = s0*cadence + epoch;
00712 t_start = (t0 < t_this[0] ? t0 + cadence : t0);
00713 }
00714 else
00715 t_start = t_this[0];
00716 t_stop = t_this[nrecs-1];
00717 nslots = (t_stop - t_start + cadence/2)/cadence;
00718 recnums = (long long *)malloc(nslots*sizeof(long long));
00719 for (islot=0; islot<nslots; islot++)
00720 recnums[islot] = 0;
00721 islot = 0;
00722 t_want = t_start;
00723 t_diff = 1.0e9;
00724 for (irec = 0; irec<nrecs; irec++)
00725 {
00726 t_now = t_this[irec];
00727 quality = (int)dquality[irec] & 0xFFFFFFFF;
00728 recnum = (long long)drecnum[irec];
00729 this_t_diff = fabs(t_now - t_want);
00730 if (quality < 0)
00731 continue;
00732 if (t_now <= (t_want-half))
00733 continue;
00734 while (t_now > (t_want+half))
00735 {
00736 islot++;
00737 if (islot >= nslots)
00738 break;
00739 t_want = t_start + cadence * islot;
00740 this_t_diff = fabs(t_now - t_want);
00741 t_diff = 1.0e8;
00742 }
00743 if (islot < nslots && this_t_diff <= t_diff)
00744 recnums[islot] = recnum;
00745 t_diff = fabs(t_now - t_want);
00746 }
00747 if (islot+1 < nslots)
00748 nslots = islot+1;
00749 tmpdir = getenv("TMPDIR");
00750 if (!tmpdir) tmpdir = "/tmp";
00751 sprintf(filename, "%s/%sXXXXXX", tmpdir, module_name);
00752 mkstemp(filename);
00753 tmpfile = fopen(filename,"w");
00754 for (islot=0; islot<nslots; islot++)
00755 if (recnums[islot])
00756 fprintf(tmpfile, "%s[:#%lld]\n", seriesname, recnums[islot]);
00757 fclose(tmpfile);
00758 free(recnums);
00759 drms_free_array(data);
00760 sprintf(newInQuery,"@%s", filename);
00761 return(newInQuery);
00762 }
00763 else
00764 return(inQuery);
00765 }