00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <time.h>
00011 #include <sys/time.h>
00012 #include <math.h>
00013 #include <string.h>
00014 #include "jsoc_main.h"
00015 #include "astro.h"
00016 #include "cartography.c"
00017 #include "img2helioVector.c"
00018 #include "finterpolate.h"
00019
00020
00021
00022 #define PI (M_PI)
00023 #define RADSINDEG (PI/180.)
00024 #define RAD2ARCSEC (648000./M_PI)
00025 #define SECINDAY (86400.)
00026 #define FOURK (4096)
00027 #define FOURK2 (16777216)
00028 #define DTTHRESH (518400.) // 6 day
00029 #define INTERPOPT (0) // Interpolation
00030
00031 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
00032
00033 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s, status=%d\n", msg, status); return(status);}
00034 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00035
00036 #define kNotSpecified "Not Specified"
00037 #define dpath "/home/jsoc/cvs/Development/JSOC"
00038
00039 #define NT (5) // chunk size
00040 #define FLIP_THR (120) // azimuth flipping threshold
00041
00042
00043
00044
00045 #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
00046 #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
00047 #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
00048 #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
00049
00050
00051 char *wcsCode[] = {"CAR", "CAS", "MER", "CEA", "GLS", "TAN", "ARC", "STG",
00052 "SIN", "ZEA"};
00053
00054
00055
00056 struct ephemeris {
00057 double disk_lonc, disk_latc;
00058 double disk_xc, disk_yc;
00059 double rSun, asd, pa;
00060 TIME t_rec;
00061 };
00062
00063
00064 struct reqInfo {
00065 double lonref, latref;
00066 int ncol, nrow;
00067 double dx, dy;
00068 TIME tref;
00069 int proj;
00070 };
00071
00072
00073
00074
00075
00076 int correct_dop(DRMS_Record_t *inRec, DRMS_Record_t *outRec);
00077
00078
00079 int correct_azi(DRMS_Record_t *inRec, DRMS_Record_t *outRec, float *azi_work,
00080 int edgeRec, int nx, int ny, int nt);
00081
00082
00083 int cgem_mapping(DRMS_Record_t *inRec, DRMS_Record_t *outRec, struct reqInfo *req);
00084
00085
00086 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem);
00087
00088
00089 void findCoord(struct reqInfo *req, struct ephemeris *ephem,
00090 float *u_out, float *v_out, float *mapCenter);
00091
00092
00093 void vectorTransform(float *fld, float *inc, float *az, float *bx, float *by, float *bz,
00094 int *dims, struct ephemeris *ephem);
00095
00096
00097 void getLOSVector(struct reqInfo *req, struct ephemeris *ephem, float *mapCenter,
00098 float *lx, float *ly, float *lz);
00099
00100
00101 void performSampling(float *inData, float *outData, float *u, float *v, int *dims_in, int *dims_out);
00102
00103
00104 float nnb (float *f, int nx, int ny, float x, float y);
00105
00106
00107 extern void azim_mindiff_jsoc_(float *azi_work, float *azi_out, int *nx, int *ny, int *nt2, int *flip_thr);
00108
00109
00110
00111 char *module_name = "cgem_prep";
00112
00113 ModuleArgs_t module_args[] =
00114 {
00115 {ARG_STRING, "in", kNotSpecified, "Input data series."},
00116 {ARG_STRING, "medv", "hmi_test.medv", "Intermediate series for Doppler correction."},
00117 {ARG_STRING, "meda", "hmi_test.meda", "Intermediate series for azimuth correction."},
00118 {ARG_STRING, "out", "hmi_test.cgem_prep", "Output data series."},
00119 {ARG_FLAG, "a", "", "No azimuth correction."},
00120 {ARG_FLAG, "s", "", "Save intermediate steps."},
00121 {ARG_NUME, "map", "carree", "Projetion method, carree by default.",
00122 "carree, Cassini, Mercator, cyleqa, sineqa, gnomonic, Postel, stereographic, orthographic, Lambert"},
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_FLOAT, "dx", "0.03", "X pixel size, unit depending on projection (default deg)."},
00128 {ARG_FLOAT, "dy", "0.03", "Y pixel size, unit depending on projection (default deg)."},
00129 {ARG_STRING, "tref", kNotSpecified, "Reference time."},
00130
00131 {ARG_END}
00132 };
00133
00134 int DoIt(void)
00135 {
00136
00137 int status = DRMS_SUCCESS;
00138
00139
00140
00141 char *inQuery, *outQuery, *medvQuery, *medaQuery;
00142
00143 inQuery = (char *) params_get_str(&cmdparams, "in");
00144 outQuery = (char *) params_get_str(&cmdparams, "out");
00145 medvQuery = (char *) params_get_str(&cmdparams, "medv");
00146 medaQuery = (char *) params_get_str(&cmdparams, "meda");
00147
00148
00149
00150 int do_azi = !(params_isflagset(&cmdparams, "a"));
00151 int saveInterm = params_isflagset(&cmdparams, "s");
00152 int nt = round(fabs(NT));
00153
00154
00155
00156 struct reqInfo req;
00157 req.lonref = params_get_float(&cmdparams, "lonref") * RADSINDEG;
00158 req.latref = params_get_float(&cmdparams, "latref") * RADSINDEG;
00159 req.ncol = params_get_int(&cmdparams, "cols");
00160 req.nrow = params_get_int(&cmdparams, "rows");
00161 req.tref = params_get_time(&cmdparams, "tref");
00162 req.dx = params_get_float(&cmdparams, "dx") * RADSINDEG;
00163 req.dy = params_get_float(&cmdparams, "dy") * RADSINDEG;
00164 req.proj = params_get_int(&cmdparams, "map");
00165
00166
00167 DRMS_RecLifetime_t intLife = saveInterm ? DRMS_PERMANENT : DRMS_TRANSIENT;
00168 int closeAction = saveInterm ? DRMS_INSERT_RECORD : DRMS_FREE_RECORD;
00169 nt = (nt % 2) ? nt : nt + 1;
00170 int nt2 = nt / 2;
00171
00172
00173
00174
00175
00176 DRMS_RecordSet_t *inRS = drms_open_records(drms_env, inQuery, &status);
00177 int nrecs = inRS->n;
00178 if (status || nrecs == 0 || !inRS) DIE("Input data series error");
00179 if (do_azi && nrecs < nt) DIE("Input data series not long enough for azi correction");
00180
00181
00182
00183 TIME t0 = drms_getkey_time(inRS->records[0], "T_REC", &status);
00184 if (fabs(req.tref - t0) > DTTHRESH) {
00185 req.tref = t0;
00186 }
00187
00188
00189
00190 int nx, ny;
00191 for (int irec = 0; irec < nrecs; irec++) {
00192 DRMS_Record_t *inRec = inRS->records[irec];
00193 DRMS_Segment_t *inSeg = drms_segment_lookup(inRec, "azimuth");
00194 if (!inSeg) DIE("Can't check array dimension!");
00195 if (irec == 0) {
00196 nx = inSeg->axis[0]; ny = inSeg->axis[1];
00197 continue;
00198 }
00199 if ((inSeg->axis[0] != nx) || (inSeg->axis[1] != ny)) {
00200 DIE("Array sizes do not match!");
00201 }
00202 }
00203 int nxny = nx * ny;
00204
00205
00206
00207
00208
00209 printf("==============\nStart correcting Doppler. %d image(s) in total.\n", nrecs);
00210
00211
00212
00213 DRMS_RecordSet_t *medvRS = drms_create_records(drms_env, nrecs, medvQuery, intLife, &status);
00214 if (status || !medvRS) {DIE("Error in Doppler correciton series");}
00215
00216 for (int irec = 0; irec < nrecs; irec++) {
00217
00218 DRMS_Record_t *inRec = inRS->records[irec];
00219 DRMS_Record_t *medvRec = medvRS->records[irec];
00220
00221 printf("Frame %d of %d... ", irec + 1, nrecs);
00222
00223 if (correct_dop(inRec, medvRec)) {
00224 printf("Doppler correction error, frame %s skipped.\n", irec);
00225 continue;
00226 }
00227
00228 printf("done.\n");
00229
00230 }
00231
00232 drms_close_records(inRS, DRMS_FREE_RECORD);
00233
00234
00235
00236
00237
00238 DRMS_RecordSet_t *medaRS = NULL;
00239
00240 if (do_azi) {
00241
00242 printf("==============\nStart correcting Azimuth.\n");
00243
00244 medaRS = drms_create_records(drms_env, nrecs, medaQuery, intLife, &status);
00245 if (status || !medaRS) {DIE("Error in azimuth correciton series");}
00246
00247
00248
00249 printf("Reading all azimuths... ");
00250
00251 float *azi_cube = (float *) (malloc(nxny * nrecs * sizeof(float)));
00252 for (int irec = 0; irec < nrecs; irec++) {
00253
00254 DRMS_Record_t *medvRec = medvRS->records[irec];
00255 DRMS_Segment_t *inSeg = drms_segment_lookup(medvRec, "azimuth");
00256 if (!inSeg) DIE("Can't retrieve azimtuh!");
00257
00258 DRMS_Array_t *inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00259 if (status || !inArray) return 1;
00260
00261 float *inData = (float *)inArray->data;
00262 float *azi_cube_lead = azi_cube + nxny * irec;
00263 memcpy(azi_cube_lead, inData, nxny * sizeof(float));
00264
00265 drms_free_array(inArray);
00266
00267 }
00268
00269 printf("done.\n");
00270
00271
00272
00273 float *azi_work = (float *) (malloc(nxny * nt * sizeof(float)));
00274
00275 for (int irec = 0; irec < nrecs; irec++) {
00276
00277 DRMS_Record_t *medvRec = medvRS->records[irec];
00278 DRMS_Record_t *medaRec = medaRS->records[irec];
00279
00280 printf("Frame %d of %d... ", irec + 1, nrecs);
00281
00282 int edgeRec = ((irec < nt2) || (irec >= (nrecs - nt2)));
00283 float *azi_work_lead, *azi_cube_lead;
00284
00285
00286
00287 if (irec <= nt2) {
00288
00289 azi_work_lead = azi_work + (nt2 - irec) * nxny;
00290 azi_cube_lead = azi_cube;
00291 memcpy(azi_work_lead, azi_cube_lead, nxny * (nt - nt2 + irec) * sizeof(float));
00292
00293 } else if (irec >= (nrecs - nt2)) {
00294
00295 azi_work_lead = azi_work;
00296 azi_cube_lead = azi_cube + (irec - nt2) * nxny;
00297 memcpy(azi_work_lead, azi_cube_lead, nxny * (nrecs - irec + nt2) * sizeof(float));
00298
00299 } else {
00300
00301
00302
00303 for (int i = 0; i < nt - 1; i++) {
00304 memcpy(azi_work + i * nxny, azi_work + (i + 1) * nxny, nxny * sizeof(float));
00305 }
00306 azi_work_lead = azi_work + (nt - 1) * nxny;
00307 azi_cube_lead = azi_cube + (irec + nt2) * nxny;
00308 memcpy(azi_work_lead, azi_cube_lead, nxny * sizeof(float));
00309
00310 }
00311
00312
00313
00314
00315
00316
00317 if (correct_azi(medvRec, medaRec, azi_work, edgeRec, nx, ny, nt)) {
00318 printf("Azimuth correction error, frame %s skipped.\n", irec);
00319 continue;
00320 }
00321
00322 printf("done.\n");
00323
00324 }
00325
00326
00327
00328 free(azi_work);
00329 free(azi_cube);
00330
00331
00332 } else {
00333
00334 printf("Azimuth correction skipped by request.\n");
00335
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 if (do_azi) {
00345 inRS = medaRS;
00346 } else {
00347 inRS = medvRS;
00348 }
00349
00350 printf("==============\nStart mapping.\n");
00351
00352 DRMS_RecordSet_t *outRS = drms_create_records(drms_env, nrecs, outQuery, DRMS_PERMANENT, &status);
00353 if (status || !outRS) {DIE("Error in output series");}
00354
00355 for (int irec = 0; irec < nrecs; irec++) {
00356
00357 DRMS_Record_t *inRec = inRS->records[irec];
00358 DRMS_Record_t *outRec = outRS->records[irec];
00359
00360 printf("Frame %d of %d... ", irec + 1, nrecs);
00361
00362 if (cgem_mapping(inRec, outRec, &req)) {
00363 printf("Mapping error, frame %d skipped.\n", irec);
00364 continue;
00365 }
00366
00367 printf("done.\n");
00368
00369 }
00370
00371 drms_close_records(outRS, DRMS_INSERT_RECORD);
00372
00373
00374
00375
00376
00377 drms_close_records(medvRS, closeAction);
00378 if (do_azi) drms_close_records(medaRS, closeAction);
00379
00380 return 0;
00381
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 int correct_dop(DRMS_Record_t *inRec, DRMS_Record_t *outRec)
00391 {
00392 int status = 0;
00393
00394
00395
00396 DRMS_Segment_t *inSeg = drms_segment_lookup(inRec, "Dopplergram");
00397 if (!inSeg) return 1;
00398
00399 DRMS_Array_t *inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00400 if (status || !inArray) return 1;
00401
00402 float *dop_in = (float *) inArray->data;
00403 int nx = inArray->axis[0], ny = inArray->axis[1], nxny = nx * ny;
00404 int dims[2] = {nx, ny};
00405
00406
00407
00408 float *dop_out = (float *) (malloc(nxny * sizeof(float)));
00409 double vr = drms_getkey_double(inRec, "OBS_VR", &status);
00410
00411
00412
00413
00414
00415
00416 for (int i = 0; i < nxny; i++) {
00417 dop_out[i] = dop_in[i] - vr;
00418 }
00419 float ddop = 0;
00420 drms_free_array(inArray);
00421
00422
00423
00424 DRMS_Segment_t *outSeg = drms_segment_lookup(outRec, "Dopplergram");
00425 if (!outSeg) return 1;
00426
00427 DRMS_Array_t *outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, dop_out, &status);
00428 if (status) {free(dop_out); return 1;}
00429
00430 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00431 outArray->israw = 0;
00432 outArray->bzero = outSeg->bzero;
00433 outArray->bscale = outSeg->bscale;
00434
00435 status = drms_segment_write(outSeg, outArray, 0);
00436 if (status) return status;
00437
00438 drms_free_array(outArray);
00439
00440
00441
00442 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00443 drms_setkey_float(outRec, "DDOP", ddop);
00444
00445 TIME val, trec, tnow, UNIX_epoch = -220924792.000;
00446 tnow = (double)time(NULL);
00447 tnow += UNIX_epoch;
00448 drms_setkey_time(outRec, "DATE", tnow);
00449
00450 DRMS_Link_t *link = hcon_lookup_lower(&outRec->links, "DATA");
00451 if (link) drms_link_set("DATA", outRec, inRec);
00452
00453 return 0;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 int correct_azi(DRMS_Record_t *inRec, DRMS_Record_t *outRec, float *azi_work,
00463 int edgeRec, int nx, int ny, int nt)
00464 {
00465 int status = 0;
00466
00467 int nt2 = nt / 2;
00468 int flip_thr = FLIP_THR;
00469 int nxny = nx * ny;
00470
00471 float *azi_out = (float *) (malloc(nxny * sizeof(float)));
00472
00473
00474
00475
00476 if (edgeRec) {
00477
00478 memcpy(azi_out, azi_work + nxny * nt2, nxny * sizeof(float));
00479
00480 } else {
00481
00482 azim_mindiff_jsoc_(azi_work, azi_out, &nx, &ny, &nt2, &flip_thr);
00483
00484 }
00485
00486
00487
00488 memcpy(azi_work + nxny * nt2, azi_out, nxny * sizeof(float));
00489
00490
00491
00492 DRMS_Segment_t *outSeg = drms_segment_lookup(outRec, "azimuth");
00493 if (!outSeg) return 1;
00494
00495 int dims[2] = {nx, ny};
00496 DRMS_Array_t *outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, azi_out, &status);
00497 if (status) {free(azi_out); return 1;}
00498
00499 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00500 outArray->israw = 0;
00501 outArray->bzero = outSeg->bzero;
00502 outArray->bscale = outSeg->bscale;
00503
00504 status = drms_segment_write(outSeg, outArray, 0);
00505 if (status) return status;
00506
00507 drms_free_array(outArray);
00508
00509
00510
00511 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00512
00513 TIME val, trec, tnow, UNIX_epoch = -220924792.000;
00514 tnow = (double)time(NULL);
00515 tnow += UNIX_epoch;
00516 drms_setkey_time(outRec, "DATE", tnow);
00517
00518 DRMS_Link_t *link = hcon_lookup_lower(&outRec->links, "DATA");
00519 if (link) drms_link_set("DATA", outRec, inRec);
00520
00521 return 0;
00522
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532 int cgem_mapping(DRMS_Record_t *inRec, DRMS_Record_t *outRec, struct reqInfo *req)
00533 {
00534 int status = 0;
00535
00536
00537
00538 struct ephemeris ephem;
00539
00540 if (getEphemeris(inRec, &ephem)) {
00541 SHOW("Mapping: get ephemeris error\n");
00542 return 1;
00543 }
00544
00545
00546
00547 DRMS_Segment_t *inSeg;
00548 DRMS_Array_t *inArray_fld, *inArray_inc, *inArray_azi, *inArray_dop;
00549
00550 float *fld, *inc, *azi, *dop;
00551
00552 inSeg = drms_segment_lookup(inRec, "field");
00553 inArray_fld = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00554 if (status) return 1;
00555 fld = (float *)inArray_fld->data;
00556
00557 inSeg = drms_segment_lookup(inRec, "inclination");
00558 inArray_inc = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00559 if (status) return 1;
00560 inc = (float *)inArray_inc->data;
00561
00562 inSeg = drms_segment_lookup(inRec, "azimuth");
00563 inArray_azi = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00564 if (status) return 1;
00565 azi = (float *)inArray_azi->data;
00566
00567 inSeg = drms_segment_lookup(inRec, "Dopplergram");
00568 inArray_dop = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
00569 if (status) return 1;
00570 dop = (float *)inArray_dop->data;
00571
00572 int dims_in[2] = {inArray_fld->axis[0], inArray_fld->axis[1]};
00573
00574
00575
00576 float *bx = (float *) (malloc(dims_in[0] * dims_in[1] * sizeof(float)));
00577 float *by = (float *) (malloc(dims_in[0] * dims_in[1] * sizeof(float)));
00578 float *bz = (float *) (malloc(dims_in[0] * dims_in[1] * sizeof(float)));
00579
00580 vectorTransform(fld, inc, azi, bx, by, bz, dims_in, &ephem);
00581
00582
00583
00584 int dims_out[2] = {req->ncol, req->nrow};
00585 float *u_out = (float *) (malloc(dims_out[0] * dims_out[1] * sizeof(float)));
00586 float *v_out = (float *) (malloc(dims_out[0] * dims_out[1] * sizeof(float)));
00587
00588 float mapCenter[2];
00589 findCoord(req, &ephem, u_out, v_out, mapCenter);
00590
00591
00592
00593 float *bx_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00594 float *by_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00595 float *bz_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00596 float *dop_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00597
00598 performSampling(bx, bx_map, u_out, v_out, dims_in, dims_out);
00599 performSampling(by, by_map, u_out, v_out, dims_in, dims_out);
00600 performSampling(bz, bz_map, u_out, v_out, dims_in, dims_out);
00601 performSampling(dop, dop_map, u_out, v_out, dims_in, dims_out);
00602
00603
00604
00605 float *lx_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00606 float *ly_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00607 float *lz_map = (float *) (malloc(req->ncol * req->nrow * sizeof(float)));
00608
00609 getLOSVector(req, &ephem, mapCenter, lx_map, ly_map, lz_map);
00610
00611
00612
00613 drms_free_array(inArray_fld);
00614 drms_free_array(inArray_inc);
00615 drms_free_array(inArray_azi);
00616 drms_free_array(inArray_dop);
00617 free(u_out);
00618 free(v_out);
00619
00620
00621
00622 DRMS_Segment_t *outSeg;
00623 DRMS_Array_t *outArray;
00624
00625 outSeg = drms_segment_lookup(outRec, "Bx");
00626 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, bx_map, &status);
00627 if (status) {free(bx_map); return 1;}
00628 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00629 outArray->israw = 0;
00630 outArray->bzero = outSeg->bzero;
00631 outArray->bscale = outSeg->bscale;
00632 status = drms_segment_write(outSeg, outArray, 0);
00633 if (status) { return status; } else { drms_free_array(outArray); }
00634
00635 outSeg = drms_segment_lookup(outRec, "By");
00636 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, by_map, &status);
00637 if (status) {free(by_map); return 1;}
00638 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00639 outArray->israw = 0;
00640 outArray->bzero = outSeg->bzero;
00641 outArray->bscale = outSeg->bscale;
00642 status = drms_segment_write(outSeg, outArray, 0);
00643 if (status) { return status; } else { drms_free_array(outArray); }
00644
00645 outSeg = drms_segment_lookup(outRec, "Bz");
00646 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, bz_map, &status);
00647 if (status) {free(bz_map); return 1;}
00648 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00649 outArray->israw = 0;
00650 outArray->bzero = outSeg->bzero;
00651 outArray->bscale = outSeg->bscale;
00652 status = drms_segment_write(outSeg, outArray, 0);
00653 if (status) { return status; } else { drms_free_array(outArray); }
00654
00655 outSeg = drms_segment_lookup(outRec, "Dopplergram");
00656 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, dop_map, &status);
00657 if (status) {free(dop_map); return 1;}
00658 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00659 outArray->israw = 0;
00660 outArray->bzero = outSeg->bzero;
00661 outArray->bscale = outSeg->bscale;
00662 status = drms_segment_write(outSeg, outArray, 0);
00663 if (status) { return status; } else { drms_free_array(outArray); }
00664
00665 outSeg = drms_segment_lookup(outRec, "Lx");
00666 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, lx_map, &status);
00667 if (status) {free(lx_map); return 1;}
00668 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00669 outArray->israw = 0;
00670 outArray->bzero = outSeg->bzero;
00671 outArray->bscale = outSeg->bscale;
00672 status = drms_segment_write(outSeg, outArray, 0);
00673 if (status) { return status; } else { drms_free_array(outArray); }
00674
00675 outSeg = drms_segment_lookup(outRec, "Ly");
00676 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, ly_map, &status);
00677 if (status) {free(ly_map); return 1;}
00678 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00679 outArray->israw = 0;
00680 outArray->bzero = outSeg->bzero;
00681 outArray->bscale = outSeg->bscale;
00682 status = drms_segment_write(outSeg, outArray, 0);
00683 if (status) { return status; } else { drms_free_array(outArray); }
00684
00685 outSeg = drms_segment_lookup(outRec, "Lz");
00686 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims_out, lz_map, &status);
00687 if (status) {free(lz_map); return 1;}
00688 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
00689 outArray->israw = 0;
00690 outArray->bzero = outSeg->bzero;
00691 outArray->bscale = outSeg->bscale;
00692 status = drms_segment_write(outSeg, outArray, 0);
00693 if (status) { return status; } else { drms_free_array(outArray); }
00694
00695
00696
00697 drms_copykeys(outRec, inRec, 0, kDRMS_KeyClass_Explicit);
00698
00699 drms_setkey_float(outRec, "CRPIX1", req->ncol/2. + 0.5);
00700 drms_setkey_float(outRec, "CRPIX2", req->nrow/2. + 0.5);
00701 drms_setkey_float(outRec, "CRVAL1", mapCenter[0]);
00702 drms_setkey_float(outRec, "CRVAL2", mapCenter[1]);
00703 drms_setkey_float(outRec, "CDELT1", req->dx / RADSINDEG);
00704 drms_setkey_float(outRec, "CDELT2", req->dy / RADSINDEG);
00705 drms_setkey_string(outRec, "CUNIT1", "degree");
00706 drms_setkey_string(outRec, "CUNIT2", "degree");
00707
00708 TIME val, trec, tnow, UNIX_epoch = -220924792.000;
00709 tnow = (double)time(NULL);
00710 tnow += UNIX_epoch;
00711 drms_setkey_time(outRec, "DATE", tnow);
00712
00713 char key[64];
00714 snprintf (key, 64, "CRLN-%s", wcsCode[req->proj]);
00715 drms_setkey_string(outRec, "CTYPE1", key);
00716 snprintf (key, 64, "CRLT-%s", wcsCode[req->proj]);
00717 drms_setkey_string(outRec, "CTYPE2", key);
00718 drms_setkey_float(outRec, "CROTA2", 0.0);
00719
00720 return 0;
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 void getLOSVector(struct reqInfo *req, struct ephemeris *ephem, float *mapCenter,
00732 float *lx, float *ly, float *lz)
00733 {
00734
00735 double lonc = mapCenter[0] * RADSINDEG;
00736 double latc = mapCenter[1] * RADSINDEG;
00737
00738 double x, y;
00739 double lat, lon;
00740 double lx0, ly0, lz0;
00741
00742 int ind_map;
00743 for (int row = 0; row < req->nrow; row++) {
00744 for (int col = 0; col < req->ncol; col++) {
00745
00746 ind_map = row * req->ncol + col;
00747 x = (col + 0.5 - req->ncol/2.) * req->dx;
00748 y = (row + 0.5 - req->nrow/2.) * req->dy;
00749
00750 if (plane2sphere (x, y, latc, lonc, &lat, &lon, req->proj)) {
00751 lx[ind_map] = DRMS_MISSING_FLOAT;
00752 ly[ind_map] = DRMS_MISSING_FLOAT;
00753 lz[ind_map] = DRMS_MISSING_FLOAT;
00754 continue;
00755 }
00756
00757
00758
00759 img2helioVector (0.0, 0.0, 1.0, &lx0, &ly0, &lz0,
00760 lon, lat, 0.0, ephem->disk_latc, ephem->pa);
00761
00762 lx[ind_map] = lx0;
00763 ly[ind_map] = ly0;
00764 lz[ind_map] = lz0;
00765
00766 }
00767 }
00768
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem)
00782 {
00783
00784 int status = 0;
00785
00786 float crota2 = drms_getkey_float(inRec, "CROTA2", &status);
00787 double sina = sin(crota2 * RADSINDEG);
00788 double cosa = cos(crota2 * RADSINDEG);
00789
00790 ephem->pa = - crota2 * RADSINDEG;
00791 ephem->disk_latc = drms_getkey_float(inRec, "CRLT_OBS", &status) * RADSINDEG;
00792 ephem->disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status) * RADSINDEG;
00793
00794 float crvalx = drms_getkey_float(inRec, "CRVAL1", &status);
00795 float crvaly = drms_getkey_float(inRec, "CRVAl2", &status);
00796 float crpix1 = drms_getkey_float(inRec, "CRPIX1", &status);
00797 float crpix2 = drms_getkey_float(inRec, "CRPIX2", &status);
00798 float cdelt = drms_getkey_float(inRec, "CDELT1", &status);
00799 ephem->disk_xc = PIX_X(0.0,0.0) - 1.0;
00800 ephem->disk_yc = PIX_Y(0.0,0.0) - 1.0;
00801
00802 float dSun = drms_getkey_float(inRec, "DSUN_OBS", &status);
00803 float rSun_ref = drms_getkey_float(inRec, "RSUN_REF", &status);
00804 if (status) rSun_ref = 6.96e8;
00805
00806 ephem->asd = asin(rSun_ref/dSun);
00807 ephem->rSun = asin(rSun_ref / dSun) * RAD2ARCSEC / cdelt;
00808
00809 ephem->t_rec = drms_getkey_time(inRec, "T_REC", &status);
00810
00811 return 0;
00812
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 void findCoord(struct reqInfo *req, struct ephemeris *ephem,
00825 float *u_out, float *v_out, float *mapCenter)
00826 {
00827
00828
00829
00830
00831
00832 double latc = req->latref;
00833 double difr = 2.7139 - 0.405 * pow(sin(latc),2) - 0.422 * pow(sin(latc),4);
00834 double dt = ephem->t_rec - req->tref;
00835 double lonc = req->lonref + dt * difr * 1.0e-6;
00836 mapCenter[0] = lonc / RADSINDEG;
00837 mapCenter[1] = latc / RADSINDEG;
00838
00839
00840 char tstr[100];
00841 sprint_time(tstr, ephem->t_rec, "TAI", 0);
00842
00843
00844 double x, y;
00845 double lat, lon;
00846 double u, v;
00847
00848 int ind_map;
00849 for (int row = 0; row < req->nrow; row++) {
00850 for (int col = 0; col < req->ncol; col++) {
00851
00852 ind_map = row * req->ncol + col;
00853 x = (col + 0.5 - req->ncol/2.) * req->dx;
00854 y = (row + 0.5 - req->nrow/2.) * req->dy;
00855
00856
00857
00858 if (plane2sphere (x, y, latc, lonc, &lat, &lon, req->proj)) {
00859 u_out[ind_map] = -1;
00860 v_out[ind_map] = -1;
00861 continue;
00862 }
00863
00864 if (sphere2img (lat, lon, ephem->disk_latc, 0.0, &u, &v,
00865 ephem->disk_xc, ephem->disk_yc, ephem->rSun, ephem->pa,
00866 0., 0., 0., 0.)) {
00867 u_out[ind_map] = -1;
00868 v_out[ind_map] = -1;
00869 continue;
00870 }
00871
00872 u_out[ind_map] = u;
00873 v_out[ind_map] = v;
00874
00875 }
00876 }
00877
00878 }
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 void vectorTransform(float *fld, float *inc, float *azi, float *bx, float *by, float *bz,
00890 int *dims, struct ephemeris *ephem)
00891 {
00892
00893 int ncol = dims[0], nrow = dims[1];
00894
00895 double b_xi, b_eta, b_zeta;
00896 double bx0, by0, bz0;
00897
00898 double x, y;
00899 double lat, lon;
00900 double rho, sinlat, coslat, sig, mu, chi;
00901
00902 int ind;
00903 for (int row = 0; row < nrow; row++) {
00904 for (int col = 0; col < ncol; col++) {
00905
00906 ind = row * ncol + col;
00907
00908 x = (col - ephem->disk_xc) / ephem->rSun;
00909 y = (row - ephem->disk_yc) / ephem->rSun;
00910
00911
00912 if (img2sphere(x, y, ephem->asd, ephem->disk_latc, 0.0, ephem->pa,
00913 &rho, &lat, &lon, &sinlat, &coslat, &sig, &mu, &chi)) {
00914 bx[ind] = by[ind] = bz[ind] = DRMS_MISSING_FLOAT;
00915 continue;
00916 }
00917
00918
00919
00920 b_xi = - fld[ind] * sin(inc[ind] * RADSINDEG) * sin(azi[ind] * RADSINDEG);
00921 b_eta = fld[ind] * sin(inc[ind] * RADSINDEG) * cos(azi[ind] * RADSINDEG);
00922 b_zeta = fld[ind] * cos(inc[ind] * RADSINDEG);
00923
00924
00925
00926 img2helioVector (b_xi, b_eta, b_zeta, &bx0, &by0, &bz0,
00927 lon, lat, 0.0, ephem->disk_latc, ephem->pa);
00928
00929 bx[ind] = bx0;
00930 by[ind] = by0;
00931 bz[ind] = bz0;
00932
00933 }
00934 }
00935
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 void performSampling(float *inData, float *outData, float *u, float *v,
00947 int *dims_in, int *dims_out)
00948 {
00949
00950 struct fint_struct pars;
00951
00952 switch (INTERPOPT) {
00953 case 0:
00954 init_finterpolate_wiener(&pars, 6, 1, 6, 2, 1, 1, NULL, dpath);
00955 break;
00956 case 1:
00957 init_finterpolate_cubic_conv(&pars, 1., 3.);
00958 break;
00959 case 2:
00960 init_finterpolate_linear(&pars, 1.);
00961 break;
00962 case 3:
00963 default:
00964 break;
00965 }
00966
00967 int ind;
00968 int ncol = dims_out[0], nrow = dims_out[1];
00969 if (INTERPOPT == 3) {
00970 for (int row = 0; row < nrow; row++) {
00971 for (int col = 0; col < ncol; col++) {
00972 ind = row * ncol + col;
00973 outData[ind] = nnb(inData, dims_in[0], dims_in[1], u[ind], v[ind]);
00974 }
00975 }
00976 } else {
00977
00978 finterpolate(&pars, inData, u, v, outData,
00979 dims_in[0], dims_in[1], dims_in[0], ncol, nrow, ncol, DRMS_MISSING_FLOAT);
00980 }
00981
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 float nnb (float *f, int nx, int ny, float x, float y)
00994 {
00995
00996 if (x <= -0.5 || y <= -0.5 || x > nx - 0.5 || y > ny - 0.5)
00997 return DRMS_MISSING_FLOAT;
00998 int ilow = floor (x);
00999 int jlow = floor (y);
01000 int i = ((x - ilow) > 0.5) ? ilow + 1 : ilow;
01001 int j = ((y - jlow) > 0.5) ? jlow + 1 : jlow;
01002 return f[j * nx + i];
01003
01004 }