1 xudong 1.1 /*
|
2 mbobra 1.29 * sharp.c
|
3 xudong 1.1 *
|
4 xudong 1.23 * This module creates the pipeline Space Weather Active Region Patches (SHARPs).
5 * It is a hard-coded strip-down version of bmap.c.
6 * It takes the Mharp and Bharp series and create the following quantities:
7 *
8 * Series 1: Sharp_CEA
9 * CEA remapped magnetogram, bitmap, continuum, doppler (same size in map coordinate, need manual spec?)
10 * CEA remapped vector field (Br, Bt, Bp) (same as above)
11 * Space weather indices based on vector cutouts (step 2)
12 *
13 * Series 2: Sharp_cutout:
14 * cutouts of magnetogram, bitmap, continuum, doppler (HARP defined, various sizes in CCD pixels)
15 * cutouts of all vector data segments (same as above)
|
16 mbobra 1.28 *
|
17 xudong 1.1 * Author:
18 * Xudong Sun; Monica Bobra
19 *
20 * Version:
|
21 xudong 1.23 * v0.0 Jul 02 2012
22 * v0.1 Jul 23 2012
23 * v0.2 Sep 04 2012
24 * v0.3 Dec 18 2012
25 * v0.4 Jan 02 2013
26 * v0.5 Jan 23 2013
27 * v0.6 Aug 12 2013
28 * v0.7 Jan 02 2014
29 * v0.8 Feb 12 2014
30 * v0.9 Mar 04 2014
|
31 xudong 1.1 *
32 * Notes:
33 * v0.0
34 * Mharp & Bharp must be fully specified; other input are series names only
35 * All input records need to match, otherwise quit
36 * Mapping parameters depend on keywords of each record only, not necessarily consistent for now
37 * Cutout doesn't work for char segments yet (drms_segment_readslice bug)
38 * SW indices require ephemeris info which is not passed properly as of now
39 * v0.1
40 * Fixed char I/O thanks to Art
41 * SW indices fixed
42 * Added doppler and continuum
|
43 xudong 1.3 * Added other keywords: HEADER (populated by cvs build version), DATE_B
|
44 xudong 1.6 * v0.3
45 * Fixed memory leakage of 0.15G per rec; denoted with "Dec 18"
|
46 xudong 1.7 * v0.4
47 * Took out convert_inplace(). Was causing all the images to be int
|
48 xudong 1.23 * v0.5
49 * Corrected ephemeris keywords, added argument mInfo for setKeys()
|
50 xudong 1.17 * v0.6
51 * Changes in remapping of bitmap and conf_disambig, now near neighbor without anti-aliasing
|
52 xudong 1.23 * v0.7
53 * Added full disk as "b"
54 * Global flag fullDisk is set if "b" is set
55 * Utilize BharpRS and BharpRec all around
56 * Pass mharpRec to set_keys() too in case of full disk
57 * Fixed Bunit (removed from copy_me_keys(), added loops for Bunits in set_keys() here)
58 * Error for CEA still does account for disambiguation yet
59 * v0.8
60 * Added disambig to azimuth during error propagation
61 * Changed usage for disambig: bit 2 (radial acute) for full disk, bit 0 for patch
62 * Fixed disambig cutout for patch: 0 for even, 7 for odd
63 * v0.9
64 * Fixed unit
65 * Check whether in PATCH of FD mode, so the error propagation uses disambiguated azimuth or not
66 *
67 *
68 * Example Calls:
69 * [I] B (full disk disambiguation)
70 * > sharp "mharp=hmi.Mharp_720s[1832][2012.07.12_15:24]" "b=hmi_test.B_720s[2012.07.12_15:24]" "dop=hmi.V_720s[2012.07.12_15:24]" "cont=hmi.Ic_720s[2012.07.12_15:24]" "sharp_cea=su_xudong.sharp_cea_720s" "sharp_cut=su_xudong.sharp_720s"
71 * [II] BHARP (patch disambiguation)
72 * > sharp "mharp=hmi.Mharp_720s[1832][2012.07.12_15:24]" "bharp=hmi.Bharp_720s[1832][2012.07.12_15:24]" "dop=hmi.V_720s[2012.07.12_15:24]" "cont=hmi.Ic_720s[2012.07.12_15:24]" "sharp_cea=su_xudong.sharp_cea_720s" "sharp_cut=su_xudong.sharp_720s"
|
73 arta 1.22 *
|
74 xudong 1.1 *
75 */
|
76 xudong 1.6
|
77 xudong 1.1 #include <stdio.h>
78 #include <stdlib.h>
79 #include <time.h>
80 #include <sys/time.h>
81 #include <math.h>
82 #include <string.h>
83 #include "jsoc_main.h"
84 #include "astro.h"
85 #include "fstats.h"
86 #include "cartography.c"
87 #include "fresize.h"
88 #include "finterpolate.h"
89 #include "img2helioVector.c"
90 #include "copy_me_keys.c"
91 #include "errorprop.c"
92 #include "sw_functions.c"
93
|
94 mbobra 1.14 //#include <mkl.h> // Comment out mkl.h, which can only run on solar3
|
95 xudong 1.1 #include <mkl_blas.h>
96 #include <mkl_service.h>
97 #include <mkl_lapack.h>
98 #include <mkl_vml_functions.h>
99 #include <omp.h>
|
100 xudong 1.15
|
101 xudong 1.1 #define PI (M_PI)
102 #define RADSINDEG (PI/180.)
103 #define RAD2ARCSEC (648000./M_PI)
104 #define SECINDAY (86400.)
105 #define FOURK (4096)
106 #define FOURK2 (16777216)
107
108 #define ARRLENGTH(ARR) (sizeof(ARR) / sizeof(ARR[0]))
|
109 xudong 1.23
|
110 xudong 1.1 // Nyqvist rate at disk center is 0.03 degree. Oversample above 0.015 degree
111 #define NYQVIST (0.015)
|
112 xudong 1.23
|
113 xudong 1.38 // Maximum variation of LONDTMAX-LONDTMIN
114 #define MAXLONDIFF (1.2e-4)
115
|
116 mbobra 1.16 // Some other things
|
117 xudong 1.1 #ifndef MIN
118 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
119 #endif
120 #ifndef MAX
121 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
122 #endif
123
124 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s, status=%d\n", msg, status); return(status);}
125 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
126
127 #define kNotSpecified "Not Specified"
|
128 xudong 1.6
|
129 xudong 1.1 // Macros for WCS transformations. assume crpix1, crpix2 = CRPIX1, CRPIX2, sina,cosa = sin and cos of CROTA2 resp.
130 // and crvalx and crvaly are CRVAL1 and CRVAL2, cdelt = CDELT1 == CDELT2, then
131 // PIX_X and PIX_Y are CCD pixel addresses, WX and WY are arc-sec W and N on the Sun from disk center.
132 #define PIX_X(wx,wy) ((((wx-crvalx)*cosa + (wy-crvaly)*sina)/cdelt)+crpix1)
133 #define PIX_Y(wx,wy) ((((wy-crvaly)*cosa - (wx-crvalx)*sina)/cdelt)+crpix2)
134 #define WX(pix_x,pix_y) (((pix_x-crpix1)*cosa - (pix_y-crpix2)*sina)*cdelt+crvalx)
135 #define WY(pix_x,pix_y) (((pix_y-crpix2)*cosa + (pix_x-crpix1)*sina)*cdelt+crvaly)
136
137 #define DISAMB_AZI 1
138 #define XSCALE 0.03
139 #define YSCALE 0.03
140 #define NBIN 3
141 #define INTERP 0
142 #define dpath "/home/jsoc/cvs/Development/JSOC"
143
|
144 mbobra 1.16
|
145 xudong 1.1 /* ========================================================================================================== */
146
147 // Space weather keywords
148 struct swIndex {
|
149 xudong 1.23 float mean_vf;
|
150 arta 1.22 float count_mask;
|
151 mbobra 1.29 float absFlux;
152 float mean_hf;
153 float mean_gamma;
154 float mean_derivative_btotal;
155 float mean_derivative_bh;
156 float mean_derivative_bz;
157 float mean_jz;
158 float us_i;
159 float mean_alpha;
|
160 xudong 1.23 float mean_ih;
161 float total_us_ih;
162 float total_abs_ih;
163 float totaljz;
164 float totpot;
165 float meanpot;
166 float area_w_shear_gt_45;
167 float meanshear_angle;
168 float area_w_shear_gt_45h;
169 float meanshear_angleh;
|
170 arta 1.22 float mean_derivative_btotal_err;
171 float mean_vf_err;
172 float mean_gamma_err;
173 float mean_derivative_bh_err;
174 float mean_derivative_bz_err;
175 float mean_jz_err;
176 float us_i_err;
177 float mean_alpha_err;
178 float mean_ih_err;
179 float total_us_ih_err;
180 float total_abs_ih_err;
181 float totaljz_err;
182 float meanpot_err;
183 float totpot_err;
184 float meanshear_angle_err;
|
185 xudong 1.23 float Rparam;
|
186 mbobra 1.30 float totfx;
187 float totfy;
188 float totfz;
189 float totbsq;
190 float epsx;
191 float epsy;
192 float epsz;
|
193 xudong 1.15 };
|
194 xudong 1.1
195 // Mapping method
196 enum projection {
197 carree,
198 cassini,
199 mercator,
200 cyleqa,
201 sineqa,
202 gnomonic,
203 postel,
204 stereographic,
205 orthographic,
206 lambert
207 };
208
|
209 xudong 1.15 // WSC code
210 char *wcsCode[] = {"CAR", "CAS", "MER", "CEA", "GLS", "TAN", "ARC", "STG",
211 "SIN", "ZEA"};
212
|
213 mbobra 1.14 // Ephemeris information
|
214 xudong 1.1 struct ephemeris {
215 double disk_lonc, disk_latc;
216 double disk_xc, disk_yc;
217 double rSun, asd, pa;
218 };
219
220 // Mapping information
221 struct mapInfo {
222 float xc, yc; // reference point: center
223 int nrow, ncol; // size
224 float xscale, yscale; // scale
225 int nbin;
226 enum projection proj; // projection method
227 struct ephemeris ephem; // ephemeris info
228 float *xi_out, *zeta_out; // coordinate on full disk image to sample at
229 };
230
231 /* ========================================================================================================== */
232
233 /* Get all input data series */
234 int getInputRS(DRMS_RecordSet_t **mharpRS_ptr, DRMS_RecordSet_t **bharpRS_ptr,
235 xudong 1.1 char *mharpQuery, char *bharpQuery);
236
237 /* Check if Mharp and Bharp match */
238 int compareHarp(DRMS_RecordSet_t *mharpRS, DRMS_RecordSet_t *bharpRS);
239
240 /* Get other data series */
241 int getInputRS_aux(DRMS_RecordSet_t **inRS_ptr, char *inQuery, DRMS_RecordSet_t *harpRS);
242
243 /* Find record from record set with given T_rec */
244 int getInputRec_aux(DRMS_Record_t **inRec_ptr, DRMS_RecordSet_t *inRS, TIME trec);
245
246 /* Create CEA record */
247 int createCeaRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
|
248 xudong 1.15 DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
|
249 xudong 1.1 DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr);
250
251 /* Mapping single segment, wrapper */
252 int mapScaler(DRMS_Record_t *sharpRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec,
253 struct mapInfo *mInfo, char *segName);
254
255 /* Mapping vector magnetogram, wrapper */
256 int mapVectorB(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo);
257
258 /* Mapping errors of vector magnetogram, wraper */
259 int mapVectorBErr(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo);
260
261 /* Determine reference point coordinate and patch size according to input */
262 int findPosition(DRMS_Record_t *inRec, struct mapInfo *mInfo);
263
264 /* Get ephemeris information */
265 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem);
266
267 /* Compute the coordinates at which the full disk image is sampled */
268 void findCoord(struct mapInfo *mInfo);
269
270 xudong 1.1 /* Mapping function */
|
271 xudong 1.17 int performSampling(float *outData, float *inData, struct mapInfo *mInfo, int interpOpt);
|
272 xudong 1.1
273 /* Performing local vector transformation */
274 void vectorTransform(float *bx_map, float *by_map, float *bz_map, struct mapInfo *mInfo);
275
276 /* Map and propogate errors */
277 int getBErr(float *bx_err, float *by_err, float *bz_err,
|
278 xudong 1.6 DRMS_Record_t *inRec, struct mapInfo *mInfo);
|
279 xudong 1.1
280 /* Read full disk vector magnetogram */
281 int readVectorB(DRMS_Record_t *inRec, float *bx_img, float *by_img, float *bz_img);
282
283 /* Read variances and covariances of vector magnetograms */
|
284 xudong 1.15 int readVectorBErr(DRMS_Record_t *bharpRec,
|
285 xudong 1.1 float *bT, float *bI, float *bA,
|
286 xudong 1.15 float *errbT, float *errbI, float *errbA,
|
287 xudong 1.1 float *errbTbI, float *errbTbA, float *errbIbA);
288
289 // ===================
290
291 /* Create Cutout record */
292 int createCutRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
293 DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
294 DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr);
295
296 /* Get cutout and write segment */
297 int writeCutout(DRMS_Record_t *outRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec, char *SegName);
298
299 // ===================
300
301 /* Compute space weather indices, no error checking for now */
302 void computeSWIndex(struct swIndex *swKeys_ptr, DRMS_Record_t *inRec, struct mapInfo *mInfo);
303
304 /* Set space weather indices, no error checking for now */
305 void setSWIndex(DRMS_Record_t *outRec, struct swIndex *swKeys_ptr);
306
307 /* Set all keywords, no error checking for now */
|
308 xudong 1.23 // Changed Dec 30 XS
309 void setKeys(DRMS_Record_t *outRec, DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo);
|
310 xudong 1.1
311 // ===================
312
313 /* Nearest neighbor interpolation */
314 float nnb (float *f, int nx, int ny, double x, double y);
315
316 /* Wrapper for Jesper's rebin code */
317 void frebin (float *image_in, float *image_out, int nx, int ny, int nbin, int gauss);
318
319 /* ========================================================================================================== */
320
321 /* Remap segment names */
322 #define BR_SEG_CEA "Br"
323 #define BT_SEG_CEA "Bt"
324 #define BP_SEG_CEA "Bp"
325 #define BR_ERR_SEG_CEA "Br_err"
326 #define BT_ERR_SEG_CEA "Bt_err"
327 #define BP_ERR_SEG_CEA "Bp_err"
328
329 /* Cutout segment names, input identical to output */
330 char *MharpSegs[] = {"magnetogram", "bitmap"};
331 xudong 1.1 char *BharpSegs[] = {"inclination", "azimuth", "field", "vlos_mag", "dop_width", "eta_0",
332 "damping", "src_continuum", "src_grad", "alpha_mag", "chisq",
333 "conv_flag", // fixed
334 "info_map", "confid_map",
335 "inclination_err", "azimuth_err", "field_err", "vlos_err", "alpha_err",
336 "field_inclination_err", "field_az_err", "inclin_azimuth_err",
337 "field_alpha_err","inclination_alpha_err", "azimuth_alpha_err",
338 "disambig", "conf_disambig"};
339 // For stats
|
340 xudong 1.15 char *CutSegs[] = {"magnetogram", "bitmap", "Dopplergram", "continuum",
|
341 xudong 1.1 "inclination", "azimuth", "field", "vlos_mag", "dop_width", "eta_0",
342 "damping", "src_continuum", "src_grad", "alpha_mag", "chisq",
343 "conv_flag", // fixed
344 "info_map", "confid_map",
345 "inclination_err", "azimuth_err", "field_err", "vlos_err", "alpha_err",
346 "field_inclination_err", "field_az_err", "inclin_azimuth_err",
347 "field_alpha_err","inclination_alpha_err", "azimuth_alpha_err",
348 "disambig", "conf_disambig"};
|
349 xudong 1.23 char *CEASegs[] = {"magnetogram", "bitmap", "Dopplergram", "continuum",
350 BR_SEG_CEA, BT_SEG_CEA, BP_SEG_CEA, BR_ERR_SEG_CEA, BT_ERR_SEG_CEA, BP_ERR_SEG_CEA, "conf_disambig"};
351 // For Bunits, added Dec 30 XS
352 char *CutBunits[] = {"Mx/cm^2", " ", "cm/s", "DN/s",
353 "degree", "degree", "Mx/cm^2", "cm/s", "mA", " ",
354 "length units", "DN/s", "DN/s", " ", " ",
355 " ",
356 " ", " ",
357 "degree", "degree", "Mx/cm^2", "cm/s", " ",
358 " ", " ", " ",
359 " ", " ", " ",
360 " ", " "};
361 char *CEABunits[] = {"Mx/cm^2", " ", "cm/s", "DN/s",
362 "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", "Mx/cm^2", " "}; // Mar 4 2014 XS
|
363 xudong 1.15
|
364 xudong 1.1 /* ========================================================================================================== */
365
366 char *module_name = "sharp";
|
367 mbobra 1.14 int seed;
|
368 xudong 1.1
|
369 xudong 1.23 int fullDisk; // full disk mode
370 int amb4err; // Use azimuth disambiguation for error propagation, default is 0 for patch and 1 for FD
371
|
372 xudong 1.1 ModuleArgs_t module_args[] =
373 {
374 {ARG_STRING, "mharp", kNotSpecified, "Input Mharp series."},
375 {ARG_STRING, "bharp", kNotSpecified, "Input Bharp series."},
|
376 xudong 1.23 {ARG_STRING, "b", kNotSpecified, "Input B series, if set, overrides bharp."},
|
377 xudong 1.1 {ARG_STRING, "dop", kNotSpecified, "Input Doppler series."},
378 {ARG_STRING, "cont", kNotSpecified, "Input Continuum series."},
379 {ARG_STRING, "sharp_cea", kNotSpecified, "Output Sharp CEA series."},
380 {ARG_STRING, "sharp_cut", kNotSpecified, "Output Sharp cutout series."},
|
381 xudong 1.15 {ARG_INT, "seed", "987654", "Seed for the random number generator."},
|
382 xudong 1.23 {ARG_INT, "f_amb4err", "0", "Force using disambiguation in error propagation"}, // Mar 4 2014 XS
|
383 xudong 1.1 {ARG_END}
384 };
385
|
386 xudong 1.15 int DoIt(void)
|
387 xudong 1.1 {
|
388 xudong 1.23 int errbufstat = setvbuf(stderr, NULL, _IONBF, BUFSIZ);
389 int outbufstat = setvbuf(stdout, NULL, _IONBF, BUFSIZ);
|
390 xudong 1.15
|
391 xudong 1.1 int status = DRMS_SUCCESS;
392 int nrecs, irec;
393
|
394 xudong 1.23 char *mharpQuery, *bharpQuery, *bQuery;
|
395 xudong 1.1 char *dopQuery, *contQuery;
396 char *sharpCeaQuery, *sharpCutQuery;
397
398 DRMS_RecordSet_t *mharpRS = NULL, *bharpRS = NULL;
399 DRMS_RecordSet_t *dopRS = NULL, *contRS = NULL;
400
401 /* Get parameters */
402
403 mharpQuery = (char *) params_get_str(&cmdparams, "mharp");
404 bharpQuery = (char *) params_get_str(&cmdparams, "bharp");
|
405 xudong 1.23 bQuery = (char *) params_get_str(&cmdparams, "b");
|
406 xudong 1.1 dopQuery = (char *) params_get_str(&cmdparams, "dop");
407 contQuery = (char *) params_get_str(&cmdparams, "cont");
408 sharpCeaQuery = (char *) params_get_str(&cmdparams, "sharp_cea");
409 sharpCutQuery = (char *) params_get_str(&cmdparams, "sharp_cut");
|
410 xudong 1.15
411 seed = params_get_int(&cmdparams, "seed");
|
412 xudong 1.23 int f_amb4err = params_get_int(&cmdparams, "f_amb4err");
|
413 xudong 1.1
414 /* Get input data, check everything */
415
|
416 xudong 1.23 // Full disk mode if "b" is set
417 if (strcmp(bQuery, kNotSpecified)) {
418 fullDisk = 1;
419 bharpQuery = bQuery;
420 // SHOW(bharpQuery); SHOW("\n");
421 SHOW("Full disk mode\n");
422 } else {
423 fullDisk = 0;
424 SHOW("Harp mode\n");
425 }
426
427 // Mar 4 2014
428 if (f_amb4err == 0) { // no forcing, 0 for patch and 1 for FD
429 amb4err = fullDisk ? 1 : 0;
430 } else {
431 amb4err = 1;
432 }
433 printf("amb4err=%d\n", amb4err);
434
435 // Bharp point to B if full disk
436 if (getInputRS(&mharpRS, &bharpRS, mharpQuery, bharpQuery))
437 xudong 1.23 DIE("Input harp data error.");
|
438 xudong 1.1 nrecs = mharpRS->n;
439
|
440 xudong 1.15 if (getInputRS_aux(&dopRS, dopQuery, mharpRS))
|
441 xudong 1.1 DIE("Input doppler data error.");
442
|
443 xudong 1.15 if (getInputRS_aux(&contRS, contQuery, mharpRS))
|
444 xudong 1.1 DIE("Input continuum data error.");
445
446 /* Start */
447
448 printf("==============\nStart. %d image(s) in total.\n", nrecs);
|
449 xudong 1.15
|
450 xudong 1.1 for (irec = 0; irec < nrecs; irec++) {
451
452 /* Records in work */
453
454 DRMS_Record_t *mharpRec = NULL, *bharpRec = NULL;
|
455 xudong 1.23
|
456 xudong 1.1 mharpRec = mharpRS->records[irec];
|
457 xudong 1.23
458 TIME trec = drms_getkey_time(mharpRec, "T_REC", &status);
459
460 if (!fullDisk) {
461 bharpRec = bharpRS->records[irec];
462 } else {
463 if (getInputRec_aux(&bharpRec, bharpRS, trec)) { // Bharp point to full disk B
464 printf("Fetching B failed, image #%d skipped.\n", irec);
465 continue;
466 }
467 }
468
|
469 xudong 1.1 struct swIndex swKeys;
470
471 DRMS_Record_t *dopRec = NULL, *contRec = NULL;
|
472 xudong 1.23
|
473 xudong 1.1 if (getInputRec_aux(&dopRec, dopRS, trec)) {
474 printf("Fetching Doppler failed, image #%d skipped.\n", irec);
475 continue;
476 }
477 if (getInputRec_aux(&contRec, contRS, trec)) {
478 printf("Fetching continuum failed, image #%d skipped.\n", irec);
479 continue;
480 }
|
481 xudong 1.15
|
482 xudong 1.1 /* Create CEA record */
483
484 DRMS_Record_t *sharpCeaRec = drms_create_record(drms_env, sharpCeaQuery, DRMS_PERMANENT, &status);
485 if (status) { // if failed
486 printf("Creating CEA failed, image #%d skipped.\n", irec);
487 continue;
488 }
489
490 if (createCeaRecord(mharpRec, bharpRec, dopRec, contRec, sharpCeaRec, &swKeys)) { // do the work
491 printf("Creating CEA failed, image #%d skipped.\n", irec);
492 drms_close_record(sharpCeaRec, DRMS_FREE_RECORD);
493 continue;
494 } // swKeys updated here
495
496 drms_close_record(sharpCeaRec, DRMS_INSERT_RECORD);
497
498 /* Create Cutout record */
499
500 DRMS_Record_t *sharpCutRec = drms_create_record(drms_env, sharpCutQuery, DRMS_PERMANENT, &status);
501 if (status) { // if failed
502 printf("Creating cutout failed, image #%d skipped.\n", irec);
503 xudong 1.1 continue;
504 }
505
506 if (createCutRecord(mharpRec, bharpRec, dopRec, contRec, sharpCutRec, &swKeys)) { // do the work
507 printf("Creating cutout failed, image #%d skipped.\n", irec);
508 drms_close_record(sharpCutRec, DRMS_FREE_RECORD);
509 continue;
510 } // swKeys used here
511
512 drms_close_record(sharpCutRec, DRMS_INSERT_RECORD);
513
514 /* Done */
515
516 printf("Image #%d done.\n", irec);
517
518 } // irec
|
519 xudong 1.15
|
520 xudong 1.1
521 drms_close_records(mharpRS, DRMS_FREE_RECORD);
522 drms_close_records(bharpRS, DRMS_FREE_RECORD);
|
523 xudong 1.6 drms_close_records(dopRS, DRMS_FREE_RECORD); // Dec 18 2012
524 drms_close_records(contRS, DRMS_FREE_RECORD); // Dec 18 2012
|
525 xudong 1.1
526 return 0;
|
527 xudong 1.6
|
528 xudong 1.1 } // DoIt
529
530
531 // ===================================================================
532 // ===================================================================
533 // ===================================================================
534
535
536 /*
537 * Get input data series, including mHarp and bharp
538 * Need all records to match, otherwise quit
539 *
540 */
541
542 int getInputRS(DRMS_RecordSet_t **mharpRS_ptr, DRMS_RecordSet_t **bharpRS_ptr,
543 char *mharpQuery, char *bharpQuery)
544 {
545
546 int status = 0;
547
548 *mharpRS_ptr = drms_open_records(drms_env, mharpQuery, &status);
549 xudong 1.1 if (status || (*mharpRS_ptr)->n == 0) return 1;
550
|
551 xudong 1.23 if (fullDisk) {
552 if (getInputRS_aux(bharpRS_ptr, bharpQuery, *mharpRS_ptr)) return 1;
553 } else {
554 *bharpRS_ptr = drms_open_records(drms_env, bharpQuery, &status);
555 if (status || (*bharpRS_ptr)->n == 0) return 1;
556 if (compareHarp((*mharpRS_ptr), (*bharpRS_ptr))) return 1;
557 }
|
558 xudong 1.1
559 return 0;
560
561 }
562
563 /*
564 * Check if Mharp and Bharp match
565 *
566 */
567
568 int compareHarp(DRMS_RecordSet_t *mharpRS, DRMS_RecordSet_t *bharpRS)
569 {
570
571 int status = 0;
572 int nrecs = mharpRS->n;
573
574 DRMS_Record_t *mharpRec_t = NULL, *bharpRec_t = NULL; // temporary recs for utility
575
576 if (bharpRS->n != nrecs) {
577 return 1; // return 1 if different
578 }
579 xudong 1.1
580 for (int i = 0; i < nrecs; i++) {
581 mharpRec_t = mharpRS->records[i];
582 bharpRec_t = bharpRS->records[i];
|
583 xudong 1.15 if ((drms_getkey_int(mharpRec_t, "HARPNUM", &status) !=
|
584 xudong 1.1 drms_getkey_int(bharpRec_t, "HARPNUM", &status)) ||
|
585 xudong 1.15 (drms_getkey_time(mharpRec_t, "T_REC", &status) !=
|
586 xudong 1.1 drms_getkey_time(bharpRec_t, "T_REC", &status)))
587 {
588 return 1;
589 }
590 }
591
592 return 0;
593
594 }
595
|
596 xudong 1.15 /*
|
597 xudong 1.1 * Get other data series, check all T_REC are available
598 *
599 */
600
601 int getInputRS_aux(DRMS_RecordSet_t **inRS_ptr, char *inQuery, DRMS_RecordSet_t *harpRS)
602 {
603
604 int status = 0;
605
606 *inRS_ptr = drms_open_records(drms_env, inQuery, &status);
607 if (status || (*inRS_ptr)->n == 0) return status;
608
609 // Check if all T_rec are available, need to match both ways
610 int n = harpRS->n, n0 = (*inRS_ptr)->n;
|
611 xudong 1.6
|
612 xudong 1.1 for (int i0 = 0; i0 < n0; i0++) {
613 DRMS_Record_t *inRec = (*inRS_ptr)->records[i0];
614 TIME trec0 = drms_getkey_time(inRec, "T_REC", &status);
615 TIME trec = 0;
616 for (int i = 0; i < n; i++) {
617 DRMS_Record_t *harpRec = harpRS->records[i];
618 trec = drms_getkey_time(harpRec, "T_REC", &status);
619 if (fabs(trec0 - trec) < 10) break;
620 }
621 if (fabs(trec0 - trec) >= 10) return 1;
622 }
623
624 for (int i = 0; i < n; i++) {
625 DRMS_Record_t *harpRec = harpRS->records[i];
626 TIME trec = drms_getkey_time(harpRec, "T_REC", &status);
627 TIME trec0 = 0;
628 for (int i0 = 0; i0 < n0; i0++) {
629 DRMS_Record_t *inRec = (*inRS_ptr)->records[i0];
630 trec0 = drms_getkey_time(inRec, "T_REC", &status);
631 if (fabs(trec0 - trec) < 10) break;
632 }
633 xudong 1.1 if (fabs(trec0 - trec) >= 10) return 1;
634 }
635
636 return 0;
637
638 }
639
|
640 xudong 1.15 /*
|
641 xudong 1.1 * Find record from record set with given T_rec
642 *
643 */
644
645 int getInputRec_aux(DRMS_Record_t **inRec_ptr, DRMS_RecordSet_t *inRS, TIME trec)
646 {
647
648 int status = 0;
649
650 int n = inRS->n;
651 for (int i = 0; i < n; i++) {
652 *inRec_ptr = inRS->records[i];
653 TIME trec0 = drms_getkey_time((*inRec_ptr), "T_REC", &status);
654 if (fabs(trec0 - trec) < 10) return 0;
655 }
656
657 return 1;
658
659 }
660
661
662 xudong 1.1
663
664 /*
665 * Create CEA record: top level subroutine
666 * Also compute all the space weather keywords here
667 *
668 */
669
|
670 xudong 1.15 int createCeaRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
671 DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
|
672 xudong 1.1 DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr)
673 {
674
675 int status = 0;
676 DRMS_Segment_t *inSeg;
677 DRMS_Array_t *inArray;
678
679 struct mapInfo mInfo;
680 mInfo.proj = (enum projection) cyleqa; // projection method
681 mInfo.xscale = XSCALE;
682 mInfo.yscale = YSCALE;
|
683 xudong 1.17
|
684 xudong 1.23 int ncol0, nrow0; // oversampled map size
|
685 xudong 1.1
686 // Get ephemeris
|
687 xudong 1.6
|
688 xudong 1.3 if (getEphemeris(mharpRec, &(mInfo.ephem))) {
689 SHOW("CEA: get ephemeris error\n");
690 return 1;
691 }
|
692 xudong 1.1
693 // Find position
694
|
695 xudong 1.3 if (findPosition(mharpRec, &mInfo)) {
696 SHOW("CEA: find position error\n");
697 return 1;
698 }
|
699 xudong 1.1
|
700 xudong 1.17 // ========================================
701 // Do this for all bitmaps, Aug 12 2013 XS
702 // ========================================
703
|
704 xudong 1.23 mInfo.nbin = 1; // for bitmaps. suppress anti-aliasing
|
705 xudong 1.17 ncol0 = mInfo.ncol;
706 nrow0 = mInfo.nrow;
707
708 mInfo.xi_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
709 mInfo.zeta_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
710
711 findCoord(&mInfo); // compute it here so it could be shared by the following 4 functions
712
713 if (mapScaler(sharpRec, mharpRec, mharpRec, &mInfo, "bitmap")) {
714 SHOW("CEA: mapping bitmap error\n");
715 return 1;
716 }
717 printf("Bitmap mapping done.\n");
718
|
719 xudong 1.23 if (mapScaler(sharpRec, bharpRec, mharpRec, &mInfo, "conf_disambig")) {
|
720 xudong 1.17 SHOW("CEA: mapping conf_disambig error\n");
721 return 1;
722 }
723 printf("Conf disambig mapping done.\n");
724
|
725 xudong 1.23 free(mInfo.xi_out);
|
726 xudong 1.17 free(mInfo.zeta_out);
727
728 // ========================================
729 // Do this again for floats, Aug 12 2013 XS
730 // ========================================
|
731 xudong 1.1 // Create xi_out, zeta_out array in mInfo:
732 // Coordinates to sample in original full disk image
733
|
734 xudong 1.17 mInfo.nbin = NBIN;
|
735 xudong 1.1 ncol0 = mInfo.ncol * mInfo.nbin + (mInfo.nbin / 2) * 2; // pad with nbin/2 on edge to avoid NAN
736 nrow0 = mInfo.nrow * mInfo.nbin + (mInfo.nbin / 2) * 2;
737
738 mInfo.xi_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
739 mInfo.zeta_out = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
740
741 findCoord(&mInfo); // compute it here so it could be shared by the following 4 functions
742
743 // Mapping single segment: Mharp, etc.
|
744 xudong 1.15
|
745 xudong 1.3 if (mapScaler(sharpRec, mharpRec, mharpRec, &mInfo, "magnetogram")) {
746 SHOW("CEA: mapping magnetogram error\n");
747 return 1;
748 }
|
749 xudong 1.1 printf("Magnetogram mapping done.\n");
|
750 xudong 1.23
|
751 xudong 1.3 if (mapScaler(sharpRec, dopRec, mharpRec, &mInfo, "Dopplergram")) {
752 SHOW("CEA: mapping dopplergram error\n");
753 return 1;
754 }
|
755 xudong 1.1 printf("Dopplergram mapping done.\n");
756
|
757 xudong 1.3 if (mapScaler(sharpRec, contRec, mharpRec, &mInfo, "continuum")) {
758 SHOW("CEA: mapping continuum error\n");
759 return 1;
760 }
|
761 xudong 1.1 printf("Intensitygram mapping done.\n");
|
762 xudong 1.6
|
763 xudong 1.1 // Mapping vector B
764
|
765 xudong 1.3 if (mapVectorB(sharpRec, bharpRec, &mInfo)) {
766 SHOW("CEA: mapping vector B error\n");
767 return 1;
768 }
|
769 xudong 1.1 printf("Vector B mapping done.\n");
770
771 // Mapping vector B errors
772
|
773 xudong 1.3 if (mapVectorBErr(sharpRec, bharpRec, &mInfo)) {
774 SHOW("CEA: mapping vector B uncertainty error\n");
775 return 1;
776 }
|
777 xudong 1.1 printf("Vector B error done.\n");
778
779 // Keywords & Links
780
781 drms_copykey(sharpRec, mharpRec, "T_REC");
782 drms_copykey(sharpRec, mharpRec, "HARPNUM");
783
|
784 xudong 1.23 if (fullDisk) {
785 DRMS_Link_t *bLink = hcon_lookup_lower(&sharpRec->links, "B");
786 if (bLink) drms_link_set("B", sharpRec, bharpRec);
787 } else {
788 DRMS_Link_t *bHarpLink = hcon_lookup_lower(&sharpRec->links, "BHARP");
789 if (bHarpLink) drms_link_set("BHARP", sharpRec, bharpRec);
790 }
|
791 xudong 1.1 DRMS_Link_t *mHarpLink = hcon_lookup_lower(&sharpRec->links, "MHARP");
792 if (mHarpLink) drms_link_set("MHARP", sharpRec, mharpRec);
793
|
794 xudong 1.23 setKeys(sharpRec, mharpRec, bharpRec, &mInfo); // Set all other keywords
|
795 xudong 1.3 drms_copykey(sharpRec, mharpRec, "QUALITY"); // copied from los records
|
796 xudong 1.6
|
797 xudong 1.1 // Space weather
798
799 computeSWIndex(swKeys_ptr, sharpRec, &mInfo); // compute it!
800 printf("Space weather indices done.\n");
801
802 setSWIndex(sharpRec, swKeys_ptr); // Set space weather indices
|
803 xudong 1.6
|
804 xudong 1.1 // Stats
805
806 int nCEASegs = ARRLENGTH(CEASegs);
807 for (int iSeg = 0; iSeg < nCEASegs; iSeg++) {
808 DRMS_Segment_t *outSeg = drms_segment_lookupnum(sharpRec, iSeg);
809 DRMS_Array_t *outArray = drms_segment_read(outSeg, DRMS_TYPE_FLOAT, &status);
810 int stat = set_statistics(outSeg, outArray, 1);
|
811 xudong 1.6 // printf("%d => %d\n", iSeg, stat);
|
812 xudong 1.1 drms_free_array(outArray);
813 }
814
815 free(mInfo.xi_out);
816 free(mInfo.zeta_out);
817 return 0;
818
819 }
820
821
|
822 xudong 1.15 /*
|
823 xudong 1.1 * Mapping a single segment
824 * Read in full disk image, utilize mapImage for mapping
825 * then write the segment out, segName same in in/out Rec
826 *
827 */
828
829 int mapScaler(DRMS_Record_t *sharpRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec,
830 struct mapInfo *mInfo, char *segName)
831 {
832
833 int status = 0;
834 int nx = mInfo->ncol, ny = mInfo->nrow, nxny = nx * ny;
835 int dims[2] = {nx, ny};
|
836 xudong 1.17 int interpOpt = INTERP; // Aug 12 XS, default, overridden below for bitmaps and conf_disambig
|
837 xudong 1.1
838 // Input full disk array
839
840 DRMS_Segment_t *inSeg = NULL;
841 inSeg = drms_segment_lookup(inRec, segName);
842 if (!inSeg) return 1;
843
844 DRMS_Array_t *inArray = NULL;
845 inArray = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
846 if (!inArray) return 1;
847
|
848 xudong 1.23 if (!strcmp(segName, "conf_disambig") || !strcmp(segName, "bitmap")) {
849 // Moved out so it works for FD conf_disambig as well
850 // Jan 2 2014 XS
851 interpOpt = 3; // Aug 12 XS, near neighbor
852 }
853
|
854 xudong 1.1 float *inData;
855 int xsz = inArray->axis[0], ysz = inArray->axis[1];
856 if ((xsz != FOURK) || (ysz != FOURK)) { // for bitmap, make tmp full disk
857 float *inData0 = (float *) inArray->data;
858 inData = (float *) (calloc(FOURK2, sizeof(float)));
859 int x0 = (int) drms_getkey_float(harpRec, "CRPIX1", &status) - 1;
860 int y0 = (int) drms_getkey_float(harpRec, "CRPIX2", &status) - 1;
861 int ind_map;
862 for (int row = 0; row < ysz; row++) {
863 for (int col = 0; col < xsz; col++) {
864 ind_map = (row + y0) * FOURK + (col + x0);
865 inData[ind_map] = inData0[row * xsz + col];
866 }
867 }
868 drms_free_array(inArray); inArray = NULL;
869 } else {
870 inData = (float *) inArray->data;
871 }
872
873 // Mapping
874
875 xudong 1.1 float *map = (float *) (malloc(nxny * sizeof(float)));
|
876 xudong 1.17 if (performSampling(map, inData, mInfo, interpOpt)) // Add interpOpt for different types, Aug 12 XS
|
877 xudong 1.6 {if (inArray) drms_free_array(inArray); free(map); return 1;}
|
878 xudong 1.1
879 // Write out
880
|
881 xudong 1.15 DRMS_Segment_t *outSeg = NULL;
|
882 xudong 1.1 outSeg = drms_segment_lookup(sharpRec, segName);
883 if (!outSeg) return 1;
884
|
885 xudong 1.15 // DRMS_Type_t arrayType = outSeg->info->type;
|
886 xudong 1.1 DRMS_Array_t *outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, map, &status);
887 if (status) {if (inArray) drms_free_array(inArray); free(map); return 1;}
888
889 // convert to needed data type
890
|
891 xudong 1.15 // drms_array_convert_inplace(outSeg->info->type, 0, 1, outArray); // Jan 02 2013
|
892 xudong 1.1
893 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
|
894 xudong 1.15 // outArray->parent_segment = outSeg;
|
895 xudong 1.8 outArray->israw = 0; // always compressed
|
896 xudong 1.1 outArray->bzero = outSeg->bzero;
897 outArray->bscale = outSeg->bscale;
|
898 xudong 1.6
|
899 xudong 1.1 status = drms_segment_write(outSeg, outArray, 0);
900 if (status) return 0;
901
902 if (inArray) drms_free_array(inArray);
|
903 xudong 1.6 if ((xsz != FOURK) || (ysz != FOURK)) free(inData); // Dec 18 2012
|
904 xudong 1.1 if (outArray) drms_free_array(outArray);
905 return 0;
906
907 }
908
909
|
910 xudong 1.15 /*
|
911 xudong 1.1 * Mapping vector magnetogram
912 *
913 */
914
915 int mapVectorB(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo)
916 {
917
918 int status = 0;
919 int nx = mInfo->ncol, ny = mInfo->nrow, nxny = nx * ny;
920 int dims[2] = {nx, ny};
921
922 // Read in segments, filling factor assume to be 1
923
924 float *bx_img = (float *) (malloc(FOURK2 * sizeof(float)));
925 float *by_img = (float *) (malloc(FOURK2 * sizeof(float)));
926 float *bz_img = (float *) (malloc(FOURK2 * sizeof(float)));
927
928 if (readVectorB(bharpRec, bx_img, by_img, bz_img)) {
929 printf("Read full disk image error\n");
930 free(bx_img); free(by_img); free(bz_img);
931 return 1;
932 xudong 1.1 }
933
934 // Mapping
935
936 float *bx_map = NULL, *by_map = NULL, *bz_map = NULL; // intermediate maps, in CCD bxyz representation
|
937 xudong 1.6
|
938 xudong 1.1 bx_map = (float *) (malloc(nxny * sizeof(float)));
|
939 xudong 1.17 if (performSampling(bx_map, bx_img, mInfo, INTERP))
|
940 xudong 1.6 {free(bx_img); free(by_img); free(bz_img); free(bx_map); return 1;}
941
|
942 xudong 1.1 by_map = (float *) (malloc(nxny * sizeof(float)));
|
943 xudong 1.17 if (performSampling(by_map, by_img, mInfo, INTERP))
|
944 xudong 1.6 {free(bx_img); free(by_img); free(bz_img); free(bz_map); return 1;}
945
|
946 xudong 1.1 bz_map = (float *) (malloc(nxny * sizeof(float)));
|
947 xudong 1.17 if (performSampling(bz_map, bz_img, mInfo, INTERP))
|
948 xudong 1.6 {free(bx_img); free(by_img); free(bz_img); free(bz_map); return 1;}
|
949 xudong 1.1
950 free(bx_img); free(by_img); free(bz_img);
951
952 // Vector transform
953
954 vectorTransform(bx_map, by_map, bz_map, mInfo);
955
956 for (int i = 0; i < nxny; i++) by_map[i] *= -1; // positive theta pointing south
957
958 // Write out
959
960 DRMS_Segment_t *outSeg;
961 DRMS_Array_t *outArray;
962
963 float *data_prt[3] = {bx_map, by_map, bz_map};
964 char *segName[3] = {BP_SEG_CEA, BT_SEG_CEA, BR_SEG_CEA};
965
966 for (int iSeg = 0; iSeg < 3; iSeg++) {
967 outSeg = drms_segment_lookup(sharpRec, segName[iSeg]);
968 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, data_prt[iSeg], &status);
969 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
|
970 xudong 1.15 // outArray->parent_segment = outSeg;
|
971 xudong 1.8 outArray->israw = 0;
|
972 xudong 1.1 outArray->bzero = outSeg->bzero;
973 outArray->bscale = outSeg->bscale;
974 status = drms_segment_write(outSeg, outArray, 0);
975 if (status) return 1;
976 drms_free_array(outArray);
977 }
978
979 //
980
981 return 0;
982
983 }
984
985
|
986 xudong 1.15 /*
|
987 xudong 1.1 * Mapping vector magnetogram errors
988 *
989 */
990
991 int mapVectorBErr(DRMS_Record_t *sharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo)
992 {
993
994 int status = 0;
995
996 int nx = mInfo->ncol, ny = mInfo->nrow, nxny = nx * ny;
997 int dims[2] = {nx, ny};
998
999 // Compute propogated errors, using nearest neighbour interpolation
1000
1001 float *bx_err = (float *) (malloc(nxny * sizeof(float)));
1002 float *by_err = (float *) (malloc(nxny * sizeof(float)));
1003 float *bz_err = (float *) (malloc(nxny * sizeof(float)));
1004
1005 if (getBErr(bx_err, by_err, bz_err, bharpRec, mInfo)) {
1006 free(bx_err); free(by_err); free(bz_err);
1007 return 1;
1008 xudong 1.1 }
|
1009 xudong 1.6
|
1010 xudong 1.1 // Write out
1011
1012 DRMS_Segment_t *outSeg;
1013 DRMS_Array_t *outArray;
1014
1015 float *data_prt[3] = {bx_err, by_err, bz_err};
1016 char *segName[3] = {BP_ERR_SEG_CEA, BT_ERR_SEG_CEA, BR_ERR_SEG_CEA};
1017
1018 for (int iSeg = 0; iSeg < 3; iSeg++) {
1019 outSeg = drms_segment_lookup(sharpRec, segName[iSeg]);
1020 outArray = drms_array_create(DRMS_TYPE_FLOAT, 2, dims, data_prt[iSeg], &status);
1021 outSeg->axis[0] = outArray->axis[0]; outSeg->axis[1] = outArray->axis[1];
|
1022 xudong 1.15 // outArray->parent_segment = outSeg;
|
1023 xudong 1.8 outArray->israw = 0;
|
1024 xudong 1.1 outArray->bzero = outSeg->bzero;
1025 outArray->bscale = outSeg->bscale;
1026 status = drms_segment_write(outSeg, outArray, 0);
1027 if (status) return 1;
1028 drms_free_array(outArray);
1029 }
1030
1031 //
1032
1033 return 0;
1034
1035 }
1036
1037
1038
|
1039 xudong 1.15 /*
|
1040 xudong 1.1 * Determine reference point coordinate and patch size according to keywords
1041 * xc, yc are the coordinate of patch center, in degrees
1042 * ncol and nrow are the final size
1043 *
1044 */
1045
1046 int findPosition(DRMS_Record_t *inRec, struct mapInfo *mInfo)
1047 {
1048
1049 int status = 0;
1050 int harpnum = drms_getkey_int(inRec, "HARPNUM", &status);
1051 TIME trec = drms_getkey_time(inRec, "T_REC", &status);
1052 float disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status);
1053
1054 /* Center coord */
|
1055 xudong 1.31 // Changed into double Jun 16 2014 XS
|
1056 xudong 1.1
|
1057 xudong 1.31 double minlon = drms_getkey_double(inRec, "LONDTMIN", &status); if (status) return 1; // Stonyhurst lon
1058 double maxlon = drms_getkey_double(inRec, "LONDTMAX", &status); if (status) return 1;
1059 double minlat = drms_getkey_double(inRec, "LATDTMIN", &status); if (status) return 1;
1060 double maxlat = drms_getkey_double(inRec, "LATDTMAX", &status); if (status) return 1;
|
1061 xudong 1.1
1062 // A bug fixer for HARP (per M. Turmon)
1063 // When AR is below threshold, "LONDTMIN", "LONDTMAX" will be wrong
1064 // Also keywords such as "SIZE" will be NaN
1065 // We compute minlon & minlat then by
1066 // LONDTMIN(t) = LONDTMIN(t0) + (t - t0) * OMEGA_DT
1067
|
1068 xudong 1.15 // float psize = drms_getkey_float(inRec, "SIZE", &status);
1069 // if (psize != psize) {
1070
1071 if (minlon != minlon || maxlon != maxlon) { // check lons instead of SIZE
|
1072 xudong 1.12 TIME t0 = drms_getkey_time(inRec, "T_FRST1", &status); if (status) return 1; // changed from T_FRST to T_FRST1, T_FRST may not exist
|
1073 xudong 1.1 double omega = drms_getkey_double(inRec, "OMEGA_DT", &status); if (status) return 1;
1074 char firstRecQuery[100], t0_str[100];
1075 sprint_time(t0_str, t0, "TAI", 0);
1076 snprintf(firstRecQuery, 100, "%s[%d][%s]", inRec->seriesinfo->seriesname, harpnum, t0_str);
1077 DRMS_RecordSet_t *tmpRS = drms_open_records(drms_env, firstRecQuery, &status);
1078 if (status || tmpRS->n != 1) return 1;
1079 DRMS_Record_t *tmpRec = tmpRS->records[0];
1080 double minlon0 = drms_getkey_double(tmpRec, "LONDTMIN", &status); if (status) return 1;
1081 double maxlon0 = drms_getkey_double(tmpRec, "LONDTMAX", &status); if (status) return 1;
1082 minlon = minlon0 + (trec - t0) * omega / SECINDAY;
1083 maxlon = maxlon0 + (trec - t0) * omega / SECINDAY;
1084 printf("%s, %f, %f\n", firstRecQuery, minlon, maxlon);
1085 }
1086
1087 mInfo->xc = (maxlon + minlon) / 2. + disk_lonc;
1088 mInfo->yc = (maxlat + minlat) / 2.;
1089
1090 /* Size */
|
1091 xudong 1.31 // Rounded to 1.d3 precision first. Jun 16 2014 XS
|
1092 xudong 1.38 // The previous fix does not work. LONDTMAX-LONDTMIN varies from frame to frame
1093 // Need to find out the maximum possible difference, MAXLONDIFF (1.2e-4)
1094 // Now, ncol = (maxlon-minlon)/xscale, if the decimal part is outside 0.5 \pm (MAXLONDIFF/xscale)
1095 // proceed as it is. else, all use floor on ncol
1096
1097 float dpix = (MAXLONDIFF / mInfo->xscale) * 1.5; // "danger zone"
1098 float ncol = (maxlon - minlon) / mInfo->xscale;
1099 float d_ncol = fabs(ncol - floor(ncol) - 0.5); // distance to 0.5
1100 if (d_ncol < dpix) {
1101 mInfo->ncol = floor(ncol);
1102 } else {
1103 mInfo->ncol = round(ncol);
1104 }
1105
1106 mInfo->nrow = round((maxlat - minlat) / mInfo->yscale);
|
1107 xudong 1.1
|
1108 xudong 1.38 printf("xcol=%f, ncol=%d, nrow=%d\n", ncol, mInfo->ncol, mInfo->nrow);
|
1109 xudong 1.1
1110 return 0;
1111
1112 }
1113
1114
1115 /*
1116 * Fetch ephemeris info from a DRMS record
1117 * No error checking for now
1118 *
1119 */
1120
1121 int getEphemeris(DRMS_Record_t *inRec, struct ephemeris *ephem)
1122 {
1123
1124 int status = 0;
1125
1126 float crota2 = drms_getkey_float(inRec, "CROTA2", &status); // rotation
|
1127 xudong 1.15 double sina = sin(crota2 * RADSINDEG);
|
1128 xudong 1.1 double cosa = cos(crota2 * RADSINDEG);
1129
1130 ephem->pa = - crota2 * RADSINDEG;
1131 ephem->disk_latc = drms_getkey_float(inRec, "CRLT_OBS", &status) * RADSINDEG;
1132 ephem->disk_lonc = drms_getkey_float(inRec, "CRLN_OBS", &status) * RADSINDEG;
1133
1134 float crvalx = 0.0;
1135 float crvaly = 0.0;
1136 float crpix1 = drms_getkey_float(inRec, "IMCRPIX1", &status);
1137 float crpix2 = drms_getkey_float(inRec, "IMCRPIX2", &status);
1138 float cdelt = drms_getkey_float(inRec, "CDELT1", &status); // in arcsec, assumimg dx=dy
1139 ephem->disk_xc = PIX_X(0.0,0.0) - 1.0; // Center of disk in pixel, starting at 0
1140 ephem->disk_yc = PIX_Y(0.0,0.0) - 1.0;
1141
1142 float dSun = drms_getkey_float(inRec, "DSUN_OBS", &status);
1143 float rSun_ref = drms_getkey_float(inRec, "RSUN_REF", &status);
1144 if (status) rSun_ref = 6.96e8;
1145
1146 ephem->asd = asin(rSun_ref/dSun);
1147 ephem->rSun = asin(rSun_ref / dSun) * RAD2ARCSEC / cdelt;
1148
1149 xudong 1.1 return 0;
1150
1151 }
1152
1153
1154 /*
1155 * Compute the coordinates to be sampled on full disk image
1156 * mInfo->xi_out & mInfo->zeta_out
1157 * This is oversampled, its size is ncol0 & nrow0 as shown below
1158 *
1159 *
1160 */
1161
1162 void findCoord(struct mapInfo *mInfo)
1163 {
1164
1165 int ncol0 = mInfo->ncol * mInfo->nbin + (mInfo->nbin / 2) * 2; // pad with nbin/2 on edge to avoid NAN
1166 int nrow0 = mInfo->nrow * mInfo->nbin + (mInfo->nbin / 2) * 2;
1167
1168 float xscale0 = mInfo->xscale / mInfo->nbin * RADSINDEG; // oversampling resolution
1169 float yscale0 = mInfo->yscale / mInfo->nbin * RADSINDEG; // in rad
1170 xudong 1.1
1171 double lonc = mInfo->xc * RADSINDEG; // in rad
1172 double latc = mInfo->yc * RADSINDEG;
1173
1174 double disk_lonc = (mInfo->ephem).disk_lonc;
1175 double disk_latc = (mInfo->ephem).disk_latc;
1176
1177 double rSun = (mInfo->ephem).rSun;
1178 double disk_xc = (mInfo->ephem).disk_xc / rSun;
1179 double disk_yc = (mInfo->ephem).disk_yc / rSun;
1180 double pa = (mInfo->ephem).pa;
1181
1182 // Temp pointers
1183
1184 float *xi_out = mInfo->xi_out;
1185 float *zeta_out = mInfo->zeta_out;
1186
1187 // start
1188
1189 double x, y; // map coord
1190 double lat, lon; // helio coord
1191 xudong 1.1 double xi, zeta; // image coord (for one point)
1192
1193 int ind_map;
1194
1195 for (int row0 = 0; row0 < nrow0; row0++) {
1196 for (int col0 = 0; col0 < ncol0; col0++) {
1197
1198 ind_map = row0 * ncol0 + col0;
1199
1200 x = (col0 + 0.5 - ncol0/2.) * xscale0; // in rad
1201 y = (row0 + 0.5 - nrow0/2.) * yscale0;
1202
|
1203 xudong 1.15 /* map grid [x, y] corresponds to the point [lon, lat] in the heliographic coordinates.
|
1204 xudong 1.1 * the [x, y] are in radians with respect of the center of the map [xcMap, ycMap].
1205 * projection methods could be Mercator, Lambert, and many others. [maplonc, mapLatc]
|
1206 xudong 1.15 * is the heliographic longitude and latitude of the map center. Both are in degree.
|
1207 xudong 1.1 */
1208
1209 if (plane2sphere (x, y, latc, lonc, &lat, &lon, (int) mInfo->proj)) {
1210 xi_out[ind_map] = -1;
1211 zeta_out[ind_map] = -1;
1212 continue;
1213 }
1214
1215 /* map the grid [lon, lat] in the heliographic coordinates to [xi, zeta], a point in the
1216 * image coordinates. The image properties, xCenter, yCenter, rSun, pa, ecc and chi are given.
1217 */
1218
|
1219 xudong 1.15 if (sphere2img (lat, lon, disk_latc, disk_lonc, &xi, &zeta,
|
1220 xudong 1.1 disk_xc, disk_yc, 1.0, pa, 0., 0., 0., 0.)) {
1221 xi_out[ind_map] = -1;
1222 zeta_out[ind_map] = -1;
1223 continue;
1224 }
1225
1226 xi_out[ind_map] = xi * rSun;
1227 zeta_out[ind_map] = zeta * rSun;
1228
1229 }
1230 }
1231
1232 }
1233
1234
|
1235 xudong 1.15 /*
|
1236 xudong 1.1 * Sampling function
1237 * oversampling by nbin, then binning using a Gaussian
1238 * save results in outData, always of float type
1239 *
1240 */
1241
|
1242 xudong 1.17 int performSampling(float *outData, float *inData, struct mapInfo *mInfo, int interpOpt)
|
1243 xudong 1.1 {
1244
1245 int status = 0;
|
1246 xudong 1.17 int ind_map;
|
1247 xudong 1.1
1248 int ncol0 = mInfo->ncol * mInfo->nbin + (mInfo->nbin / 2) * 2; // pad with nbin/2 on edge to avoid NAN
1249 int nrow0 = mInfo->nrow * mInfo->nbin + (mInfo->nbin / 2) * 2;
1250
|
1251 xudong 1.17 // Changed Aug 12 2013, XS, for bitmaps
1252 float *outData0;
1253 if (interpOpt == 3 && mInfo->nbin == 1) {
|
1254 xudong 1.23 outData0 = outData;
|
1255 xudong 1.17 } else {
|
1256 xudong 1.23 outData0 = (float *) (malloc(ncol0 * nrow0 * sizeof(float)));
|
1257 xudong 1.17 }
|
1258 xudong 1.1
1259 float *xi_out = mInfo->xi_out;
1260 float *zeta_out = mInfo->zeta_out;
|
1261 xudong 1.6
|
1262 xudong 1.1 // Interpolation
1263
1264 struct fint_struct pars;
|
1265 xudong 1.17 // Aug 12 2013, passed in as argument now
|
1266 xudong 1.1
1267 switch (interpOpt) {
1268 case 0: // Wiener, 6 order, 1 constraint
1269 init_finterpolate_wiener(&pars, 6, 1, 6, 2, 1, 1, NULL, dpath);
1270 break;
1271 case 1: // Cubic convolution
1272 init_finterpolate_cubic_conv(&pars, 1., 3.);
1273 break;
1274 case 2: // Bilinear
1275 init_finterpolate_linear(&pars, 1.);
1276 break;
|
1277 xudong 1.17 case 3: // Near neighbor
|
1278 xudong 1.23 break;
|
1279 xudong 1.1 default:
1280 return 1;
1281 }
1282
|
1283 xudong 1.17 printf("interpOpt = %d, nbin = %d ", interpOpt, mInfo->nbin);
1284 if (interpOpt == 3) { // Aug 6 2013, Xudong
1285 for (int row0 = 0; row0 < nrow0; row0++) {
|
1286 xudong 1.23 for (int col0 = 0; col0 < ncol0; col0++) {
1287 ind_map = row0 * ncol0 + col0;
1288 outData0[ind_map] = nnb(inData, FOURK, FOURK, xi_out[ind_map], zeta_out[ind_map]);
1289 }
1290 }
|
1291 xudong 1.17 } else {
|
1292 xudong 1.23 finterpolate(&pars, inData, xi_out, zeta_out, outData0,
1293 FOURK, FOURK, FOURK, ncol0, nrow0, ncol0, DRMS_MISSING_FLOAT);
|
1294 xudong 1.17 }
|
1295 xudong 1.1
1296 // Rebinning, smoothing
1297
|
1298 xudong 1.17 if (interpOpt == 3 && mInfo->nbin == 1) {
|
1299 xudong 1.23 return 0;
|
1300 xudong 1.17 } else {
|
1301 xudong 1.23 frebin(outData0, outData, ncol0, nrow0, mInfo->nbin, 1); // Gaussian
1302 free(outData0); // Dec 18 2012
|
1303 xudong 1.17 }
|
1304 xudong 1.1
1305 //
1306
1307 return 0;
1308
1309 }
1310
1311
|
1312 xudong 1.15 /*
|
1313 xudong 1.1 * Performing local vector transformation
1314 * xyz: z refers to vertical (radial) component, x EW (phi), y NS
1315 *
1316 */
1317
1318 void vectorTransform(float *bx_map, float *by_map, float *bz_map, struct mapInfo *mInfo)
1319 {
1320
1321 int ncol = mInfo->ncol;
1322 int nrow = mInfo->nrow;
1323
1324 float xscale = mInfo->xscale * RADSINDEG; // in rad
1325 float yscale = mInfo->yscale * RADSINDEG;
1326
1327 double lonc = mInfo->xc * RADSINDEG; // in rad
1328 double latc = mInfo->yc * RADSINDEG;
1329
1330 double disk_lonc = (mInfo->ephem).disk_lonc;
1331 double disk_latc = (mInfo->ephem).disk_latc;
1332
1333 double rSun = (mInfo->ephem).rSun;
1334 xudong 1.1 double disk_xc = (mInfo->ephem).disk_xc / rSun;
1335 double disk_yc = (mInfo->ephem).disk_yc / rSun;
1336 double pa = (mInfo->ephem).pa;
1337
1338 int ind_map;
1339 double x, y;
1340 double lat, lon; // lat / lon for current point
1341
1342 double bx_tmp, by_tmp, bz_tmp;
1343
1344 //
1345
1346 for (int row = 0; row < mInfo->nrow; row++) {
1347 for (int col = 0; col < mInfo->ncol; col++) {
1348
1349 ind_map = row * mInfo->ncol + col;
1350
1351 x = (col + 0.5 - ncol / 2.) * xscale;
1352 y = (row + 0.5 - nrow / 2.) * yscale;
1353
1354 if (plane2sphere (x, y, latc, lonc, &lat, &lon, (int) mInfo->proj)) {
1355 xudong 1.1 bx_map[ind_map] = DRMS_MISSING_FLOAT;
1356 by_map[ind_map] = DRMS_MISSING_FLOAT;
1357 bz_map[ind_map] = DRMS_MISSING_FLOAT;
1358 continue;
1359 }
1360
1361 bx_tmp = by_tmp = bz_tmp = 0;
1362
1363 img2helioVector (bx_map[ind_map], by_map[ind_map], bz_map[ind_map],
1364 &bx_tmp, &by_tmp, &bz_tmp,
1365 lon, lat, disk_lonc, disk_latc, pa);
1366
1367 bx_map[ind_map] = bx_tmp;
1368 by_map[ind_map] = by_tmp;
1369 bz_map[ind_map] = bz_tmp;
1370
1371 }
1372 }
|
1373 xudong 1.6
|
1374 xudong 1.1 }
1375
1376
1377
|
1378 xudong 1.15 /*
|
1379 xudong 1.1 * Map and propogate vector field errors
1380 *
1381 */
1382
1383 int getBErr(float *bx_err, float *by_err, float *bz_err,
|
1384 xudong 1.6 DRMS_Record_t *inRec, struct mapInfo *mInfo)
|
1385 xudong 1.1 {
1386
1387 int status = 0;
1388
1389 // Get variances and covariances, filling factor assume to be 1
1390
1391 float *bT = (float *) (malloc(FOURK2 * sizeof(float))); // field
1392 float *bI = (float *) (malloc(FOURK2 * sizeof(float))); // inclination
1393 float *bA = (float *) (malloc(FOURK2 * sizeof(float))); // azimuth
1394
1395 float *errbT = (float *) (malloc(FOURK2 * sizeof(float)));
1396 float *errbI = (float *) (malloc(FOURK2 * sizeof(float)));
1397 float *errbA = (float *) (malloc(FOURK2 * sizeof(float)));
1398
1399 float *errbTbI = (float *) (malloc(FOURK2 * sizeof(float)));
1400 float *errbTbA = (float *) (malloc(FOURK2 * sizeof(float)));
1401 float *errbIbA = (float *) (malloc(FOURK2 * sizeof(float)));
1402
|
1403 xudong 1.15 if (readVectorBErr(inRec,
|
1404 xudong 1.1 bT, bI, bA,
|
1405 xudong 1.15 errbT, errbI, errbA,
|
1406 xudong 1.1 errbTbI, errbTbA, errbIbA)) {
1407 printf("Read full disk variances & covariances error\n");
1408 free(bT); free(bI); free(bA);
1409 free(errbT); free(errbI); free(errbA);
1410 free(errbTbI); free(errbTbA); free(errbIbA);
1411 return 1;
1412 }
1413
1414 // Size
1415
1416 int ncol = mInfo->ncol;
1417 int nrow = mInfo->nrow;
1418
1419 float xscale = mInfo->xscale * RADSINDEG; // in rad
1420 float yscale = mInfo->yscale * RADSINDEG;
1421
1422 double lonc = mInfo->xc * RADSINDEG; // in rad
1423 double latc = mInfo->yc * RADSINDEG;
1424
1425 double disk_lonc = (mInfo->ephem).disk_lonc;
1426 double disk_latc = (mInfo->ephem).disk_latc;
1427 xudong 1.1
1428 double rSun = (mInfo->ephem).rSun;
1429 double disk_xc = (mInfo->ephem).disk_xc / rSun;
1430 double disk_yc = (mInfo->ephem).disk_yc / rSun;
1431 double pa = (mInfo->ephem).pa;
1432
1433 // Start
1434
1435 double x, y; // map coord
1436 double lat, lon; // spherical coord
1437 double xi, zeta; // image coord, round to full pixel
1438
1439 int ind_map, ind_img;
1440
1441 double bpSigma2, btSigma2, brSigma2; // variances after prop
|
1442 xudong 1.6
|
1443 xudong 1.1 for (int row = 0; row < mInfo->nrow; row++) {
1444 for (int col = 0; col < mInfo->ncol; col++) {
1445
1446 ind_map = row * mInfo->ncol + col;
1447
1448 x = (col + 0.5 - ncol / 2.) * xscale;
1449 y = (row + 0.5 - nrow / 2.) * yscale;
1450
1451 if (plane2sphere (x, y, latc, lonc, &lat, &lon, (int) mInfo->proj)) {
1452 bx_err[ind_map] = DRMS_MISSING_FLOAT;
1453 by_err[ind_map] = DRMS_MISSING_FLOAT;
1454 bz_err[ind_map] = DRMS_MISSING_FLOAT;
1455 continue;
1456 }
1457
|
1458 xudong 1.15 if (sphere2img (lat, lon, disk_latc, disk_lonc, &xi, &zeta,
|
1459 xudong 1.1 disk_xc, disk_yc, 1.0, pa, 0., 0., 0., 0.)) {
1460 bx_err[ind_map] = DRMS_MISSING_FLOAT;
|
1461 xudong 1.24 by_err[ind_map] = DRMS_MISSING_FLOAT;
1462 bz_err[ind_map] = DRMS_MISSING_FLOAT; // Mar 7
|
1463 xudong 1.1 continue;
1464 }
1465
1466 xi *= rSun; xi = round(xi);
1467 zeta *= rSun; zeta = round(zeta); // nearest neighbor
1468
1469 ind_img = round(zeta * FOURK + xi);
1470
|
1471 xudong 1.15 if (errorprop(bT, bA, bI,
1472 errbT, errbA, errbI, errbTbA, errbTbI, errbIbA,
1473 lon, lat, disk_lonc, disk_latc, pa, FOURK, FOURK, xi, zeta,
|
1474 xudong 1.1 &btSigma2, &bpSigma2, &brSigma2)) {
1475 bx_err[ind_map] = DRMS_MISSING_FLOAT;
1476 by_err[ind_map] = DRMS_MISSING_FLOAT;
1477 bz_err[ind_map] = DRMS_MISSING_FLOAT;
1478 continue;
1479 }
1480
1481 bx_err[ind_map] = sqrt(bpSigma2);
1482 by_err[ind_map] = sqrt(btSigma2);
1483 bz_err[ind_map] = sqrt(brSigma2);
1484
1485 }
1486 }
1487
1488 //
1489
1490 free(bT); free(bI); free(bA);
1491 free(errbT); free(errbI); free(errbA);
1492 free(errbTbI); free(errbTbA); free(errbIbA);
1493 return 0;
1494
1495 xudong 1.1 }
1496
1497
1498
1499 /*
1500 * Read full disk vector magnetograms
1501 * Fill factor is 1, use default disambiguity resolution
1502 *
1503 */
1504
1505 int readVectorB(DRMS_Record_t *inRec, float *bx_img, float *by_img, float *bz_img)
1506 {
1507
1508 int status = 0;
1509
1510 DRMS_Segment_t *inSeg;
1511 DRMS_Array_t *inArray_ambig;
|
1512 xudong 1.6 DRMS_Array_t *inArray_bTotal, *inArray_bAzim, *inArray_bIncl;
|
1513 xudong 1.1
1514 char *ambig;
1515 float *bTotal, *bAzim, *bIncl;
1516
1517 inSeg = drms_segment_lookup(inRec, "disambig");
1518 inArray_ambig = drms_segment_read(inSeg, DRMS_TYPE_CHAR, &status);
1519 if (status) return 1;
1520 ambig = (char *)inArray_ambig->data;
1521
1522 inSeg = drms_segment_lookup(inRec, "field");
1523 inArray_bTotal = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
1524 if (status) return 1;
1525 bTotal = (float *)inArray_bTotal->data;
1526
1527 inSeg = drms_segment_lookup(inRec, "azimuth");
1528 inArray_bAzim = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
1529 if (status) return 1;
1530 bAzim = (float *)inArray_bAzim->data;
1531
1532 inSeg = drms_segment_lookup(inRec, "inclination");
1533 inArray_bIncl = drms_segment_read(inSeg, DRMS_TYPE_FLOAT, &status);
1534 xudong 1.1 if (status) return 1;
1535 bIncl = (float *)inArray_bIncl->data;
1536
1537 // Convert CCD xyz
1538
1539 int llx, lly; // lower-left corner
1540 int bmx, bmy; // bitmap size
|
1541 xudong 1.23
1542 if (fullDisk) {
1543 llx = lly = 0;
1544 bmx = bmy = FOURK;
1545 } else {
1546 llx = (int)(drms_getkey_float(inRec, "CRPIX1", &status)) - 1;
1547 lly = (int)(drms_getkey_float(inRec, "CRPIX2", &status)) - 1;
1548 bmx = inArray_ambig->axis[0];
1549 bmy = inArray_ambig->axis[1];
1550 }
|
1551 xudong 1.1
1552 int kx, ky, kOff;
1553 int ix = 0, jy = 0, yOff = 0, iData = 0;
1554 int xDim = FOURK, yDim = FOURK;
|
1555 xudong 1.23 int amb = 0;
|
1556 xudong 1.1
1557 for (jy = 0; jy < yDim; jy++)
1558 {
1559 ix = 0;
1560 yOff = jy * xDim;
1561 ky = jy - lly;
1562 for (ix = 0; ix < xDim; ix++)
1563 {
1564 iData = yOff + ix;
1565 kx = ix - llx;
1566
1567 // zero azi pointing up, zero incl pointing out from sun
1568 bx_img[iData] = - bTotal[iData] * sin(bIncl[iData] * RADSINDEG) * sin(bAzim[iData] * RADSINDEG);
1569 by_img[iData] = bTotal[iData] * sin(bIncl[iData] * RADSINDEG) * cos(bAzim[iData] * RADSINDEG);
1570 bz_img[iData] = bTotal[iData] * cos(bIncl[iData] * RADSINDEG);
1571
1572 // Disambiguation
1573
1574 if (kx < 0 || kx >= bmx || ky < 0 || ky >= bmy) {
1575 continue;
1576 } else {
1577 xudong 1.1 kOff = ky * bmx + kx;
|
1578 xudong 1.23 // if (ambig[kOff] % 2) { // 180
1579 // Feb 12 2014, use bit #2 for full disk, lowest bit for patch
1580 if (fullDisk) { amb = (ambig[kOff] / 4) % 2; } else { amb = ambig[kOff] % 2; }
1581 if (amb) { // Feb 12 2014, use bit #2
|
1582 xudong 1.1 bx_img[iData] *= -1.; by_img[iData] *= -1.;
|
1583 xudong 1.15 }
|
1584 xudong 1.1 }
1585 }
1586 }
1587
1588 // Clean up
1589
1590 drms_free_array(inArray_ambig);
1591 drms_free_array(inArray_bTotal);
1592 drms_free_array(inArray_bAzim);
1593 drms_free_array(inArray_bIncl);
1594
1595 return 0;
1596
1597 }
1598
1599
1600 /*
1601 * Read variances and covariances of vector magnetograms
1602 *
1603 */
1604
|
1605 xudong 1.15 int readVectorBErr(DRMS_Record_t *inRec,
|
1606 xudong 1.1 float *bT, float *bI, float *bA,
|
1607 xudong 1.15 float *errbT, float *errbI, float *errbA,
|
1608 xudong 1.1 float *errbTbI, float *errbTbA, float *errbIbA)
1609 {
1610
1611 int status = 0;
1612
1613 float *data_ptr[9];
1614 char *segName[9] = {"field", "inclination", "azimuth",
|
1615 xudong 1.6 "field_err", "inclination_err", "azimuth_err",
1616 "field_inclination_err", "field_az_err", "inclin_azimuth_err"};
|
1617 xudong 1.1 DRMS_Segment_t *inSegs[9];
1618 DRMS_Array_t *inArrays[9];
1619
1620 // Read full disk images
|
1621 xudong 1.23 // Do we need disambig? Dec 30 XS
|
1622 xudong 1.1
1623 for (int iSeg = 0; iSeg < 9; iSeg++) {
1624
1625 inSegs[iSeg] = drms_segment_lookup(inRec, segName[iSeg]);
1626 inArrays[iSeg] = drms_segment_read(inSegs[iSeg], DRMS_TYPE_FLOAT, &status);
1627 data_ptr[iSeg] = (float *) inArrays[iSeg]->data;
1628
1629 }
1630
1631 float *bT0 = data_ptr[0], *bI0 = data_ptr[1], *bA0 = data_ptr[2];
1632 float *errbT0 = data_ptr[3], *errbI0 = data_ptr[4], *errbA0 = data_ptr[5];
1633 float *errbTbI0 = data_ptr[6], *errbTbA0 = data_ptr[7], *errbIbA0 = data_ptr[8];
1634
|
1635 xudong 1.23 // Add disambig, Feb 12 2014
1636
1637 DRMS_Segment_t *inSeg;
1638 DRMS_Array_t *inArray_ambig;
1639
1640 if (amb4err) { // Mar 4 2014
1641
1642 inSeg = drms_segment_lookup(inRec, "disambig");
1643 inArray_ambig = drms_segment_read(inSeg, DRMS_TYPE_CHAR, &status);
1644 if (status) return 1;
1645 char *ambig = (char *)inArray_ambig->data;
1646
1647 int llx, lly; // lower-left corner
1648 int bmx, bmy; // bitmap size
1649
1650 if (fullDisk) {
1651 llx = lly = 0;
1652 bmx = bmy = FOURK;
1653 } else {
1654 llx = (int)(drms_getkey_float(inRec, "CRPIX1", &status)) - 1;
1655 lly = (int)(drms_getkey_float(inRec, "CRPIX2", &status)) - 1;
1656 xudong 1.23 bmx = inArray_ambig->axis[0];
1657 bmy = inArray_ambig->axis[1];
1658 }
1659
1660 int idx, idx_a;
1661 int amb;
1662
1663 for (int j = 0; j < bmy; j++) {
1664 for (int i = 0; i < bmx; i++) {
1665 idx_a = j * bmx + i;
1666 idx = (j + lly) * FOURK + (i + llx);
1667 // Feb 12 2014, use bit #2 for full disk, lowest bit for patch
1668 if (fullDisk) { amb = (ambig[idx_a] / 4) % 2; } else { amb = ambig[idx_a] % 2; }
1669 if (amb) { bA0[idx] += 180.; }
1670 }
1671 }
1672
1673 }
1674
|
1675 xudong 1.1 // Convert errors to variances, correlation coefficients to covariances
1676
1677 for (int i = 0; i < FOURK2; i++) {
1678
1679 if (fabs(errbI0[i]) > 180.) errbI0[i] = 180.;
1680 if (fabs(errbA0[i]) > 180.) errbA0[i] = 180.;
1681
1682 bT[i] = bT0[i];
|
1683 xudong 1.23 bI[i] = bI0[i]; // in deg, coverted in errorprop
|
1684 xudong 1.1 bA[i] = bA0[i];
1685
1686 errbT[i] = errbT0[i] * errbT0[i];
1687 errbI[i] = errbI0[i] * errbI0[i] * RADSINDEG * RADSINDEG;
1688 errbA[i] = errbA0[i] * errbA0[i] * RADSINDEG * RADSINDEG;
1689
1690 errbTbI[i] = errbTbI0[i] * errbT0[i] * errbI0[i] * RADSINDEG;
1691 errbTbA[i] = errbTbA0[i] * errbT0[i] * errbA0[i] * RADSINDEG;
1692 errbIbA[i] = errbIbA0[i] * errbI0[i] * errbA0[i] * RADSINDEG * RADSINDEG;
|
1693 xudong 1.6
|
1694 xudong 1.1 }
1695
1696 //
1697
1698 for (int iSeg = 0; iSeg < 9; iSeg++) drms_free_array(inArrays[iSeg]);
|
1699 xudong 1.23 if (amb4err) drms_free_array(inArray_ambig); // Feb 12; Mar 04 2014
|
1700 xudong 1.6
|
1701 xudong 1.1 return 0;
1702
1703 }
1704
1705
1706 /*
1707 * Create Cutout record: top level subroutine
1708 * Do the loops on segments and set the keywords here
1709 * Work is done in writeCutout routine below
|
1710 xudong 1.15 *
|
1711 xudong 1.1 */
1712
|
1713 xudong 1.15 int createCutRecord(DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec,
1714 DRMS_Record_t *dopRec, DRMS_Record_t *contRec,
|
1715 xudong 1.1 DRMS_Record_t *sharpRec, struct swIndex *swKeys_ptr)
1716 {
1717
1718 int status = 0;
1719
1720 int iHarpSeg;
1721 int nMharpSegs = ARRLENGTH(MharpSegs), nBharpSegs = ARRLENGTH(BharpSegs);
1722
1723 // Cutout Mharp
1724
1725 for (iHarpSeg = 0; iHarpSeg < nMharpSegs; iHarpSeg++) {
1726 if (writeCutout(sharpRec, mharpRec, mharpRec, MharpSegs[iHarpSeg])) {
1727 printf("Mharp cutout fails for %s\n", MharpSegs[iHarpSeg]);
1728 break;
1729 }
1730 }
|
1731 xudong 1.3 if (iHarpSeg != nMharpSegs) {
1732 SHOW("Cutout: segment number unmatch\n");
1733 return 1; // if failed
1734 }
|
1735 xudong 1.1 printf("Magnetogram cutout done.\n");
1736
1737 // Cutout Doppler
1738
1739 if (writeCutout(sharpRec, dopRec, mharpRec, "Dopplergram")) {
1740 printf("Doppler cutout failed\n");
1741 return 1;
1742 }
1743 printf("Dopplergram cutout done.\n");
1744
1745 // Cutout Continuum
1746
1747 if (writeCutout(sharpRec, contRec, mharpRec, "continuum")) {
1748 printf("Continuum cutout failed\n");
1749 return 1;
1750 }
1751 printf("Intensitygram cutout done.\n");
1752
1753 // Coutout Bharp
1754
1755 for (iHarpSeg = 0; iHarpSeg < nBharpSegs; iHarpSeg++) {
1756 xudong 1.1 if (writeCutout(sharpRec, bharpRec, mharpRec, BharpSegs[iHarpSeg])) {
1757 printf("Bharp cutout fails for %s\n", BharpSegs[iHarpSeg]);
1758 break;
1759 }
1760 }
1761 if (iHarpSeg != nBharpSegs) return 1; // if failed
1762 printf("Vector B cutout done.\n");
1763
1764 // Keywords & Links
1765
1766 drms_copykey(sharpRec, mharpRec, "T_REC");
1767 drms_copykey(sharpRec, mharpRec, "HARPNUM");
1768
1769 DRMS_Link_t *mHarpLink = hcon_lookup_lower(&sharpRec->links, "MHARP");
1770 if (mHarpLink) drms_link_set("MHARP", sharpRec, mharpRec);
1771 DRMS_Link_t *bHarpLink = hcon_lookup_lower(&sharpRec->links, "BHARP");
1772 if (bHarpLink) drms_link_set("BHARP", sharpRec, bharpRec);
1773
1774 setSWIndex(sharpRec, swKeys_ptr); // Set space weather indices
|
1775 xudong 1.23 setKeys(sharpRec, mharpRec, bharpRec, NULL); // Set all other keywords, NULL specifies cutout
|
1776 xudong 1.6
|
1777 xudong 1.1 // Stats
|
1778 xudong 1.6
|
1779 xudong 1.1 int nCutSegs = ARRLENGTH(CutSegs);
1780 for (int iSeg = 0; iSeg < nCutSegs; iSeg++) {
1781 DRMS_Segment_t *outSeg = drms_segment_lookupnum(sharpRec, iSeg);
1782 DRMS_Array_t *outArray = drms_segment_read(outSeg, DRMS_TYPE_FLOAT, &status);
1783 set_statistics(outSeg, outArray, 1);
1784 drms_free_array(outArray);
1785 }
|
1786 xudong 1.6
|
1787 xudong 1.1 return 0;
1788
|
1789 xudong 1.15 }
|
1790 xudong 1.1
1791
|
1792 xudong 1.15 /*
|
1793 xudong 1.1 * Get cutout and write segment
1794 * Change DISAMB_AZI to apply disambiguation to azimuth
1795 *
1796 */
1797
1798 int writeCutout(DRMS_Record_t *outRec, DRMS_Record_t *inRec, DRMS_Record_t *harpRec, char *SegName)
1799 {
1800
1801 int status = 0;
1802
1803 DRMS_Segment_t *inSeg = NULL, *outSeg = NULL;
1804 DRMS_Array_t *cutoutArray = NULL;
1805 // DRMS_Type_t arrayType;
1806
1807 int ll[2], ur[2], nx, ny, nxny; // lower-left and upper right coords
1808
1809 /* Info */
1810
1811 inSeg = drms_segment_lookup(inRec, SegName);
1812 if (!inSeg) return 1;
1813
1814 xudong 1.1 nx = (int) drms_getkey_float(harpRec, "CRSIZE1", &status);
1815 ny = (int) drms_getkey_float(harpRec, "CRSIZE2", &status);
1816 nxny = nx * ny;
1817 ll[0] = (int) drms_getkey_float(harpRec, "CRPIX1", &status) - 1; if (status) return 1;
1818 ll[1] = (int) drms_getkey_float(harpRec, "CRPIX2", &status) - 1; if (status) return 1;
1819 ur[0] = ll[0] + nx - 1; if (status) return 1;
1820 ur[1] = ll[1] + ny - 1; if (status) return 1;
1821
1822 if (inSeg->axis[0] == nx && inSeg->axis[1] == ny) { // for bitmaps, infomaps, etc.
1823 cutoutArray = drms_segment_read(inSeg, DRMS_TYPE_DOUBLE, &status);
1824 if (status) return 1;
1825 } else if (inSeg->axis[0] == FOURK && inSeg->axis[1] == FOURK) { // for full disk ones
1826 cutoutArray = drms_segment_readslice(inSeg, DRMS_TYPE_DOUBLE, ll, ur, &status);
1827 if (status) return 1;
1828 } else {
1829 return 1;
1830 }
|
1831 xudong 1.6
|
1832 xudong 1.23 // Feb 12 2014, fool-proof, for patch, change everything to 0 or 7!!!
1833 // This is a fix for disambiguation before Aug 2013
1834
1835 if (!strcmp(SegName, "disambig") && !fullDisk) {
1836 double *disamb = (double *) (cutoutArray->data);
1837 for (int i = 0; i < nxny; i++) {
1838 if (((int)disamb[i]) % 2) { disamb[i] = 7; } else { disamb[i] = 0; }
1839 }
1840 }
1841
|
1842 xudong 1.1 /* Adding disambiguation resolution to cutout azimuth? */
|
1843 xudong 1.6
|
1844 xudong 1.1 #if DISAMB_AZI
|
1845 xudong 1.23 int amb;
|
1846 xudong 1.1 if (!strcmp(SegName, "azimuth")) {
|
1847 xudong 1.6 DRMS_Segment_t *disambSeg = NULL;
1848 disambSeg = drms_segment_lookup(inRec, "disambig");
|
1849 xudong 1.1 if (!disambSeg) {drms_free_array(cutoutArray); return 1;}
1850 DRMS_Array_t *disambArray;
|
1851 xudong 1.23 if (fullDisk) { // Jan 2 2014 XS
1852 disambArray = drms_segment_readslice(disambSeg, DRMS_TYPE_CHAR, ll, ur, &status);
1853 if (status) return 1;
1854 } else {
1855 if (disambSeg->axis[0] == nx && disambSeg->axis[1] == ny) {
1856 disambArray = drms_segment_read(disambSeg, DRMS_TYPE_CHAR, &status);
1857 if (status) {drms_free_array(cutoutArray); return 1;}
1858 } else {
1859 drms_free_array(cutoutArray);
1860 return 1;
1861 }
1862 }
|
1863 xudong 1.1 double *azimuth = (double *) cutoutArray->data;
1864 char *disamb = (char *) disambArray->data;
1865 for (int n = 0; n < nxny; n++) {
|
1866 xudong 1.23 // if (disamb[n] % 2) azimuth[n] += 180.; // Nov 12 2013 Fixed!!!
1867 // Feb 12 2014, use bit #2 for full disk, lowest bit for patch
1868 if (fullDisk) { amb = (disamb[n] / 4) % 2; } else { amb = disamb[n] % 2; }
1869 if (amb) azimuth[n] += 180.;
|
1870 xudong 1.1 }
1871 drms_free_array(disambArray);
1872 }
1873 #endif
|
1874 xudong 1.6
|
1875 xudong 1.1 /* Write out */
1876
1877 outSeg = drms_segment_lookup(outRec, SegName);
1878 if (!outSeg) return 1;
|
1879 xudong 1.15 // drms_array_convert_inplace(outSeg->info->type, 0, 1, cutoutArray); // Jan 02 2013
|
1880 xudong 1.1 outSeg->axis[0] = cutoutArray->axis[0];
1881 outSeg->axis[1] = cutoutArray->axis[1];
|
1882 xudong 1.15 // cutoutArray->parent_segment = outSeg;
|
1883 xudong 1.8 cutoutArray->israw = 0; // always compressed
|
1884 xudong 1.1 cutoutArray->bzero = outSeg->bzero;
1885 cutoutArray->bscale = outSeg->bscale; // Same as inArray's
1886 status = drms_segment_write(outSeg, cutoutArray, 0);
1887 drms_free_array(cutoutArray);
1888 if (status) return 1;
1889
1890 return 0;
1891
1892 }
1893
1894
|
1895 xudong 1.15 /*
|
1896 xudong 1.1 * Compute space weather indices, no error checking for now
1897 * Based on M. Bobra's swharp_vectorB.c
1898 * No error checking for now
1899 *
1900 */
1901
1902 void computeSWIndex(struct swIndex *swKeys_ptr, DRMS_Record_t *inRec, struct mapInfo *mInfo)
1903 {
1904
1905 int status = 0;
1906 int nx = mInfo->ncol, ny = mInfo->nrow;
1907 int nxny = nx * ny;
1908 int dims[2] = {nx, ny};
|
1909 xudong 1.15
|
1910 xudong 1.1 // Get bx, by, bz, mask
1911
|
1912 xudong 1.6 // Use HARP (Turmon) bitmap as a threshold on spaceweather quantities
|
1913 mbobra 1.5 DRMS_Segment_t *bitmaskSeg = drms_segment_lookup(inRec, "bitmap");
1914 DRMS_Array_t *bitmaskArray = drms_segment_read(bitmaskSeg, DRMS_TYPE_INT, &status);
1915 int *bitmask = (int *) bitmaskArray->data; // get the previously made mask array
|
1916 xudong 1.6
|
1917 xudong 1.15 //Use conf_disambig map as a threshold on spaceweather quantities
1918 DRMS_Segment_t *maskSeg = drms_segment_lookup(inRec, "conf_disambig");
|
1919 xudong 1.1 DRMS_Array_t *maskArray = drms_segment_read(maskSeg, DRMS_TYPE_INT, &status);
1920 int *mask = (int *) maskArray->data; // get the previously made mask array
|
1921 xudong 1.6
|
1922 xudong 1.1 DRMS_Segment_t *bxSeg = drms_segment_lookup(inRec, BP_SEG_CEA);
1923 DRMS_Array_t *bxArray = drms_segment_read(bxSeg, DRMS_TYPE_FLOAT, &status);
1924 float *bx = (float *) bxArray->data; // bx
1925
1926 DRMS_Segment_t *bySeg = drms_segment_lookup(inRec, BT_SEG_CEA);
1927 DRMS_Array_t *byArray = drms_segment_read(bySeg, DRMS_TYPE_FLOAT, &status);
1928 float *by = (float *) byArray->data; // by
1929 for (int i = 0; i < nxny; i++) by[i] *= -1;
1930
1931 DRMS_Segment_t *bzSeg = drms_segment_lookup(inRec, BR_SEG_CEA);
1932 DRMS_Array_t *bzArray = drms_segment_read(bzSeg, DRMS_TYPE_FLOAT, &status);
1933 float *bz = (float *) bzArray->data; // bz
|
1934 xudong 1.15
|
1935 mbobra 1.29 //Use magnetogram map to compute R
1936 DRMS_Segment_t *losSeg = drms_segment_lookup(inRec, "magnetogram");
1937 DRMS_Array_t *losArray = drms_segment_read(losSeg, DRMS_TYPE_FLOAT, &status);
1938 float *los = (float *) losArray->data; // los
|
1939 xudong 1.23
|
1940 mbobra 1.14 DRMS_Segment_t *bz_errSeg = drms_segment_lookup(inRec, BR_ERR_SEG_CEA);
1941 DRMS_Array_t *bz_errArray = drms_segment_read(bz_errSeg, DRMS_TYPE_FLOAT, &status);
1942 float *bz_err = (float *) bz_errArray->data; // bz_err
|
1943 xudong 1.15
|
1944 mbobra 1.14 DRMS_Segment_t *by_errSeg = drms_segment_lookup(inRec, BT_ERR_SEG_CEA);
1945 DRMS_Array_t *by_errArray = drms_segment_read(by_errSeg, DRMS_TYPE_FLOAT, &status);
1946 float *by_err = (float *) by_errArray->data; // by_err
1947 //for (int i = 0; i < nxny; i++) by_err[i] *= -1;
|
1948 xudong 1.15
|
1949 mbobra 1.14 DRMS_Segment_t *bx_errSeg = drms_segment_lookup(inRec, BP_ERR_SEG_CEA);
1950 DRMS_Array_t *bx_errArray = drms_segment_read(bx_errSeg, DRMS_TYPE_FLOAT, &status);
1951 float *bx_err = (float *) bx_errArray->data; // bx_err
|
1952 xudong 1.1
1953 // Get emphemeris
|
1954 mbobra 1.16 float cdelt1_orig = drms_getkey_float(inRec, "CDELT1", &status);
|
1955 xudong 1.9 float dsun_obs = drms_getkey_float(inRec, "DSUN_OBS", &status);
|
1956 mbobra 1.16 double rsun_ref = drms_getkey_double(inRec, "RSUN_REF", &status);
1957 double rsun_obs = drms_getkey_double(inRec, "RSUN_OBS", &status);
1958 float imcrpix1 = drms_getkey_float(inRec, "IMCRPIX1", &status);
1959 float imcrpix2 = drms_getkey_float(inRec, "IMCRPIX2", &status);
1960 float crpix1 = drms_getkey_float(inRec, "CRPIX1", &status);
1961 float crpix2 = drms_getkey_float(inRec, "CRPIX2", &status);
|
1962 xudong 1.23
|
1963 mbobra 1.28 // convert cdelt1_orig from degrees to arcsec
1964 float cdelt1 = (atan((rsun_ref*cdelt1_orig*RADSINDEG)/(dsun_obs)))*(1/RADSINDEG)*(3600.);
1965
|
1966 mbobra 1.29 //if (nx1 > floor((nx-1)/scale + 1) )
1967 // DIE("X-dimension of output array in fsample() is too large.");
1968 //if (ny1 > floor((ny-1)/scale + 1) )
1969 // DIE("Y-dimension of output array in fsample() is too large.");
|
1970 xudong 1.23
|
1971 xudong 1.15 // Temp arrays
|
1972 mbobra 1.14 float *bh = (float *) (malloc(nxny * sizeof(float)));
1973 float *bt = (float *) (malloc(nxny * sizeof(float)));
1974 float *jz = (float *) (malloc(nxny * sizeof(float)));
|
1975 xudong 1.9 float *jz_smooth = (float *) (malloc(nxny * sizeof(float)));
|
1976 mbobra 1.14 float *bpx = (float *) (malloc(nxny * sizeof(float)));
1977 float *bpy = (float *) (malloc(nxny * sizeof(float)));
1978 float *bpz = (float *) (malloc(nxny * sizeof(float)));
1979 float *derx = (float *) (malloc(nxny * sizeof(float)));
1980 float *dery = (float *) (malloc(nxny * sizeof(float)));
|
1981 xudong 1.1 float *derx_bt = (float *) (malloc(nxny * sizeof(float)));
1982 float *dery_bt = (float *) (malloc(nxny * sizeof(float)));
1983 float *derx_bh = (float *) (malloc(nxny * sizeof(float)));
1984 float *dery_bh = (float *) (malloc(nxny * sizeof(float)));
1985 float *derx_bz = (float *) (malloc(nxny * sizeof(float)));
1986 float *dery_bz = (float *) (malloc(nxny * sizeof(float)));
|
1987 mbobra 1.14 float *bt_err = (float *) (malloc(nxny * sizeof(float)));
1988 float *bh_err = (float *) (malloc(nxny * sizeof(float)));
|
1989 mbobra 1.29 float *jz_err = (float *) (malloc(nxny * sizeof(float)));
1990 float *jz_err_squared = (float *) (malloc(nxny * sizeof(float)));
1991 float *jz_err_squared_smooth = (float *) (malloc(nxny * sizeof(float)));
|
1992 mbobra 1.34 float *jz_rms_err = (float *) (malloc(nxny * sizeof(float)));
|
1993 mbobra 1.35 float *err_term1 = (float *) (calloc(nxny, sizeof(float)));
1994 float *err_term2 = (float *) (calloc(nxny, sizeof(float)));
|
1995 mbobra 1.34 float *err_termA = (float *) (calloc(nxny, sizeof(float)));
1996 float *err_termB = (float *) (calloc(nxny, sizeof(float)));
1997 float *err_termAt = (float *) (calloc(nxny, sizeof(float)));
1998 float *err_termBt = (float *) (calloc(nxny, sizeof(float)));
1999 float *err_termAh = (float *) (calloc(nxny, sizeof(float)));
2000 float *err_termBh = (float *) (calloc(nxny, sizeof(float)));
|
2001 mbobra 1.29
|
2002 mbobra 1.34 // define some values for the R calculation
|
2003 mbobra 1.29 int scale = round(2.0/cdelt1);
2004 int nx1 = nx/scale;
2005 int ny1 = ny/scale;
2006 int nxp = nx1+40;
2007 int nyp = ny1+40;
2008 float *rim = (float *)malloc(nx1*ny1*sizeof(float));
2009 float *p1p0 = (float *)malloc(nx1*ny1*sizeof(float));
2010 float *p1n0 = (float *)malloc(nx1*ny1*sizeof(float));
2011 float *p1p = (float *)malloc(nx1*ny1*sizeof(float));
2012 float *p1n = (float *)malloc(nx1*ny1*sizeof(float));
2013 float *p1 = (float *)malloc(nx1*ny1*sizeof(float));
2014 float *pmap = (float *)malloc(nxp*nyp*sizeof(float));
2015 float *p1pad = (float *)malloc(nxp*nyp*sizeof(float));
2016 float *pmapn = (float *)malloc(nx1*ny1*sizeof(float));
|
2017 mbobra 1.30
2018 // define some arrays for the lorentz force calculation
2019 float *fx = (float *) (malloc(nxny * sizeof(float)));
2020 float *fy = (float *) (malloc(nxny * sizeof(float)));
2021 float *fz = (float *) (malloc(nxny * sizeof(float)));
|
2022 xudong 1.23
|
2023 mbobra 1.30
|
2024 arta 1.22 //spaceweather quantities computed
|
2025 xudong 1.15 if (computeAbsFlux(bz_err, bz , dims, &(swKeys_ptr->absFlux), &(swKeys_ptr->mean_vf), &(swKeys_ptr->mean_vf_err),
|
2026 mbobra 1.29 &(swKeys_ptr->count_mask), mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2027 {
|
2028 xudong 1.1 swKeys_ptr->absFlux = DRMS_MISSING_FLOAT; // If fail, fill in NaN
2029 swKeys_ptr->mean_vf = DRMS_MISSING_FLOAT;
|
2030 mbobra 1.29 swKeys_ptr->mean_vf_err = DRMS_MISSING_FLOAT;
2031 swKeys_ptr->count_mask = DRMS_MISSING_INT;
|
2032 xudong 1.1 }
|
2033 xudong 1.15
|
2034 xudong 1.1 for (int i = 0; i < nxny; i++) bpz[i] = bz[i];
|
2035 xudong 1.15 greenpot(bpx, bpy, bpz, nx, ny);
|
2036 xudong 1.1
|
2037 mbobra 1.14 computeBh(bx_err, by_err, bh_err, bx, by, bz, bh, dims, &(swKeys_ptr->mean_hf), mask, bitmask);
|
2038 xudong 1.15
|
2039 mbobra 1.14 if (computeGamma(bz_err, bh_err, bx, by, bz, bh, dims, &(swKeys_ptr->mean_gamma), &(swKeys_ptr->mean_gamma_err),mask, bitmask))
|
2040 xudong 1.15 {
|
2041 mbobra 1.29 swKeys_ptr->mean_gamma = DRMS_MISSING_FLOAT;
2042 swKeys_ptr->mean_gamma_err = DRMS_MISSING_FLOAT;
2043 }
|
2044 xudong 1.1
|
2045 mbobra 1.14 computeB_total(bx_err, by_err, bz_err, bt_err, bx, by, bz, bt, dims, mask, bitmask);
|
2046 xudong 1.1
|
2047 mbobra 1.29 if (computeBtotalderivative(bt, dims, &(swKeys_ptr->mean_derivative_btotal), mask, bitmask, derx_bt,
|
2048 mbobra 1.34 dery_bt, bt_err, &(swKeys_ptr->mean_derivative_btotal_err), err_termAt, err_termBt))
|
2049 mbobra 1.29 {
|
2050 xudong 1.1 swKeys_ptr->mean_derivative_btotal = DRMS_MISSING_FLOAT;
|
2051 mbobra 1.14 swKeys_ptr->mean_derivative_btotal_err = DRMS_MISSING_FLOAT;
|
2052 mbobra 1.29 }
|
2053 xudong 1.1
|
2054 mbobra 1.29 if (computeBhderivative(bh, bh_err, dims, &(swKeys_ptr->mean_derivative_bh),
|
2055 mbobra 1.34 &(swKeys_ptr->mean_derivative_bh_err), mask, bitmask, derx_bh, dery_bh, err_termAh, err_termBh))
|
2056 mbobra 1.29 {
|
2057 xudong 1.1 swKeys_ptr->mean_derivative_bh = DRMS_MISSING_FLOAT;
|
2058 mbobra 1.29 swKeys_ptr->mean_derivative_bh_err = DRMS_MISSING_FLOAT;
|
2059 mbobra 1.14 }
|
2060 xudong 1.15
|
2061 mbobra 1.29 if (computeBzderivative(bz, bz_err, dims, &(swKeys_ptr->mean_derivative_bz), &(swKeys_ptr->mean_derivative_bz_err),
|
2062 mbobra 1.34 mask, bitmask, derx_bz, dery_bz, err_termA, err_termB))
|
2063 mbobra 1.29 {
|
2064 xudong 1.1 swKeys_ptr->mean_derivative_bz = DRMS_MISSING_FLOAT; // If fail, fill in NaN
|
2065 mbobra 1.29 swKeys_ptr->mean_derivative_bz_err = DRMS_MISSING_FLOAT;
2066 }
|
2067 xudong 1.1
|
2068 xudong 1.15 computeJz(bx_err, by_err, bx, by, dims, jz, jz_err, jz_err_squared, mask, bitmask, cdelt1, rsun_ref, rsun_obs,
|
2069 mbobra 1.32 derx, dery, err_term1, err_term2);
|
2070 xudong 1.15
2071
|
2072 mbobra 1.29 if(computeJzsmooth(bx, by, dims, jz, jz_smooth, jz_err, jz_rms_err, jz_err_squared_smooth, &(swKeys_ptr->mean_jz),
|
2073 xudong 1.15 &(swKeys_ptr->mean_jz_err), &(swKeys_ptr->us_i), &(swKeys_ptr->us_i_err), mask, bitmask, cdelt1,
2074 rsun_ref, rsun_obs, derx, dery))
|
2075 mbobra 1.29 {
2076 swKeys_ptr->mean_jz = DRMS_MISSING_FLOAT;
|
2077 mbobra 1.14 swKeys_ptr->us_i = DRMS_MISSING_FLOAT;
|
2078 mbobra 1.29 swKeys_ptr->mean_jz_err = DRMS_MISSING_FLOAT;
2079 swKeys_ptr->us_i_err = DRMS_MISSING_FLOAT;
|
2080 xudong 1.1 }
|
2081 xudong 1.15
|
2082 mbobra 1.29 if (computeAlpha(jz_err, bz_err, bz, dims, jz, jz_smooth, &(swKeys_ptr->mean_alpha), &(swKeys_ptr->mean_alpha_err),
2083 mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2084 {
|
2085 mbobra 1.14 swKeys_ptr->mean_alpha = DRMS_MISSING_FLOAT;
|
2086 mbobra 1.29 swKeys_ptr->mean_alpha_err = DRMS_MISSING_FLOAT;
2087 }
|
2088 mbobra 1.14
|
2089 mbobra 1.29 if (computeHelicity(jz_err, jz_rms_err, bz_err, bz, dims, jz, &(swKeys_ptr->mean_ih), &(swKeys_ptr->mean_ih_err),
2090 &(swKeys_ptr->total_us_ih), &(swKeys_ptr->total_abs_ih),
2091 &(swKeys_ptr->total_us_ih_err), &(swKeys_ptr->total_abs_ih_err), mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2092 {
|
2093 xudong 1.15 swKeys_ptr->mean_ih = DRMS_MISSING_FLOAT;
|
2094 mbobra 1.14 swKeys_ptr->total_us_ih = DRMS_MISSING_FLOAT;
2095 swKeys_ptr->total_abs_ih = DRMS_MISSING_FLOAT;
|
2096 mbobra 1.29 swKeys_ptr->mean_ih_err = DRMS_MISSING_FLOAT;
2097 swKeys_ptr->total_us_ih_err = DRMS_MISSING_FLOAT;
2098 swKeys_ptr->total_abs_ih_err = DRMS_MISSING_FLOAT;
|
2099 xudong 1.1 }
|
2100 xudong 1.15
2101 if (computeSumAbsPerPolarity(jz_err, bz_err, bz, jz, dims, &(swKeys_ptr->totaljz), &(swKeys_ptr->totaljz_err),
|
2102 mbobra 1.29 mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2103 {
|
2104 mbobra 1.14 swKeys_ptr->totaljz = DRMS_MISSING_FLOAT;
|
2105 mbobra 1.29 swKeys_ptr->totaljz_err = DRMS_MISSING_FLOAT;
|
2106 mbobra 1.14 }
|
2107 xudong 1.6
|
2108 xudong 1.15 if (computeFreeEnergy(bx_err, by_err, bx, by, bpx, bpy, dims,
|
2109 mbobra 1.29 &(swKeys_ptr->meanpot), &(swKeys_ptr->meanpot_err), &(swKeys_ptr->totpot), &(swKeys_ptr->totpot_err),
2110 mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2111 {
|
2112 mbobra 1.14 swKeys_ptr->meanpot = DRMS_MISSING_FLOAT; // If fail, fill in NaN
2113 swKeys_ptr->totpot = DRMS_MISSING_FLOAT;
|
2114 mbobra 1.29 swKeys_ptr->meanpot_err = DRMS_MISSING_FLOAT;
2115 swKeys_ptr->totpot_err = DRMS_MISSING_FLOAT;
|
2116 xudong 1.1 }
|
2117 xudong 1.15
|
2118 xudong 1.24
|
2119 mbobra 1.18 if (computeShearAngle(bx_err, by_err, bz_err, bx, by, bz, bpx, bpy, bpz, dims,
|
2120 mbobra 1.29 &(swKeys_ptr->meanshear_angle), &(swKeys_ptr->meanshear_angle_err), &(swKeys_ptr->area_w_shear_gt_45),
2121 mask, bitmask))
2122 {
|
2123 mbobra 1.14 swKeys_ptr->meanshear_angle = DRMS_MISSING_FLOAT; // If fail, fill in NaN
|
2124 xudong 1.1 swKeys_ptr->area_w_shear_gt_45 = DRMS_MISSING_FLOAT;
|
2125 mbobra 1.29 swKeys_ptr->meanshear_angle_err= DRMS_MISSING_FLOAT;
|
2126 xudong 1.1 }
|
2127 xudong 1.23
2128 if (computeR(bz_err, los , dims, &(swKeys_ptr->Rparam), cdelt1, rim, p1p0, p1n0,
|
2129 mbobra 1.29 p1p, p1n, p1, pmap, nx1, ny1, scale, p1pad, nxp, nyp, pmapn))
|
2130 mbobra 1.25 {
|
2131 xudong 1.23 swKeys_ptr->Rparam = DRMS_MISSING_FLOAT; // If fail, fill in NaN
|
2132 mbobra 1.29 }
|
2133 mbobra 1.25
|
2134 mbobra 1.30
2135 if (computeLorentz(bx, by, bz, fx, fy, fz, dims, &(swKeys_ptr->totfx), &(swKeys_ptr->totfy), &(swKeys_ptr->totfz), &(swKeys_ptr->totbsq),
2136 &(swKeys_ptr->epsx), &(swKeys_ptr->epsy), &(swKeys_ptr->epsz), mask, bitmask, cdelt1, rsun_ref, rsun_obs))
2137 {
2138 swKeys_ptr->totfx = DRMS_MISSING_FLOAT;
2139 swKeys_ptr->totfy = DRMS_MISSING_FLOAT;
2140 swKeys_ptr->totfz = DRMS_MISSING_FLOAT;
2141 swKeys_ptr->totbsq = DRMS_MISSING_FLOAT;
2142 swKeys_ptr->epsx = DRMS_MISSING_FLOAT;
2143 swKeys_ptr->epsy = DRMS_MISSING_FLOAT;
2144 swKeys_ptr->epsz = DRMS_MISSING_FLOAT;
2145
2146 }
|
2147 xudong 1.6
|
2148 mbobra 1.14 // Clean up the arrays
|
2149 xudong 1.1
|
2150 xudong 1.6 drms_free_array(bitmaskArray); // Dec 18 2012 Xudong
|
2151 xudong 1.1 drms_free_array(maskArray);
|
2152 xudong 1.15 drms_free_array(bxArray);
|
2153 xudong 1.1 drms_free_array(byArray);
2154 drms_free_array(bzArray);
|
2155 mbobra 1.29 drms_free_array(losArray); // Mar 7
|
2156 mbobra 1.25 drms_free_array(bx_errArray);
|
2157 xudong 1.24 drms_free_array(by_errArray);
2158 drms_free_array(bz_errArray);
|
2159 xudong 1.1
|
2160 xudong 1.9 free(bh); free(bt); free(jz); free(jz_smooth);
|
2161 xudong 1.1 free(bpx); free(bpy); free(bpz);
|
2162 xudong 1.15 free(derx); free(dery);
2163 free(derx_bt); free(dery_bt);
2164 free(derx_bz); free(dery_bz);
|
2165 xudong 1.1 free(derx_bh); free(dery_bh);
|
2166 mbobra 1.14 free(bt_err); free(bh_err); free(jz_err);
|
2167 mbobra 1.25 free(jz_err_squared); free(jz_rms_err);
2168 free(jz_err_squared_smooth);
|
2169 mbobra 1.34
2170 // free the arrays that are related to the numerical derivatives
|
2171 mbobra 1.33 free(err_term2);
2172 free(err_term1);
|
2173 mbobra 1.34 free(err_termB);
2174 free(err_termA);
2175 free(err_termBt);
2176 free(err_termAt);
2177 free(err_termBh);
2178 free(err_termAh);
|
2179 mbobra 1.30
2180 // free the arrays that are related to the r calculation
|
2181 mbobra 1.25 free(rim);
2182 free(p1p0);
2183 free(p1n0);
2184 free(p1p);
2185 free(p1n);
2186 free(p1);
2187 free(pmap);
|
2188 mbobra 1.29 free(p1pad);
2189 free(pmapn);
|
2190 mbobra 1.30
2191 // free the arrays that are related to the lorentz calculation
2192 free(fx); free(fy); free(fz);
|
2193 xudong 1.1 }
2194
|
2195 xudong 1.15 /*
|
2196 xudong 1.1 * Set space weather indices, no error checking for now
2197 *
2198 */
2199
2200 void setSWIndex(DRMS_Record_t *outRec, struct swIndex *swKeys_ptr)
2201 {
|
2202 mbobra 1.25 drms_setkey_float(outRec, "USFLUX", swKeys_ptr->mean_vf);
2203 drms_setkey_float(outRec, "MEANGAM", swKeys_ptr->mean_gamma);
2204 drms_setkey_float(outRec, "MEANGBT", swKeys_ptr->mean_derivative_btotal);
2205 drms_setkey_float(outRec, "MEANGBH", swKeys_ptr->mean_derivative_bh);
2206 drms_setkey_float(outRec, "MEANGBZ", swKeys_ptr->mean_derivative_bz);
2207 drms_setkey_float(outRec, "MEANJZD", swKeys_ptr->mean_jz);
2208 drms_setkey_float(outRec, "TOTUSJZ", swKeys_ptr->us_i);
2209 drms_setkey_float(outRec, "MEANALP", swKeys_ptr->mean_alpha);
2210 drms_setkey_float(outRec, "MEANJZH", swKeys_ptr->mean_ih);
2211 drms_setkey_float(outRec, "TOTUSJH", swKeys_ptr->total_us_ih);
2212 drms_setkey_float(outRec, "ABSNJZH", swKeys_ptr->total_abs_ih);
2213 drms_setkey_float(outRec, "SAVNCPP", swKeys_ptr->totaljz);
2214 drms_setkey_float(outRec, "MEANPOT", swKeys_ptr->meanpot);
2215 drms_setkey_float(outRec, "TOTPOT", swKeys_ptr->totpot);
2216 drms_setkey_float(outRec, "MEANSHR", swKeys_ptr->meanshear_angle);
2217 drms_setkey_float(outRec, "SHRGT45", swKeys_ptr->area_w_shear_gt_45);
|
2218 arta 1.22 drms_setkey_float(outRec, "CMASK", swKeys_ptr->count_mask);
2219 drms_setkey_float(outRec, "ERRBT", swKeys_ptr->mean_derivative_btotal_err);
2220 drms_setkey_float(outRec, "ERRVF", swKeys_ptr->mean_vf_err);
2221 drms_setkey_float(outRec, "ERRGAM", swKeys_ptr->mean_gamma_err);
2222 drms_setkey_float(outRec, "ERRBH", swKeys_ptr->mean_derivative_bh_err);
2223 drms_setkey_float(outRec, "ERRBZ", swKeys_ptr->mean_derivative_bz_err);
2224 drms_setkey_float(outRec, "ERRJZ", swKeys_ptr->mean_jz_err);
2225 drms_setkey_float(outRec, "ERRUSI", swKeys_ptr->us_i_err);
2226 drms_setkey_float(outRec, "ERRALP", swKeys_ptr->mean_alpha_err);
2227 drms_setkey_float(outRec, "ERRMIH", swKeys_ptr->mean_ih_err);
2228 drms_setkey_float(outRec, "ERRTUI", swKeys_ptr->total_us_ih_err);
2229 drms_setkey_float(outRec, "ERRTAI", swKeys_ptr->total_abs_ih_err);
2230 drms_setkey_float(outRec, "ERRJHT", swKeys_ptr->totaljz_err);
2231 drms_setkey_float(outRec, "ERRMPOT", swKeys_ptr->meanpot_err);
2232 drms_setkey_float(outRec, "ERRTPOT", swKeys_ptr->totpot_err);
2233 drms_setkey_float(outRec, "ERRMSHA", swKeys_ptr->meanshear_angle_err);
|
2234 xudong 1.23 drms_setkey_float(outRec, "R_VALUE", swKeys_ptr->Rparam);
|
2235 mbobra 1.30 drms_setkey_float(outRec, "TOTFX", swKeys_ptr->totfx);
2236 drms_setkey_float(outRec, "TOTFY", swKeys_ptr->totfy);
2237 drms_setkey_float(outRec, "TOTFZ", swKeys_ptr->totfz);
2238 drms_setkey_float(outRec, "TOTBSQ", swKeys_ptr->totbsq);
2239 drms_setkey_float(outRec, "EPSX", swKeys_ptr->epsx);
2240 drms_setkey_float(outRec, "EPSY", swKeys_ptr->epsy);
2241 drms_setkey_float(outRec, "EPSZ", swKeys_ptr->epsz);
|
2242 xudong 1.1 };
2243
|
2244 xudong 1.15 /*
|
2245 xudong 1.1 * Set all keywords, no error checking for now
2246 *
2247 */
2248
|
2249 xudong 1.23 void setKeys(DRMS_Record_t *outRec, DRMS_Record_t *mharpRec, DRMS_Record_t *bharpRec, struct mapInfo *mInfo)
|
2250 xudong 1.1 {
|
2251 xudong 1.23
2252 copy_me_keys(bharpRec, outRec);
2253 copy_patch_keys(mharpRec, outRec); // Dec 30
2254 copy_geo_keys(mharpRec, outRec); // Dec 30
2255 copy_ambig_keys(bharpRec, outRec);
2256
|
2257 xudong 1.15 int status = 0;
2258
|
2259 xudong 1.23 // Change a few geometry keywords for CEA & cutout records
2260 if (mInfo != NULL) { // CEA
|
2261 xudong 1.15
2262 drms_setkey_float(outRec, "CRPIX1", mInfo->ncol/2. + 0.5);
2263 drms_setkey_float(outRec, "CRPIX2", mInfo->nrow/2. + 0.5);
2264
2265 drms_setkey_float(outRec, "CRVAL1", mInfo->xc);
2266 drms_setkey_float(outRec, "CRVAL2", mInfo->yc);
2267 drms_setkey_float(outRec, "CDELT1", mInfo->xscale);
2268 drms_setkey_float(outRec, "CDELT2", mInfo->yscale);
2269 drms_setkey_string(outRec, "CUNIT1", "degree");
2270 drms_setkey_string(outRec, "CUNIT2", "degree");
2271
2272 char key[64];
2273 snprintf (key, 64, "CRLN-%s", wcsCode[(int) mInfo->proj]);
2274 drms_setkey_string(outRec, "CTYPE1", key);
2275 snprintf (key, 64, "CRLT-%s", wcsCode[(int) mInfo->proj]);
2276 drms_setkey_string(outRec, "CTYPE2", key);
2277 drms_setkey_float(outRec, "CROTA2", 0.0);
|
2278 xudong 1.23
2279 // Jan 2 2014 XS
2280 int nSeg = ARRLENGTH(CEASegs);
2281 for (int iSeg = 0; iSeg < nSeg; iSeg++) {
2282 DRMS_Segment_t *outSeg = NULL;
2283 outSeg = drms_segment_lookup(outRec, CEASegs[iSeg]);
2284 if (!outSeg) continue;
2285 // Set Bunit
2286 char bunit_xxx[20];
2287 sprintf(bunit_xxx, "BUNIT_%03d", iSeg);
2288 //printf("%s, %s\n", bunit_xxx, CEABunits[iSeg]);
2289 drms_setkey_string(outRec, bunit_xxx, CEABunits[iSeg]);
2290 }
|
2291 xudong 1.15
|
2292 xudong 1.23 } else { // Cutout
|
2293 xudong 1.15
|
2294 xudong 1.23 float disk_xc, disk_yc;
2295 if (fullDisk) {
2296 disk_xc = drms_getkey_float(bharpRec, "CRPIX1", &status);
2297 disk_yc = drms_getkey_float(bharpRec, "CRPIX2", &status);
2298 } else {
2299 disk_xc = drms_getkey_float(mharpRec, "IMCRPIX1", &status);
2300 disk_yc = drms_getkey_float(mharpRec, "IMCRPIX2", &status);
2301 }
2302 float x_ll = drms_getkey_float(mharpRec, "CRPIX1", &status);
2303 float y_ll = drms_getkey_float(mharpRec, "CRPIX2", &status);
|
2304 xudong 1.15 // Defined as disk center's pixel address wrt lower-left of cutout
2305 drms_setkey_float(outRec, "CRPIX1", disk_xc - x_ll + 1.);
2306 drms_setkey_float(outRec, "CRPIX2", disk_yc - y_ll + 1.);
2307 // Always 0.
2308 drms_setkey_float(outRec, "CRVAL1", 0);
2309 drms_setkey_float(outRec, "CRVAL2", 0);
|
2310 xudong 1.23
2311 // Jan 2 2014 XS
2312 int nSeg = ARRLENGTH(CutSegs);
2313 for (int iSeg = 0; iSeg < nSeg; iSeg++) {
2314 DRMS_Segment_t *outSeg = NULL;
2315 outSeg = drms_segment_lookup(outRec, CutSegs[iSeg]);
2316 if (!outSeg) continue;
2317 // Set Bunit
2318 char bunit_xxx[20];
2319 sprintf(bunit_xxx, "BUNIT_%03d", iSeg);
2320 //printf("%s, %s\n", bunit_xxx, CutBunits[iSeg]);
2321 drms_setkey_string(outRec, bunit_xxx, CutBunits[iSeg]);
2322 }
2323
|
2324 xudong 1.15
2325 }
|
2326 xudong 1.26
2327 // Mar 19 XS
2328 if (fullDisk) {
2329 drms_setkey_int(outRec, "AMBPATCH", 0);
|
2330 xudong 1.27 drms_setkey_int(outRec, "AMBWEAK", 2);
|
2331 xudong 1.26 } else {
2332 drms_setkey_int(outRec, "AMBPATCH", 1);
2333 }
|
2334 xudong 1.23
2335 TIME val, trec, tnow, UNIX_epoch = -220924792.000; /* 1970.01.01_00:00:00_UTC */
2336 tnow = (double)time(NULL);
2337 tnow += UNIX_epoch;
2338
2339 val = drms_getkey_time(bharpRec, "DATE", &status);
2340 drms_setkey_time(outRec, "DATE_B", val);
2341 drms_setkey_time(outRec, "DATE", tnow);
2342
2343 // set cvs commit version into keyword HEADER
|
2344 xudong 1.38 char *cvsinfo = strdup("$Id: sharp.c,v 1.37 2015/03/11 21:46:52 mbobra Exp $");
|
2345 xudong 1.23 char *cvsinfo2 = sw_functions_version();
2346 char cvsinfoall[2048];
2347 strcat(cvsinfoall,cvsinfo);
2348 strcat(cvsinfoall,"\n");
2349 strcat(cvsinfoall,cvsinfo2);
2350 status = drms_setkey_string(outRec, "CODEVER7", cvsinfoall);
|
2351 xudong 1.6
|
2352 xudong 1.1 };
2353
2354
2355 /* ############# Nearest neighbour interpolation ############### */
2356
2357 float nnb (float *f, int nx, int ny, double x, double y)
2358 {
2359
2360 if (x <= -0.5 || y <= -0.5 || x > nx - 0.5 || y > ny - 0.5)
2361 return DRMS_MISSING_FLOAT;
2362 int ilow = floor (x);
2363 int jlow = floor (y);
2364 int i = ((x - ilow) > 0.5) ? ilow + 1 : ilow;
2365 int j = ((y - jlow) > 0.5) ? jlow + 1 : jlow;
2366 return f[j * nx + i];
2367
2368 }
2369
|
2370 mbobra 1.29
|
2371 xudong 1.1 /* ################## Wrapper for Jesper's rebin code ################## */
2372
2373 void frebin (float *image_in, float *image_out, int nx, int ny, int nbin, int gauss)
2374 {
2375
2376 struct fresize_struct fresizes;
2377 int nxout, nyout, xoff, yoff;
2378 int nlead = nx;
2379
2380 nxout = nx / nbin; nyout = ny / nbin;
2381 if (gauss && nbin != 1)
2382 init_fresize_gaussian(&fresizes, (nbin / 2), (nbin / 2 * 2), nbin); // for nbin=3, sigma=1, half truncate width=2
2383 else
2384 init_fresize_bin(&fresizes, nbin);
2385 xoff = nbin / 2 + nbin / 2;
2386 yoff = nbin / 2 + nbin / 2;
2387 fresize(&fresizes, image_in, image_out, nx, ny, nlead, nxout, nyout, nxout, xoff, yoff, DRMS_MISSING_FLOAT);
2388
2389 }
|