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