00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <jsoc_main.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include "cartography.c"
00026
00027
00028
00029 #ifndef MIN
00030 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
00031 #endif
00032 #ifndef MAX
00033 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
00034 #endif
00035
00036 #define SHOW(msg) {printf("%s", msg); fflush(stdout);}
00037 #define DIE(msg) {fflush(stdout); fprintf(stderr,"%s (status=%d)\n", msg, status); return(status);}
00038
00039 #define FREE_ARR(arr) {if (arr) {free(arr);}}
00040 #define DRMS_FREE_ARR(arr) {if (arr) {drms_free_array(arr);}}
00041
00042 #define EPSL (1.0E-5)
00043 #define RAD2DEG (180. / M_PI)
00044 #define RAD2ARCSEC (648000. / M_PI)
00045
00046
00047 #define APOD (0.990)
00048 #define BRTHRESH (0.0)
00049 #define BLTHRESH (0.0)
00050
00051
00052
00053 struct ephemeris {
00054 double rsun_obs;
00055 double asd;
00056 double xc, yc;
00057 double cdelt;
00058 double p0, b0;
00059 double rsun;
00060 double da;
00061 };
00062
00063
00064
00065
00066
00067 double getwalltime(void)
00068 {
00069 struct timeval tv;
00070 gettimeofday(&tv, NULL);
00071 return tv.tv_sec * 1000.0 + tv.tv_usec/1000.0;
00072 }
00073
00074 double getcputime(double *utime, double *stime)
00075 {
00076 struct rusage ru;
00077 getrusage(RUSAGE_SELF, &ru);
00078 *utime = ru.ru_utime.tv_sec * 1000.0 + ru.ru_utime.tv_usec/1000.0;
00079 *stime = ru.ru_stime.tv_sec * 1000.0 + ru.ru_stime.tv_usec/1000.0;
00080 return *utime + *stime;
00081 }
00082
00083
00084
00085 int get_ephemeris(DRMS_Record_t *inRec, struct ephemeris *ephem);
00086
00087
00088 void get_lonlat(struct ephemeris *ephem, int *dims, double *lon, double *lat, double *wght);
00089
00090
00091 void los2radial(struct ephemeris *ephem, int *dims, double *bl, double *br, double *wght);
00092
00093
00094 void compute_flux(int *dims, double *br, double *bl, double *wght,
00095 double *ntflux_bl, double *ntflux_br, double *usflux_bl, double *usflux_br,
00096 double *w_bl, double *w_br, double *r_bl, double *r_br);
00097
00098
00099
00100
00101
00102
00103
00104 char *module_name = "usflux";
00105
00106 ModuleArgs_t module_args[] =
00107 {
00108 {ARG_STRING, "in", "", "Input query"},
00109 {ARG_STRING, "out", "hmi_test.usflux_720s", "Output query"},
00110 {ARG_END}
00111 };
00112
00113 int DoIt(void)
00114 {
00115
00116 int status = DRMS_SUCCESS;
00117
00118
00119
00120 double wt0, wt1, wt;
00121 double ut0, ut1, ut;
00122 double st0, st1, st;
00123 double ct0, ct1, ct;
00124 wt0 = getwalltime();
00125 ct0 = getcputime(&ut0, &st0);
00126
00127
00128
00129
00130
00131 char *inQuery = (char *)params_get_str(&cmdparams, "in");
00132 char *outQuery = (char *)params_get_str(&cmdparams, "out");
00133
00134
00135
00136
00137
00138 DRMS_RecordSet_t *inRS = NULL;
00139 inRS = drms_open_records(drms_env, inQuery, &status);
00140 if (status || inRS->n == 0) DIE("Input records error.");
00141
00142 int nrecs = inRS->n;
00143
00144
00145
00146
00147
00148 DRMS_RecordSet_t *outRS = drms_create_records(drms_env, nrecs, outQuery, DRMS_PERMANENT, &status);
00149 if (status) DIE("Output records not created.");
00150
00151
00152
00153
00154
00155 printf("Start, %d records in total\n", nrecs);
00156
00157 for (int irec = 0; irec < nrecs; irec++) {
00158
00159
00160
00161 wt1 = getwalltime();
00162 ct1 = getcputime(&ut, &st);
00163
00164
00165
00166 DRMS_Record_t *inRec = inRS->records[irec];
00167 TIME t_rec = drms_getkey_time(inRec, "T_REC", &status);
00168
00169 char t_rec_str[100];
00170 sprint_time(t_rec_str, t_rec, "TAI", 0);
00171 printf("==============\nRecord #%d, [%s]\n", irec, t_rec_str);
00172
00173 struct ephemeris ephem;
00174 status = get_ephemeris(inRec, &ephem);
00175 if (status) {
00176 SHOW("Input record ephemeris error, record skipped.\n");
00177 }
00178
00179 DRMS_Segment_t *inSeg = drms_segment_lookupnum(inRec, 0);
00180 DRMS_Array_t *inArray = NULL;
00181 inArray = drms_segment_read(inSeg, DRMS_TYPE_DOUBLE, &status);
00182 if (status) {
00183 SHOW("Input array read error, record skipped.\n");
00184 if (inArray) drms_free_array(inArray);
00185 continue;
00186 }
00187
00188 int nx = inArray->axis[0], ny = inArray->axis[1];
00189 int nxny = nx * ny;
00190 int dims[2] = {nx, ny};
00191
00192
00193
00194 SHOW("Get lon/lat...\n");
00195
00196 double *lon = NULL, *lat = NULL, *wght = NULL;
00197 lon = (double *) (calloc(sizeof(double), nxny));
00198 lat = (double *) (calloc(sizeof(double), nxny));
00199 wght = (double *) (calloc(sizeof(double), nxny));
00200
00201 get_lonlat(&ephem, dims, lon, lat, wght);
00202
00203
00204
00205 double *bl = NULL, *br = NULL;
00206 bl = (double *) (inArray->data);
00207 br = (double *) (calloc(sizeof(double), nxny));
00208
00209 SHOW("Convert bl to br...\n");
00210 los2radial(&ephem, dims, bl, br, wght);
00211
00212
00213
00214 SHOW("Compute usflux...\n");
00215
00216
00217 double ntflux_bl = 0, ntflux_br = 0, usflux_bl = 0, usflux_br = 0;
00218
00219 double w_bl = 0, w_br = 0, r_bl = 0, r_br = 0;
00220
00221 compute_flux(dims, br, bl, wght,
00222 &ntflux_bl, &ntflux_br, &usflux_bl, &usflux_br,
00223 &w_bl, &w_br, &r_bl, &r_br);
00224
00225
00226
00227 drms_free_array(inArray);
00228 FREE_ARR(br); FREE_ARR(wght); FREE_ARR(lon); FREE_ARR(lat);
00229
00230
00231
00232 SHOW("Output...\n");
00233 printf("mean bl: %.4f G\n", ntflux_bl / w_bl);
00234
00235 DRMS_Record_t *outRec = outRS->records[irec];
00236
00237 drms_copykey(outRec, inRec, "T_REC");
00238
00239 char timebuf[1024];
00240 double UNIX_epoch = -220924792.0;
00241 sprint_time(timebuf, (double)time(NULL) + UNIX_epoch, "ISO", 0);
00242 drms_setkey_string(outRec, "DATE", timebuf);
00243
00244 double k = ephem.da * 1.e-4;
00245 drms_setkey_double(outRec, "NTFLUX_BL", ntflux_bl * k);
00246 drms_setkey_double(outRec, "NTFLUX_BR", ntflux_br * k);
00247 drms_setkey_double(outRec, "USFLUX_BL", usflux_bl * k);
00248 drms_setkey_double(outRec, "USFLUX_BR", usflux_br * k);
00249
00250 drms_setkey_double(outRec, "BRTHRESH", BRTHRESH);
00251 drms_setkey_double(outRec, "BLTHRESH", BRTHRESH);
00252 drms_setkey_double(outRec, "W_BL", w_bl);
00253 drms_setkey_double(outRec, "W_BR", w_br);
00254 drms_setkey_double(outRec, "R_BL", r_bl);
00255 drms_setkey_double(outRec, "R_BR", r_br);
00256 drms_setkey_double(outRec, "DA", ephem.da);
00257 drms_setkey_double(outRec, "APOD", APOD);
00258
00259 drms_copykey(outRec, inRec, "QUALITY");
00260 drms_copykey(outRec, inRec, "CRLT_OBS");
00261 drms_copykey(outRec, inRec, "CRLN_OBS");
00262 drms_copykey(outRec, inRec, "CAR_ROT");
00263 drms_copykey(outRec, inRec, "OBS_VR");
00264
00265
00266
00267 wt = getwalltime();
00268 ct = getcputime(&ut, &st);
00269 printf("Record %d of %d done, %.2f ms wall time, %.2f ms cpu time\n",
00270 irec + 1, nrecs, wt - wt1, ct - ct1);
00271
00272 }
00273
00274
00275
00276 drms_close_records(inRS, DRMS_FREE_RECORD);
00277 drms_close_records(outRS, DRMS_INSERT_RECORD);
00278
00279 wt = getwalltime();
00280 ct = getcputime(&ut, &st);
00281 printf("==============\nTotal time spent: %.2f ms wall time, %.2f ms cpu time\n",
00282 wt - wt0, ct - ct0);
00283
00284 return DRMS_SUCCESS;
00285
00286 }
00287
00288
00289
00290
00291
00292 int get_ephemeris(DRMS_Record_t *inRec, struct ephemeris *ephem)
00293 {
00294
00295 int status = 0;
00296
00297 ephem->rsun_obs = drms_getkey_double(inRec, "RSUN_OBS", &status);
00298 if (status) return status;
00299 ephem->asd = ephem->rsun_obs / RAD2ARCSEC;
00300
00301 ephem->xc = drms_getkey_double(inRec, "CRPIX1", &status) - 1.;
00302 if (status) return status;
00303 ephem->yc = drms_getkey_double(inRec, "CRPIX2", &status) - 1.;
00304 if (status) return status;
00305
00306 double cdelt1 = drms_getkey_double(inRec, "CDELT1", &status);
00307 if (status) return status;
00308 double cdelt2 = drms_getkey_double(inRec, "CDELT2", &status);
00309 if (status) return status;
00310 if (fabs(cdelt1 - cdelt2) > EPSL) return 1;
00311 ephem->cdelt = cdelt1;
00312
00313 ephem->rsun = ephem->rsun_obs / ephem->cdelt;
00314
00315 ephem->p0 = drms_getkey_double(inRec, "CROTA2", &status) / RAD2DEG * (-1.);
00316 if (status) return status;
00317
00318 ephem->b0 = drms_getkey_double(inRec, "CRLT_OBS", &status) / RAD2DEG;
00319 if (status) return status;
00320
00321 double dsun_obs = drms_getkey_double(inRec, "DSUN_OBS", &status) / 1.e6;
00322 double dx = cdelt1 * ((dsun_obs - 696.) / RAD2ARCSEC);
00323 ephem->da = dx * dx;
00324
00325 return 0;
00326
00327 }
00328
00329
00330
00331 void get_lonlat(struct ephemeris *ephem, int *dims, double *lon, double *lat, double *wght)
00332 {
00333
00334 int ncol = dims[0], nrow = dims[1];
00335 int idx;
00336 int status = 0;
00337
00338 double x, y, r;
00339 double rho, sinlat, coslat, sig, mu, chi;
00340 double lat0, lon0;
00341
00342 for (int row = 0; row < nrow; row++) {
00343 y = (row - ephem->yc) / ephem->rsun;
00344 for (int col = 0; col < ncol; col++) {
00345 x = (col - ephem->xc) / ephem->rsun;
00346 r = hypot(x, y);
00347 idx = row * ncol + col;
00348 if (r <= APOD) {
00349 status = img2sphere(x, y, ephem->asd, ephem->b0, 0.0, ephem->p0,
00350 &rho, &lat0, &lon0, &sinlat, &coslat, &sig, &mu, &chi);
00351 if (status) {
00352 lon[idx] = lat[idx] = wght[idx] = DRMS_MISSING_DOUBLE;
00353 } else {
00354 lon[idx] = ((lon0 > M_PI) ? (lon0 - M_PI * 2) : lon0) * RAD2DEG;
00355 lat[idx] = lat0 * RAD2DEG;
00356 wght[idx] = 1.0 / mu;
00357 }
00358 } else {
00359 lon[idx] = lat[idx] = wght[idx] = DRMS_MISSING_DOUBLE;
00360 }
00361 }
00362 }
00363
00364 }
00365
00366
00367
00368 void los2radial(struct ephemeris *ephem, int *dims, double *bl, double *br, double *wght)
00369 {
00370
00371 int nxny = dims[0] * dims[1];
00372 int idx;
00373
00374 double x, y, r;
00375 double crho;
00376
00377 for (int idx = 0; idx < nxny; idx++) {
00378 if (isnan(wght[idx])) {
00379 br[idx] = bl[idx] = DRMS_MISSING_DOUBLE;
00380 } else {
00381 br[idx] = bl[idx] * wght[idx];
00382 }
00383 }
00384 }
00385
00386
00387
00388 void compute_flux(int *dims, double *br, double *bl, double *wght,
00389 double *ntflux_bl, double *ntflux_br, double *usflux_bl, double *usflux_br,
00390 double *w_bl, double *w_br, double *r_bl, double *r_br)
00391 {
00392 int nx = dims[0], ny = dims[1];
00393 int nxny = nx * ny;
00394
00395
00396 for (int idx = 0; idx < nxny; idx++) {
00397 if (isnan(wght[idx])) continue;
00398 (*w_bl) += 1;
00399 (*w_br) += wght[idx];
00400
00401 if (fabs(bl[idx]) >= BLTHRESH) {
00402 (*ntflux_bl) += (bl[idx]);
00403 (*usflux_bl) += fabs(bl[idx]);
00404 (*r_bl) += 1;
00405 }
00406 if (fabs(br[idx]) >= BRTHRESH) {
00407 (*ntflux_br) += (br[idx] * wght[idx]);
00408 (*usflux_br) += fabs(br[idx] * wght[idx]);
00409 (*r_br) += wght[idx];
00410 }
00411 }
00412
00413 (*r_bl) /= (*w_bl);
00414 (*r_br) /= (*w_br);
00415
00416 }
00417