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 "fstats.h"
00033
00034
00035
00036
00037 #define PI (M_PI)
00038 #define TWOPI (2*M_PI)
00039 #define RADSINDEG (PI/180.)
00040 #define RAD2ARCSEC (648000./M_PI)
00041 #define SECINDAY (86400.)
00042 #define FOURK (4096)
00043 #define FOURK2 (16777216)
00044
00045 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
00046
00047
00048 #ifndef MIN
00049 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
00050 #endif
00051 #ifndef MAX
00052 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
00053 #endif
00054
00055 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s, status=%d\n", msg, status); return(status);}
00056 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00057
00058 #define FREE_ARR(arr) {if (arr) {free(arr);}}
00059 #define DRMS_FREE_ARR(arr) {if (arr && (arr->data)) {drms_free_array(arr);}}
00060
00061 #define kNotSpecified "Not Specified"
00062
00063
00064
00065
00066 #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
00067 #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
00068 #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
00069 #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
00070
00071
00072 struct ephemeris {
00073 double disk_lonc, disk_latc;
00074 double disk_xc, disk_yc;
00075 double rSun, asd, pa;
00076 };
00077
00078
00079
00080
00081 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem);
00082
00083
00084 void get_bptr(struct ephemeris *ephem, int *dims, float *fld, float *inc, float *azi,
00085 float *bp, float *bt, float *br, float *lon, float *lat);
00086
00087
00088 void get_bptr_err(struct ephemeris *ephem, int *dims, float *fld, float *inc, float *azi,
00089 float *lon, float *lat,
00090 float *err_fld, float *err_inc, float *err_azi, float *cc_fi, float *cc_fa, float *cc_ia,
00091 float *err_bp, float *err_bt, float *err_br);
00092
00093
00094 int img2helioVector (double bxImg, double byImg, double bzImg, double *bxHelio,
00095 double *byHelio, double *bzHelio, double lon, double lat,
00096 double lonc, double latc, double pAng);
00097
00098
00099 void vecErrProp(float fld, float inc, float azi,
00100 float var_fld, float var_inc, float var_azi, float cov_fi, float cov_fa, float cov_ia,
00101 double lon, double lat, double lonc, double latc, double pa,
00102 double *var_bp, double *var_bt, double *var_br);
00103
00104
00105 int img2sphere (double x, double y, double ang_r, double latc, double lonc,
00106 double pa, double *rho, double *lat, double *lon, double *sinlat,
00107 double *coslat, double *sig, double *mu, double *chi);
00108
00109
00110
00111 char *module_name = "sharp";
00112
00113 ModuleArgs_t module_args[] =
00114 {
00115 {ARG_STRING, "in", kNotSpecified, "Input B series."},
00116 {ARG_STRING, "out", kNotSpecified, "Input Bptr series."},
00117 {ARG_STRING, "requestid", kNotSpecified, "Request ID."},
00118 {ARG_INT, "ambweak", "2", "Disambiguation method. 0: potential acute, 1: random, 2: radial acute"},
00119 {ARG_FLAG, "l", "0", "Flag for lat/lon output."},
00120 {ARG_FLAG, "e", "0", "Flag for error output."},
00121 {ARG_END}
00122 };
00123
00124 int DoIt(void)
00125 {
00126
00127 int status = DRMS_SUCCESS;
00128
00129
00130
00131 char *inQuery = (char *) params_get_str(&cmdparams, "in");
00132 char *outQuery = (char *) params_get_str(&cmdparams, "out");
00133 char *requestid = (char *) params_get_str(&cmdparams, "requestid");
00134 int ambweak = params_get_int(&cmdparams, "ambweak");
00135 int do_lonlat = params_isflagset(&cmdparams, "l");
00136 int do_error = params_isflagset(&cmdparams, "e");
00137
00138 if (ambweak < 0 || ambweak > 2) ambweak = 2;
00139
00140
00141
00142 DRMS_RecordSet_t *inRS = drms_open_records(drms_env, inQuery, &status);
00143
00144 if (!inRS)
00145 {
00146 DIE("No records specified by record-set specification.\n");
00147 }
00148
00149 int nrecs = inRS->n;
00150 if (status || nrecs == 0) DIE("Input records error.");
00151
00152 DRMS_RecordSet_t *outRS = drms_create_records(drms_env, nrecs, outQuery, DRMS_PERMANENT, &status);
00153 if (status) {
00154 drms_close_records(inRS, DRMS_FREE_RECORD);
00155 DIE("Output records not created.");
00156 }
00157
00158
00159
00160 printf("Processing %d records:\n", nrecs);
00161
00162 for (int irec = 0; irec < nrecs; irec++) {
00163
00164
00165 DRMS_Record_t *inRec = inRS->records[irec];
00166
00167 if (!inRec)
00168 {
00169 fprintf(stderr, "No record with index %d in record set.\n", irec);
00170 continue;
00171 }
00172
00173 TIME t_rec = drms_getkey_time(inRec, "T_REC", &status);
00174
00175 if (status != DRMS_SUCCESS)
00176 {
00177 fprintf(stderr, "Unable to obtain keyword value for T_REC.\n");
00178 continue;
00179 }
00180
00181 char t_rec_str[100];
00182 sprint_time(t_rec_str, t_rec, "TAI", 0);
00183 printf("Processing record #%d, T_REC=%s\n", irec, t_rec_str);
00184
00185
00186
00187 struct ephemeris ephem;
00188 status = getEphemeris(inRec, &ephem);
00189
00190
00191
00192 DRMS_Segment_t *inSeg_fld = drms_segment_lookup(inRec, "field");
00193 if (!inSeg_fld)
00194 {
00195 fprintf(stderr, "Missing required segment 'field'.\n");
00196 continue;
00197 }
00198
00199 DRMS_Segment_t *inSeg_inc = drms_segment_lookup(inRec, "inclination");
00200 if (!inSeg_inc)
00201 {
00202 fprintf(stderr, "Missing required segment 'inclination'.\n");
00203 continue;
00204 }
00205
00206 DRMS_Segment_t *inSeg_azi = drms_segment_lookup(inRec, "azimuth");
00207 if (!inSeg_azi)
00208 {
00209 fprintf(stderr, "Missing required segment 'azimuth'.\n");
00210 continue;
00211 }
00212
00213 DRMS_Segment_t *inSeg_amb = drms_segment_lookup(inRec, "disambig");
00214 if (!inSeg_amb)
00215 {
00216 fprintf(stderr, "Missing required segment 'disambig'.\n");
00217 continue;
00218 }
00219
00220 int status_fld = 0, status_inc = 0, status_azi = 0, status_amb = 0;
00221 DRMS_Array_t *inArray_fld = NULL, *inArray_inc = NULL, *inArray_azi = NULL, *inArray_amb = NULL;
00222 inArray_fld = drms_segment_read(inSeg_fld, DRMS_TYPE_FLOAT, &status_fld);
00223 inArray_inc = drms_segment_read(inSeg_inc, DRMS_TYPE_FLOAT, &status_inc);
00224 inArray_azi = drms_segment_read(inSeg_azi, DRMS_TYPE_FLOAT, &status_azi);
00225 inArray_amb = drms_segment_read(inSeg_amb, DRMS_TYPE_CHAR, &status_amb);
00226 if (status_fld || status_inc || status_azi || status_amb) {
00227 printf("Reading input arrays error, record skipped\n");
00228 DRMS_FREE_ARR(inArray_fld); DRMS_FREE_ARR(inArray_inc);
00229 DRMS_FREE_ARR(inArray_azi); DRMS_FREE_ARR(inArray_amb);
00230 continue;
00231 }
00232
00233
00234
00235 DRMS_Array_t *inArray_err_fld = NULL, *inArray_err_inc = NULL, *inArray_err_azi = NULL;
00236 DRMS_Array_t *inArray_cc_fi = NULL, *inArray_cc_fa = NULL, *inArray_cc_ia = NULL;
00237 if (do_error) {
00238 DRMS_Segment_t *inSeg_err_fld = drms_segment_lookup(inRec, "field_err");
00239 DRMS_Segment_t *inSeg_err_inc = drms_segment_lookup(inRec, "inclination_err");
00240 DRMS_Segment_t *inSeg_err_azi = drms_segment_lookup(inRec, "azimuth_err");
00241 DRMS_Segment_t *inSeg_cc_fi = drms_segment_lookup(inRec, "field_inclination_err");
00242 DRMS_Segment_t *inSeg_cc_fa = drms_segment_lookup(inRec, "field_az_err");
00243 DRMS_Segment_t *inSeg_cc_ia = drms_segment_lookup(inRec, "inclin_azimuth_err");
00244
00245 if (!inSeg_err_fld || !inSeg_err_inc || !inSeg_err_azi || !inSeg_cc_fi || !inSeg_cc_fa || !inSeg_cc_ia)
00246 {
00247 fprintf(stderr, "Missing one or more required error segments.\n");
00248 continue;
00249 }
00250
00251 int status_err_fld = 0, status_err_inc = 0, status_err_azi = 0;
00252 int status_cc_fi = 0, status_cc_fa = 0, status_cc_ia = 0;
00253
00254 inArray_err_fld = drms_segment_read(inSeg_err_fld, DRMS_TYPE_FLOAT, &status_err_fld);
00255 inArray_err_inc = drms_segment_read(inSeg_err_inc, DRMS_TYPE_FLOAT, &status_err_inc);
00256 inArray_err_azi = drms_segment_read(inSeg_err_azi, DRMS_TYPE_FLOAT, &status_err_azi);
00257 inArray_cc_fi = drms_segment_read(inSeg_cc_fi, DRMS_TYPE_FLOAT, &status_cc_fi);
00258 inArray_cc_fa = drms_segment_read(inSeg_cc_fa, DRMS_TYPE_FLOAT, &status_cc_fa);
00259 inArray_cc_ia = drms_segment_read(inSeg_cc_ia, DRMS_TYPE_FLOAT, &status_cc_ia);
00260 if (status_err_fld || status_err_inc || status_err_azi ||
00261 status_cc_fi || status_cc_fa || status_cc_ia) {
00262 printf("Reading input uncertainty arrays error, record skipped\n");
00263 DRMS_FREE_ARR(inArray_err_fld); DRMS_FREE_ARR(inArray_err_inc); DRMS_FREE_ARR(inArray_err_azi);
00264 DRMS_FREE_ARR(inArray_cc_fi); DRMS_FREE_ARR(inArray_cc_fa); DRMS_FREE_ARR(inArray_cc_ia);
00265 DRMS_FREE_ARR(inArray_fld); DRMS_FREE_ARR(inArray_inc);
00266 DRMS_FREE_ARR(inArray_azi); DRMS_FREE_ARR(inArray_amb);
00267 continue;
00268 }
00269 }
00270
00271
00272
00273 int ncols = inArray_fld->axis[0], nrows = inArray_fld->axis[1];
00274 int npix = ncols * nrows;
00275 int dims[2] = {ncols, nrows};
00276
00277 float *fld = (float *) (inArray_fld->data);
00278 float *inc = (float *) (inArray_inc->data);
00279 float *azi = (float *) (inArray_azi->data);
00280 char *amb = (char *) (inArray_amb->data);
00281 for (int ipix = 0; ipix < npix; ipix++) {
00282 inc[ipix] *= RADSINDEG;
00283 if (amb[ipix] >> ambweak) azi[ipix] += 180.;
00284 azi[ipix] *= RADSINDEG;
00285 }
00286
00287 float *err_fld = NULL, *err_inc = NULL, *err_azi = NULL;
00288 float *cc_fi = NULL, *cc_fa = NULL, *cc_ia = NULL;
00289 if (do_error) {
00290 err_fld = (float *) (inArray_err_fld->data);
00291 err_inc = (float *) (inArray_err_inc->data);
00292 err_azi = (float *) (inArray_err_azi->data);
00293 cc_fi = (float *) (inArray_cc_fi->data);
00294 cc_fa = (float *) (inArray_cc_fa->data);
00295 cc_ia = (float *) (inArray_cc_ia->data);
00296 for (int ipix = 0; ipix < npix; ipix++) {
00297 err_inc[ipix] *= RADSINDEG;
00298 err_azi[ipix] *= RADSINDEG;
00299 }
00300 }
00301
00302
00303
00304 float *bp = (float *) (malloc(npix * sizeof(float)));
00305 float *bt = (float *) (malloc(npix * sizeof(float)));
00306 float *br = (float *) (malloc(npix * sizeof(float)));
00307 float *lon = (float *) (malloc(npix * sizeof(float)));
00308 float *lat = (float *) (malloc(npix * sizeof(float)));
00309 get_bptr(&ephem, dims, fld, inc, azi, bp, bt, br, lon, lat);
00310
00311
00312
00313 float *err_bp = NULL, *err_bt = NULL, *err_br = NULL;
00314 if (do_error) {
00315 err_bp = (float *) (malloc(npix * sizeof(float)));
00316 err_bt = (float *) (malloc(npix * sizeof(float)));
00317 err_br = (float *) (malloc(npix * sizeof(float)));
00318 get_bptr_err(&ephem, dims, fld, inc, azi, lon, lat,
00319 err_fld, err_inc, err_azi, cc_fi, cc_fa, cc_ia,
00320 err_bp, err_bt, err_br);
00321 }
00322
00323
00324
00325 if (do_lonlat) {
00326 for (int ipix = 0; ipix < npix; ipix++) {
00327 lon[ipix] /= RADSINDEG;
00328 lat[ipix] /= RADSINDEG;
00329 }
00330 }
00331
00332
00333
00334 DRMS_FREE_ARR(inArray_fld); DRMS_FREE_ARR(inArray_inc);
00335 DRMS_FREE_ARR(inArray_azi); DRMS_FREE_ARR(inArray_amb);
00336 if (do_error) {
00337 DRMS_FREE_ARR(inArray_err_fld); DRMS_FREE_ARR(inArray_err_inc); DRMS_FREE_ARR(inArray_err_azi);
00338 DRMS_FREE_ARR(inArray_cc_fi); DRMS_FREE_ARR(inArray_cc_fa); DRMS_FREE_ARR(inArray_cc_ia);
00339 }
00340 if (!do_lonlat) {
00341 FREE_ARR(lon); FREE_ARR(lat);
00342 }
00343
00344
00345
00346 DRMS_Record_t *outRec = outRS->records[irec];
00347 if (!outRec)
00348 {
00349 fprintf(stderr, "No output record with index %d in record set.\n", irec);
00350 continue;
00351 }
00352
00353 DRMS_Segment_t *outSeg_bp = drms_segment_lookup(outRec, "Bp");
00354 if (!outSeg_bp)
00355 {
00356 fprintf(stderr, "Missing required output segment 'Bp'.\n");
00357 continue;
00358 }
00359
00360 DRMS_Segment_t *outSeg_bt = drms_segment_lookup(outRec, "Bt");
00361 if (!outSeg_bt)
00362 {
00363 fprintf(stderr, "Missing required output segment 'Bt'.\n");
00364 continue;
00365 }
00366
00367 DRMS_Segment_t *outSeg_br = drms_segment_lookup(outRec, "Br");
00368 if (!outSeg_br)
00369 {
00370 fprintf(stderr, "Missing required output segment 'Br'.\n");
00371 continue;
00372 }
00373
00374 int status_bp = 0, status_bt = 0, status_br = 0;
00375 DRMS_Array_t *outArray_bp = NULL, *outArray_bt = NULL, *outArray_br = NULL;
00376 outArray_bp = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, bp, &status_bp);
00377 outArray_bt = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, bt, &status_bt);
00378 outArray_br = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, br, &status_br);
00379 if (status_bp || status_bt || status_br) {
00380 printf("Writing output arrays error, record skipped\n");
00381 DRMS_FREE_ARR(outArray_bp); DRMS_FREE_ARR(outArray_bt); DRMS_FREE_ARR(outArray_br);
00382 continue;
00383 }
00384 outArray_bp->israw = outArray_bt->israw = outArray_br->israw = 0;
00385 outArray_bp->bzero = outSeg_bp->bzero; outArray_bp->bscale = outSeg_bp->bscale;
00386 outArray_bt->bzero = outSeg_bt->bzero; outArray_bt->bscale = outSeg_bt->bscale;
00387 outArray_br->bzero = outSeg_br->bzero; outArray_br->bscale = outSeg_br->bscale;
00388
00389 status_bp = drms_segment_write(outSeg_bp, outArray_bp, 0);
00390 status_bt = drms_segment_write(outSeg_bt, outArray_bt, 0);
00391 status_br = drms_segment_write(outSeg_br, outArray_br, 0);
00392 DRMS_FREE_ARR(outArray_bp); DRMS_FREE_ARR(outArray_bt); DRMS_FREE_ARR(outArray_br);
00393
00394 if (status_bp || status_bt || status_br) {
00395 printf("Writing output arrays error, record skipped\n");
00396 continue;
00397 }
00398
00399
00400
00401 if (do_error) {
00402 DRMS_Segment_t *outSeg_err_bp = drms_segment_lookup(outRec, "Bp_err");
00403 if (!outSeg_err_bp)
00404 {
00405 fprintf(stderr, "Missing required output segment 'Bp_err'.\n");
00406 continue;
00407 }
00408
00409 DRMS_Segment_t *outSeg_err_bt = drms_segment_lookup(outRec, "Bt_err");
00410 if (!outSeg_err_bt)
00411 {
00412 fprintf(stderr, "Missing required output segment 'Bt_err'.\n");
00413 continue;
00414 }
00415
00416 DRMS_Segment_t *outSeg_err_br = drms_segment_lookup(outRec, "Br_err");
00417 if (!outSeg_err_br)
00418 {
00419 fprintf(stderr, "Missing required output segment 'Br_err'.\n");
00420 continue;
00421 }
00422
00423 int status_err_bp = 0, status_err_bt = 0, status_err_br = 0;
00424 DRMS_Array_t *outArray_err_bp = NULL, *outArray_err_bt = NULL, *outArray_err_br = NULL;
00425 outArray_err_bp = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, err_bp, &status_err_bp);
00426 outArray_err_bt = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, err_bt, &status_err_bt);
00427 outArray_err_br = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, err_br, &status_err_br);
00428 if (status_err_bp || status_err_bt || status_err_br) {
00429 printf("Writing error output arrays error, record skipped\n");
00430 DRMS_FREE_ARR(outArray_err_bp); DRMS_FREE_ARR(outArray_err_bt); DRMS_FREE_ARR(outArray_err_br);
00431 continue;
00432 }
00433 outArray_err_bp->israw = outArray_err_bt->israw = outArray_err_br->israw = 0;
00434 outArray_err_bp->bzero = outSeg_err_bp->bzero; outArray_err_bp->bscale = outSeg_err_bp->bscale;
00435 outArray_err_bt->bzero = outSeg_err_bt->bzero; outArray_err_bt->bscale = outSeg_err_bt->bscale;
00436 outArray_err_br->bzero = outSeg_err_br->bzero; outArray_err_br->bscale = outSeg_err_br->bscale;
00437
00438 status_err_bp = drms_segment_write(outSeg_err_bp, outArray_err_bp, 0);
00439 status_err_bt = drms_segment_write(outSeg_err_bt, outArray_err_bt, 0);
00440 status_err_br = drms_segment_write(outSeg_err_br, outArray_err_br, 0);
00441 DRMS_FREE_ARR(outArray_err_bp); DRMS_FREE_ARR(outArray_err_bt); DRMS_FREE_ARR(outArray_err_br);
00442
00443 if (status_err_bp || status_err_bt || status_err_br) {
00444 printf("Writing error output arrays error, record skipped\n");
00445 continue;
00446 }
00447 }
00448
00449 if (do_lonlat) {
00450 DRMS_Segment_t *outSeg_lon = drms_segment_lookup(outRec, "lon");
00451 if (!outSeg_lon)
00452 {
00453 fprintf(stderr, "Missing required output segment 'lon'.\n");
00454 continue;
00455 }
00456
00457 DRMS_Segment_t *outSeg_lat = drms_segment_lookup(outRec, "lat");
00458 if (!outSeg_lon)
00459 {
00460 fprintf(stderr, "Missing required output segment 'lat'.\n");
00461 continue;
00462 }
00463
00464 int status_lon = 0, status_lat = 0;
00465 DRMS_Array_t *outArray_lon = NULL, *outArray_lat = NULL;
00466 outArray_lon = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, lon, &status_lon);
00467 outArray_lat = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, lat, &status_lat);
00468 if (status_lon || status_lat) {
00469 printf("Writing lon/lat arrays error, record skipped\n");
00470 DRMS_FREE_ARR(outArray_lon); DRMS_FREE_ARR(outArray_lat);
00471 continue;
00472 }
00473 outArray_lon->israw = outArray_lat->israw = 0;
00474 outArray_lon->bzero = outSeg_lon->bzero; outArray_lon->bscale = outSeg_lon->bscale;
00475 outArray_lat->bzero = outSeg_lat->bzero; outArray_lat->bscale = outSeg_lat->bscale;
00476
00477 status_lon = drms_segment_write(outSeg_lon, outArray_lon, 0);
00478 status_lat = drms_segment_write(outSeg_lat, outArray_lat, 0);
00479 DRMS_FREE_ARR(outArray_lon); DRMS_FREE_ARR(outArray_lat);
00480
00481 if (status_lon || status_lat) {
00482 printf("Writing lon/lat arrays error, record skipped\n");
00483 continue;
00484 }
00485 }
00486
00487
00488
00489 drms_copykeys(outRec, inRec, 0, 0);
00490
00491 TIME val, trec, tnow, UNIX_epoch = -220924792.000;
00492 tnow = (double)time(NULL);
00493 tnow += UNIX_epoch;
00494 drms_setkey_time(outRec, "DATE", tnow);
00495 drms_setkey_int(outRec, "AMBWEAK", ambweak);
00496 drms_setkey_string(outRec, "RequestID", requestid);
00497 drms_setkey_string(outRec, "BUNIT_000", "Mx/cm^2");
00498 drms_setkey_string(outRec, "BUNIT_001", "Mx/cm^2");
00499 drms_setkey_string(outRec, "BUNIT_002", "Mx/cm^2");
00500 drms_setkey_string(outRec, "BUNIT_003", "Mx/cm^2");
00501 drms_setkey_string(outRec, "BUNIT_004", "Mx/cm^2");
00502 drms_setkey_string(outRec, "BUNIT_005", "Mx/cm^2");
00503 drms_setkey_string(outRec, "BUNIT_006", "degree");
00504 drms_setkey_string(outRec, "BUNIT_007", "degree");
00505
00506 }
00507
00508 drms_close_records(inRS, DRMS_FREE_RECORD);
00509 drms_close_records(outRS, DRMS_INSERT_RECORD);
00510
00511 return 0;
00512
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem)
00525 {
00526
00527 int status = 0;
00528
00529 float crota2 = drms_getkey_float(inRec, "CROTA2", &status);
00530 double sina = sin(crota2 * RADSINDEG);
00531 double cosa = cos(crota2 * RADSINDEG);
00532
00533 ephem->pa = - crota2 * RADSINDEG;
00534 ephem->disk_latc = drms_getkey_float(inRec, "CRLT_OBS", &status) * RADSINDEG;
00535 ephem->disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status) * RADSINDEG;
00536
00537 float crvalx = 0.0;
00538 float crvaly = 0.0;
00539 float crpix1 = drms_getkey_float(inRec, "CRPIX1", &status);
00540 float crpix2 = drms_getkey_float(inRec, "CRPIX2", &status);
00541 float cdelt = drms_getkey_float(inRec, "CDELT1", &status);
00542 ephem->disk_xc = PIX_X(0.0,0.0) - 1.0;
00543 ephem->disk_yc = PIX_Y(0.0,0.0) - 1.0;
00544
00545 float dSun = drms_getkey_float(inRec, "DSUN_OBS", &status);
00546 float rSun_ref = drms_getkey_float(inRec, "RSUN_REF", &status);
00547 if (status) rSun_ref = 6.96e8;
00548
00549 ephem->asd = asin(rSun_ref/dSun);
00550 ephem->rSun = asin(rSun_ref / dSun) * RAD2ARCSEC / cdelt;
00551
00552 return 0;
00553
00554 }
00555
00556
00557 void get_bptr(struct ephemeris *ephem, int *dims, float *fld, float *inc, float *azi,
00558 float *bp, float *bt, float *br, float *lon, float *lat)
00559 {
00560 int ncols = dims[0], nrows = dims[1];
00561 int ipix = 0;
00562
00563 double lonc = 0., latc = ephem->disk_latc;
00564 double xc = ephem->disk_xc, yc = ephem->disk_yc;
00565 double asd = ephem->asd, pa = ephem->pa, rSun = ephem->rSun;
00566 double x, y, b_xi, b_eta, b_zeta;
00567 double rho, lat_t, lon_t, sinlat_t, coslat_t, sig, mu, chi;
00568 double bx_t, by_t, bz_t;
00569
00570
00571 for (int row = 0; row < nrows; row++) {
00572 for (int col = 0; col < ncols; col++) {
00573 ipix = row * ncols + col;
00574
00575
00576 x = (col - xc) / rSun; y = (row - yc) / rSun;
00577 if (img2sphere(x, y, asd, latc, lonc, pa,
00578 &rho, &lat_t, &lon_t, &sinlat_t, &coslat_t,
00579 &sig, &mu, &chi)) {
00580 lon[ipix] = lat[ipix] = DRMS_MISSING_FLOAT;
00581 bp[ipix] = bt[ipix] = br[ipix] = DRMS_MISSING_FLOAT;
00582 continue;
00583 }
00584 if (lon_t > PI) lon_t -= TWOPI;
00585 lon[ipix] = lon_t; lat[ipix] = lat_t;
00586
00587
00588 b_xi = - fld[ipix] * sin(inc[ipix]) * sin(azi[ipix]);
00589 b_eta = fld[ipix] * sin(inc[ipix]) * cos(azi[ipix]);
00590 b_zeta = fld[ipix] * cos(inc[ipix]);
00591 img2helioVector(b_xi, b_eta, b_zeta, &bx_t, &by_t, &bz_t,
00592 lon_t, lat_t, lonc, latc, pa);
00593 bp[ipix] = bx_t;
00594 bt[ipix] = by_t * (-1);
00595 br[ipix] = bz_t;
00596 }
00597 }
00598 }
00599
00600
00601 void get_bptr_err(struct ephemeris *ephem, int *dims, float *fld, float *inc, float *azi,
00602 float *lon, float *lat,
00603 float *err_fld, float *err_inc, float *err_azi, float *cc_fi, float *cc_fa, float *cc_ia,
00604 float *err_bp, float *err_bt, float *err_br)
00605 {
00606 int ncols = dims[0], nrows = dims[1];
00607 int npix = ncols * nrows;
00608
00609 double lonc = 0., latc = ephem->disk_latc, pa = ephem->pa;
00610
00611 float var_fld, var_inc, var_azi;
00612 float cov_fi, cov_fa, cov_ia;
00613
00614 double var_bp, var_bt, var_br;
00615
00616 for (int ipix = 0; ipix < npix; ipix++) {
00617 if (isnan(lon[ipix])) {
00618 err_bp[ipix] = err_bt[ipix] = err_br[ipix] = DRMS_MISSING_FLOAT;
00619 continue;
00620 }
00621
00622
00623 var_fld = err_fld[ipix] * err_fld[ipix];
00624 var_inc = err_inc[ipix] * err_inc[ipix];
00625 var_azi = err_azi[ipix] * err_azi[ipix];
00626 cov_fi = cc_fi[ipix] * err_fld[ipix] * err_inc[ipix];
00627 cov_fa = cc_fa[ipix] * err_fld[ipix] * err_azi[ipix];
00628 cov_ia = cc_ia[ipix] * err_inc[ipix] * err_azi[ipix];
00629
00630
00631 vecErrProp(fld[ipix], inc[ipix], azi[ipix], var_fld, var_inc, var_azi, cov_fi, cov_fa, cov_ia,
00632 lon[ipix], lat[ipix], lonc, latc, pa, &var_bp, &var_bt, &var_br);
00633 err_bp[ipix] = sqrt(var_bp);
00634 err_bt[ipix] = sqrt(var_bt);
00635 err_br[ipix] = sqrt(var_br);
00636 }
00637 }
00638
00639
00640 int img2helioVector (double bxImg, double byImg, double bzImg, double *bxHelio,
00641 double *byHelio, double *bzHelio, double lon, double lat,
00642 double lonc, double latc, double pAng) {
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 static double raddeg = M_PI / 180.;
00661 double a11, a12, a13, a21, a22, a23, a31, a32, a33;
00662
00663 a11 = -sin(latc) * sin(pAng) * sin(lon - lonc) + cos(pAng) * cos(lon - lonc);
00664 a12 = sin(latc) * cos(pAng) * sin(lon - lonc) + sin(pAng) * cos(lon - lonc);
00665 a13 = -cos(latc) * sin(lon - lonc);
00666 a21 = -sin(lat) * (sin(latc) * sin(pAng) * cos(lon - lonc) + cos(pAng) * sin(lon - lonc))
00667 - cos(lat) * cos(latc) * sin(pAng);
00668 a22 = sin(lat) * (sin(latc) * cos(pAng) * cos(lon - lonc) - sin(pAng) * sin(lon - lonc))
00669 + cos(lat) * cos(latc) * cos(pAng);
00670 a23 = -cos(latc) * sin(lat) * cos(lon - lonc) + sin(latc) * cos(lat);
00671 a31 = cos(lat) * (sin(latc) * sin(pAng) * cos(lon - lonc) + cos(pAng) * sin(lon - lonc))
00672 - sin(lat) * cos(latc) * sin(pAng);
00673 a32 = -cos(lat) * (sin(latc) * cos(pAng) * cos(lon - lonc) - sin(pAng) * sin(lon - lonc))
00674 + sin(lat) * cos(latc) * cos(pAng);
00675 a33 = cos(lat) * cos(latc) * cos(lon - lonc) + sin(lat) * sin(latc);
00676
00677 *bxHelio = a11 * bxImg + a12 * byImg + a13 * bzImg;
00678 *byHelio = a21 * bxImg + a22 * byImg + a23 * bzImg;
00679 *bzHelio = a31 * bxImg + a32 * byImg + a33 * bzImg;
00680
00681 return 0;
00682 }
00683
00684
00685
00686
00687
00688
00689
00690 void vecErrProp(float fld, float inc, float azi,
00691 float var_fld, float var_inc, float var_azi, float cov_fi, float cov_fa, float cov_ia,
00692 double lon, double lat, double lonc, double latc, double pa,
00693 double *var_bp, double *var_bt, double *var_br)
00694
00695 {
00696
00697
00698
00699 double a11, a12, a13, a21, a22, a23, a31, a32, a33;
00700 a11 = - sin(latc) * sin(pa) * sin(lon - lonc) + cos(pa) * cos(lon - lonc);
00701 a12 = sin(latc) * cos(pa) * sin(lon - lonc) + sin(pa) * cos(lon - lonc);
00702 a13 = - cos(latc) * sin(lon - lonc);
00703 a21 = - sin(lat) * (sin(latc) * sin(pa) * cos(lon - lonc) + cos(pa) * sin(lon - lonc))
00704 - cos(lat) * cos(latc) * sin(pa);
00705 a22 = sin(lat) * (sin(latc) * cos(pa) * cos(lon - lonc) - sin(pa) * sin(lon - lonc))
00706 + cos(lat) * cos(latc) * cos(pa);
00707 a23 = - cos(latc) * sin(lat) * cos(lon - lonc) + sin(latc) * cos(lat);
00708 a31 = cos(lat) * (sin(latc) * sin(pa) * cos(lon - lonc) + cos(pa) * sin(lon - lonc))
00709 - sin(lat) * cos(latc) * sin(pa);
00710 a32 = - cos(lat) * (sin(latc) * cos(pa) * cos(lon - lonc) - sin(pa) * sin(lon - lonc))
00711 + sin(lat) * cos(latc) * cos(pa);
00712 a33 = cos(lat) * cos(latc) * cos(lon - lonc) + sin(lat) * sin(latc);
00713
00714
00715
00716 double dBpdfld, dBpdinc, dBpdazi;
00717 double dBtdfld, dBtdinc, dBtdazi;
00718 double dBrdfld, dBrdinc, dBrdazi;
00719
00720 dBpdfld = (- a11 * sin(inc) * sin(azi) + a12 * sin(inc) * cos(azi) + a13 * cos(inc));
00721 dBpdinc = fld * (- a11 * cos(inc) * sin(azi) + a12 * cos(inc) * cos(azi) - a13 * sin(inc));
00722 dBpdazi = fld * (- a11 * sin(inc) * cos(azi) - a12 * sin(inc) * sin(azi));
00723
00724 dBtdfld = (- a21 * sin(inc) * sin(azi) + a22 * sin(inc) * cos(azi) + a23 * cos(inc));
00725 dBtdinc = fld * (- a21 * cos(inc) * sin(azi) + a22 * cos(inc) * cos(azi) - a23 * sin(inc));
00726 dBtdazi = fld * (- a21 * sin(inc) * cos(azi) - a22 * sin(inc) * sin(azi));
00727
00728 dBrdfld = (- a31 * sin(inc) * sin(azi) + a32 * sin(inc) * cos(azi) + a33 * cos(inc));
00729 dBrdinc = fld * (- a31 * cos(inc) * sin(azi) + a32 * cos(inc) * cos(azi) - a33 * sin(inc));
00730 dBrdazi = fld * (- a31 * sin(inc) * cos(azi) - a32 * sin(inc) * sin(azi));
00731
00732
00733
00734 *var_bp = dBpdfld * dBpdfld * var_fld + dBpdinc * dBpdinc * var_inc + dBpdazi * dBpdazi * var_azi +
00735 2.0 * dBpdfld * dBpdinc * cov_fi + 2.0 * dBpdfld * dBpdazi * cov_fa + 2.0 * dBpdinc * dBpdazi * cov_ia;
00736
00737 *var_bt = dBtdfld * dBtdfld * var_fld + dBtdinc * dBtdinc * var_inc + dBtdazi * dBtdazi * var_azi +
00738 2.0 * dBtdfld * dBtdinc * cov_fi + 2.0 * dBtdfld * dBtdazi * cov_fa + 2.0 * dBtdinc * dBtdazi * cov_ia;
00739
00740 *var_br = dBrdfld * dBrdfld * var_fld + dBrdinc * dBrdinc * var_inc + dBrdazi * dBrdazi * var_azi +
00741 2.0 * dBrdfld * dBrdinc * cov_fi + 2.0 * dBrdfld * dBrdazi * cov_fa + 2.0 * dBrdinc * dBrdazi * cov_ia;
00742
00743 }
00744
00745
00746 int img2sphere (double x, double y, double ang_r, double latc, double lonc,
00747 double pa, double *rho, double *lat, double *lon, double *sinlat,
00748 double *coslat, double *sig, double *mu, double *chi) {
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 static double ang_r0 = 0.0, sinang_r = 0.0, tanang_r = 0.0;
00781 static double latc0 = 0.0, coslatc = 1.0, sinlatc = 0.0;
00782 double cosr, sinr, sinlon, sinsig;
00783
00784 if (ang_r != ang_r0) {
00785 sinang_r = sin (ang_r);
00786 tanang_r = tan (ang_r);
00787 ang_r0 = ang_r;
00788 }
00789 if (latc != latc0) {
00790 sinlatc = sin (latc);
00791 coslatc = cos (latc);
00792 latc0 = latc;
00793 }
00794 *chi = atan2 (x, y) + pa;
00795 while (*chi > 2 * M_PI) *chi -= 2 * M_PI;
00796 while (*chi < 0.0) *chi += 2 * M_PI;
00797
00798 *sig = atan (hypot (x, y) * tanang_r);
00799 sinsig = sin (*sig);
00800 *rho = asin (sinsig / sinang_r) - *sig;
00801 if (*sig > ang_r) return (-1);
00802 *mu = cos (*rho + *sig);
00803 sinr = sin (*rho);
00804 cosr = cos (*rho);
00805
00806 *sinlat = sinlatc * cos (*rho) + coslatc * sinr * cos (*chi);
00807 *coslat = sqrt (1.0 - *sinlat * *sinlat);
00808 *lat = asin (*sinlat);
00809 sinlon = sinr * sin (*chi) / *coslat;
00810 *lon = asin (sinlon);
00811 if (cosr < (*sinlat * sinlatc)) *lon = M_PI - *lon;
00812 *lon += lonc;
00813 while (*lon < 0.0) *lon += 2 * M_PI;
00814 while (*lon >= 2 * M_PI) *lon -= 2 * M_PI;
00815 return (0);
00816 }