00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <time.h>
00027 #include <sys/time.h>
00028 #include <math.h>
00029 #include <string.h>
00030 #include "jsoc_main.h"
00031 #include "astro.h"
00032 #include "cartography.c"
00033
00034 #define PI (M_PI)
00035 #define RADSINDEG (PI/180.)
00036 #define RAD2ARCSEC (648000./M_PI)
00037 #define SECINDAY (86400.)
00038 #define FOURK (4096)
00039 #define FOURK2 (16777216)
00040 #define DTTHRESH (518400.)
00041
00042 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
00043
00044 #define DISAMB_AZI 1
00045
00046
00047 #ifndef MIN
00048 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
00049 #endif
00050 #ifndef MAX
00051 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
00052 #endif
00053
00054 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s, status=%d\n", msg, status); return(status);}
00055 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00056
00057 #define kNotSpecified "Not Specified"
00058 #define dpath "/home/jsoc/cvs/Development/JSOC"
00059
00060
00061
00062
00063 #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
00064 #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
00065 #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
00066 #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
00067
00068
00069 struct ephemeris {
00070 double disk_lonc, disk_latc;
00071 double disk_xc, disk_yc;
00072 double rSun, asd, pa;
00073 };
00074
00075
00076 struct patchInfo {
00077 double lonref, latref;
00078 int cols, rows;
00079 TIME tref;
00080 int cgemnum;
00081 };
00082
00083
00084 char *BSegs[] = {"vlos_mag", "inclination", "azimuth", "field", "disambig", "conf_disambig"};
00085 char *CutSegs[] = {"vlos_mag", "inclination", "azimuth", "field", "disambig", "conf_disambig"};
00086 char *CutBunits[] = {"cm/s", "degree", "degree", "Mx/cm^2", " ", " "};
00087
00088
00089
00090
00091 int getInputRS(DRMS_RecordSet_t **bRS_ptr, DRMS_RecordSet_t **dopRS_ptr,
00092 char *bQuery, char *dopQuery, struct patchInfo *pInfo);
00093
00094
00095 int createCutRecord(DRMS_Record_t *bRec, DRMS_Record_t *dopRec,
00096 DRMS_Record_t *outRec, struct patchInfo *pInfo);
00097
00098
00099 int findCoord(DRMS_Record_t *inRec, struct patchInfo *pInfo, int *ll, int *ur);
00100
00101
00102 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem);
00103
00104
00105 int writeCutout(DRMS_Record_t *outRec, DRMS_Record_t *inRec,
00106 int *ll, int *ur, char *SegName);
00107
00108
00109 void setKeys(DRMS_Record_t *outRec, DRMS_Record_t *inRec, struct patchInfo *pInfo, int *ll);
00110
00111
00112
00113
00114 char *module_name = "cgem_cutout";
00115
00116 ModuleArgs_t module_args[] =
00117 {
00118 {ARG_STRING, "b", kNotSpecified, "Input B series."},
00119
00120 {ARG_STRING, "dop", kNotSpecified, "Data sereis containing Doppler bias correction"},
00121 {ARG_STRING, "out", kNotSpecified, "Output Sharp cutout series."},
00122 {ARG_INT, "cgemnum", "-1", "CGEM dataset ID."},
00123 {ARG_FLOAT, "lonref", "0", "Reference patch center Stonyhurst lon, in deg."},
00124 {ARG_FLOAT, "latref", "0", "Reference patch center Stonyhurst lat, in deg."},
00125 {ARG_INT, "cols", "500", "Columns of output cutout."},
00126 {ARG_INT, "rows", "500", "Rows of output cutout."},
00127 {ARG_STRING, "tref", kNotSpecified, "Reference time."},
00128 {ARG_END}
00129 };
00130
00131 int DoIt(void)
00132 {
00133
00134 int status = DRMS_SUCCESS;
00135
00136
00137
00138 char *bQuery = NULL, *dopQuery = NULL;
00139 char *outQuery = NULL;
00140
00141 bQuery = (char *) params_get_str(&cmdparams, "b");
00142 dopQuery = (char *) params_get_str(&cmdparams, "dop");
00143 outQuery = (char *) params_get_str(&cmdparams, "out");
00144
00145
00146
00147 struct patchInfo pInfo;
00148 pInfo.lonref = params_get_float(&cmdparams, "lonref") * RADSINDEG;
00149 pInfo.latref = params_get_float(&cmdparams, "latref") * RADSINDEG;
00150 pInfo.cols = params_get_int(&cmdparams, "cols");
00151 pInfo.rows = params_get_int(&cmdparams, "rows");
00152 pInfo.tref = params_get_time(&cmdparams, "tref");
00153 pInfo.cgemnum = params_get_int(&cmdparams, "cgemnum");
00154
00155
00156
00157 DRMS_RecordSet_t *bRS = NULL, *dopRS = NULL;
00158
00159 if (getInputRS(&bRS, &dopRS, bQuery, dopQuery, &pInfo))
00160 DIE("Input data error.");
00161 int nrecs = bRS->n;
00162
00163
00164
00165 printf("==============\nStart. %d image(s) in total.\n", nrecs);
00166
00167 for (int irec = 0; irec < nrecs; irec++) {
00168
00169
00170
00171 DRMS_Record_t *bRec = NULL, *dopRec = NULL;
00172
00173 bRec = bRS->records[irec];
00174 dopRec = dopRS->records[irec];
00175
00176 TIME trec = drms_getkey_time(bRec, "T_REC", &status);
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 DRMS_Record_t *outRec = NULL;
00188 outRec = drms_create_record(drms_env, outQuery, DRMS_PERMANENT, &status);
00189 if (status) {
00190 printf("Creating cutout failed, image #%d skipped.\n", irec);
00191 continue;
00192 }
00193
00194 if (createCutRecord(bRec, dopRec, outRec, &pInfo)) {
00195 printf("Creating cutout failed, image #%d skipped.\n", irec);
00196 drms_close_record(outRec, DRMS_FREE_RECORD);
00197 continue;
00198 }
00199
00200
00201
00202 drms_close_record(outRec, DRMS_INSERT_RECORD);
00203
00204 printf("Image #%d done.\n", irec);
00205
00206 }
00207
00208
00209
00210 drms_close_records(bRS, DRMS_FREE_RECORD);
00211
00212
00213 return 0;
00214
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 int getInputRS(DRMS_RecordSet_t **bRS_ptr, DRMS_RecordSet_t **dopRS_ptr,
00230 char *bQuery, char *dopQuery, struct patchInfo *pInfo)
00231 {
00232
00233 int status = 0;
00234
00235 *bRS_ptr = drms_open_records(drms_env, bQuery, &status);
00236 if (status || (*bRS_ptr)->n == 0) return 1;
00237
00238 *dopRS_ptr = drms_open_records(drms_env, dopQuery, &status);
00239 if (status || (*dopRS_ptr)->n == 0) return 1;
00240
00241
00242
00243
00244 if ((*bRS_ptr)->n != (*dopRS_ptr)->n) return 1;
00245 int nrecs = (*bRS_ptr)->n;
00246
00247 DRMS_Record_t *bRec_t = NULL, *dopRec_t = NULL;
00248
00249 for (int i = 0; i < nrecs; i++) {
00250 bRec_t = (*bRS_ptr)->records[i];
00251 dopRec_t = (*dopRS_ptr)->records[i];
00252 if (drms_getkey_time(bRec_t, "T_REC", &status) !=
00253 drms_getkey_time(dopRec_t, "T_REC", &status))
00254 return 1;
00255 }
00256
00257
00258
00259 TIME t0 = drms_getkey_time((*bRS_ptr)->records[0], "T_REC", &status);
00260 if (fabs(pInfo->tref - t0) > DTTHRESH)
00261 pInfo->tref = t0;
00262
00263 return 0;
00264
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 int createCutRecord(DRMS_Record_t *bRec, DRMS_Record_t *dopRec,
00276 DRMS_Record_t *outRec, struct patchInfo *pInfo)
00277 {
00278
00279 int status = 0;
00280
00281
00282
00283 int ll[2], ur[2];
00284 if (findCoord(bRec, pInfo, ll, ur)) {
00285 printf("Coordinate unreasonable\n");
00286 return 1;
00287 }
00288 printf("ll=%d,%d\n", ll[0], ll[1]);
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 int iSeg, nSegs = ARRLENGTH(BSegs);
00303
00304 for (iSeg = 0; iSeg < nSegs; iSeg++) {
00305 if (writeCutout(outRec, bRec, ll, ur, BSegs[iSeg])) {
00306 printf("B cutout fails for %s\n", BSegs[iSeg]);
00307 break;
00308 }
00309 }
00310 if (iSeg != nSegs) return 1;
00311 printf("Vector B cutout done.\n");
00312
00313
00314
00315 setKeys(outRec, bRec, pInfo, ll);
00316 drms_copykey(outRec, dopRec, "DOPPBIAS");
00317
00318 return 0;
00319
00320 }
00321
00322
00323
00324
00325
00326
00327
00328 int findCoord(DRMS_Record_t *inRec, struct patchInfo *pInfo, int *ll, int *ur)
00329 {
00330
00331 int status = 0;
00332
00333
00334
00335 struct ephemeris ephem;
00336 if (getEphemeris(inRec, &ephem)) {
00337 SHOW("Get ephemeris error\n");
00338 return 1;
00339 }
00340
00341
00342
00343
00344
00345 double lat_c = pInfo->latref;
00346 double difr = 2.7139 - 0.405 * pow(sin(lat_c),2) - 0.422 * pow(sin(lat_c),4);
00347 double dt = drms_getkey_time(inRec, "T_REC", &status) - pInfo->tref;
00348 double lon_c = pInfo->lonref + dt * difr * 1.0e-6;
00349 printf("lon_c=%f\n", lon_c/RADSINDEG);
00350
00351 double xc, yc;
00352 if (sphere2img (lat_c, lon_c, ephem.disk_latc, 0., &xc, &yc,
00353 ephem.disk_xc, ephem.disk_yc, ephem.rSun,
00354 ephem.pa, 0., 0., 0., 0.)) {
00355 SHOW("Patch center on far side\n");
00356 return 1;
00357 }
00358
00359
00360
00361 ll[0] = round(xc - pInfo->cols / 2.0);
00362 ll[1] = round(yc - pInfo->rows / 2.0);
00363 ur[0] = ll[0] + pInfo->cols - 1;
00364 ur[1] = ll[1] + pInfo->rows - 1;
00365
00366 return 0;
00367
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem)
00378 {
00379
00380 int status = 0;
00381
00382 float crota2 = drms_getkey_float(inRec, "CROTA2", &status);
00383 double sina = sin(crota2 * RADSINDEG);
00384 double cosa = cos(crota2 * RADSINDEG);
00385
00386 ephem->pa = - crota2 * RADSINDEG;
00387 ephem->disk_latc = drms_getkey_float(inRec, "CRLT_OBS", &status) * RADSINDEG;
00388 ephem->disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status) * RADSINDEG;
00389
00390 float crvalx = 0.0;
00391 float crvaly = 0.0;
00392 float crpix1 = drms_getkey_float(inRec, "CRPIX1", &status);
00393 float crpix2 = drms_getkey_float(inRec, "CRPIX2", &status);
00394 float cdelt = drms_getkey_float(inRec, "CDELT1", &status);
00395 ephem->disk_xc = PIX_X(0.0,0.0) - 1.0;
00396 ephem->disk_yc = PIX_Y(0.0,0.0) - 1.0;
00397
00398 float dSun = drms_getkey_float(inRec, "DSUN_OBS", &status);
00399 float rSun_ref = drms_getkey_float(inRec, "RSUN_REF", &status);
00400 if (status) rSun_ref = 6.96e8;
00401
00402 ephem->asd = asin(rSun_ref/dSun);
00403 ephem->rSun = asin(rSun_ref / dSun) * RAD2ARCSEC / cdelt;
00404
00405 return 0;
00406
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416 int writeCutout(DRMS_Record_t *outRec, DRMS_Record_t *inRec,
00417 int *ll, int *ur, char *SegName)
00418 {
00419
00420 int status = 0;
00421
00422 DRMS_Segment_t *inSeg = NULL, *outSeg = NULL;
00423 DRMS_Array_t *cutoutArray = NULL;
00424
00425 inSeg = drms_segment_lookup(inRec, SegName);
00426 if (!inSeg) return 1;
00427
00428
00429
00430 int nx, ny, nxny;
00431 nx = ur[0] - ll[0] + 1;
00432 ny = ur[1] - ll[1] + 1;
00433 nxny = nx * ny;
00434
00435
00436
00437 if (inSeg->axis[0] == FOURK && inSeg->axis[1] == FOURK) {
00438 cutoutArray = drms_segment_readslice(inSeg, DRMS_TYPE_DOUBLE, ll, ur, &status);
00439 if (status) return 1;
00440 } else {
00441 return 1;
00442 }
00443
00444
00445
00446 #if DISAMB_AZI
00447 if (!strcmp(SegName, "azimuth")) {
00448 DRMS_Segment_t *disambSeg = NULL;
00449 disambSeg = drms_segment_lookup(inRec, "disambig");
00450 if (!disambSeg) {drms_free_array(cutoutArray); return 1;}
00451 DRMS_Array_t *disambArray = drms_segment_readslice(disambSeg, DRMS_TYPE_CHAR, ll, ur, &status);
00452 if (status) return 1;
00453 double *azimuth = (double *) cutoutArray->data;
00454 char *disamb = (char *) disambArray->data;
00455 for (int n = 0; n < nxny; n++) {
00456
00457 if ((disamb[n] / 4) % 2) azimuth[n] += 180.;
00458 }
00459 drms_free_array(disambArray);
00460 }
00461 #endif
00462
00463
00464
00465 outSeg = drms_segment_lookup(outRec, SegName);
00466 if (!outSeg) return 1;
00467 outSeg->axis[0] = cutoutArray->axis[0];
00468 outSeg->axis[1] = cutoutArray->axis[1];
00469 cutoutArray->israw = 0;
00470 cutoutArray->bzero = outSeg->bzero;
00471 cutoutArray->bscale = outSeg->bscale;
00472 status = drms_segment_write(outSeg, cutoutArray, 0);
00473 drms_free_array(cutoutArray);
00474 if (status) return 1;
00475
00476 return 0;
00477
00478 }
00479
00480
00481
00482 void setKeys(DRMS_Record_t *outRec, DRMS_Record_t *inRec, struct patchInfo *pInfo, int *ll)
00483 {
00484
00485 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00486 drms_setkey_int(outRec, "CGEMNUM", pInfo->cgemnum);
00487
00488 TIME val, trec, tnow, UNIX_epoch = -220924792.000;
00489 tnow = (double)time(NULL);
00490 tnow += UNIX_epoch;
00491 drms_setkey_time(outRec, "DATE", tnow);
00492
00493
00494
00495 int status = 0;
00496
00497 float disk_xc = drms_getkey_float(outRec, "CRPIX1", &status);
00498 float disk_yc = drms_getkey_float(outRec, "CRPIX2", &status);
00499
00500 drms_setkey_float(outRec, "CRPIX1", disk_xc - ll[0] + 1.);
00501 drms_setkey_float(outRec, "CRPIX2", disk_yc - ll[1] + 1.);
00502 drms_setkey_float(outRec, "IMCRPIX1", disk_xc + 1.);
00503 drms_setkey_float(outRec, "IMCRPIX2", disk_yc + 1.);
00504
00505 drms_setkey_float(outRec, "CRVAL1", 0);
00506 drms_setkey_float(outRec, "CRVAL2", 0);
00507 drms_setkey_float(outRec, "IMCRVAL1", 0);
00508 drms_setkey_float(outRec, "IMCRVAL2", 0);
00509
00510
00511 int nSeg = ARRLENGTH(CutSegs);
00512 for (int iSeg = 0; iSeg < nSeg; iSeg++) {
00513 DRMS_Segment_t *outSeg = NULL;
00514 outSeg = drms_segment_lookup(outRec, CutSegs[iSeg]);
00515 if (!outSeg) continue;
00516
00517 char bunit_xxx[20];
00518 sprintf(bunit_xxx, "BUNIT_%03d", iSeg);
00519
00520 drms_setkey_string(outRec, bunit_xxx, CutBunits[iSeg]);
00521 }
00522
00523 }