00001
00067 #include "jsoc.h"
00068 #include "jsoc_main.h"
00069 #include "fstats.h"
00070
00071 char *module_name = "resizeb3compwitherror";
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<4; vcomp++) {
00243 double power = 1.0;
00244 inSeg = drms_segment_lookupnum(inRec, vcomp);
00245 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00246 if (vcomp == 3) power = 2.0;
00247
00248 if (status)
00249 {
00250 printf(" No data file found but QUALITY not bad, status=%d\n", status);
00251 drms_free_array(inArray);
00252 continue;
00253 }
00254 if (crop || !as_is)
00255 {
00256 ObsLoc = GetObsInfo(inSeg, NULL, &status);
00257 if (!as_is) upNcenter(inArray, ObsLoc);
00258 if (crop) crop_image(inArray, ObsLoc);
00259 }
00260 else
00261 {
00262 ObsLoc = GetMinObsInfo(inSeg, NULL, &status);
00263 }
00264
00265 in_nx = inArray->axis[0];
00266 in_ny = inArray->axis[1];
00267 out_nx = in_nx * fscale + 0.5;
00268 out_ny = in_ny * fscale + 0.5;
00269 outDims[0] = out_nx; outDims[1] = out_ny;
00270 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, outDims, NULL, &status);
00271 inData = (float *)inArray->data;
00272 outData = (float *)outArray->data;
00273
00274 if (fscale > 1.0)
00275 {
00276 int out_go = (iscale-1)/2.0 + 0.5;
00277 for (iny = 0; iny < in_ny; iny += 1)
00278 for (inx = 0; inx < in_nx; inx += 1)
00279 {
00280 val = inData[in_nx*iny + inx];
00281 for (j = 0; j < nvector; j += 1)
00282 {
00283 outy = iny*iscale + out_go + j - vec_half;
00284 for (i = 0; i < nvector; i += 1)
00285 {
00286 outx = inx*iscale + out_go + i - vec_half;
00287 if (outx >= 0 && outx < out_nx && outy >= 0 && outy < out_ny)
00288 outData[out_nx*outy + outx] = val;
00289 }
00290 }
00291 }
00292 }
00293 else
00294 {
00295 int in_go = (iscale-1)/2.0 + 0.5;
00296 for (outy = 0; outy < out_ny; outy += 1)
00297 for (outx = 0; outx < out_nx; outx += 1)
00298 {
00299 double total = 0.0;
00300 double weight = 0.0;
00301 int nn = 0;
00302 for (j = 0; j < nvector; j += 1)
00303 {
00304 iny = outy*iscale + in_go + j - vec_half;
00305 for (i = 0; i < nvector; i += 1)
00306 {
00307 inx = outx*iscale + in_go + i - vec_half;
00308 if (inx >= 0 && inx < in_nx && iny >=0 && iny < in_ny)
00309 {
00310 val = inData[in_nx*(iny) + inx];
00311 if (!drms_ismissing_float(val))
00312 {
00313 double w = vector[i]*vector[j];
00314 total += pow(w*val, power);
00315 weight += w;
00316 nn++;
00317 }
00318 }
00319 }
00320 }
00321 if (vcomp == 3) total = sqrt(total);
00322 outData[out_nx*outy + outx] = (nn > 0 ? total/weight : DRMS_MISSING_FLOAT);
00323 }
00324 }
00325
00326
00327 outArray->bzero = inArray->bzero;
00328 outArray->bscale = inArray->bscale;
00329
00330 drms_free_array(inArray);
00331
00332
00333 outSeg = drms_segment_lookupnum(outRec, vcomp);
00334 outArray->parent_segment = outSeg;
00335 status = drms_segment_write(outSeg, outArray, 0);
00336 if (status)
00337 DIE("problem writing file");
00338 }
00339
00340
00341 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00342
00343
00344
00345 drms_setkey_double(outRec, "CDELT1", ObsLoc->cdelt1/fscale);
00346 drms_setkey_double(outRec, "CDELT2", ObsLoc->cdelt2/fscale);
00347 drms_setkey_double(outRec, "CRPIX1", (ObsLoc->crpix1-0.5) * fscale + 0.5);
00348 drms_setkey_double(outRec, "CRPIX2", (ObsLoc->crpix2-0.5) * fscale + 0.5);
00349 drms_setkey_double(outRec, "CROTA2", ObsLoc->crota2);
00350 mapmmax = drms_getkey_int(inRec, "MAPMMAX", &status);
00351 drms_setkey_int(outRec, "MAPMMAX", (mapmmax-0.5) * fscale + 0.5);
00352 sinbdivs = drms_getkey_int(inRec, "SINBDIVS", &status);
00353 drms_setkey_int(outRec, "SINBDIVS", (sinbdivs-0.5) * fscale + 0.5);
00354
00355 if (strcasecmp(method, "gaussian")==0)
00356 drms_setkey_double(outRec, "FWHM", fwhm);
00357 drms_appendhistory(outRec, history, 1);
00358 drms_setkey_time(outRec, "DATE", CURRENT_SYSTEM_TIME);
00359 if (strcmp(requestid, "NA") != 0)
00360 drms_setkey_string(outRec, "RequestID", requestid);
00361 drms_setkey_int(outRec, "TOTVALS_1", out_nx*out_ny);
00362 set_statistics(outSeg, outArray, 1);
00363 drms_free_array(outArray);
00364
00365 }
00366 }
00367
00368 drms_close_records(inRS, DRMS_FREE_RECORD);
00369 drms_close_records(outRS, DRMS_INSERT_RECORD);
00370 return (DRMS_SUCCESS);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379 int upNcenter(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00380 {
00381 int nx, ny, ix, iy, i, j, xoff, yoff, max_off;
00382 double rot, x0, y0, midx, midy;
00383 float *data;
00384 float *data2;
00385 if (!arr || !ObsLoc)
00386 return(1);
00387 data = arr->data;
00388 nx = arr->axis[0];
00389 ny = arr->axis[1];
00390 x0 = ObsLoc->crpix1 - 1;
00391 y0 = ObsLoc->crpix2 - 1;
00392 midx = (nx-1.0)/2.0;
00393 midy = (ny-1.0)/2.0;
00394 if ((rot = fabs(ObsLoc->crota2)) > 179 && rot < 181)
00395 {
00396
00397 float val;
00398 int half = ny / 2;
00399 int odd = ny & 1;
00400 if (odd) half++;
00401 for (iy=0; iy<half; iy++)
00402 {
00403 for (ix=0; ix<nx; ix++)
00404 {
00405 i = iy*nx + ix;
00406 j = (ny - 1 - iy)*nx + (nx - 1 - ix);
00407 val = data[i];
00408 data[i] = data[j];
00409 data[j] = val;
00410 }
00411 }
00412 x0 = nx - 1 - x0;
00413 y0 = ny - 1 - y0;
00414 rot = ObsLoc->crota2 - 180.0;
00415 if (rot < -90.0) rot += 360.0;
00416 ObsLoc->crota2 = rot;
00417 }
00418
00419 xoff = round(x0 - midx);
00420 yoff = round(y0 - midy);
00421 max_off = 20.0 / ObsLoc->cdelt1;
00422 if (arr->parent_segment &&
00423 arr->parent_segment->record &&
00424 arr->parent_segment->record->seriesinfo &&
00425 arr->parent_segment->record->seriesinfo->seriesname &&
00426 strncasecmp(arr->parent_segment->record->seriesinfo->seriesname, "aia", 3) &&
00427 abs(xoff) < max_off && abs(yoff) < max_off)
00428 {
00429 if (abs(xoff) >= 1 || abs(yoff) >= 1)
00430 {
00431 data2 = malloc(4*nx*ny);
00432 for (iy=0; iy<ny; iy++)
00433 {
00434 int jy = iy + yoff;
00435 for (ix=0; ix<nx; ix++)
00436 {
00437 int jx = ix + xoff;
00438 int idx = jy*nx + jx;
00439 int idx2 = iy*nx + ix;
00440 if (jx<0 || jx>=nx || jy<0 || jy>=ny)
00441 data2[idx2] = DRMS_MISSING_FLOAT;
00442 else
00443 data2[idx2] = data[idx];
00444 }
00445 }
00446 x0 -= xoff;
00447 y0 -= yoff;
00448 free(data);
00449 arr->data = data2;
00450 }
00451 }
00452
00453 ObsLoc->crpix1 = x0 + 1;
00454 ObsLoc->crpix2 = y0 + 1;
00455 return(0);
00456 }
00457
00458
00459
00460 int crop_image(DRMS_Array_t *arr, ObsInfo_t *ObsLoc)
00461 {
00462 int nx, ny, ix, iy, i, j, xoff, yoff;
00463 double x0, y0;
00464 double rsun = ObsLoc->rsun_obs/ObsLoc->cdelt1;
00465 double scale, crop_limit2;
00466 float *data;
00467 if (!arr || !ObsLoc)
00468 return(1);
00469 data = arr->data;
00470 nx = arr->axis[0];
00471 ny = arr->axis[1];
00472 x0 = ObsLoc->crpix1 - 1;
00473 y0 = ObsLoc->crpix2 - 1;
00474 scale = 1.0/rsun;
00475
00476 crop_limit2 = 0.99950;
00477 for (iy=0; iy<ny; iy++)
00478 for (ix=0; ix<nx; ix++)
00479 {
00480 double x, y, R2;
00481 float *Ip = data + iy*nx + ix;
00482 if (drms_ismissing_float(*Ip))
00483 continue;
00484 x = ((double)ix - x0) * scale;
00485 y = ((double)iy - y0) * scale;
00486 R2 = x*x + y*y;
00487 if (R2 > crop_limit2)
00488 *Ip = DRMS_MISSING_FLOAT;
00489 }
00490 return(0);
00491 }
00492
00493
00494
00495 #define CHECK(keyname) {if (status) {fprintf(stderr,"Keyword failure to find: %s, status=%d\n",keyname,status); *rstatus=status; return(NULL);}}
00496
00497 ObsInfo_t *GetObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus)
00498 {
00499 TIME t_prev;
00500 DRMS_Record_t *rec;
00501 TIME t_obs;
00502 double dv;
00503 ObsInfo_t *ObsLoc;
00504 int status;
00505
00506 if (!seg || !(rec = seg->record))
00507 { *rstatus = 1; return(NULL); }
00508
00509 ObsLoc = (pObsLoc ? pObsLoc : (ObsInfo_t *)malloc(sizeof(ObsInfo_t)));
00510 if (!pObsLoc)
00511 memset(ObsLoc, 0, sizeof(ObsInfo_t));
00512
00513 t_prev = ObsLoc->t_obs;
00514 t_obs = drms_getkey_time(rec, "T_OBS", &status); CHECK("T_OBS");
00515
00516 if (t_obs <= 0.0)
00517 { *rstatus = 2; return(NULL); }
00518
00519 if (t_obs != t_prev)
00520 {
00521 ObsLoc->crpix1 = drms_getkey_double(rec, "CRPIX1", &status); CHECK("CRPIX1");
00522 ObsLoc->crpix2 = drms_getkey_double(rec, "CRPIX2", &status); CHECK("CRPIX2");
00523 ObsLoc->crval1 = drms_getkey_double(rec, "CRVAL1", &status); CHECK("CRVAL1");
00524 ObsLoc->crval2 = drms_getkey_double(rec, "CRVAL2", &status); CHECK("CRVAL2");
00525 ObsLoc->cdelt1 = drms_getkey_double(rec, "CDELT1", &status); CHECK("CDELT1");
00526 ObsLoc->cdelt2 = drms_getkey_double(rec, "CDELT2", &status); CHECK("CDELT1");
00527 ObsLoc->crota2 = drms_getkey_double(rec, "CROTA2", &status); if (status) ObsLoc->crota2 = 0.0;
00528 ObsLoc->sina = sin(ObsLoc->crota2*Deg2Rad);
00529 ObsLoc->cosa = sqrt (1.0 - ObsLoc->sina*ObsLoc->sina);
00530 ObsLoc->rsun_obs = drms_getkey_double(rec, "RSUN_OBS", &status);
00531 if (status)
00532 {
00533 double dsun_obs = drms_getkey_double(rec, "DSUN_OBS", &status); CHECK("DSUN_OBS");
00534 ObsLoc->rsun_obs = asin(696000000.0/dsun_obs)/arcsec2Rad;
00535 }
00536 ObsLoc->obs_vr = drms_getkey_double(rec, "OBS_VR", &status); CHECK("OBS_VR");
00537 ObsLoc->obs_vw = drms_getkey_double(rec, "OBS_VW", &status); CHECK("OBS_VW");
00538 ObsLoc->obs_vn = drms_getkey_double(rec, "OBS_VN", &status); CHECK("OBS_VN");
00539 ObsLoc->obs_b0 = drms_getkey_double(rec, "CRLT_OBS", &status); CHECK("CRLT_OBS");
00540 ObsLoc->t_obs = t_obs;
00541 }
00542 *rstatus = 0;
00543 return(ObsLoc);
00544 }
00545
00546
00547 ObsInfo_t *GetMinObsInfo(DRMS_Segment_t *seg, ObsInfo_t *pObsLoc, int *rstatus)
00548 {
00549 TIME t_prev;
00550 DRMS_Record_t *rec;
00551 TIME t_obs;
00552 double dv;
00553 ObsInfo_t *ObsLoc;
00554 int status;
00555
00556 if (!seg || !(rec = seg->record))
00557 { *rstatus = 1; return(NULL); }
00558
00559 ObsLoc = (pObsLoc ? pObsLoc : (ObsInfo_t *)malloc(sizeof(ObsInfo_t)));
00560 if (!pObsLoc)
00561 memset(ObsLoc, 0, sizeof(ObsInfo_t));
00562
00563 t_prev = ObsLoc->t_obs;
00564 t_obs = drms_getkey_time(rec, "T_OBS", &status); CHECK("T_OBS");
00565
00566 if (t_obs <= 0.0)
00567 { *rstatus = 2; return(NULL); }
00568
00569 if (t_obs != t_prev)
00570 {
00571 ObsLoc->crpix1 = drms_getkey_double(rec, "CRPIX1", &status); CHECK("CRPIX1");
00572 ObsLoc->crpix2 = drms_getkey_double(rec, "CRPIX2", &status); CHECK("CRPIX2");
00573 ObsLoc->crval1 = drms_getkey_double(rec, "CRVAL1", &status); CHECK("CRVAL1");
00574 ObsLoc->crval2 = drms_getkey_double(rec, "CRVAL2", &status); CHECK("CRVAL2");
00575 ObsLoc->cdelt1 = drms_getkey_double(rec, "CDELT1", &status); CHECK("CDELT1");
00576 ObsLoc->cdelt2 = drms_getkey_double(rec, "CDELT2", &status); CHECK("CDELT1");
00577 ObsLoc->crota2 = drms_getkey_double(rec, "CROTA2", &status); if (status) ObsLoc->crota2 = 0.0;
00578 ObsLoc->sina = sin(ObsLoc->crota2*Deg2Rad);
00579 ObsLoc->cosa = sqrt (1.0 - ObsLoc->sina*ObsLoc->sina);
00580 ObsLoc->rsun_obs = drms_getkey_double(rec, "RSUN_OBS", &status);
00581 ObsLoc->obs_vr = drms_getkey_double(rec, "OBS_VR", &status);
00582 ObsLoc->obs_vw = drms_getkey_double(rec, "OBS_VW", &status);
00583 ObsLoc->obs_vn = drms_getkey_double(rec, "OBS_VN", &status);
00584 ObsLoc->obs_b0 = drms_getkey_double(rec, "CRLT_OBS", &status);
00585 ObsLoc->t_obs = t_obs;
00586 }
00587 *rstatus = 0;
00588 return(ObsLoc);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 const char *get_input_recset(DRMS_Env_t *drms_env, const char *inQuery)
00606 {
00607 static char newInQuery[102];
00608 TIME epoch = (cmdparams_exists(&cmdparams, "epoch")) ? params_get_time(&cmdparams, "epoch") : 0;
00609 DRMS_Array_t *data;
00610 TIME t_start, t_stop, t_now, t_want, t_diff, this_t_diff;
00611 int status = 1;
00612 int nrecs, irec;
00613 int nslots, islot;
00614 long long *recnums;
00615 TIME *t_this, half;
00616 TIME cadence;
00617 double *drecnum, *dquality;
00618 int quality;
00619 long long recnum;
00620 char keylist[DRMS_MAXQUERYLEN];
00621 static char filename[100];
00622 char *tmpdir;
00623 FILE *tmpfile;
00624 char newIn[DRMS_MAXQUERYLEN];
00625 char seriesname[DRMS_MAXQUERYLEN];
00626 char *lbracket;
00627 char *at = index(inQuery, '@');
00628 if (at && *at && (strncmp(inQuery,"aia.lev1[", 9)==0 ||
00629 strncmp(inQuery,"hmi.lev1[", 9)==0 ||
00630 strncmp(inQuery,"aia.lev1_nrt2[",14)==0 ||
00631 strncmp(inQuery,"hmi.lev1_nrt[", 13)==0 ))
00632 {
00633 char *ip=(char *)inQuery, *op=newIn, *p;
00634 long n, mul;
00635 while ( *ip && ip<at )
00636 *op++ = *ip++;
00637 ip++;
00638 n = strtol(ip, &p, 10);
00639 if (*p == 's') mul = 1;
00640 else if (*p == 'm') mul = 60;
00641 else if (*p == 'h') mul = 3600;
00642 else if (*p == 'd') mul = 86400;
00643 else
00644 {
00645 fprintf(stderr,"cant make sense of @xx cadence spec for aia or hmi lev1 data");
00646 return(NULL);
00647 }
00648 cadence = n * mul;
00649 ip = ++p;
00650 while ( *ip )
00651 *op++ = *ip++;
00652 *op = '\0';
00653 half = cadence/2.0;
00654 sprintf(keylist, "T_OBS,QUALITY,recnum");
00655 data = drms_record_getvector(drms_env, newIn, keylist, DRMS_TYPE_DOUBLE, 0, &status);
00656 if (!data || status)
00657 {
00658 fprintf(stderr,"getkey_vector failed status=%d\n", status);
00659 return(NULL);
00660 }
00661 nrecs = data->axis[1];
00662 irec = 0;
00663 t_this = (TIME *)data->data;
00664 dquality = (double *)data->data + 1*nrecs;
00665 drecnum = (double *)data->data + 2*nrecs;
00666 if (epoch > 0.0)
00667 {
00668 int s0 = (t_this[0] - epoch)/cadence;
00669 TIME t0 = s0*cadence + epoch;
00670 t_start = (t0 < t_this[0] ? t0 + cadence : t0);
00671 }
00672 else
00673 t_start = t_this[0];
00674 t_stop = t_this[nrecs-1];
00675 nslots = (t_stop - t_start + cadence/2)/cadence;
00676 recnums = (long long *)malloc(nslots*sizeof(long long));
00677 for (islot=0; islot<nslots; islot++)
00678 recnums[islot] = 0;
00679 islot = 0;
00680 t_want = t_start;
00681 t_diff = 1.0e9;
00682 for (irec = 0; irec<nrecs; irec++)
00683 {
00684 t_now = t_this[irec];
00685 quality = (int)dquality[irec] & 0xFFFFFFFF;
00686 recnum = (long long)drecnum[irec];
00687 this_t_diff = fabs(t_now - t_want);
00688 if (quality < 0)
00689 continue;
00690 if (t_now <= (t_want-half))
00691 continue;
00692 while (t_now > (t_want+half))
00693 {
00694 islot++;
00695 if (islot >= nslots)
00696 break;
00697 t_want = t_start + cadence * islot;
00698 this_t_diff = fabs(t_now - t_want);
00699 t_diff = 1.0e8;
00700 }
00701 if (this_t_diff <= t_diff)
00702 recnums[islot] = recnum;
00703 t_diff = fabs(t_now - t_want);
00704 }
00705 if (islot+1 < nslots)
00706 nslots = islot+1;
00707 strcpy(seriesname, inQuery);
00708 lbracket = index(seriesname,'[');
00709 if (lbracket) *lbracket = '\0';
00710 tmpdir = getenv("TMPDIR");
00711 if (!tmpdir) tmpdir = "/tmp";
00712 sprintf(filename, "%s/hg_patchXXXXXX", tmpdir);
00713 mkstemp(filename);
00714 tmpfile = fopen(filename,"w");
00715 for (islot=0; islot<nslots; islot++)
00716 if (recnums[islot])
00717 fprintf(tmpfile, "%s[:#%lld]\n", seriesname, recnums[islot]);
00718 fclose(tmpfile);
00719 free(recnums);
00720 drms_free_array(data);
00721 sprintf(newInQuery,"@%s", filename);
00722 return(newInQuery);
00723 }
00724 else
00725 return(inQuery);
00726 }