00001
00068 #include "jsoc.h"
00069 #include "jsoc_main.h"
00070 #include "fstats.h"
00071
00072 char *module_name = "jsoc_rebin";
00073
00074 #define DIE(msg) {fflush(stdout);fprintf(stderr,"%s, status=%d\n",msg,status); return(status);}
00075
00076 ModuleArgs_t module_args[] =
00077 {
00078 {ARG_STRING, "in", "NOT SPECIFIED", "Input data series."},
00079 {ARG_STRING, "out", "NOT SPECIFIED", "Output data series."},
00080 {ARG_FLAG, "A", "0", "Process all segments in the input series"},
00081 {ARG_FLAG, "c", "0", "Crop at rsun_obs."},
00082 {ARG_FLAG, "h", "0", "Include full FITS header in output segment."},
00083 {ARG_FLAG, "u", "0", "do not rotate by 180 if needed."},
00084 {ARG_FLOAT, "scale", "1.0", "Scale factor."},
00085 {ARG_FLOAT, "FWHM", "-1.0", "Smoothing Gaussian FWHM for method=gaussian."},
00086 {ARG_INT, "nvector", "-1.0", "Smoothing Gaussian vector length for method=gaussian."},
00087 {ARG_INT, "inseg", "-1", "Input segment number"},
00088 {ARG_INT, "outseg", "-1", "Output segment number"},
00089 {ARG_STRING, "method", "boxcar", "conversion type, one of: boxcar, gaussian."},
00090 {ARG_STRING, "requestid", "NA", "RequestID if called as an export processing step."},
00091 {ARG_END}
00092 };
00093
00094 #define Deg2Rad (M_PI/180.0)
00095 #define Rad2arcsec (3600.0/Deg2Rad)
00096 #define arcsec2Rad (Deg2Rad/3600.0)
00097 #define Rad2Deg (180.0/M_PI)
00098
00099 struct ObsInfo_struct
00100 {
00101
00102 TIME t_obs;
00103 double rsun_obs, obs_vr, obs_vw, obs_vn;
00104 double crpix1, crpix2, cdelt1, cdelt2, crota2;
00105 double crval1, crval2;
00106 double cosa, sina;
00107 double obs_b0;
00108
00109 int i,j;
00110
00111 double x,y,r;
00112 double rho;
00113 double lon;
00114 double lat;
00115 double sinlat, coslat;
00116 double sig;
00117 double mu;
00118 double chi;
00119 double obs_v;
00120 };
00121
00122 typedef struct ObsInfo_struct ObsInfo_t;
00123
00124 void rebinArraySF(DRMS_Array_t *out, DRMS_Array_t *in);
00125 int upNcenter(DRMS_Array_t *arr, ObsInfo_t *ObsLoc);
00126 int crop_image(DRMS_Array_t *arr, ObsInfo_t *ObsLoc);
00127 const char *get_input_recset(DRMS_Env_t *drms_env, const char *in);
00128
00129 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus);
00130 ObsInfo_t *GetMinObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus);
00131
00132 int DoIt(void)
00133 {
00134 int status = DRMS_SUCCESS;
00135 DRMS_RecordSet_t *inRS, *outRS;
00136 int irec, nrecs;
00137 const char *inQuery = params_get_str(&cmdparams, "in");
00138 char *inStr;
00139 const char *outSeries = params_get_str(&cmdparams, "out");
00140 const char *method = params_get_str(&cmdparams, "method");
00141 const char *requestid = params_get_str(&cmdparams, "requestid");
00142 int nvector = params_get_int(&cmdparams, "nvector");
00143 float fscale = params_get_float(&cmdparams, "scale");
00144 float fwhm = params_get_float(&cmdparams, "FWHM");
00145 int crop = params_get_int(&cmdparams, "c");
00146 int as_is = params_get_int(&cmdparams, "u");
00147 int wantAllSegs = params_get_int(&cmdparams, "A");
00148 int inseg = params_get_int(&cmdparams, "inseg");
00149 int outseg = params_get_int(&cmdparams, "outseg");
00150 int full_header = params_get_int(&cmdparams, "h") || strcmp(requestid, "NA");
00151 char *in_filename = NULL;
00152 DRMS_Record_t *template = NULL;
00153 int firstNx = 0, firstNy = 0, firstNaxis = 0;
00154 int wantSeg = 1;
00155
00156 int iscale, ivec, vec_half;
00157 double *vector;
00158 char history[4096];
00159
00160 if (fscale < 1.0)
00161 iscale = 1.0/fscale + 0.5;
00162 else
00163 iscale = fscale + 0.5;
00164 if (nvector < 0)
00165 nvector = iscale;
00166
00167 if (((iscale & 1) && !(nvector & 1)) || ((!(iscale & 1) && (nvector & 1) )))
00168 nvector += 1;
00169 vector = (double *)malloc(nvector * sizeof(double));
00170 vec_half = nvector/2;
00171
00172 if (strcasecmp(method, "boxcar")==0 && fscale < 1)
00173 {
00174 for (ivec = 0; ivec < nvector; ivec++)
00175 vector[ivec] = 1.0;
00176 sprintf(history, "Boxcar bin by %d%s%s",
00177 iscale,
00178 (crop ? ", Cropped at rsun_obs" : ""),
00179 (!as_is ? ", North is up" : "") );
00180 }
00181 else if (strcasecmp(method, "boxcar")==0 && fscale >= 1)
00182 {
00183 if (nvector != iscale)
00184 DIE("For fscale>=1 nvector must be fscale");
00185 for (ivec = 0; ivec < nvector; ivec++)
00186 vector[ivec] = 1.0;
00187 sprintf(history, "Replicate to expand by %d%s%s",
00188 iscale,
00189 (crop ? ", Cropped at rsun_obs" : ""),
00190 (!as_is ? ", North is up" : "") );
00191 }
00192 else if (strcasecmp(method, "gaussian")==0)
00193 {
00194 if (fwhm < 0)
00195 DIE("Need FWHM parameter");
00196 for (ivec = 0; ivec < nvector; ivec++)
00197 {
00198 double arg = (ivec - (nvector-1)/2.0) * (ivec - (nvector-1)/2.0);
00199 vector[ivec] = exp(-arg/(fwhm*fwhm*0.52034));
00200 }
00201 sprintf(history, "Scale by %f with Gasussian smoothing FWHM=%f, nvector=%d%s%s",
00202 fscale, fwhm, nvector,
00203 (crop ? ", Cropped at rsun_obs" : ""),
00204 (!as_is ? ", North is up" : "") );
00205 }
00206 else
00207 DIE("invalid conversion method");
00208
00209 printf(history);
00210
00211 inStr = strdup(get_input_recset(drms_env, (char *)inQuery));
00212 if (!inStr || *inStr=='\0') DIE("Cant make special cadence recordset list file");
00213 inRS = drms_open_records(drms_env, inStr, &status);
00214 if (strcmp(inStr, inQuery) && *inStr == '@')
00215 unlink(inStr+1);
00216 if (status || inRS->n == 0)
00217 DIE("No input data found");
00218
00219 nrecs = inRS->n;
00220 if (nrecs == 0)
00221 DIE("No records found");
00222 drms_stage_records(inRS, 1, 1);
00223
00224 outRS = drms_create_records(drms_env, nrecs, (char *)outSeries, DRMS_PERMANENT, &status);
00225 if (status)
00226 DIE("Output recordset not created");
00227
00228 int iSet;
00229 int iSubRec;
00230 int nSubRecs = 0;
00231
00232
00233 for (iSet = 0, irec = 0; iSet < inRS->ss_n; iSet++)
00234 {
00235 int hasSeglist = wantAllSegs ? 1 : 0;
00236
00237
00238
00239
00240 if (strchr(inRS->ss_queries[iSet], '{'))
00241 {
00242 hasSeglist = 1;
00243 }
00244
00245 nSubRecs = drms_recordset_getssnrecs(inRS, iSet, &status);
00246
00247 for (iSubRec = 0; iSubRec < nSubRecs; iSubRec++, irec++)
00248 {
00249 ObsInfo_t *ObsLoc;
00250 DRMS_Record_t *outRec, *inRec;
00251 DRMS_Segment_t *outSeg, *inSeg;
00252 DRMS_Segment_t *orig = NULL;
00253 DRMS_Array_t *inArray, *outArray;
00254 float *inData, *outData;
00255 float val;
00256 int quality=0;
00257
00258 inRec = inRS->records[(inRS->ss_starts)[iSet] + iSubRec];
00259
00260 quality = drms_getkey_int(inRec, "QUALITY", &status);
00261 if (status || (!status && quality >= 0))
00262 {
00263
00264 HIterator_t *segIter = NULL;
00265
00266 while ((inSeg = drms_record_nextseg2(inRec, &segIter, 1, &orig)) != NULL)
00267 {
00268
00269
00270
00271 if (inseg >= 0)
00272 {
00273
00274
00275
00276
00277
00278 if (orig->info->segnum != inseg)
00279 {
00280
00281 continue;
00282 }
00283 }
00284 wantSeg = 1;
00285
00286 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00287 if (status)
00288 {
00289 printf(" No data file found but QUALITY not bad, status=%d\n", status);
00290 drms_free_array(inArray);
00291 continue;
00292 }
00293 int inx, iny, outx, outy, i, j;
00294 int in_nx = inArray->axis[0];
00295 int in_ny = inArray->axis[1];
00296 int out_nx = in_nx * fscale + 0.5;
00297 int out_ny = in_ny * fscale + 0.5;
00298 int outDims[2] = {out_nx, out_ny};
00299 if (firstNaxis == 0)
00300 {
00301 if (inArray->naxis != 2)
00302 wantSeg = 0;
00303 else
00304 {
00305 firstNaxis = inArray->naxis;
00306 firstNx = in_nx;
00307 firstNy = in_ny;
00308 }
00309 }
00310 if (inArray->naxis != firstNaxis || in_nx != firstNx || in_ny != firstNy)
00311 {
00312 wantSeg = 0;
00313 }
00314
00315 if (wantSeg && (crop || !as_is))
00316 {
00317 ObsLoc = GetObsInfo(inSeg, NULL, &status);
00318 if (!as_is) upNcenter(inArray, ObsLoc);
00319 if (crop) crop_image(inArray, ObsLoc);
00320 }
00321 else if (wantSeg)
00322 {
00323 ObsLoc = GetMinObsInfo(inSeg, NULL, &status);
00324 }
00325
00326 if (wantSeg)
00327 {
00328 inData = (float *)inArray->data;
00329 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, outDims, NULL, &status);
00330 outData = (float *)outArray->data;
00331 }
00332
00333 if (wantSeg && fscale > 1.0)
00334 {
00335 int out_go = (iscale-1)/2.0 + 0.5;
00336 for (iny = 0; iny < in_ny; iny += 1)
00337 for (inx = 0; inx < in_nx; inx += 1)
00338 {
00339 val = inData[in_nx*iny + inx];
00340 for (j = 0; j < nvector; j += 1)
00341 {
00342 outy = iny*iscale + out_go + j - vec_half;
00343 for (i = 0; i < nvector; i += 1)
00344 {
00345 outx = inx*iscale + out_go + i - vec_half;
00346 if (outx >= 0 && outx < out_nx && outy >= 0 && outy < out_ny)
00347 outData[out_nx*outy + outx] = val;
00348 }
00349 }
00350 }
00351 }
00352 else if (wantSeg)
00353 {
00354 int in_go = (iscale-1)/2.0 + 0.5;
00355 for (outy = 0; outy < out_ny; outy += 1)
00356 for (outx = 0; outx < out_nx; outx += 1)
00357 {
00358 double total = 0.0;
00359 double weight = 0.0;
00360 int nn = 0;
00361 for (j = 0; j < nvector; j += 1)
00362 {
00363 iny = outy*iscale + in_go + j - vec_half;
00364 for (i = 0; i < nvector; i += 1)
00365 {
00366 inx = outx*iscale + in_go + i - vec_half;
00367 if (inx >= 0 && inx < in_nx && iny >=0 && iny < in_ny)
00368 {
00369 val = inData[in_nx*(iny) + inx];
00370 if (!drms_ismissing_float(val))
00371 {
00372 double w = vector[i]*vector[j];
00373 total += w*val;
00374 weight += w;
00375 nn++;
00376 }
00377 }
00378 }
00379 }
00380 outData[out_nx*outy + outx] = (nn > 0 ? total/weight : DRMS_MISSING_FLOAT);
00381 }
00382 }
00383
00384
00385
00386 outRec = outRS->records[irec];
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 outSeg = drms_segment_lookupnum(outRec, (outseg >= 0) ? outseg : orig->info->segnum);
00397
00398 if (!outSeg)
00399 {
00400 DIE("Unable to look-up output segment.");
00401 }
00402
00403
00404 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00405
00406
00407
00408 drms_setkey_double(outRec, "CDELT1", ObsLoc->cdelt1/fscale);
00409 drms_setkey_double(outRec, "CDELT2", ObsLoc->cdelt2/fscale);
00410 drms_setkey_double(outRec, "CRPIX1", (ObsLoc->crpix1-0.5) * fscale + 0.5);
00411 drms_setkey_double(outRec, "CRPIX2", (ObsLoc->crpix2-0.5) * fscale + 0.5);
00412 drms_setkey_double(outRec, "CROTA2", ObsLoc->crota2);
00413
00414 if (strcasecmp(method, "gaussian")==0)
00415 drms_setkey_double(outRec, "FWHM", fwhm);
00416 drms_appendhistory(outRec, history, 1);
00417 drms_setkey_time(outRec, "DATE", CURRENT_SYSTEM_TIME);
00418 if (strcmp(requestid, "NA") != 0)
00419 drms_setkey_string(outRec, "RequestID", requestid);
00420
00421
00422 if (!wantSeg)
00423 {
00424 drms_free_array(inArray);
00425 inArray = drms_segment_read(inSeg,DRMS_TYPE_RAW,&status);
00426 if (!inArray || status)
00427 DIE("Problem reading ancillary array");
00428 status = drms_segment_write(outSeg, inArray, 0);
00429 if (status)
00430 DIE("Problem writing ancillary array");
00431 drms_free_array(inArray);
00432 }
00433 else
00434 {
00435
00436 outArray->parent_segment = outSeg;
00437
00438 drms_setkey_int(outRec, "TOTVALS", out_nx*out_ny);
00439 set_statistics(outSeg, outArray, 1);
00440
00441
00442 outArray->bzero = inArray->bzero;
00443 outArray->bscale = inArray->bscale;
00444
00445 drms_free_array(inArray);
00446 if (full_header)
00447 status = drms_segment_writewithkeys(outSeg, outArray, 0);
00448 else
00449 status = drms_segment_write(outSeg, outArray, 0);
00450 if (status)
00451 DIE("problem writing file");
00452 drms_free_array(outArray);
00453 }
00454
00455 if (inseg >= 0)
00456 {
00457
00458 break;
00459 }
00460
00461
00462
00463 if (inRec->seriesinfo && *inRec->seriesinfo->seriesname)
00464 {
00465 template = drms_template_record(drms_env, inRec->seriesinfo->seriesname, &status);
00466 }
00467 else
00468 {
00469 template = NULL;
00470 }
00471
00472 if (status || !template)
00473 {
00474 DIE("Cannot obtain DRMS-record template.");
00475 }
00476
00477 if (drms_record_numsegments(inRec) == drms_record_numsegments(template) && !hasSeglist)
00478 {
00479 break;
00480 }
00481 }
00482
00483 if (segIter)
00484 {
00485 hiter_destroy(&segIter);
00486 }
00487 }
00488 }
00489 }
00490
00491 drms_close_records(inRS, DRMS_FREE_RECORD);
00492 drms_close_records(outRS, DRMS_INSERT_RECORD);
00493 return (DRMS_SUCCESS);
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 int upNcenter(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00503 {
00504 int nx, ny, ix, iy, i, j, xoff, yoff, max_off;
00505 double rot, x0, y0, midx, midy;
00506 float *data;
00507 float *data2;
00508 if (!arr || !ObsLoc)
00509 return(1);
00510 data = arr->data;
00511 nx = arr->axis[0];
00512 ny = arr->axis[1];
00513 x0 = ObsLoc->crpix1 - 1;
00514 y0 = ObsLoc->crpix2 - 1;
00515 midx = (nx-1.0)/2.0;
00516 midy = (ny-1.0)/2.0;
00517 if ((rot = fabs(ObsLoc->crota2)) > 179 && rot < 181)
00518 {
00519
00520 float val;
00521 int half = ny / 2;
00522 int odd = ny & 1;
00523 for (iy=0; iy<half; iy++)
00524 {
00525 for (ix=0; ix<nx; ix++)
00526 {
00527 i = iy*nx + ix;
00528 j = (ny - 1 - iy)*nx + (nx - 1 - ix);
00529 val = data[i];
00530 data[i] = data[j];
00531 data[j] = val;
00532 }
00533 }
00534
00535 if (odd) {
00536 for (ix=0; ix<nx/2; ++ix) {
00537 i = nx*half + ix;
00538 j = nx*half + nx - ix - 1;
00539 val = data[i];
00540 data[i] = data[j];
00541 data[j] = val;
00542 }
00543 }
00544 x0 = nx - 1 - x0;
00545 y0 = ny - 1 - y0;
00546 rot = ObsLoc->crota2 - 180.0;
00547 if (rot < -90.0) rot += 360.0;
00548 ObsLoc->crota2 = rot;
00549 }
00550
00551 xoff = round(x0 - midx);
00552 yoff = round(y0 - midy);
00553 max_off = 20.0 / ObsLoc->cdelt1;
00554 if (arr->parent_segment &&
00555 arr->parent_segment->record &&
00556 arr->parent_segment->record->seriesinfo &&
00557 arr->parent_segment->record->seriesinfo->seriesname &&
00558 strncasecmp(arr->parent_segment->record->seriesinfo->seriesname, "aia", 3) &&
00559 abs(xoff) < max_off && abs(yoff) < max_off)
00560 {
00561 if (abs(xoff) >= 1 || abs(yoff) >= 1)
00562 {
00563 data2 = malloc(4*nx*ny);
00564 for (iy=0; iy<ny; iy++)
00565 {
00566 int jy = iy + yoff;
00567 for (ix=0; ix<nx; ix++)
00568 {
00569 int jx = ix + xoff;
00570 int idx = jy*nx + jx;
00571 int idx2 = iy*nx + ix;
00572 if (jx<0 || jx>=nx || jy<0 || jy>=ny)
00573 data2[idx2] = DRMS_MISSING_FLOAT;
00574 else
00575 data2[idx2] = data[idx];
00576 }
00577 }
00578 x0 -= xoff;
00579 y0 -= yoff;
00580 free(data);
00581 arr->data = data2;
00582 }
00583 }
00584
00585 ObsLoc->crpix1 = x0 + 1;
00586 ObsLoc->crpix2 = y0 + 1;
00587 return(0);
00588 }
00589
00590
00591
00592 int crop_image(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00593 {
00594 int nx, ny, ix, iy, i, j, xoff, yoff;
00595 double x0, y0;
00596 double rsun = ObsLoc->rsun_obs/ObsLoc->cdelt1;
00597 double scale, crop_limit2;
00598 float *data;
00599 if (!arr || !ObsLoc)
00600 return(1);
00601 data = arr->data;
00602 nx = arr->axis[0];
00603 ny = arr->axis[1];
00604 x0 = ObsLoc->crpix1 - 1;
00605 y0 = ObsLoc->crpix2 - 1;
00606 scale = 1.0/rsun;
00607
00608 crop_limit2 = 0.99950;
00609 for (iy=0; iy<ny; iy++)
00610 for (ix=0; ix<nx; ix++)
00611 {
00612 double x, y, R2;
00613 float *Ip = data + iy*nx + ix;
00614 if (drms_ismissing_float(*Ip))
00615 continue;
00616 x = ((double)ix - x0) * scale;
00617 y = ((double)iy - y0) * scale;
00618 R2 = x*x + y*y;
00619 if (R2 > crop_limit2)
00620 *Ip = DRMS_MISSING_FLOAT;
00621 }
00622 return(0);
00623 }
00624
00625
00626
00627 #define CHECK(keyname) {if (status) {fprintf(stderr,"Keyword failure to find: %s, status=%d\n",keyname,status); *rstatus=status; return(NULL);}}
00628
00629 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus)
00630 {
00631 TIME t_prev;
00632 DRMS_Record_t *rec;
00633 TIME t_obs;
00634 double dv;
00635 ObsInfo_t *ObsLoc;
00636 int status;
00637
00638 if (!seg || !(rec = seg->record))
00639 { *rstatus = 1; return(NULL); }
00640
00641 ObsLoc = (pObsLoc ? pObsLoc : (ObsInfo_t *)malloc(sizeof(ObsInfo_t)));
00642 if (!pObsLoc)
00643 memset(ObsLoc, 0, sizeof(ObsInfo_t));
00644
00645 t_prev = ObsLoc->t_obs;
00646 t_obs = drms_getkey_time(rec, "T_OBS", &status); CHECK("T_OBS");
00647
00648 if (t_obs <= 0.0)
00649 { *rstatus = 2; return(NULL); }
00650
00651 if (t_obs != t_prev)
00652 {
00653 ObsLoc->crpix1 = drms_getkey_double(rec, "CRPIX1", &status); CHECK("CRPIX1");
00654 ObsLoc->crpix2 = drms_getkey_double(rec, "CRPIX2", &status); CHECK("CRPIX2");
00655 ObsLoc->crval1 = drms_getkey_double(rec, "CRVAL1", &status); CHECK("CRVAL1");
00656 ObsLoc->crval2 = drms_getkey_double(rec, "CRVAL2", &status); CHECK("CRVAL2");
00657 ObsLoc->cdelt1 = drms_getkey_double(rec, "CDELT1", &status); CHECK("CDELT1");
00658 ObsLoc->cdelt2 = drms_getkey_double(rec, "CDELT2", &status); CHECK("CDELT1");
00659 ObsLoc->crota2 = drms_getkey_double(rec, "CROTA2", &status); if (status) ObsLoc->crota2 = 0.0;
00660 ObsLoc->sina = sin(ObsLoc->crota2*Deg2Rad);
00661 ObsLoc->cosa = sqrt (1.0 - ObsLoc->sina*ObsLoc->sina);
00662 ObsLoc->rsun_obs = drms_getkey_double(rec, "RSUN_OBS", &status);
00663 if (status)
00664 {
00665 double dsun_obs = drms_getkey_double(rec, "DSUN_OBS", &status); CHECK("DSUN_OBS");
00666 ObsLoc->rsun_obs = asin(696000000.0/dsun_obs)/arcsec2Rad;
00667 }
00668 ObsLoc->obs_vr = drms_getkey_double(rec, "OBS_VR", &status); CHECK("OBS_VR");
00669 ObsLoc->obs_vw = drms_getkey_double(rec, "OBS_VW", &status); CHECK("OBS_VW");
00670 ObsLoc->obs_vn = drms_getkey_double(rec, "OBS_VN", &status); CHECK("OBS_VN");
00671 ObsLoc->obs_b0 = drms_getkey_double(rec, "CRLT_OBS", &status); CHECK("CRLT_OBS");
00672 ObsLoc->t_obs = t_obs;
00673 }
00674 *rstatus = 0;
00675 return(ObsLoc);
00676 }
00677
00678
00679 ObsInfo_t *GetMinObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus)
00680 {
00681 TIME t_prev;
00682 DRMS_Record_t *rec;
00683 TIME t_obs;
00684 double dv;
00685 ObsInfo_t *ObsLoc;
00686 int status;
00687
00688 if (!seg || !(rec = seg->record))
00689 { *rstatus = 1; return(NULL); }
00690
00691 ObsLoc = (pObsLoc ? pObsLoc : (ObsInfo_t *)malloc(sizeof(ObsInfo_t)));
00692 if (!pObsLoc)
00693 memset(ObsLoc, 0, sizeof(ObsInfo_t));
00694
00695 t_prev = ObsLoc->t_obs;
00696 t_obs = drms_getkey_time(rec, "T_OBS", &status); CHECK("T_OBS");
00697
00698 if (t_obs <= 0.0)
00699 { *rstatus = 2; return(NULL); }
00700
00701 if (t_obs != t_prev)
00702 {
00703 ObsLoc->crpix1 = drms_getkey_double(rec, "CRPIX1", &status); CHECK("CRPIX1");
00704 ObsLoc->crpix2 = drms_getkey_double(rec, "CRPIX2", &status); CHECK("CRPIX2");
00705 ObsLoc->crval1 = drms_getkey_double(rec, "CRVAL1", &status); CHECK("CRVAL1");
00706 ObsLoc->crval2 = drms_getkey_double(rec, "CRVAL2", &status); CHECK("CRVAL2");
00707 ObsLoc->cdelt1 = drms_getkey_double(rec, "CDELT1", &status); CHECK("CDELT1");
00708 ObsLoc->cdelt2 = drms_getkey_double(rec, "CDELT2", &status); CHECK("CDELT1");
00709 ObsLoc->crota2 = drms_getkey_double(rec, "CROTA2", &status); if (status) ObsLoc->crota2 = 0.0;
00710 ObsLoc->sina = sin(ObsLoc->crota2*Deg2Rad);
00711 ObsLoc->cosa = sqrt (1.0 - ObsLoc->sina*ObsLoc->sina);
00712 ObsLoc->rsun_obs = drms_getkey_double(rec, "RSUN_OBS", &status);
00713 ObsLoc->obs_vr = drms_getkey_double(rec, "OBS_VR", &status);
00714 ObsLoc->obs_vw = drms_getkey_double(rec, "OBS_VW", &status);
00715 ObsLoc->obs_vn = drms_getkey_double(rec, "OBS_VN", &status);
00716 ObsLoc->obs_b0 = drms_getkey_double(rec, "CRLT_OBS", &status);
00717 ObsLoc->t_obs = t_obs;
00718 }
00719 *rstatus = 0;
00720 return(ObsLoc);
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 const char *get_input_recset(DRMS_Env_t *drms_env, const char *inQuery)
00738 {
00739 static char newInQuery[102];
00740 TIME epoch = (cmdparams_exists(&cmdparams, "epoch")) ? params_get_time(&cmdparams, "epoch") : 0;
00741 DRMS_Array_t *data;
00742 TIME t_start, t_stop, t_now, t_want, t_diff, this_t_diff;
00743 int status = 1;
00744 int nrecs, irec;
00745 int nslots, islot;
00746 long long *recnums;
00747 TIME *t_this, half;
00748 TIME cadence;
00749 double *drecnum, *dquality;
00750 int quality;
00751 long long recnum;
00752 char keylist[DRMS_MAXQUERYLEN];
00753 static char filename[100];
00754 char *tmpdir;
00755 FILE *tmpfile;
00756 char newIn[DRMS_MAXQUERYLEN];
00757 char seriesname[DRMS_MAXQUERYLEN];
00758 char *lbracket;
00759 char *at = index(inQuery, '@');
00760
00761 if (at && *at && (strncmp(inQuery,"aia.lev1[", 9)==0 ||
00762 strncmp(inQuery,"hmi.lev1[", 9)==0 ||
00763 strncmp(inQuery,"aia.lev1_nrt2[",14)==0 ||
00764 strncmp(inQuery,"hmi.lev1_nrt[", 13)==0 ))
00765 {
00766 char *ip=(char *)inQuery, *op=newIn, *p;
00767 long n, mul;
00768
00769 char *segSpec = NULL;
00770 const char *psl = NULL;
00771 char *pbracket = NULL;
00772
00773 psl = strchr(inQuery, '{');
00774 if (psl)
00775 {
00776 segSpec = strdup(psl + 1);
00777
00778 if (!segSpec)
00779 {
00780 fprintf(stderr, "No memory.\n");
00781 return NULL;
00782 }
00783
00784 pbracket = strchr(segSpec, '}');
00785
00786 if (!pbracket)
00787 {
00788 fprintf(stderr, "Invalid segment specification.\n");
00789 return NULL;
00790 }
00791
00792 *pbracket = '\0';
00793
00794 if (!*segSpec)
00795 {
00796 fprintf(stderr, "Invalid segment specification.\n");
00797 return NULL;
00798 }
00799 }
00800
00801 while ( *ip && ip<at )
00802 *op++ = *ip++;
00803 ip++;
00804 n = strtol(ip, &p, 10);
00805 if (*p == 's') mul = 1;
00806 else if (*p == 'm') mul = 60;
00807 else if (*p == 'h') mul = 3600;
00808 else if (*p == 'd') mul = 86400;
00809 else
00810 {
00811 fprintf(stderr,"cant make sense of @xx cadence spec for aia or hmi lev1 data");
00812 return(NULL);
00813 }
00814 cadence = n * mul;
00815 ip = ++p;
00816 while ( *ip )
00817 *op++ = *ip++;
00818 *op = '\0';
00819 half = cadence/2.0;
00820 sprintf(keylist, "T_OBS,QUALITY,recnum");
00821 data = drms_record_getvector(drms_env, newIn, keylist, DRMS_TYPE_DOUBLE, 0, &status);
00822 if (!data || status)
00823 {
00824 fprintf(stderr,"getkey_vector failed status=%d\n", status);
00825 return(NULL);
00826 }
00827 nrecs = data->axis[1];
00828 irec = 0;
00829 t_this = (TIME *)data->data;
00830 dquality = (double *)data->data + 1*nrecs;
00831 drecnum = (double *)data->data + 2*nrecs;
00832 if (epoch > 0.0)
00833 {
00834 int s0 = (t_this[0] - epoch)/cadence;
00835 TIME t0 = s0*cadence + epoch;
00836 t_start = (t0 < t_this[0] ? t0 + cadence : t0);
00837 }
00838 else
00839 t_start = t_this[0];
00840 t_stop = t_this[nrecs-1];
00841 nslots = (t_stop - t_start + cadence/2)/cadence;
00842 recnums = (long long *)malloc(nslots*sizeof(long long));
00843 for (islot=0; islot<nslots; islot++)
00844 recnums[islot] = 0;
00845 islot = 0;
00846 t_want = t_start;
00847 t_diff = 1.0e9;
00848 for (irec = 0; irec<nrecs; irec++)
00849 {
00850 t_now = t_this[irec];
00851 quality = (int)dquality[irec] & 0xFFFFFFFF;
00852 recnum = (long long)drecnum[irec];
00853 this_t_diff = fabs(t_now - t_want);
00854 if (quality < 0)
00855 continue;
00856 if (t_now <= (t_want-half))
00857 continue;
00858 while (t_now > (t_want+half))
00859 {
00860 islot++;
00861 if (islot >= nslots)
00862 break;
00863 t_want = t_start + cadence * islot;
00864 this_t_diff = fabs(t_now - t_want);
00865 t_diff = 1.0e8;
00866 }
00867 if (islot < nslots && this_t_diff <= t_diff)
00868 recnums[islot] = recnum;
00869 t_diff = fabs(t_now - t_want);
00870 }
00871 if (islot+1 < nslots)
00872 nslots = islot+1;
00873 strcpy(seriesname, inQuery);
00874 lbracket = index(seriesname,'[');
00875 if (lbracket) *lbracket = '\0';
00876
00877 tmpdir = getenv("TMPDIR");
00878 if (!tmpdir) tmpdir = "/tmp";
00879 sprintf(filename, "%s/hg_patchXXXXXX", tmpdir);
00880 mkstemp(filename);
00881 tmpfile = fopen(filename,"w");
00882 for (islot=0; islot<nslots; islot++)
00883 if (recnums[islot])
00884 {
00885 if (!segSpec)
00886 {
00887 fprintf(tmpfile, "%s[:#%lld]\n", seriesname, recnums[islot]);
00888 }
00889 else
00890 {
00891 fprintf(tmpfile, "%s[:#%lld]{%s}\n", seriesname, recnums[islot], segSpec);
00892 }
00893 }
00894
00895 if (segSpec)
00896 {
00897 free(segSpec);
00898 }
00899
00900 fclose(tmpfile);
00901 free(recnums);
00902 drms_free_array(data);
00903 sprintf(newInQuery,"@%s", filename);
00904 return(newInQuery);
00905 }
00906 else
00907 return(inQuery);
00908 }