00001
00140 #include "jsoc.h"
00141 #include "jsoc_main.h"
00142 #include "astro.h"
00143 #include "fstats.h"
00144 #include "atoinc.h"
00145 #include <math.h>
00146
00147 int get_tracking_xy(char *FDSfile, TIME want, double *xp, double *yp, double *radius);
00148 void HeliographicLocation(TIME t, int *crot, double *L, double *B);
00149 TIME HeliographicTime(int crot, double L);
00150
00151 char *module_name = "im_patch";
00152
00153 #define DIE(msg) {fprintf(stderr,"%s Status=%d\n",msg, status); return(status?status:1);}
00154 #define DIE2(msg,val) {fprintf(stderr,"%s %s, Status=%d\n",msg, val, status); return(status?status:1);}
00155 #define TEST_PARAM(param) {if (status) DIE2("Required keyword missing: ", param);}
00156
00157 #define Deg2Rad (M_PI/180.0)
00158 #define Rad2arcsec (3600.0/Deg2Rad)
00159 #define Rad2Deg (180.0/M_PI)
00160
00161 ModuleArgs_t module_args[] =
00162 {
00163 {ARG_STRING, "in", "NOTSPECIFIED", "input series. e.g 'mdi.fd_M_96m_lev18'"},
00164 {ARG_STRING, "out", "NOTSPECIFIED", "output seies. e.g. 'su_bala.extractreg'"},
00165 {ARG_STRING, "log", "NOTSPECIFIED", "output log file of records made"},
00166 {ARG_STRING, "requestid", "NOTSPECIFIED", "RequestID if im_patch call originated in an export request."},
00167 {ARG_INT, "car_rot", "-1", "Carrington Rotation when the region crosses CM"},
00168 {ARG_FLOAT, "width", "0", "width of box in boxunits (conversion to pixels made when at CM)"},
00169 {ARG_FLOAT, "height", "0", "height of box in boxunits (conversion to pixels made when at CM)"},
00170 {ARG_STRING, "boxunits", "NOTSPECIFIED", "units of patch, 'pixels', 'arcsecs', or 'degrees'"},
00171 {ARG_TIME, "t_start", "JD_0", "Start time, defaults to time at 90E"},
00172 {ARG_TIME, "t_stop", "JD_0", "End time, defauolts to 90W"},
00173 {ARG_TIME, "cadence", "NOTSPECIFIED", "Cadence of product, defaults to input cadence."},
00174 {ARG_TIME, "t_ref", "JD_0", "Time for which x and y apply, implies ref image."},
00175 {ARG_STRING, "locunits", "NOTSPECIFIED", "Location units in 'pixels', 'arcsec', 'stony', or 'carrlong'"},
00176 {ARG_STRING, "where", "NOTSPECIFIED", "Additional 'where' clause if needed"},
00177 {ARG_FLOAT, "x", "0", "Location of extract box center in pixels in array (1,1), arcsec from Sun center, degrees from Sun center, or Carrington longitude"},
00178 {ARG_FLOAT, "y", "0", "Location of extract box center, same units as x"},
00179 {ARG_FLAG, "A", NULL, "Generate output for all input segments"},
00180 {ARG_FLAG, "t", "0", "Disable Carrington rate tracking"},
00181 {ARG_FLAG, "h", "0", "Export keywords, i.e. include full metadata in FITS files"},
00182 {ARG_FLAG, "c", "0", "Crop at limb, useful for HMI M data."},
00183 {ARG_FLAG, "f", "0", "FAKE tracking target added, val=0"},
00184 {ARG_FLAG, "F", "0", "FAKE tracking target added, val=datamax"},
00185 {ARG_FLAG, "r", "0", "Register to fractional CRPIXi, all frames to first frame round(crpix)"},
00186 {ARG_STRING, "FDS", "NOTSPECIFIED", "FDS file for tracking coords"},
00187 {ARG_END}
00188 };
00189
00190 int img2sphere (double x, double y, double ang_r, double latc, double lonc,
00191 double pa, double *rho, double *lat, double *lon, double *sinlat,
00192 double *coslat, double *sig, double *mu, double *chi);
00193 int sphere2img (double lat, double lon, double latc, double lonc,
00194 double *x, double *y, double xcenter, double ycenter,
00195 double rsun, double peff, double ecc, double chi,
00196 int xinvrt, int yinvrt);
00197 int image_magrotate(void *, int nin, int min, int data_type_input, float theta, float mag,
00198 float dx, float dy, void **outarray, int *nx, int *ny, int regridtype_input, int stretch_lines);
00199
00200
00201
00202 char *get_input_recset(DRMS_Env_t *drms_env, char *inQuery);
00203
00204
00205
00206
00207
00208 #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
00209 #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
00210 #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
00211 #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
00212
00213 #define BOXBAD 0
00214 #define BOXARCSEC 1
00215 #define BOXPIXELS 2
00216 #define BOXDEGREE 3
00217
00218 #define LOCBAD 0
00219 #define LOCARCSEC 1
00220 #define LOCPIXELS 2
00221 #define LOCSTONY 3
00222 #define LOCCARR 4
00223
00224 #define TIMES_RECSET 0 // recordset spec contains time range
00225 #define TIMES_GIVEN 1 // explicit t_start and t_stop provided
00226 #define TIMES_IMPLICIT 2 // times to be deduced for disk transit of specified box
00227 int DoIt(void)
00228 {
00229 CmdParams_t *params = &cmdparams;
00230 DRMS_RecordSet_t *inRS = NULL;
00231 DRMS_RecordSet_t *outRS = NULL;
00232 DRMS_Record_t *inRec = NULL;
00233 DRMS_Record_t *outRec = NULL;
00234 DRMS_Record_t *inTemplate = NULL;
00235 DRMS_Record_t *outTemplate = NULL;
00236 DRMS_Segment_t *inSeg = NULL;
00237 DRMS_Segment_t *outSeg = NULL;
00238 DRMS_Array_t *inArray = NULL;
00239 DRMS_Array_t *outArray = NULL;
00240 int i, ii, status = DRMS_SUCCESS, nrecs;
00241 int irec;
00242 int OK_recs = 0;
00243 double center_x, center_y, crpix1, crpix2, x0, y0;
00244 double rsun_ref, dsun_obs, rsun, rsun_rad, rsunpix;
00245 double r2;
00246 double this_x0;
00247 double this_y0;
00248 double crln_obs, crlt_obs;
00249 double crln_obs_rad, crlt_obs_rad;
00250 double crln_rad, crlt_rad;
00251 double pa_rad;
00252 double cdelt;
00253 double llx, lly;
00254 int inAxis[2];
00255 int this_car_rot;
00256 char *ctype1, *ctype2;
00257 TIME t_rec;
00258 double box_x, box_y;
00259 double crln, crlt;
00260 char outseries[DRMS_MAXSERIESNAMELEN];
00261 char inseries[DRMS_MAXSERIESNAMELEN];
00262 char extractedSeries[DRMS_MAXSERIESNAMELEN];
00263 int is_mod;
00264 char testseries[DRMS_MAXSERIESNAMELEN];
00265 char inQuery[DRMS_MAXQUERYLEN];
00266 char in[DRMS_MAXQUERYLEN];
00267
00268 const char *ingiven = params_get_str(params, "in");
00269 char *inparam;
00270 char *lbracket, *rbracket;
00271 char *moreQuery = NULL;
00272 const char *outparam = params_get_str(params, "out");
00273 const char *logfile = params_get_str(params, "log");
00274 const char *requestid = params_get_str(params, "requestid");
00275 const char *where = params_get_str(params, "where");
00276 const char *FDSfile = params_get_str(params, "FDS");
00277 TIME t_start = params_get_time(params, "t_start");
00278 TIME t_stop = params_get_time(params, "t_stop");
00279 const char *cadence_str = params_get_str(params, "cadence");
00280 double cadence;
00281 TIME t_ref = params_get_time(params, "t_ref");
00282 double width = params_get_double(params, "width");
00283 double height = params_get_double(params, "height");
00284 int pixwidth, pixheight;
00285 double midx, midy;
00286 int car_rot = params_get_int(params, "car_rot");
00287 double x = params_get_double(params, "x");
00288 double y = params_get_double(params, "y");
00289 const char *boxunits = params_get_str(params, "boxunits");
00290 const char *locunits = params_get_str(params, "locunits");
00291 int NoTrack = params_isflagset(params, "t");
00292 int wantFAKEwhite = params_isflagset(params, "F");
00293 int wantFAKE = params_isflagset(params, "f") || wantFAKEwhite;
00294 int do_register = params_isflagset(params, "r");
00295 int export_keys = params_isflagset(params, "h");
00296 int do_crop = params_isflagset(params, "c");
00297 TIME tNotSpecified = sscan_time("JD_0");
00298 int do_reftime = 0;
00299 double crvalx = 0.0;
00300 double crvaly = 0.0;
00301 double crota, sina, cosa;
00302 double pa, deltlong;
00303 double target_x, target_y;
00304 int firstimage = 1;
00305 int boxtype, loctype;
00306 char *timekeyname;
00307 TIME t_step, t_epoch;
00308 int npkeys;
00309 int times_source = TIMES_RECSET;
00310 char timebuf[20];
00311 char *in_filename = NULL;
00312 double trackx, tracky;
00313 double track_radius;
00314 double crpix1_0, crpix2_0;
00315 int register_padding = 60;
00316 char *tmpstr = NULL;
00317 int hasSegList = 0;
00318 int doingAllSegs = params_isflagset(params, "A");
00319
00320 FILE *log = NULL;
00321
00322 if (strcmp(FDSfile,"NOTSPECIFIED")==0)
00323 FDSfile = NULL;
00324
00325 if (strncasecmp(locunits, "arcsec", 6) == 0) loctype = LOCARCSEC;
00326 else if (strncasecmp(locunits, "pixels", 3) == 0) loctype = LOCPIXELS;
00327 else if (strncasecmp(locunits, "stony", 5) == 0) loctype = LOCSTONY;
00328 else if (strncasecmp(locunits, "carrlong", 4) == 0) loctype = LOCCARR;
00329 else loctype = LOCBAD;
00330
00331 if (strncasecmp(boxunits, "arcsec", 6) == 0) boxtype = BOXARCSEC;
00332 else if (strncasecmp(boxunits, "pixels", 3) == 0) boxtype = BOXPIXELS;
00333 else if (strncasecmp(boxunits, "degrees", 3) == 0) boxtype = BOXDEGREE;
00334 else loctype = BOXBAD;
00335
00336 if (loctype == LOCCARR)
00337 {
00338 if (car_rot < 0) DIE("Carrington rotation number must be provided for locunits=carrlong");
00339
00340 do_reftime = 0;
00341 }
00342 else
00343 {
00344 if (t_ref < 0)
00345 DIE("t_ref must be provided for locunits!=carrlong");
00346 do_reftime = 1;
00347 }
00348
00349 if (loctype==LOCBAD)
00350 DIE2("Location units not detected, locunits", locunits)
00351 if (boxtype==BOXBAD)
00352 DIE2("patch dimensions not understood,", boxunits);
00353
00354 if (strcasecmp(logfile, "NOTSPECIFIED") != 0)
00355 {
00356 log = fopen(logfile, "w");
00357 if (!log) DIE2("Can not create log file.",logfile);
00358 }
00359
00360 if (strcasecmp(where, "NOTSPECIFIED") == 0 || *where == '\0')
00361 {
00362 where = "";
00363 }
00364 else
00365 {
00366 char wherework[4096];
00367 sprintf(wherework,"[? %s ?]", where);
00368 where = strdup(wherework);
00369 }
00370
00371
00372
00373
00374
00375
00376 char *testSegList = NULL;
00377 char *pCh = NULL;
00378
00379 testSegList = rindex(ingiven, '}');
00380 if (testSegList)
00381 {
00382 for (pCh = testSegList + 1, hasSegList = 1; *pCh; pCh++)
00383 {
00384 if (!isspace(*pCh))
00385 {
00386
00387 hasSegList = 0;
00388 break;
00389 }
00390 }
00391 }
00392
00393 inparam = strdup(ingiven);
00394 if (strcasecmp(inparam, "NOTSPECIFIED") == 0) DIE("Input series must be specified.");
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 char *allvers = NULL;
00410 char **sets = NULL;
00411 DRMS_RecordSetType_t *settypes = NULL;
00412 char **snames = NULL;
00413 char **filts = NULL;
00414 int nsets = 0;
00415 DRMS_RecQueryInfo_t rsinfo;
00416 DRMS_Keyword_t *firstPKey = NULL;
00417
00418 if (drms_record_parserecsetspec(inparam, &allvers, &sets, &settypes, &snames, &filts, &nsets, &rsinfo) == DRMS_SUCCESS)
00419 {
00420 if (nsets > 1)
00421 {
00422 status = DRMS_ERROR_INVALIDDATA;
00423 DIE("im_patch supports single-set record-set specifications only.");
00424 }
00425 }
00426 else
00427 {
00428 status = DRMS_ERROR_INVALIDDATA;
00429 DIE("Invalid record-set specification provided.");
00430 }
00431
00432 snprintf(inseries, sizeof(inseries), "%s", snames[0]);
00433 lbracket = index(inparam, '[');
00434
00435 inTemplate = drms_template_record(drms_env, inseries, &status);
00436 if (status || !inTemplate) DIE2("Input series can not be found: ", inseries);
00437
00438 if (drms_keyword_isindex(inTemplate->seriesinfo->pidx_keywords[0]))
00439 {
00440 firstPKey = drms_keyword_slotfromindex(inTemplate->seriesinfo->pidx_keywords[0]);
00441 }
00442 else
00443 {
00444 firstPKey = inTemplate->seriesinfo->pidx_keywords[0];
00445 }
00446
00447 if (firstPKey->info->type != DRMS_TYPE_TIME)
00448 {
00449 status = DRMS_ERROR_INVALIDDATA;
00450 DIE("The first prime-key constituent keyword must be of type TIME.");
00451 }
00452
00453 if (filts && filts[0])
00454 {
00455 if (strlen(filts[0]) == 3 && filts[0][1] == '$')
00456 {
00457
00458 moreQuery = lbracket + 3;
00459 *lbracket = '\0';
00460 lbracket = NULL;
00461
00462 if (t_start == tNotSpecified || t_stop == tNotSpecified)
00463 times_source = TIMES_IMPLICIT;
00464 else
00465 times_source = TIMES_GIVEN;
00466 }
00467 else
00468 {
00469 rbracket = index(lbracket, ']');
00470 moreQuery = rbracket ? rbracket + 1 : lbracket;
00471 }
00472 }
00473 else
00474 {
00475
00476 if (t_start == tNotSpecified || t_stop == tNotSpecified)
00477 times_source = TIMES_IMPLICIT;
00478 else
00479 times_source = TIMES_GIVEN;
00480 }
00481
00482 drms_record_freerecsetspecarr(&allvers, &sets, &settypes, &snames, &filts, nsets);
00483
00484
00485 if (do_reftime)
00486 {
00487 fprintf(stderr,"doing reftime\n");
00488 int okrec = -1;
00489 char t_ref_pre[100];
00490 char t_ref_post[100];
00491 TIME search_width = 15;
00492 while (search_width < 10000)
00493 {
00494 sprint_at(t_ref_pre, t_ref-search_width);
00495 sprint_at(t_ref_post, t_ref+search_width);
00496 sprintf(in, "%s[%s-%s][? QUALITY >= 0 ?]%s%s", inseries, t_ref_pre, t_ref_post, moreQuery, where);
00497 fprintf(stderr,"searchwidth=%f, t_ref query is: %s\n",search_width,in);
00498 inRS = drms_open_records(drms_env, in, &status);
00499 if (!status && inRS->n > 0)
00500 {
00501 int irec, nrecs = inRS->n;
00502 TIME tdiff = 100000;
00503 for (irec=0, okrec=-1; irec<nrecs; irec++)
00504 {
00505 TIME newdiff;
00506 inRec = inRS->records[irec];
00507 fprintf(stderr,"irec=%d, tdiff=%lf\n",irec,tdiff);
00508 if ((newdiff=(fabs(drms_getkey_time(inRec,"T_OBS",NULL) - t_ref))) > tdiff)
00509 break;
00510 okrec = irec;
00511 tdiff = newdiff;
00512 }
00513 }
00514 if (okrec >= 0)
00515 break;
00516 search_width *= 2;
00517 drms_close_records(inRS, DRMS_FREE_RECORD);
00518 }
00519 if (search_width >= 10000)
00520 DIE2("No input data found within 2-hours of t_ref",in);
00521 inRec = inRS->records[okrec];
00522 this_car_rot = drms_getkey_int(inRec, "CAR_ROT", &status); TEST_PARAM("CAR_ROT");
00523 crlt_obs = drms_getkey_double(inRec, "CRLT_OBS", &status); TEST_PARAM("CRLT_OBS");
00524 crln_obs = drms_getkey_double(inRec, "CRLN_OBS", &status); TEST_PARAM("CRLN_OBS");
00525 crpix1 = drms_getkey_double(inRec, "CRPIX1", &status); TEST_PARAM("CRPIX1");
00526 x0 = crpix1 - 1;
00527 crpix2 = drms_getkey_double(inRec, "CRPIX2", &status); TEST_PARAM("CRPIX2");
00528 y0 = crpix2 - 1;
00529 crvalx = drms_getkey_double(inRec, "CRVAL1", &status); TEST_PARAM("CRVAL1");
00530 crvaly = drms_getkey_double(inRec, "CRVAL2", &status); TEST_PARAM("CRVAL2");
00531 crota = drms_getkey_double(inRec, "CROTA2", &status); if (status) crota = 0.0;
00532 pa = -crota;
00533 crlt_obs_rad = Deg2Rad * crlt_obs;
00534 crln_obs_rad = Deg2Rad * crln_obs;
00535 pa_rad = Deg2Rad * pa;
00536 sina = sin(crota*Deg2Rad);
00537 cosa = cos(crota*Deg2Rad);
00538 tmpstr = drms_getkey_string(inRec, "CTYPE1", &status);
00539 ctype1 = strdup(tmpstr); TEST_PARAM("CTYPE1");
00540 if (tmpstr)
00541 {
00542 free(tmpstr);
00543 }
00544 if (strcmp(ctype1, "HPLN-TAN") != 0)
00545 DIE2("CTYPE1 not HPLN-TAN as required, is: ", ctype1);
00546 if (ctype1)
00547 {
00548 free(ctype1);
00549 ctype1 = NULL;
00550 }
00551 tmpstr = drms_getkey_string(inRec, "CTYPE2", &status);
00552 ctype2 = strdup(tmpstr); TEST_PARAM("CTYPE2");
00553 if (tmpstr)
00554 {
00555 free(tmpstr);
00556 }
00557 if (strcmp(ctype2, "HPLT-TAN") != 0)
00558 DIE2("CTYPE2 not HPLT-TAN as required, is: ", ctype2);
00559 if (ctype2)
00560 {
00561 free(ctype2);
00562 ctype2 = NULL;
00563 }
00564 rsun_ref = drms_getkey_double(inRec, "RSUN_REF", &status);
00565 if (status)
00566 rsun_ref = 6.96e8;
00567 dsun_obs = drms_getkey_double(inRec, "DSUN_OBS", &status); TEST_PARAM("DSUN_OBS");
00568 rsun_rad = asin(rsun_ref/dsun_obs);
00569 rsun = rsun_rad*Rad2arcsec;
00570 cdelt = drms_getkey_double(inRec, "CDELT1", &status); TEST_PARAM("CDELT1");
00571 rsunpix = rsun/cdelt;
00572 if (loctype == LOCPIXELS || loctype==LOCARCSEC)
00573 {
00574
00575
00576 if (loctype==LOCARCSEC)
00577 {
00578 center_x = PIX_X(x,y) - 1;
00579 center_y = PIX_Y(x,y) - 1;
00580 }
00581 else
00582 {
00583 center_x = x - 1;
00584 center_y = y - 1;
00585 }
00586
00587 inSeg = drms_segment_lookupnum(inRec, 0);
00588 inAxis[0] = inSeg->axis[0];
00589 inAxis[1] = inSeg->axis[1];
00590 if ( img2sphere((center_x - x0)/rsunpix, (center_y -y0)/rsunpix, rsun_rad, crlt_obs_rad, crln_obs_rad, pa_rad,
00591 NULL, &crlt_rad, &crln_rad, NULL, NULL, NULL, NULL, NULL) < 0)
00592 fprintf(stderr, "Starting location is off the solar disk.");
00593 crln = crln_rad * Rad2Deg;
00594 crlt = crlt_rad * Rad2Deg;
00595 fprintf(stderr,"at do reftime, center_x=%f\n", center_x);
00596 }
00597 else
00598 {
00599 crlt = y;
00600 crln = crln_obs + x;
00601 sphere2img(crlt/Rad2Deg, crln/Rad2Deg, crlt_obs_rad, crln_obs_rad, ¢er_x, ¢er_y, x0, y0, rsunpix, pa_rad, 0, 0, 0, 0);
00602 }
00603 deltlong = crln - crln_obs;
00604 car_rot = this_car_rot;
00605 if (crln >= 360.0)
00606 { car_rot--; crln -= 360.0; }
00607 else if (crln < 0)
00608 { car_rot++; crln += 360.0; }
00609 drms_close_records(inRS, DRMS_FREE_RECORD);
00610 }
00611 else
00612 {
00613 crln = x;
00614 crlt = y;
00615 if (crln < 0) DIE("Box longitude must be specified.");
00616 if (crlt < -990) DIE("box latitude must be specified.");
00617 sphere2img(crlt/Rad2Deg, crln/Rad2Deg, crlt_obs_rad, crln_obs_rad, ¢er_x, ¢er_y, x0, y0, rsunpix, pa_rad, 0, 0, 0, 0);
00618 }
00619 crln_rad = crln * Deg2Rad;
00620 crlt_rad = crlt * Deg2Rad;
00621
00622
00623
00624
00625
00626
00627 t_ref = HeliographicTime(car_rot, crln);
00628 if (times_source == TIMES_IMPLICIT)
00629 {
00630 if (t_start == tNotSpecified)
00631 {
00632 if (NoTrack) DIE("Must have t_start or explicit times for NoTrack");
00633 t_start = HeliographicTime(car_rot, crln + 90);
00634 }
00635 if (t_stop == tNotSpecified)
00636 {
00637 if (NoTrack) DIE("Must have t_stop or explicit times for NoTrack");
00638 t_stop = HeliographicTime(car_rot, crln - 90);
00639 }
00640 }
00641
00642
00643
00644
00645 is_mod = 0;
00646 if (strcasecmp(outparam, "NOTSPECIFIED") == 0)
00647 {
00648 strncpy(outseries, inseries, DRMS_MAXSERIESNAMELEN);
00649 strncat(outseries, "_mod", DRMS_MAXSERIESNAMELEN);
00650 is_mod = 1;
00651 }
00652 else
00653 {
00654 strncpy(outseries, outparam, DRMS_MAXSERIESNAMELEN);
00655 strncpy(testseries, inseries, DRMS_MAXSERIESNAMELEN);
00656 strcat(testseries, "_mod");
00657 if (strcmp(testseries, outseries) == 0)
00658 is_mod = 1;
00659 }
00660
00661
00662 outTemplate = drms_template_record(drms_env, outseries, &status);
00663 if (status || !outTemplate) DIE2("Output series can not be found: ", outseries);
00664
00665
00666 npkeys = inTemplate->seriesinfo->pidx_num;
00667 timekeyname = NULL;
00668 if (npkeys > 0)
00669 {
00670 int i;
00671 for (i=0; i<npkeys; i++)
00672 {
00673 DRMS_Keyword_t *pkey, *skey;
00674 pkey = inTemplate->seriesinfo->pidx_keywords[i];
00675 if (pkey->info->recscope > 1)
00676 pkey = drms_keyword_slotfromindex(pkey);
00677 if (pkey->info->type != DRMS_TYPE_TIME)
00678 continue;
00679 if(i > 0) DIE("Input series must have TIME keyword first, for now...");
00680 timekeyname = pkey->info->name;
00681 t_step = drms_keyword_getdouble(drms_keyword_stepfromslot(pkey), &status);
00682 if (status) DIE("problem getting t_step");
00683 t_epoch = drms_keyword_getdouble(drms_keyword_epochfromslot(pkey), &status);
00684 if (status) DIE("problem getting t_epoch");
00685 }
00686 }
00687 else
00688 DIE("Must have time prime key");
00689
00690
00691
00692
00693 if (strcasecmp(cadence_str, "NOTSPECIFIED") == 0)
00694 cadence = t_step;
00695 else
00696 {
00697 int ratio;
00698 double initial_cadence;
00699 initial_cadence = atoinc((char *)cadence_str);
00700 ratio = round(initial_cadence/t_step);
00701 cadence = ratio * t_step;
00702 if (cadence != initial_cadence)
00703 fprintf(stderr,"Cadence rounded from %f to %f, since t_step == %f\n", initial_cadence, cadence, t_step);
00704 }
00705
00706
00707 if (lbracket && times_source == TIMES_RECSET)
00708 strncpy(in, inparam, DRMS_MAXQUERYLEN);
00709 else
00710 {
00711 char t_start_text[100], t_stop_text[100], cadence_text[100];
00712 if (cadence > t_step)
00713 {
00714 sprintf(cadence_text,"@%0.0fs", cadence);
00715 if (times_source == TIMES_IMPLICIT)
00716 {
00717 int nsteps;
00718 nsteps = round((t_start - t_epoch)/cadence);
00719 t_start = t_epoch + nsteps * cadence;
00720 nsteps = round((t_stop - t_epoch)/cadence);
00721 t_stop = t_epoch + nsteps * cadence;
00722 }
00723 }
00724 else
00725 cadence_text[0] = '\0';
00726 sprint_at(t_start_text, t_start);
00727 sprint_at(t_stop_text, t_stop);
00728 sprintf(in, "%s[%s-%s%s]%s%s", inseries, t_start_text, t_stop_text, cadence_text, where, (moreQuery ? moreQuery : ""));
00729 }
00730
00731 if (inparam)
00732 {
00733 free(inparam);
00734 inparam = NULL;
00735 }
00736
00737
00738 if (cmdparams_exists(&cmdparams, "epoch") || (cadence > 1.0 &&
00739 (strncmp(inseries, "aia.lev1", 8)==0 || strncmp(inseries, "hmi.lev1", 8)==0 )))
00740 {
00741 char *new_in;
00742 new_in = get_input_recset(drms_env, in);
00743 if (new_in != in)
00744 {
00745 strcpy(in, new_in);
00746 in_filename = new_in+1;
00747 }
00748 }
00749
00750
00751
00752
00753
00754 inRS = drms_open_records(drms_env, in, &status);
00755 if (status || inRS->n == 0)
00756 {
00757 fprintf(stderr,"Query is: %s\n",in);
00758 DIE("No input data found");
00759 }
00760 nrecs = inRS->n;
00761
00762
00763 int nextRec = 0;
00764 for (irec = 0; irec < nrecs; irec ++)
00765 {
00766 double use_bzero, use_bscale;
00767 char history[4096];
00768
00769 nextRec = 0;
00770
00771 *history = '\0';
00772 inRec = inRS->records[irec];
00773 if (status || !inRec) DIE("Record read failed.");
00774
00775
00776 TIME trec = drms_getkey_time(inRec, timekeyname, &status); TEST_PARAM(timekeyname);
00777 if (t_start != tNotSpecified && trec < t_start)
00778 {
00779 continue;
00780 }
00781 if (t_stop != tNotSpecified && trec > t_stop)
00782 break;
00783
00784 if (drms_keyword_lookup(inRec, "QUALITY", 1))
00785 {
00786 int quality = drms_getkey_int(inRec, "QUALITY", &status);
00787 if (quality < 0)
00788 {
00789 continue;
00790 }
00791 }
00792
00793
00794 if (FDSfile)
00795 {
00796 TIME t_obs = drms_getkey_time(inRec, "T_OBS", NULL);
00797 if(get_tracking_xy((char *)FDSfile, t_obs, &trackx, &tracky, &track_radius))
00798 DIE("Failed to open FDS file");
00799 }
00800
00801
00802 this_car_rot = drms_getkey_int(inRec, "CAR_ROT", &status); TEST_PARAM("CAR_ROT");
00803 crlt_obs = drms_getkey_double(inRec, "CRLT_OBS", &status); TEST_PARAM("CRLT_OBS");
00804 crln_obs = drms_getkey_double(inRec, "CRLN_OBS", &status); TEST_PARAM("CRLN_OBS");
00805 crpix1 = drms_getkey_double(inRec, "CRPIX1", &status); TEST_PARAM("CRPIX1");
00806 x0 = crpix1 - 1;
00807 crpix2 = drms_getkey_double(inRec, "CRPIX2", &status); TEST_PARAM("CRPIX2");
00808 y0 = crpix2 - 1;
00809 crota = drms_getkey_double(inRec, "CROTA2", &status); TEST_PARAM("CROTA2");
00810 cdelt = drms_getkey_double(inRec, "CDELT1", &status); TEST_PARAM("CDELT1");
00811 pa = -crota;
00812
00813 int paIs180 = 0;
00814 if (fabs(fabs(pa)-180.0) < 1.0)
00815 {
00816 paIs180 = 1;
00817 }
00818
00819 crlt_obs_rad = Deg2Rad * crlt_obs;
00820 crln_obs_rad = Deg2Rad * crln_obs;
00821 pa_rad = Deg2Rad * pa;
00822 sina = sin(crota*Deg2Rad);
00823 cosa = cos(crota*Deg2Rad);
00824
00825 fprintf(stderr,"T_OBS=%s, crpix1=%f, crpix2=%f\n", drms_getkey_string(inRec,"T_OBS", NULL), crpix1, crpix2);
00826
00827
00828 if (firstimage)
00829 {
00830 firstimage = 0;
00831
00832 int idx, idy;
00833 idx = crpix1 + 0.5;
00834 idy = crpix2 + 0.5;
00835 crpix1_0 = idx;
00836 crpix2_0 = idy;
00837
00838 if (loctype==LOCCARR)
00839 {
00840 tmpstr = drms_getkey_string(inRec, "CTYPE1", &status);
00841 ctype1 = strdup(tmpstr); TEST_PARAM("CTYPE1");
00842 if (tmpstr)
00843 {
00844 free(tmpstr);
00845 }
00846
00847 tmpstr = drms_getkey_string(inRec, "CTYPE2", &status);
00848 if (strcmp(ctype1, "HPLN-TAN") != 0) DIE2("CTYPE1 not HPLN-TAN as required, is: ", ctype1);
00849 if (ctype1)
00850 {
00851 free(ctype1);
00852 ctype1 = NULL;
00853 }
00854 ctype2 = strdup(tmpstr); TEST_PARAM("CTYPE2");
00855 if (tmpstr)
00856 {
00857 free(tmpstr);
00858 }
00859
00860 if (strcmp(ctype2, "HPLT-TAN") != 0) DIE2("CTYPE2 not HPLT-TAN as required, is: ", ctype2);
00861 if (ctype2)
00862 {
00863 free(ctype2);
00864 ctype2 = NULL;
00865 }
00866 rsun_ref = drms_getkey_double(inRec, "RSUN_REF", &status);
00867 if (status) rsun_ref = 6.96e8;
00868 dsun_obs = drms_getkey_double(inRec, "DSUN_OBS", &status); TEST_PARAM("DSUN_OBS");
00869 rsun_rad = asin(rsun_ref/dsun_obs);
00870 rsun = rsun_rad*Rad2arcsec;
00871 cdelt = drms_getkey_double(inRec, "CDELT1", &status); TEST_PARAM("CDELT1");
00872
00873
00874 rsunpix = rsun/cdelt;
00875 }
00876
00877 if (boxtype == BOXDEGREE)
00878 {
00879 int nx, ny;
00880 double urx, ury;
00881
00882 sphere2img(Deg2Rad*(crlt+height/2), Deg2Rad*(width/2), crlt_obs_rad, 0.0,
00883 &urx, &ury, 0.0, 0.0, rsunpix, pa_rad, 0, 0, 0, 0);
00884 sphere2img(Deg2Rad*(crlt-height/2), -Deg2Rad*(width/2), crlt_obs_rad, 0.0,
00885 &llx, &lly, 0.0, 0.0, rsunpix, pa_rad, 0, 0, 0, 0);
00886
00887
00888 nx = urx - llx ;
00889 ny = ury - lly ;
00890 if (nx < 0) { nx = -nx; llx = urx; }
00891 if (ny < 0) { ny = -ny; lly = ury; }
00892 pixwidth = nx + 1;
00893 pixheight = ny + 1;
00894 }
00895 else if (boxtype==BOXARCSEC)
00896 {
00897 int nx, ny;
00898 llx = -width/(2.0*cdelt);
00899 lly = -height/(2.0*cdelt);
00900 pixwidth = 1 - 2 * llx;
00901 pixheight = 1 - 2 * lly;
00902 }
00903 else
00904 {
00905 pixwidth = round(width);
00906 pixheight = round(height);
00907 llx = -pixwidth / 2.0;
00908 lly = -pixheight / 2.0;
00909 }
00910 }
00911
00912 if (!NoTrack)
00913 {
00914 if (FDSfile)
00915 {
00916 center_x = PIX_X(trackx,tracky) - 1;
00917 center_y = PIX_Y(trackx,tracky) - 1;
00918 sprintf(history+strlen(history), "Image center tracked as per %s\n", FDSfile);
00919 fprintf(stderr,"center_x=%f,center_y=%f\n",center_x,center_y);
00920 }
00921 else
00922 sphere2img(crlt_rad, crln_rad, crlt_obs_rad, crln_obs_rad, ¢er_x, ¢er_y, x0, y0, rsunpix, pa_rad, 0, 0, 0, 0);
00923 }
00924
00925
00926
00927 target_x = center_x;
00928 target_y = center_y;
00929 int x1Orig;
00930 int y1Orig;
00931
00932 int x1 = round(target_x + llx);
00933 int y1 = round(target_y + lly);
00934 int x2 = x1 + pixwidth - 1;
00935 int y2 = y1 + pixheight - 1;
00936 if (do_register)
00937 {
00938 x1 -= register_padding;
00939 y1 -= register_padding;
00940 x2 += register_padding;
00941 y2 += register_padding;
00942 }
00943 crpix1 = 1 + x0 - x1;
00944 crpix2 = 1 + y0 - y1;
00945 fprintf(stderr,"at box define, crpix1=%f, x0=%f, x1=%d\n",crpix1,x0,x1);
00946
00947 int start1[2] = {x1, y1};
00948 int end1[2] = {x2, y2};
00949
00950 outRS = drms_create_records(drms_env, 1, outseries, DRMS_PERMANENT, &status);
00951 if (status) {fprintf(stderr,"Output series is %s, ",outseries); DIE("Cant make outout record");}
00952 outRec = outRS->records[0];
00953
00954
00955 if (do_crop)
00956 {
00957
00958 int retStat;
00959 dsun_obs = drms_getkey_double(inRec, "DSUN_OBS", &retStat);
00960 rsun_rad = asin(rsun_ref/dsun_obs);
00961 rsun = rsun_rad*Rad2arcsec/cdelt;
00962 r2 = rsun*rsun;
00963 r2 *= 0.9995;
00964
00965
00966 this_x0 = crpix1 - 1;
00967 this_y0 = crpix2 - 1;
00968 }
00969
00970
00971
00972
00973
00974
00975
00976 x1Orig = x1;
00977 y1Orig = y1;
00978
00979 if (paIs180)
00980 {
00981 pa -= 180.0;
00982 crota -= 180.0;
00983
00984 crpix1 = 1 + x2 - x0;
00985 crpix2 = 1 + y2 - y0;
00986 fprintf(stderr,"after rotate, crpix1=%f\n",crpix1);
00987
00988
00989
00990
00991
00992 x1 = inAxis[0] - 1 - x2;
00993 y1 = inAxis[1] - 1 - y2;
00994 target_x = inAxis[0] - 1 - center_x;
00995 target_y = inAxis[1] - 1 - center_y;
00996
00997 strcat(history, "Image rotated 180 degrees.");
00998 fprintf(stderr,"after flip x1=%d, target_x=%lf, y1=%d, target_y=%lf\n",x1,target_x,y1,target_y);
00999 }
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 DRMS_Segment_t *firstSeg = NULL;
01011 HIterator_t *segIter = NULL;
01012 DRMS_Segment_t *orig = NULL;
01013
01014 float regShiftX = 0;
01015 float regShiftY = 0;
01016 char patchIntersection;
01017
01018 while ((inSeg = drms_record_nextseg2(inRec, &segIter, 1, &orig)) != NULL)
01019 {
01020 if (!firstSeg)
01021 {
01022 firstSeg = inSeg;
01023
01024
01025
01026 if (x1Orig >= inSeg->axis[0] || y1Orig >= inSeg->axis[1] || x2 < 0 || y2 < 0)
01027 {
01028
01029 patchIntersection = 'N';
01030
01031 }
01032 else if (x1Orig >= 0 && y1Orig >= 0 && x2 < inSeg->axis[0] && y2 < inSeg->axis[1])
01033 {
01034
01035 patchIntersection = 'F';
01036 }
01037 else
01038 {
01039
01040 patchIntersection = 'P';
01041 }
01042 }
01043 else
01044 {
01045 if (!hasSegList && !doingAllSegs)
01046 {
01047
01048 break;
01049 }
01050
01051
01052 int iSeg;
01053 int mismatch;
01054
01055 mismatch = 0;
01056 if (firstSeg->info->naxis == inSeg->info->naxis)
01057 {
01058 for (iSeg = 0; iSeg < firstSeg->info->naxis; iSeg++)
01059 {
01060 if (firstSeg->axis[iSeg] != inSeg->axis[iSeg])
01061 {
01062 mismatch = 1;
01063 break;
01064 }
01065 }
01066 }
01067 else
01068 {
01069 mismatch = 1;
01070 }
01071
01072 if (!mismatch)
01073 {
01074 if (firstSeg->info->protocol == DRMS_TAS && inSeg->info->protocol == DRMS_TAS)
01075 {
01076 for (iSeg = 0; iSeg < firstSeg->info->protocol; iSeg++)
01077 {
01078 if (firstSeg->blocksize[iSeg] != inSeg->blocksize[iSeg])
01079 {
01080 mismatch = 1;
01081 break;
01082 }
01083 }
01084 }
01085 }
01086
01087 if (mismatch)
01088 {
01089 DIE("When processing more than one segment, all segments' dimensions must match.");
01090 }
01091 }
01092 }
01093
01094 if (segIter)
01095 {
01096 hiter_destroy(&segIter);
01097 }
01098
01099 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
01100 drms_sprint_rec_query(inQuery, inRec);
01101 drms_setkey_string(outRec, "SOURCE", inQuery);
01102 drms_appendhistory(outRec, inQuery, 1);
01103 drms_setkey_time(outRec, "T_REC", trec);
01104 drms_setkey_double(outRec, "CRVAL1", 0.0);
01105 drms_setkey_double(outRec, "CRVAL2", 0.0);
01106 drms_setkey_double(outRec, "CRDELT1", cdelt);
01107 drms_setkey_double(outRec, "CRDELT2", cdelt);
01108
01109 if (do_register)
01110 {
01111
01112
01113
01114
01115
01116 drms_setkey_double(outRec, "CROTA2", 0.0);
01117 }
01118 else
01119 {
01120 drms_setkey_double(outRec, "CROTA2", crota);
01121 }
01122
01123 drms_setkey_string(outRec, "CONTENT", "Tracked Extracted Patches, made by im_patch");
01124 drms_appendcomment(outRec, "Patches", 1);
01125 drms_setkey_string(outRec, "RequestID", requestid);
01126 drms_setkey_string(outRec, "HGBOXUNITS", boxunits);
01127 drms_setkey_string(outRec, "HGLOCUNITS", locunits);
01128 drms_setkey_float(outRec, "HGWIDE", width);
01129 drms_setkey_float(outRec, "HGHIGH", height);
01130 drms_setkey_float(outRec, "HGCRLN", crln);
01131 drms_setkey_float(outRec, "HGCRLT", crlt);
01132 drms_setkey_int(outRec, "HGCARROT", car_rot);
01133 drms_setkey_time(outRec, "HGTSTART", t_start);
01134 drms_setkey_time(outRec, "HGTSTOP", t_stop);
01135 drms_setkey_time(outRec, "DATE", time(0) + UNIX_EPOCH);
01136 drms_setkey_string(outRec, "HGQUERY", in);
01137 fprintf(stderr,"DATAMIN=%f, DATAMAX=%f\n",drms_getkey_float(outRec,"DATAMIN",NULL),drms_getkey_float(outRec,"DATAMAX",NULL));
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 int numInSegs = hcon_size(&(inTemplate->segments));
01150 int numOutSegs = hcon_size(&(outTemplate->segments));
01151
01152 if (numInSegs != numOutSegs)
01153 {
01154 DIE("Input and output series are incompatible (the number of segments differs).\n");
01155 }
01156
01157 if (numInSegs < 1)
01158 {
01159 DIE("The input series must have at least one segment.\n");
01160 }
01161
01162
01163
01164
01165
01166 int iSeg = 0;
01167 char msgBuf[512];
01168
01169 while ((inSeg = drms_record_nextseg2(inRec, &segIter, 1, &orig)) != NULL)
01170 {
01171
01172 if (!hasSegList && !doingAllSegs && iSeg > 0)
01173 {
01174
01175
01176 break;
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 outSeg = drms_segment_lookupnum(outRec, orig->info->segnum);
01222
01223 if (outSeg == NULL || (numInSegs != 1 && strncasecmp(orig->info->name, outSeg->info->name, DRMS_MAXSEGNAMELEN - 1) != 0))
01224 {
01225
01226 snprintf(msgBuf, sizeof(msgBuf), "Input and output series are incompatible (there is no segment named %s in the output series).\n", orig->info->name);
01227 DIE(msgBuf);
01228 }
01229
01230 if (inSeg->info->naxis != 2 || (inSeg->info->protocol != DRMS_FITZ && inSeg->info->protocol != DRMS_FITS && inSeg->info->protocol != DRMS_TAS))
01231 {
01232
01233 snprintf(msgBuf, sizeof(msgBuf), "Input segment %s is not a 2D FITS segment.\n", orig->info->name);
01234 }
01235
01236 inAxis[0] = inSeg->axis[0];
01237 inAxis[1] = inSeg->axis[1];
01238
01239
01240 if (patchIntersection == 'N')
01241 {
01242 fprintf(stderr, "patch completely outside image, x1=%d, y1=%d, x2=%d, y2=%d\n", x1Orig, y1Orig, x2, y2);
01243
01244
01245 nextRec = 1;
01246 break;
01247 }
01248 else if (patchIntersection == 'F')
01249 {
01250 status = 0;
01251 outArray = drms_segment_readslice(inSeg, DRMS_TYPE_FLOAT, start1, end1, &status);
01252 if (status) DIE("Cant read input record");
01253 fprintf(stderr,"$$$$$$$ outArray bzero, bscale are %f, %f\n", outArray->bzero, outArray->bscale);
01254 }
01255 else
01256 {
01257 int dims[2] = {x2-x1Orig+1,y2-y1Orig+1};
01258 int start2[2], end2[2];
01259
01260 int x,y;
01261 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, NULL, &status);
01262 drms_array2missing(outArray);
01263
01264 start2[0] = x1Orig < 0 ? 0 : x1Orig;
01265 start2[1] = y1Orig < 0 ? 0 : y1Orig;
01266 end2[0] = x2 >= inAxis[0] ? inAxis[0]-1 : x2;
01267 end2[1] = y2 >= inAxis[1] ? inAxis[1]-1 : y2;
01268
01269 status = 0;
01270 inArray = drms_segment_readslice(inSeg, DRMS_TYPE_FLOAT, start2, end2, &status);
01271 if (status || !inArray) DIE("Cant read input record");
01272
01273
01274 outArray->bzero = inArray->bzero;
01275 outArray->bscale = inArray->bscale;
01276
01277 int start3[2] = {start2[0]-start1[0],start2[1]-start1[1]};
01278 int end3[2] = {end2[0]-end1[0],end2[1]-end1[1]};
01279 int n3x = end2[0] - start2[0] + 1;
01280 int n3y = end2[1] - start2[1] + 1;
01281
01282 for (y=0; y< n3y; y++)
01283 {
01284 for (x=0; x < n3x; x++)
01285 {
01286 *((float *)outArray->data + ((start3[1]+y)*dims[0] + x + start3[0])) =
01287 *((float *)inArray->data + (y*n3x + x));
01288 }
01289 }
01290
01291 drms_free_array(inArray);
01292 }
01293
01294 use_bzero = outArray->bzero;
01295 use_bscale = outArray->bscale;
01296
01297
01298 if (do_crop)
01299 {
01300 int stat;
01301
01302 float *data = (float *)outArray->data;
01303 int i,j;
01304 int nx = outArray->axis[0];
01305 int ny = outArray->axis[1];
01306
01307 for (j=0; j<ny; j++)
01308 {
01309 for (i=0; i<nx; i++)
01310 {
01311 double x = i - this_x0;
01312 double y = j - this_y0;
01313
01314 if ((x*x + y*y) >= r2)
01315 {
01316 data[j*nx + i] = DRMS_MISSING_FLOAT;
01317 }
01318 }
01319 }
01320 }
01321
01322
01323 if (paIs180)
01324 {
01325
01326 float *data = (float *)outArray->data;
01327 int i,j;
01328 int nx = outArray->axis[0];
01329 int ny = outArray->axis[1];
01330 int midrow = (ny)/2;
01331 int midcol = (nx)/2;
01332 float val;
01333
01334 for (j=0; j<midrow; j++)
01335 {
01336 for (i=0; i<nx; i++)
01337 {
01338 val = data[j*nx + i];
01339 data[j*nx + i] = data[(ny - 1 - j)*nx + nx - 1 - i];
01340 data[(ny - 1 - j)*nx + nx - 1 - i] = val;
01341 }
01342 }
01343
01344 if ((ny & 1) != 0)
01345 {
01346 for (i=0; i<midcol; i++)
01347 {
01348 val = data[midrow*nx + i];
01349 data[midrow*nx + i] = data[midrow*nx + nx - 1 - i];
01350 data[midrow*nx + nx - 1 - i] = val;
01351 }
01352 }
01353 }
01354
01355
01356
01357
01358 if (do_register)
01359 {
01360
01361 DRMS_Array_t *tmpArray;
01362 int status;
01363 int i,j;
01364 float *data = (float *)outArray->data;
01365 float *newdata = NULL;
01366 int newnx, newny;
01367 int nx = outArray->axis[0];
01368 int ny = outArray->axis[1];
01369 float midx = (nx-1)/2.0;
01370 float midy = (ny-1)/2.0;
01371
01372
01373 float dx = (x1 + midx) - target_x;
01374 float dy = (y1 + midy) - target_y;
01375
01376
01377 if (iSeg == 0)
01378 {
01379 sprintf(history+strlen(history), "\nImage registered by shift of (%0.3f,%0.3f) pixels.", dx, dy);
01380 crpix1 += dx - register_padding;
01381 crpix2 += dy - register_padding;
01382 }
01383
01384 regShiftX = dx;
01385 regShiftY = dy;
01386
01387 int dtyp = 3;
01388
01389 if (status=image_magrotate((void *)data, nx, ny, dtyp, crota, 1.0, regShiftX, regShiftY, &(void *)newdata, &newnx, &newny, 1, 0))
01390 {
01391 DIE("XXXX Failure in call to image_magrotate. Either malloc error or nx or ny too large. Must quit.\n");
01392 }
01393
01394 if (newnx != nx || newny != ny)
01395 {
01396 fprintf(stderr,"image_magrotate changed dimensions: nx want %d got %d, ny want %d got %d\n",nx,newnx,ny,newny);
01397 }
01398
01399 drms_free_array(outArray);
01400 int outdims[2] = {pixwidth, pixheight};
01401 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, outdims, NULL, &status);
01402 data = (float *)outArray->data;
01403 for (j=0; j<pixheight; j++)
01404 {
01405 for (i=0; i< pixwidth; i++)
01406 {
01407 data[j*pixwidth + i] = newdata[(j+register_padding)*nx + i+register_padding];
01408 }
01409 }
01410
01411
01412 if (newdata)
01413 {
01414 free(newdata);
01415 newdata = NULL;
01416 }
01417
01418 outArray->bzero = use_bzero;
01419 outArray->bscale = use_bscale;
01420 }
01421
01422 if (wantFAKE && FDSfile)
01423 {
01424 double r;
01425 int ix0, iy0;
01426 int nx = outArray->axis[0];
01427 int ny = outArray->axis[1];
01428 double x0, y0, r2;
01429 float *data = (float *)outArray->data;
01430 float datamax = drms_getkey_float(outRec, "DATAMAX", NULL);
01431 int ix,iy,ir,ir2;
01432
01433 if (NoTrack)
01434 {
01435 x0 = trackx/cdelt + crpix1;
01436 y0 = tracky/cdelt + crpix2;
01437 }
01438 else
01439 {
01440 x0 = nx/2.0;
01441 y0 = ny/2.0;
01442 }
01443
01444 ix0 = x0+0.5;
01445 iy0 = y0+0.5;
01446
01447 r = track_radius/cdelt;
01448 ir = r + 0.5;
01449 r2 = r*r;
01450
01451 for (ix = -ir; ix <= ir; ix++)
01452 {
01453 for (iy = -ir; iy <= ir; iy++)
01454 {
01455 x = x0 - ix0 + ix;
01456 y = y0 - iy0 + iy;
01457 if (x*x + y*y < r2 && ix0+ix >=0 && ix0+ix < nx && iy0+iy >=0 && iy0+iy < ny)
01458 {
01459 if (wantFAKEwhite)
01460 {
01461 data[(iy+iy0)*nx + (ix+ix0)] = datamax;
01462 }
01463 else
01464 {
01465 if (ix==0 || iy==0)
01466 {
01467 data[(iy+iy0)*nx + (ix+ix0)] = datamax;
01468 }
01469 else
01470 {
01471 data[(iy+iy0)*nx + (ix+ix0)] = 0.0;
01472 }
01473 }
01474 }
01475 }
01476 }
01477 }
01478
01479 if (iSeg == 0)
01480 {
01481 drms_setkey_double(outRec, "CRPIX1", crpix1);
01482 drms_setkey_double(outRec, "CRPIX2", crpix2);
01483 }
01484
01485 set_statistics(outSeg, outArray, 1);
01486
01487 if (export_keys)
01488 {
01489 status = drms_segment_writewithkeys(outSeg, outArray, 0);
01490 }
01491 else
01492 {
01493 status = drms_segment_write(outSeg, outArray, 0);
01494 }
01495
01496 if (status)
01497 {
01498 DIE("problem writing file");
01499 }
01500
01501 if (outArray)
01502 {
01503 drms_free_array(outArray);
01504 outArray = NULL;
01505 }
01506
01507 iSeg++;
01508 }
01509
01510 if (segIter)
01511 {
01512 hiter_destroy(&segIter);
01513 }
01514
01515 if (log)
01516 {
01517 drms_fprint_rec_query(log, outRec);
01518 fprintf(log, "\n");
01519 }
01520
01521 if (*history)
01522 drms_appendhistory(outRec, history, 1);
01523
01524 if (nextRec)
01525 {
01526 drms_close_records(outRS, DRMS_FREE_RECORD);
01527 continue;
01528 }
01529 else
01530 {
01531 drms_close_records(outRS, DRMS_INSERT_RECORD);
01532 drms_free_array(outArray);
01533 }
01534
01535 OK_recs += 1;
01536 }
01537
01538 drms_close_records(inRS, DRMS_FREE_RECORD);
01539 if (in_filename)
01540 {
01541 unlink(in_filename);
01542 }
01543
01544 if (OK_recs)
01545 printf(" DONE, %d records made! \n \n",OK_recs);
01546 else
01547 printf(" DONE but no useful records created! \n \n");
01548
01549 if (log)
01550 fclose(log);
01551 return DRMS_SUCCESS;
01552 }
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 int img2sphere (double x, double y, double ang_r, double latc, double lonc,
01564 double pa, double *p_rho, double *p_lat, double *p_lon, double *p_sinlat,
01565 double *p_coslat, double *p_sig, double *p_mu, double *p_chi)
01566 {
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 double w_rho, w_lat, w_lon, w_sinlat, w_coslat, w_sig, w_mu, w_chi;
01604 double *rho= &w_rho, *lat= &w_lat, *lon= &w_lon, *sinlat= &w_sinlat, *coslat= &w_coslat, *sig= &w_sig, *mu= &w_mu, *chi= &w_chi;
01605 static double ang_r0 = 0.0, sinang_r = 0.0, tanang_r = 0.0;
01606 static double latc0 = 0.0, coslatc = 1.0, sinlatc = 0.0;
01607 double cosr, sinr, sinlon, sinsig;
01608
01609 if (p_rho) rho=p_rho;
01610 if (p_lat) lat=p_lat;
01611 if (p_lon) lon=p_lon;
01612 if (p_sinlat) sinlat=p_sinlat;
01613 if (p_coslat) coslat=p_coslat;
01614 if (p_sig) sig=p_sig;
01615 if (p_mu) mu=p_mu;
01616 if (p_chi) chi=p_chi;
01617
01618 if (ang_r != ang_r0) {
01619 sinang_r = sin(ang_r);
01620 tanang_r = tan(ang_r);
01621 ang_r0 = ang_r;
01622 }
01623
01624 if (latc != latc0) {
01625 sinlatc = sin(latc);
01626 coslatc = cos(latc);
01627 latc0 = latc;
01628 }
01629
01630
01631 *chi = atan2 (x, y) + pa;
01632 while (*chi > 2 * M_PI) *chi -= 2 * M_PI;
01633 while (*chi < 0.0) *chi += 2 * M_PI;
01634
01635 *sig = atan (hypot (x, y) * tanang_r);
01636 sinsig = sin (*sig);
01637 *rho = asin (sinsig / sinang_r) - *sig;
01638 if (*sig > ang_r) return (-1);
01639 *mu = cos (*rho + *sig);
01640 sinr = sin (*rho);
01641 cosr = cos (*rho);
01642 *sinlat = sinlatc * cosr + coslatc * sinr * cos (*chi);
01643 *coslat = sqrt (1.0 - *sinlat * *sinlat);
01644 *lat = asin (*sinlat);
01645
01646 sinlon = sinr * sin (*chi) / *coslat;
01647 *lon = asin (sinlon);
01648 if (cosr < (*sinlat * sinlatc)) *lon = M_PI - *lon;
01649 *lon += lonc;
01650 while (*lon < 0.0) *lon += 2 * M_PI;
01651 while (*lon >= 2 * M_PI) *lon -= 2 * M_PI;
01652 return (0);
01653 }
01654
01655
01656
01657
01658
01659
01660
01661
01662 int sphere2img (double lat, double lon, double latc, double lonc,
01663 double *x, double *y, double xcenter, double ycenter,
01664 double rsun, double peff, double ecc, double chi,
01665 int xinvrt, int yinvrt) {
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716 static double sin_asd = 0.004660, cos_asd = 0.99998914;
01717
01718 static double last_latc = 0.0, cos_latc = 1.0, sin_latc = 0.0;
01719 double r, cos_cang, xr, yr;
01720 double sin_lat, cos_lat, cos_lat_lon, cospa, sinpa;
01721 double squash, cchi, schi, c2chi, s2chi, xp, yp;
01722 int hemisphere;
01723
01724 if (latc != last_latc) {
01725 sin_latc = sin (latc);
01726 cos_latc = cos (latc);
01727 last_latc = latc;
01728 }
01729 sin_lat = sin (lat);
01730 cos_lat = cos (lat);
01731 cos_lat_lon = cos_lat * cos (lon - lonc);
01732
01733 cos_cang = sin_lat * sin_latc + cos_latc * cos_lat_lon;
01734 hemisphere = (cos_cang < 0.0) ? 1 : 0;
01735 r = rsun * cos_asd / (1.0 - cos_cang * sin_asd);
01736 xr = r * cos_lat * sin (lon - lonc);
01737 yr = r * (sin_lat * cos_latc - sin_latc * cos_lat_lon);
01738
01739 if (xinvrt) xr *= -1.0;
01740 if (yinvrt) yr *= -1.0;
01741
01742 if (ecc > 0.0 && ecc < 1.0) {
01743 squash = sqrt (1.0 - ecc * ecc);
01744 cchi = cos (chi);
01745 schi = sin (chi);
01746 s2chi = schi * schi;
01747 c2chi = 1.0 - s2chi;
01748 xp = xr * (s2chi + squash * c2chi) - yr * (1.0 - squash) * schi * cchi;
01749 yp = yr * (c2chi + squash * s2chi) - xr * (1.0 - squash) * schi * cchi;
01750 xr = xp;
01751 yr = yp;
01752 }
01753
01754 cospa = cos (peff);
01755 sinpa = sin (peff);
01756 *x = xr * cospa - yr * sinpa;
01757 *y = xr * sinpa + yr * cospa;
01758
01759 *y += ycenter;
01760 *x += xcenter;
01761
01762 return (hemisphere);
01763 }
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 #define DIE_get_recset(msg) {fprintf(stderr,"$$$$ %s: %s\n", module_name, msg); return NULL;}
01778 char *get_input_recset(DRMS_Env_t *drms_env, char *inQuery)
01779 {
01780 static char newInQuery[DRMS_MAXSERIESNAMELEN+2];
01781 int epoch_given = cmdparams_exists(&cmdparams, "epoch");
01782 TIME epoch, t_epoch;
01783 DRMS_Array_t *data;
01784 DRMS_Record_t *inTemplate;
01785 TIME t_start, t_stop, t_now, t_want, t_diff, this_t_diff;
01786 int status = 1;
01787 int nrecs, irec;
01788 int nslots, islot;
01789 long long *recnums;
01790 TIME *t_this, half;
01791 TIME cadence;
01792 double *drecnum, *dquality;
01793 int quality;
01794 long long recnum;
01795 char keylist[DRMS_MAXQUERYLEN];
01796 char filename[DRMS_MAXSERIESNAMELEN];
01797 char *tmpdir;
01798 FILE *tmpfile;
01799 char newIn[DRMS_MAXQUERYLEN];
01800 char seriesname[DRMS_MAXQUERYLEN];
01801 char *lbracket;
01802 char *at = index(inQuery, '@');
01803 int npkeys;
01804 char *timekeyname;
01805 double t_step;
01806
01807 strcpy(seriesname, inQuery);
01808 lbracket = index(seriesname,'[');
01809 if (lbracket) *lbracket = '\0';
01810 inTemplate = drms_template_record(drms_env, seriesname, &status);
01811 if (status || !inTemplate) DIE_get_recset("Input series can not be found");
01812
01813
01814 npkeys = inTemplate->seriesinfo->pidx_num;
01815 timekeyname = NULL;
01816 if (npkeys > 0)
01817 {
01818 int i;
01819 for (i=0; i<npkeys; i++)
01820 {
01821 DRMS_Keyword_t *pkey, *skey;
01822 pkey = inTemplate->seriesinfo->pidx_keywords[i];
01823 if (pkey->info->recscope > 1)
01824 pkey = drms_keyword_slotfromindex(pkey);
01825 if (pkey->info->type != DRMS_TYPE_TIME)
01826 continue;
01827 if(i > 0) DIE_get_recset("Input series must have TIME keyword first, for now...");
01828 timekeyname = pkey->info->name;
01829 t_step = drms_keyword_getdouble(drms_keyword_stepfromslot(pkey), &status);
01830 if (status) DIE_get_recset("problem getting t_step");
01831 t_epoch = drms_keyword_getdouble(drms_keyword_epochfromslot(pkey), &status);
01832 if (status) DIE_get_recset("problem getting t_epoch");
01833 }
01834 }
01835 else
01836 DIE_get_recset("Must have time prime key");
01837 epoch = epoch_given ? params_get_time(&cmdparams, "epoch") : t_epoch;
01838
01839 if (at && *at && ((strncmp(inQuery,"aia.lev1[", 9)==0 ||
01840 strncmp(inQuery,"hmi.lev1[", 9)==0 ||
01841 strncmp(inQuery,"aia.lev1_nrt2[",14)==0 ||
01842 strncmp(inQuery,"hmi.lev1_nrt[", 13)==0 ) ||
01843 epoch_given))
01844 {
01845 char *ip=(char *)inQuery, *op=newIn, *p;
01846 long n, mul;
01847 while ( *ip && ip<at )
01848 *op++ = *ip++;
01849 ip++;
01850 n = strtol(ip, &p, 10);
01851 if (*p == 's') mul = 1;
01852 else if (*p == 'm') mul = 60;
01853 else if (*p == 'h') mul = 3600;
01854 else if (*p == 'd') mul = 86400;
01855 else
01856 DIE_get_recset("cant make sense of @xx cadence spec");
01857 cadence = n * mul;
01858 ip = ++p;
01859 while ( *ip )
01860 *op++ = *ip++;
01861 *op = '\0';
01862 half = cadence/2.0;
01863 sprintf(keylist, "%s,QUALITY,recnum", timekeyname);
01864 data = drms_record_getvector(drms_env, newIn, keylist, DRMS_TYPE_DOUBLE, 0, &status);
01865 if (!data || status)
01866 {
01867 fprintf(stderr, "status=%d\n", status);
01868 DIE_get_recset("getkey_vector failed\n");
01869 }
01870 nrecs = data->axis[1];
01871 irec = 0;
01872 t_this = (TIME *)data->data;
01873 dquality = (double *)data->data + 1*nrecs;
01874 drecnum = (double *)data->data + 2*nrecs;
01875 if (epoch_given)
01876 {
01877 int s0 = (t_this[0] - epoch)/cadence;
01878 TIME t0 = s0*cadence + epoch;
01879 t_start = (t0 < t_this[0] ? t0 + cadence : t0);
01880 }
01881 else
01882 t_start = t_this[0];
01883 t_stop = t_this[nrecs-1];
01884 nslots = (t_stop - t_start + cadence/2)/cadence;
01885 recnums = (long long *)malloc(nslots*sizeof(long long));
01886 for (islot=0; islot<nslots; islot++)
01887 recnums[islot] = 0;
01888 islot = 0;
01889 t_want = t_start;
01890 t_diff = 1.0e9;
01891 for (irec = 0; irec<nrecs; irec++)
01892 {
01893 t_now = t_this[irec];
01894 quality = (int)dquality[irec] & 0xFFFFFFFF;
01895 recnum = (long long)drecnum[irec];
01896 this_t_diff = fabs(t_now - t_want);
01897 if (quality < 0)
01898 continue;
01899 if (t_now <= (t_want-half))
01900 continue;
01901 while (t_now > (t_want+half))
01902 {
01903 islot++;
01904 if (islot >= nslots)
01905 break;
01906 t_want = t_start + cadence * islot;
01907 this_t_diff = fabs(t_now - t_want);
01908 t_diff = 1.0e8;
01909 }
01910 if (islot < nslots && this_t_diff <= t_diff)
01911 recnums[islot] = recnum;
01912 t_diff = fabs(t_now - t_want);
01913 }
01914 if (islot+1 < nslots)
01915 nslots = islot+1;
01916 tmpdir = getenv("TMPDIR");
01917 if (!tmpdir) tmpdir = "/tmp";
01918 sprintf(filename, "%s/%sXXXXXX", tmpdir, module_name);
01919 mkstemp(filename);
01920 tmpfile = fopen(filename,"w");
01921 for (islot=0; islot<nslots; islot++)
01922 if (recnums[islot])
01923 fprintf(tmpfile, "%s[:#%lld]\n", seriesname, recnums[islot]);
01924 fclose(tmpfile);
01925 free(recnums);
01926 drms_free_array(data);
01927 sprintf(newInQuery,"@%s", filename);
01928 return(newInQuery);
01929 }
01930 else
01931 return(inQuery);
01932 }
01933
01934
01935
01936 int get_tracking_xy(char *FDSfile, TIME want, double *xp, double *yp, double *radius)
01937 {
01938 int iline;
01939 char buf[200];
01940 TIME now0;
01941 FILE *data = fopen(FDSfile,"r");
01942 double lambda, phi, x, y, dist, obj_radius;
01943 double frac, x0, y0, obj_radius0;
01944 char object[100], now_txt[100];
01945 if (!data)
01946 return(1);
01947
01948
01949 for (iline=0; iline<13; iline++)
01950 fgets(buf, 200, data);
01951
01952
01953 while (fscanf(data, "%s %s %lf %lf %lf %lf %lf %lf", object, now_txt, &lambda, &phi, &x, &y, &dist, &obj_radius) == 8)
01954 {
01955 int yyyy, doy, hh, mm, ss;
01956 int m,d;
01957 int dim[] = {31,28,31,30,31,30,31,31,30,31,30,31};
01958 double distance;
01959 TIME now;
01960
01961
01962 x = -x;
01963 y = -y;
01964 obj_radius *= 3600;
01965
01966 sscanf(now_txt,"%4d%3d.%2d%2d%2d", &yyyy, &doy, &hh, &mm, &ss);
01967 if (yyyy % 4 == 0) dim[1] = 29; else dim[1] = 28;
01968 for (m=1; m<=12; m++)
01969 {
01970 if (doy > dim[m-1])
01971 doy -= dim[m-1];
01972 else
01973 break;
01974 }
01975 d = doy;
01976
01977 sprintf(now_txt, "%4d.%02d.%02d_%02d:%02d:%02d_UTC", yyyy, m, d, hh, mm, ss);
01978 now = sscan_time(now_txt);
01979
01980 if (now < want)
01981 {
01982 now0 = now;
01983 x0 = x;
01984 y0 = y;
01985 obj_radius0 = obj_radius;
01986 }
01987 else
01988 {
01989 if (fabs(now-want) >= fabs(now0-want))
01990 {
01991 obj_radius = obj_radius0;
01992 if (now == want)
01993 {
01994 x = x0;
01995 y = y0;
01996 }
01997 else
01998 {
01999 frac = (want-now0)/(now-now0);
02000 x = x0 + (x-x0)*frac;
02001 y = y0 + (y-y0)*frac;
02002 }
02003 }
02004 break;
02005 }
02006 }
02007 fclose(data);
02008 fprintf(stderr,"Found %s, x=%f, y=%f, radius=%f (all arcsecs)\n",now_txt,x,y,obj_radius);
02009 *xp = x;
02010 *yp = y;
02011 *radius = obj_radius;
02012 return(0);
02013 }