00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #include <jsoc_main.h>
00081 #include "fstats.h"
00082 #include "cartography.h"
00083 #include "magutils.h"
00084
00085 #define RECTANGULAR (0)
00086 #define CASSINI (1)
00087 #define MERCATOR (2)
00088 #define CYLEQA (3)
00089 #define SINEQA (4)
00090 #define GNOMONIC (5)
00091 #define POSTEL (6)
00092 #define STEREOGRAPHIC (7)
00093 #define ORTHOGRAPHIC (8)
00094 #define LAMBERT (9)
00095
00096 #define PI (M_PI)
00097 #define RADSINDEG (PI/180)
00098 #define ARCSECSINRAD (3600*180/PI)
00099 #define RAD2ARCSEC (648000. / M_PI)
00100 #define RSUNM (6.96e8)
00101 #define INTERP_NEAREST_NEIGHBOR (1)
00102 #define INTERP_BILINEAR (2)
00103
00104
00105 extern int synop_solar_image_info(DRMS_Record_t *img, double *xscl, double *yscl, double *ctrx, double *ctry, double *apsd, const char *rsun_key, const char *apsd_key, double *pang, double *ellipse_e, double *ellipse_pa, int *x_invrt, int *y_invrt, int *need_ephem, int AIPS_convention);
00106
00107
00108 extern int synop_plane2sphere (double x, double y, double latc, double lonc, double *lat, double *lon, int projection);
00109 extern int synop_img2sphere(double x, double y, double ang_r, double latc, double lonc, double pa, double *rho, double *lat, double *lon, double *sinlat, double *coslat, double *sig, double *mu, double *chi);
00110 extern int synop_sphere2img(double lat, double lon, double latc, double lonc, double *x, double *y, double xcenter, double ycenter, double rsun, double peff, double ecc, double chi, int xinvrt, int yinvrt);
00111 extern int synop_sphere2plane(double lat, double lon, double latc, double lonc, double *x, double *y, int projection);
00112
00113 void do_boxcar(float *image_in, float *image_out, int in_nx, int in_ny, float fscale, int power);
00114
00115
00116 char *module_name = "maproj3comperrorlonat02deg";
00117 char *module_desc = "mapping from solar images rounded at 0.2 degree at longitude";
00118 char *version_id = "1.0";
00119
00120 ModuleArgs_t module_args[] = {
00121 {ARG_DATASET, "in", "", "input data set"},
00122 {ARG_DATASERIES, "out", "", "output data series"},
00123 {ARG_DOUBLE, "clat", "0.0", "heliographic latitude of map center [deg]"},
00124 {ARG_DOUBLE, "clon", "0.0", "Carrington longitude of map center [deg]"},
00125 {ARG_DOUBLE, "scale", "Not specified", "map scale at center [deg/pxl]"},
00126 {ARG_NUME, "map", "orthographic", "map projection",
00127 "carree, Cassini, Mercator, cyleqa, sineqa, gnomonic, Postel, stereographic, orthographic, Lambert"},
00128 {ARG_NUME, "interp", "cubiconv", "interpolation option",
00129 "cubiconv, nearest, bilinear"},
00130 {ARG_FLOAT, "grid", "Not Specified",
00131 "if specified, spacing of grid overlay [deg]"},
00132 {ARG_INT, "cols", "0", "columns in output map"},
00133 {ARG_INT, "rows", "0", "rows in output map"},
00134 {ARG_FLOAT, "map_pa", "0.0", "position angle of north on output map [deg]"},
00135 {ARG_FLOAT, "bscale", "0.0", "output scaling factor"},
00136 {ARG_FLOAT, "bzero", "Default", "output offset"},
00137 {ARG_FLOAT, "RESCALE", "0.1", "Scale factor."},
00138 {ARG_STRING, "clon_key", "CRLN_OBS", "keyname for image central longitude"},
00139 {ARG_STRING, "clat_key", "CRLT_OBS", "keyname for image central latitude"},
00140 {ARG_STRING, "rsun_key", "R_SUN", "keyname for image semi-diameter (pixel)"},
00141 {ARG_STRING, "apsd_key", "RSUN_OBS", "keyname for apparent solar semi-diameter (arcsec)"},
00142 {ARG_STRING, "dsun_key", "DSUN_OBS", "keyname for observer distance"},
00143 {ARG_FLAG, "c", "", "center map at center of image"},
00144 {ARG_FLAG, "s", "", "clon is Stonyhurst longitude"},
00145 {ARG_FLAG, "v", "", "verbose mode"},
00146 {}
00147 };
00148
00149
00150 float missing_val;
00151
00152
00153 void ccker (double *u, double s) {
00154 double s2, s3;
00155
00156 s2= s * s;
00157 s3= s2 * s;
00158 u[0] = s2 - 0.5 * (s3 + s);
00159 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
00160 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
00161 u[3] = 0.5 * (s3 - s2);
00162 }
00163
00164 float ccint2 (float *f, int nx, int ny, double x, double y) {
00165 double ux[4], uy[4];
00166 double sum;
00167 int ix, iy, ix1, iy1, i, j;
00168
00169 if (x < 1.0 || x >= (float)(nx-2) || y < 1.0 || y >= (float)(ny-2))
00170 return missing_val;
00171
00172 ix = (int)x;
00173 ccker (ux, x - (double)ix);
00174 iy = (int)y;
00175 ccker (uy, y - (double)iy);
00176
00177 ix1 = ix - 1;
00178 iy1 = iy - 1;
00179 sum = 0.;
00180 for (i = 0; i < 4; i++)
00181 for (j = 0; j < 4; j++)
00182 sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00183 return (float)sum;
00184 }
00185
00186
00187 float ccint2_error (float *f, int nx, int ny, double x, double y) {
00188 double ux[4], uy[4];
00189 double sum, squareValue;
00190 int ix, iy, ix1, iy1, i, j;
00191
00192 if (x < 1.0 || x >= (float)(nx-2) || y < 1.0 || y >= (float)(ny-2))
00193 return missing_val;
00194
00195 ix = (int)x;
00196 ccker (ux, x - (double)ix);
00197 iy = (int)y;
00198 ccker (uy, y - (double)iy);
00199
00200 ix1 = ix - 1;
00201 iy1 = iy - 1;
00202 sum = 0.;
00203 for (i = 0; i < 4; i++){
00204 for (j = 0; j < 4; j++){
00205 squareValue = f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00206 sum = sum + squareValue * squareValue;
00207 }
00208 }
00209 return (float)sqrt(sum);
00210 }
00211
00212 float linint2 (float *f, int cols, int rows, double x, double y) {
00213 double p, q, val;
00214 int col = (int)x, row = (int)y;
00215 int onerow = cols * row;
00216 int colp1 = col + 1, onerowp1 = onerow + cols;
00217
00218 if (x < 0.0 || x > cols || y < 0.0 || y >= rows)
00219 return missing_val;
00220 p = x - col;
00221 q = y - row;
00222 val = (1 - p) * (1 - q) * f[col + onerow]
00223 + p * (1 - q) * f[colp1 + onerow]
00224 + (1 - p) * q * f[col + onerowp1]
00225 + p * q * f[colp1 + onerowp1];
00226 return val;
00227 }
00228
00229
00230 float linint2_error (float *f, int cols, int rows, double x, double y) {
00231 double p, q, val;
00232 int col = (int)x, row = (int)y;
00233 int onerow = cols * row;
00234 int colp1 = col + 1, onerowp1 = onerow + cols;
00235
00236 if (x < 0.0 || x > cols || y < 0.0 || y >= rows)
00237 return missing_val;
00238 p = x - col;
00239 q = y - row;
00240 val = (1 - p) * (1 - q) * f[col + onerow] * (1 - p) * (1 - q) * f[col + onerow]
00241 + p * (1 - q) * f[colp1 + onerow] * p * (1 - q) * f[colp1 + onerow]
00242 + (1 - p) * q * f[col + onerowp1] * (1 - p) * q * f[col + onerowp1]
00243 + p * q * f[colp1 + onerowp1] * p * q * f[colp1 + onerowp1];
00244 return sqrt(val);
00245 }
00246
00247
00248 float nearest_val (float *f, int cols, int rows, double x, double y) {
00249 int col, row;
00250 if (x < -0.5 || x >= (cols - 0.5) || y < -0.5 || y >= (rows - 0.5))
00251 return missing_val;
00252 col = x + 0.5;
00253 row = y + 0.5;
00254 return f[col + row * cols];
00255 }
00256
00257
00258 float array_imaginterp (DRMS_Array_t *img, double x, double y,
00259 int schema) {
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 double xs, ys;
00285 int cols, rows, mdim;
00286
00287 cols = img->axis[0];
00288 rows = img->axis[1];
00289 mdim = (cols > rows) ? cols : rows;
00290 xs = 0.5 * (x + 1.0) * mdim - 0.5;
00291 ys = 0.5 * (y + 1.0) * mdim - 0.5;
00292 if (schema == INTERP_NEAREST_NEIGHBOR)
00293 return nearest_val (img->data, cols, rows, xs, ys);
00294 else if (schema == INTERP_BILINEAR)
00295 return linint2 (img->data, cols, rows, xs, ys);
00296 else return ccint2 (img->data, cols, rows, xs, ys);
00297 }
00298
00299 float array_imaginterp_error (DRMS_Array_t *img, double x, double y,
00300 int schema) {
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 double xs, ys;
00327 int cols, rows, mdim;
00328
00329 cols = img->axis[0];
00330 rows = img->axis[1];
00331 mdim = (cols > rows) ? cols : rows;
00332 xs = 0.5 * (x + 1.0) * mdim - 0.5;
00333 ys = 0.5 * (y + 1.0) * mdim - 0.5;
00334 if (schema == INTERP_NEAREST_NEIGHBOR)
00335 return nearest_val (img->data, cols, rows, xs, ys);
00336 else if (schema == INTERP_BILINEAR)
00337 return linint2_error (img->data, cols, rows, xs, ys);
00338 else return ccint2_error (img->data, cols, rows, xs, ys);
00339 }
00340
00341 void perform_mapping (DRMS_Array_t *img, float *map,
00342 double *maplat, double *maplon, double *map_coslat, double *map_sinlat,
00343 int pixct, unsigned char *offsun, double latc, double lonc,
00344 double xc, double yc, double radius, double pa, double ellipse_e,
00345 double ellipse_pa, int x_invrt, int y_invrt, int interpolator,
00346 int MDI_correct_distort) {
00347
00348
00349
00350
00351
00352 static double sin_asd = 0.004660, cos_asd = 0.99998914;
00353
00354 double r, cos_cang, xr, yr;
00355 double cos_lat, sin_lat, lon, cos_lat_lon;
00356 double xx, yy;
00357 float interpval;
00358 int n;
00359
00360 double cos_pa = cos (pa);
00361 double sin_pa = sin (pa);
00362 double cos_latc = cos (latc);
00363 double sin_latc = sin (latc);
00364 int plate_cols = img->axis[0];
00365 int plate_rows = img->axis[1];
00366 double plate_width = (plate_cols > plate_rows) ? plate_cols : plate_rows;
00367
00368 xc *= 2.0 / plate_width;
00369 yc *= 2.0 / plate_width;
00370 radius *= 2.0 / plate_width;
00371
00372 for (n = 0; n < pixct; n++) {
00373
00374 if (offsun[n]) {
00375 map[n] = missing_val;
00376 continue;
00377 }
00378 sin_lat = map_sinlat[n];
00379 cos_lat = map_coslat[n];
00380 lon = maplon[n];
00381 cos_lat_lon = cos_lat * cos (lon - lonc);
00382 cos_cang = sin_lat * sin_latc + cos_latc * cos_lat_lon;
00383 if (cos_cang < 0.0) {
00384 map[n] = missing_val;
00385 continue;
00386 }
00387 r = radius * cos_asd / (1.0 - cos_cang * sin_asd);
00388 xr = r * cos_lat * sin (lon - lonc);
00389 yr = r * (sin_lat * cos_latc - sin_latc * cos_lat_lon);
00390 xx = xr * cos_pa - yr * sin_pa;
00391 yy = xr * sin_pa + yr * cos_pa;
00392 yy += yc;
00393 xx += xc;
00394
00395 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00396 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00397 interpval = array_imaginterp (img, xx, yy, interpolator);
00398
00399
00400 if (MDI_correct_distort) {
00401 mtrack_MDI_image_tip (&xx, &yy, 1, 1);
00402 mtrack_MDI_image_stretch (&xx, &yy, 1, 1);
00403 }
00404 map[n] = (isnan (interpval)) ? missing_val : interpval;
00405 }
00406 }
00407
00408 void perform_mapping_error (DRMS_Array_t *img, float *map,
00409 double *maplat, double *maplon, double *map_coslat, double *map_sinlat,
00410 int pixct, unsigned char *offsun, double latc, double lonc,
00411 double xc, double yc, double radius, double pa, double ellipse_e,
00412 double ellipse_pa, int x_invrt, int y_invrt, int interpolator,
00413 int MDI_correct_distort) {
00414
00415
00416
00417
00418
00419 static double sin_asd = 0.004660, cos_asd = 0.99998914;
00420
00421 double r, cos_cang, xr, yr;
00422 double cos_lat, sin_lat, lon, cos_lat_lon;
00423 double xx, yy;
00424 float interpval;
00425 int n;
00426
00427 double cos_pa = cos (pa);
00428 double sin_pa = sin (pa);
00429 double cos_latc = cos (latc);
00430 double sin_latc = sin (latc);
00431 int plate_cols = img->axis[0];
00432 int plate_rows = img->axis[1];
00433 double plate_width = (plate_cols > plate_rows) ? plate_cols : plate_rows;
00434
00435 xc *= 2.0 / plate_width;
00436 yc *= 2.0 / plate_width;
00437 radius *= 2.0 / plate_width;
00438
00439 for (n = 0; n < pixct; n++) {
00440
00441 if (offsun[n]) {
00442 map[n] = missing_val;
00443 continue;
00444 }
00445 sin_lat = map_sinlat[n];
00446 cos_lat = map_coslat[n];
00447 lon = maplon[n];
00448 cos_lat_lon = cos_lat * cos (lon - lonc);
00449 cos_cang = sin_lat * sin_latc + cos_latc * cos_lat_lon;
00450 if (cos_cang < 0.0) {
00451 map[n] = missing_val;
00452 continue;
00453 }
00454 r = radius * cos_asd / (1.0 - cos_cang * sin_asd);
00455 xr = r * cos_lat * sin (lon - lonc);
00456 yr = r * (sin_lat * cos_latc - sin_latc * cos_lat_lon);
00457 xx = xr * cos_pa - yr * sin_pa;
00458 yy = xr * sin_pa + yr * cos_pa;
00459 yy += yc;
00460 xx += xc;
00461
00462 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00463 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00464 interpval = array_imaginterp_error (img, xx, yy, interpolator);
00465
00466
00467 if (MDI_correct_distort) {
00468 mtrack_MDI_image_tip (&xx, &yy, 1, 1);
00469 mtrack_MDI_image_stretch (&xx, &yy, 1, 1);
00470 }
00471 map[n] = (isnan (interpval)) ? missing_val : interpval;
00472 }
00473 }
00474
00475 int near_grid_line (double lon, double lat, double grid, double near) {
00476
00477
00478
00479
00480 static double degrad = 180.0 / M_PI;
00481 double g2 = 0.5 * grid;
00482
00483 lon *= degrad;
00484 lat *= degrad;
00485
00486 while (lon < 0.0) lon += grid;
00487 while (lon > g2) lon -= grid;
00488 if (fabs (lon) < near) return 1;
00489 while (lat < 0.0) lat += grid;
00490 while (lat > g2) lat -= grid;
00491 if (fabs (lat) < near) return 1;
00492 return 0;
00493 }
00494
00495
00496
00497 void do_boxcar(float *image_in, float *image_out, int in_nx, int in_ny, float fscale, int power)
00498 {
00499 int iscale, nvector, vec_half;
00500 int inx, iny, outx, outy, i, j;
00501 float val;
00502
00503 iscale = 1.0/fscale + 0.5;
00504 nvector = iscale;
00505 vec_half = nvector/2;
00506
00507 int in_go = (iscale-1)/2.0 + 0.5;
00508 int out_nx = in_nx * fscale + 0.5;
00509 int out_ny = in_ny * fscale + 0.5;
00510
00511 for (outy = 0; outy < out_ny; outy += 1)
00512 for (outx = 0; outx < out_nx; outx += 1)
00513 {
00514 double total = 0.0;
00515 double weight = 0.0;
00516 int nn = 0;
00517 for (j = 0; j < nvector; j += 1)
00518 {
00519 iny = outy*iscale + in_go + j - vec_half;
00520 for (i = 0; i < nvector; i += 1)
00521 {
00522 inx = outx*iscale + in_go + i - vec_half;
00523 if (inx >= 0 && inx < in_nx && iny >=0 && iny < in_ny)
00524 {
00525 val = image_in[in_nx*(iny) + inx];
00526 if (!drms_ismissing_float(val))
00527 {
00528 double w = 1.0;
00529 total += pow(w*val, power);
00530 weight += w;
00531 nn++;
00532 }
00533 }
00534 }
00535 }
00536 if (power == 2) total = sqrt(total);
00537 image_out[out_nx*outy + outx] = (nn > 0 ? total/weight : DRMS_MISSING_FLOAT);
00538 }
00539
00540 }
00541
00542
00543
00544
00545 int DoIt (void) {
00546 CmdParams_t *params = &cmdparams;
00547 DRMS_RecordSet_t *ids, *ods;
00548 double *maplat, *maplon, *map_coslat, *map_sinlat;
00549 double x, y, x0, y0, xstp, ystp, xrot, yrot;
00550 double lat, lon, cos_phi, sin_phi;
00551 double img_lat, img_lon;
00552 double img_xscl, img_yscl, img_xc, img_yc, img_radius, img_pa;
00553 double grid_width;
00554 double ellipse_e, ellipse_pa;
00555 int axes[2], outaxes[2];
00556 int img, imgct, pixct, segct;
00557 int isegnum, osegnum;
00558 int found, kstat, status;
00559 int need_ephem;
00560 int x_invrt, y_invrt;
00561 int n, col, row;
00562 int MDI_correct, MDI_correct_distort;
00563 unsigned char *offsun, *ongrid;
00564 char *input, *isegname, *osegname;
00565 char source[DRMS_MAXQUERYLEN], recid[DRMS_MAXQUERYLEN];
00566 char module_ident[64], key[64], tbuf[64];
00567
00568 double raddeg = M_PI / 180.0;
00569 double degrad = 1.0 / raddeg;
00570 int scaling_override = 0;
00571 char *mapname[] = {"PlateCarree", "Cassini-Soldner", "Mercator",
00572 "LambertCylindrical", "Sanson-Flamsteed", "gnomonic", "Postel",
00573 "stereographic", "orthographic", "LambertAzimuthal"};
00574 char *interpname[] = {"Cubic Convolution", "Nearest Neighbor", "Bilinear"};
00575 char *wcscode[] = {"CAR", "CAS", "MER", "CEA", "GLS", "TAN", "ARC", "STG",
00576 "SIN", "ZEA"};
00577 missing_val = 0.0 / 0.0;
00578 float bblank = -1.0 / 0.0;
00579 float wblank = 1.0 / 0.0;
00580
00581 char *inset = strdup (params_get_str (params, "in"));
00582 char *outser = strdup (params_get_str (params, "out"));
00583 double clat = params_get_double (params, "clat") * raddeg;
00584 double clon = params_get_double (params, "clon") * raddeg;
00585 double map_scale = params_get_double (params, "scale");
00586 double map_pa = params_get_double (params, "map_pa") * raddeg;
00587 float bscale = params_get_float (params, "bscale");
00588 float bzero = params_get_float (params, "bzero");
00589 float grid_spacing = params_get_float (params, "grid");
00590 float rescale = params_get_float (params, "RESCALE");
00591 int map_cols = params_get_int (params, "cols");
00592 int map_rows = params_get_int (params, "rows");
00593 int proj = params_get_int (params, "map");
00594 int intrpopt = params_get_int (params, "interp");
00595 char *clon_key = strdup (params_get_str (params, "clon_key"));
00596 char *clat_key = strdup (params_get_str (params, "clat_key"));
00597 char *rsun_key = strdup (params_get_str (params, "rsun_key"));
00598 char *apsd_key = strdup (params_get_str (params, "apsd_key"));
00599 char *dsun_key = strdup (params_get_str (params, "dsun_key"));
00600 int center = params_isflagset (params, "c");
00601 int stonyhurst = params_isflagset (params, "s");
00602 int verbose = params_isflagset (params, "v");
00603 int overlay = (isfinite (grid_spacing));
00604 int MDI_proc = params_isflagset (params, "M");
00605
00606 TIME trec, tnow, UNIX_epoch = -220924792.000;
00607
00608
00609 double vrcenter;
00610 float xcen, ycen, rsun;
00611 int sunSize, vrcent;
00612 char *tobsstring, ttemp[64], tstr[64];
00613 int maskid;
00614 int xMask = 4096, yMask = 4096;
00615
00616
00617 snprintf (module_ident, 64, "%s v %s", module_name, version_id);
00618 if (verbose) printf ("%s: JSOC version %s\n", module_ident, jsoc_version);
00619
00620 if (map_cols < 1) map_cols = map_rows;
00621 if (map_rows < 1) map_rows = map_cols;
00622 if (map_rows < 1) {
00623 fprintf (stderr, "Error: at least one of \"cols\" or \"rows\" must be set\n");
00624 return 1;
00625 }
00626 if (isnan (map_scale) || map_scale == 0.0) {
00627 fprintf (stderr,
00628 "Error: auto scaling from image resolution not implemented;\n");
00629 fprintf (stderr, " scale parameter must be set.\n");
00630 return 1;
00631 }
00632 MDI_correct = MDI_correct_distort = MDI_proc;
00633 cos_phi = cos (map_pa);
00634 sin_phi = sin (map_pa);
00635 xstp = ystp = map_scale * raddeg;
00636 x0 = 0.5 * (1.0 - map_cols) * xstp;
00637 y0 = 0.5 * (1.0 - map_rows) * ystp;
00638 grid_width = 0.01 * grid_spacing;
00639
00640 if (!(ids = drms_open_records (drms_env, inset, &status))) {
00641 fprintf (stderr, "Error: (%s) unable to open input data set \"%s\"\n",
00642 module_ident, inset);
00643 fprintf (stderr, " status = %d\n", status);
00644 return 1;
00645 }
00646 if ((imgct = ids->n) < 1) {
00647 fprintf (stderr, "Error: (%s) no records in selected input set\n",
00648 module_ident);
00649 fprintf (stderr, " %s\n", inset);
00650 drms_close_records (ids, DRMS_FREE_RECORD);
00651 return 1;
00652 }
00653 input = strdup (inset);
00654
00655 if (!(ods = drms_create_records (drms_env, imgct, outser, DRMS_PERMANENT,
00656 &status))) {
00657 fprintf (stderr, "Error: unable to create %d records in series %s\n",
00658 imgct, outser);
00659 fprintf (stderr, " drms_create_records() returned status %d\n",
00660 status);
00661 return 1;
00662 }
00663
00664
00665
00666 axes[0] = map_cols;
00667 axes[1] = map_rows;
00668 outaxes[0] = map_cols * rescale + 0.5;
00669 outaxes[1] = map_rows * rescale + 0.5;
00670
00671 pixct = map_cols * map_rows;
00672 maplat = (double *)malloc (pixct * sizeof (double));
00673 maplon = (double *)malloc (pixct * sizeof (double));
00674 map_coslat = (double *)malloc (pixct * sizeof (double));
00675 map_sinlat = (double *)malloc (pixct * sizeof (double));
00676 offsun = (unsigned char *)malloc (pixct * sizeof (char));
00677 if (overlay) ongrid = (unsigned char *)malloc (pixct * sizeof (char));
00678
00679
00680
00681 for (img = 0; img < imgct; img++) {
00682
00683 DRMS_Record_t *irec, *orec;
00684 DRMS_Segment_t *iseg, *oseg;
00685 DRMS_Array_t *image = NULL, *outimage = NULL, *map = NULL, *outmap = NULL;
00686 float *bTotal, *bIncl, *bAzim, *disamb;
00687 int length[2], outDim[2];
00688 double xcrpix1, ycrpix1, b0, obsl0, p, S, rsunobs, imagescale, rsun, dsunobs;
00689 int xDim, yDim, iData, ix, jy, yOff;
00690 float *data, *outdata;
00691
00692
00693 double dSun, rSun_ref, asd, rSun;
00694 float *mask;
00695 float cdelt;
00696 mask = (float *)malloc(xMask * yMask * sizeof(float));
00697
00698
00699 irec = ids->records[img];
00700 drms_sprint_rec_query (source, irec);
00701 iseg = drms_segment_lookup(irec, "inclination");
00702 image = drms_segment_read (iseg, DRMS_TYPE_FLOAT, &status);
00703
00704
00705 img_lon = drms_getkey_double (irec, clon_key, &status);
00706 img_lat = drms_getkey_double (irec, clat_key, &status);
00707
00708 status = synop_solar_image_info (irec, &img_xscl, &img_yscl, &img_xc, &img_yc,
00709 &img_radius, rsun_key, apsd_key, &img_pa, &ellipse_e, &ellipse_pa,
00710 &x_invrt, &y_invrt, &need_ephem, 0);
00711 if (status & NO_SEMIDIAMETER) {
00712 int keystat = 0;
00713 double dsun_obs = drms_getkey_double (irec, dsun_key, &keystat);
00714 if (keystat) {
00715 fprintf (stderr, "Error: one or more essential keywords or values missing; skipped\n");
00716 fprintf (stderr, "solar_image_info() returned %08x\n", status);
00717 continue;
00718 }
00719
00720 img_radius = asin (RSUNM / dsun_obs);
00721 img_radius *= 3600.0 * degrad;
00722 img_radius /= (img_xscl <= img_yscl) ? img_xscl : img_yscl;
00723 status &= ~NO_SEMIDIAMETER;
00724 }
00725 if (status == KEYSCOPE_VARIABLE) {
00726 fprintf (stderr, "Warning: one or more keywords expected constant are variable\n");
00727 } else if (status) {
00728 fprintf (stderr, "Error: one or more essential keywords or values missing; skipped\n");
00729 fprintf (stderr, "solar_image_info() returned %08x\n", status);
00730 continue;
00731 }
00732 if (MDI_correct) {
00733 mtrack_MDI_correct_imgctr (&img_xc, &img_yc, img_radius);
00734 mtrack_MDI_correct_pa (&img_pa);
00735 }
00736
00737 img_xc -= 0.5 * (image->axis[0] - 1);
00738 img_yc -= 0.5 * (image->axis[1] - 1);
00739
00740 img_lon = 0.2 * round(10.0 * img_lon/2.0);
00741 printf("lon=%f\n", img_lon);
00742 img_lon *= raddeg; clon = img_lon;
00743 img_lat *= raddeg;
00744
00745 bIncl = (float *)image->data;
00746
00747 iseg = drms_segment_lookup(irec, "field");
00748 image = drms_segment_read (iseg, DRMS_TYPE_FLOAT, &status);
00749
00750
00751 bTotal = (float *)image->data;
00752
00753 iseg = drms_segment_lookup(irec, "azimuth");
00754 image = drms_segment_read (iseg, DRMS_TYPE_FLOAT, &status);
00755
00756
00757 bAzim = (float *)image->data;
00758
00759 iseg = drms_segment_lookup(irec, "disambig");
00760 image = drms_segment_read (iseg, DRMS_TYPE_FLOAT, &status);
00761
00762
00763 disamb = (float *)image->data;
00764
00765
00766
00767 for (n=0, row=0, y=y0; row < map_rows; row++, y += ystp) {
00768 for (col=0, x=x0; col < map_cols; col++, x += xstp, n++) {
00769 xrot = x * cos_phi - y * sin_phi;
00770 yrot = y * cos_phi + x * sin_phi;
00771 offsun[n] = synop_plane2sphere (xrot, yrot, clat, clon, &lat, &lon, proj);
00772 maplat[n] = lat;
00773 maplon[n] = lon;
00774 map_coslat[n] = cos (lat);
00775 map_sinlat[n] = sin (lat);
00776 if (overlay) ongrid[n] =
00777 near_grid_line (maplon[n], maplat[n], grid_spacing, grid_width);
00778 }
00779 }
00780
00781
00782
00783
00784
00785 vrcenter = drms_getkey_double(irec, "OBS_VR", &status);
00786 dSun = drms_getkey_double(irec, "DSUN_OBS", &status);
00787 rSun_ref = drms_getkey_double(irec, "RSUN_REF", &status);
00788 if (status) rSun_ref = 6.96e8;
00789 cdelt = drms_getkey_float(irec, "CDELT1", &status);
00790 asd = asin(rSun_ref/dSun);
00791 rSun = asin(rSun_ref / dSun) * RAD2ARCSEC / cdelt;
00792 xcen = drms_getkey_float(irec, "CRPIX1", &status) - 1.0;
00793 ycen = drms_getkey_float(irec, "CRPIX2", &status) - 1.0;
00794 tobsstring = drms_getkey_string(irec, "INVPHMAP", &status);
00795 trec = drms_getkey_time(irec, "T_REC", &status);
00796 strcpy(ttemp, tobsstring);
00797 maskid = obstime2maskid(trec);
00798
00799 printf("vrcenter=%f, rSun=%f, xcen=%f, ycen=%f, INVPHMAP=%s\n", vrcenter, rSun, xcen, ycen, ttemp);
00800 noisemaskimag4twindow(xMask, yMask, xcen, ycen, rSun, vrcenter, maskid, mask);
00801
00802
00803
00804
00805
00806 xcrpix1 = drms_getkey_double(irec, "CRPIX1", &status) - 1.0;
00807 ycrpix1 = drms_getkey_double(irec, "CRPIX2", &status) - 1.0;
00808 b0 = drms_getkey_double(irec, "CRLT_OBS", &status);
00809 obsl0 = drms_getkey_double(irec, "CRLN_OBS", &status);
00810 p = drms_getkey_double(irec, "CROTA2", &status);
00811 rsunobs = drms_getkey_double(irec, "RSUN_OBS", &status);
00812 imagescale = drms_getkey_double(irec, "CDELT1", &status);
00813 dsunobs = drms_getkey_double(irec, "DSUN_OBS", &status);
00814 rsun = rsunobs/imagescale;
00815 S = RSUNM / dsunobs;
00816
00817 xDim = image->axis[0];
00818 yDim = image->axis[1];
00819 double bxHel, byHel, bzHel;
00820 float *bRadial, *bTheta, *bPhi;
00821 bRadial = (float *)malloc(xDim * yDim * sizeof(float));
00822 bTheta = (float *)malloc(xDim * yDim * sizeof(float));
00823 bPhi = (float *)malloc(xDim * yDim * sizeof(float));
00824
00825 double vxx, vyy, vlon, vlat, vcoslat, vsinlat;
00826 double vmu, vrho, vsig, vchi;
00827 jy = 0; iData = 0; yOff = 0;
00828 for (jy = 0; jy < yDim; jy++)
00829 {
00830 ix = 0;
00831 vyy = (double)jy - ycrpix1;
00832 vyy /= img_radius;
00833 yOff = jy * xDim;
00834
00835 for (ix = 0; ix < xDim; ix++)
00836 {
00837 iData = yOff + ix;
00838 vxx = (double)ix - xcrpix1;
00839 vxx /= img_radius;
00840 if (isnan(bTotal[iData]) || isnan(bAzim[iData]) || isnan(bIncl[iData]))
00841 {
00842 bRadial[iData] = DRMS_MISSING_FLOAT;
00843 bTheta[iData] = DRMS_MISSING_FLOAT;
00844 bPhi[iData] = DRMS_MISSING_FLOAT;
00845 continue;
00846 }
00847
00848 synop_img2sphere (vxx, vyy, asin(S), b0 * RADSINDEG, obsl0 * RADSINDEG, p * RADSINDEG, &vrho, &vlat, &vlon,
00849 &vsinlat, &vcoslat, &vsig, &vmu, &vchi);
00850
00851 double bx = 0.0, by = 0.0, bz = 0.0;
00852
00853 if ((int)(disamb[iData]/2)%2 == 1) bAzim[iData] += 180.0;
00854
00855 bx = -bTotal[iData] * sin(bIncl[iData] * RADSINDEG)
00856 * sin(bAzim[iData] * RADSINDEG);
00857 by = bTotal[iData] * sin(bIncl[iData] * RADSINDEG)
00858 * cos(bAzim[iData] * RADSINDEG);
00859 bz = bTotal[iData] * cos(bIncl[iData] * RADSINDEG);
00860
00861
00862
00863
00864 img2helioVector (bx, by, bz, &bxHel, &byHel, &bzHel, vlon, vlat, obsl0 * RADSINDEG, b0 * RADSINDEG, p * RADSINDEG);
00865 bPhi[iData] = bxHel;
00866 bTheta[iData] = -byHel;
00867 bRadial[iData] = bzHel;
00868 }
00869 }
00870
00871
00872
00873
00874 orec = ods->records[img];
00875 map = drms_array_create (DRMS_TYPE_FLOAT, 2, axes, NULL, &status);
00876 data = (float *)map->data;
00877
00878 outmap = drms_array_create (DRMS_TYPE_FLOAT, 2, outaxes, NULL, &status);
00879 outdata = (float *)outmap->data;
00880
00881 oseg = drms_segment_lookup(orec, "Br");
00882 length[0] = xDim; length[1] = yDim;
00883 outimage = drms_array_create(DRMS_TYPE_FLOAT, 2, length, NULL, &status);
00884
00885 outimage = drms_array_create(DRMS_TYPE_FLOAT, 2, length, bRadial, &status);
00886
00887 perform_mapping (outimage, data, maplat, maplon, map_coslat, map_sinlat,
00888 pixct, offsun, img_lat, img_lon, img_xc, img_yc, img_radius, img_pa,
00889 ellipse_e, ellipse_pa, x_invrt, y_invrt, intrpopt, MDI_correct_distort);
00890 if (overlay) {
00891 for (n = 0; n < pixct; n++)
00892 if (ongrid[n]) data[n] = (isfinite (data[n])) ? bblank : wblank;
00893 }
00894
00895 do_boxcar(data, outdata, axes[0], axes[1], rescale, 1);
00896
00897 outmap->israw = 0;
00898 outmap->bzero = oseg->bzero;
00899 outmap->bscale = oseg->bscale;
00900
00901 status = drms_segment_write (oseg, outmap, 0);
00902 if (status) {
00903 drms_sprint_rec_query (recid, orec);
00904 fprintf (stderr, "Error writing data to record %s\n", recid);
00905 fprintf (stderr, " series may not have appropriate structure\n");
00906 return 1;
00907 }
00908
00909 double statMin, statMax, statMedn, statMean, statSig, statSkew, statKurt;
00910 int statNgood, ipixels;
00911 if (fstats(outaxes[0] * outaxes[1], outdata, &statMin, &statMax, &statMedn, &statMean, &statSig,
00912 &statSkew, &statKurt, &statNgood)) printf("\n Statistics computation failed\n");
00913
00914 ipixels = outaxes[0] * outaxes[1];
00915 drms_setkey_int(orec, "TOTVALS_1", ipixels);
00916 drms_setkey_int(orec, "DATAVALS_1", statNgood);
00917 ipixels = outaxes[0] * outaxes[1]-statNgood;
00918 drms_setkey_int(orec, "MISSVALS_1", ipixels);
00919 drms_setkey_double(orec, "DATAMIN_1", statMin);
00920 drms_setkey_double(orec, "DATAMAX_1", statMax);
00921 drms_setkey_double(orec, "DATAMEDN_1", statMedn);
00922 drms_setkey_double(orec, "DATAMEAN_1", statMean);
00923 drms_setkey_double(orec, "DATARMS_1", statSig);
00924 drms_setkey_double(orec, "DATASKEW_1", statSkew);
00925 drms_setkey_double(orec, "DATAKURT_1", statKurt);
00926 drms_free_array(outimage);
00927
00928 oseg = drms_segment_lookup(orec, "Bt");
00929 outimage = drms_array_create(DRMS_TYPE_FLOAT, 2, length, bTheta, &status);
00930
00931
00932 perform_mapping (outimage, data, maplat, maplon, map_coslat, map_sinlat,
00933 pixct, offsun, img_lat, img_lon, img_xc, img_yc, img_radius, img_pa,
00934 ellipse_e, ellipse_pa, x_invrt, y_invrt, intrpopt, MDI_correct_distort);
00935 if (overlay) {
00936 for (n = 0; n < pixct; n++)
00937 if (ongrid[n]) data[n] = (isfinite (data[n])) ? bblank : wblank;
00938 }
00939
00940 do_boxcar(data, outdata, axes[0], axes[1], rescale, 1);
00941
00942 outmap->israw = 0;
00943 outmap->bzero = oseg->bzero;
00944 outmap->bscale = oseg->bscale;
00945
00946 status = drms_segment_write (oseg, outmap, 0);
00947 if (status) {
00948 drms_sprint_rec_query (recid, orec);
00949 fprintf (stderr, "Error writing data to record %s\n", recid);
00950 fprintf (stderr, " series may not have appropriate structure\n");
00951 return 1;
00952 }
00953
00954 if (fstats(outaxes[0] * outaxes[1], outdata, &statMin, &statMax, &statMedn, &statMean, &statSig,
00955 &statSkew, &statKurt, &statNgood)) printf("\n Statistics computation failed\n");
00956
00957 ipixels = outaxes[0] * outaxes[1];
00958 drms_setkey_int(orec, "TOTVALS_2", ipixels);
00959 drms_setkey_int(orec, "DATAVALS_2", statNgood);
00960 ipixels = outaxes[0] * outaxes[1]-statNgood;
00961 drms_setkey_int(orec, "MISSVALS_2", ipixels);
00962 drms_setkey_double(orec, "DATAMIN_2", statMin);
00963 drms_setkey_double(orec, "DATAMAX_2", statMax);
00964 drms_setkey_double(orec, "DATAMEDN_2", statMedn);
00965 drms_setkey_double(orec, "DATAMEAN_2", statMean);
00966 drms_setkey_double(orec, "DATARMS_2", statSig);
00967 drms_setkey_double(orec, "DATASKEW_2", statSkew);
00968 drms_setkey_double(orec, "DATAKURT_2", statKurt);
00969 drms_free_array(outimage);
00970
00971 oseg = drms_segment_lookup(orec, "Bp");
00972 outimage = drms_array_create(DRMS_TYPE_FLOAT, 2, length, bPhi, &status);
00973
00974 perform_mapping (outimage, data, maplat, maplon, map_coslat, map_sinlat,
00975 pixct, offsun, img_lat, img_lon, img_xc, img_yc, img_radius, img_pa,
00976 ellipse_e, ellipse_pa, x_invrt, y_invrt, intrpopt, MDI_correct_distort);
00977 if (overlay) {
00978 for (n = 0; n < pixct; n++)
00979 if (ongrid[n]) data[n] = (isfinite (data[n])) ? bblank : wblank;
00980 }
00981
00982 do_boxcar(data, outdata, axes[0], axes[1], rescale, 1);
00983
00984 outmap->israw = 0;
00985 outmap->bzero = oseg->bzero;
00986 outmap->bscale = oseg->bscale;
00987
00988 status = drms_segment_write (oseg, outmap, 0);
00989 if (status) {
00990 drms_sprint_rec_query (recid, orec);
00991 fprintf (stderr, "Error writing data to record %s\n", recid);
00992 fprintf (stderr, " series may not have appropriate structure\n");
00993 return 1;
00994 }
00995
00996 if (fstats(outaxes[0] * outaxes[1], outdata, &statMin, &statMax, &statMedn, &statMean, &statSig,
00997 &statSkew, &statKurt, &statNgood)) printf("\n Statistics computation failed\n");
00998
00999 ipixels = outaxes[0] * outaxes[1];
01000 drms_setkey_int(orec, "TOTVALS_3", ipixels);
01001 drms_setkey_int(orec, "DATAVALS_3", statNgood);
01002 ipixels = outaxes[0] * outaxes[1]-statNgood;
01003 drms_setkey_int(orec, "MISSVALS_3", ipixels);
01004 drms_setkey_double(orec, "DATAMIN_3", statMin);
01005 drms_setkey_double(orec, "DATAMAX_3", statMax);
01006 drms_setkey_double(orec, "DATAMEDN_3", statMedn);
01007 drms_setkey_double(orec, "DATAMEAN_3", statMean);
01008 drms_setkey_double(orec, "DATARMS_3", statSig);
01009 drms_setkey_double(orec, "DATASKEW_3", statSkew);
01010 drms_setkey_double(orec, "DATAKURT_3", statKurt);
01011 drms_free_array(outimage);
01012
01013
01014 oseg = drms_segment_lookup(orec, "B_error");
01015 outimage = drms_array_create(DRMS_TYPE_FLOAT, 2, length, mask, &status);
01016
01017
01018 perform_mapping (outimage, data, maplat, maplon, map_coslat, map_sinlat,
01019 pixct, offsun, img_lat, img_lon, img_xc, img_yc, img_radius, img_pa,
01020 ellipse_e, ellipse_pa, x_invrt, y_invrt, intrpopt, MDI_correct_distort);
01021 if (overlay) {
01022 for (n = 0; n < pixct; n++)
01023 if (ongrid[n]) data[n] = (isfinite (data[n])) ? bblank : wblank;
01024 }
01025
01026 do_boxcar(data, outdata, axes[0], axes[1], rescale, 2);
01027
01028 outmap->israw = 0;
01029 outmap->bzero = oseg->bzero;
01030 outmap->bscale = oseg->bscale;
01031
01032 status = drms_segment_write (oseg, outmap, 0);
01033 if (status) {
01034 drms_sprint_rec_query (recid, orec);
01035 fprintf (stderr, "Error writing data to record %s\n", recid);
01036 fprintf (stderr, " series may not have appropriate structure\n");
01037 return 1;
01038 }
01039
01040 if (fstats(outaxes[0] * outaxes[1], outdata, &statMin, &statMax, &statMedn, &statMean, &statSig,
01041 &statSkew, &statKurt, &statNgood)) printf("\n Statistics computation failed\n");
01042
01043 ipixels = outaxes[0] * outaxes[1];
01044 drms_setkey_int(orec, "TOTVALS_4", ipixels);
01045 drms_setkey_int(orec, "DATAVALS_4", statNgood);
01046 ipixels = outaxes[0] * outaxes[1]-statNgood;
01047 drms_setkey_int(orec, "MISSVALS_4", ipixels);
01048 drms_setkey_double(orec, "DATAMIN_4", statMin);
01049 drms_setkey_double(orec, "DATAMAX_4", statMax);
01050 drms_setkey_double(orec, "DATAMEDN_4", statMedn);
01051 drms_setkey_double(orec, "DATAMEAN_4", statMean);
01052 drms_setkey_double(orec, "DATARMS_4", statSig);
01053 drms_setkey_double(orec, "DATASKEW_4", statSkew);
01054 drms_setkey_double(orec, "DATAKURT_4", statKurt);
01055 drms_free_array(outimage);
01056
01057
01058
01059 drms_copykey(orec, irec, "T_REC");
01060 drms_copykey(orec, irec, "T_OBS");
01061 drms_copykey(orec, irec, "CADENCE");
01062 drms_copykey(orec, irec, "DATASIGN");
01063 drms_copykey(orec, irec, "OBS_VR");
01064 drms_copykey(orec, irec, "OBS_VW");
01065 drms_copykey(orec, irec, "OBS_VN");
01066 drms_copykey(orec, irec, "DATE__OBS");
01067 drms_copykey(orec, irec, "QUALITY");
01068 drms_copykey(orec, irec, "CAMERA");
01069 drms_copykey(orec, irec, "CRLN_OBS");
01070 drms_copykey(orec, irec, "CRLT_OBS");
01071 drms_copykey(orec, irec, "CAR_ROT");
01072 drms_copykey(orec, irec, "DSUN_OBS");
01073
01074 kstat = 0;
01075 kstat += check_and_set_key_str (orec, "WCSNAME", "Carrington Heliographic");
01076 kstat += check_and_set_key_int (orec, "WCSAXES", 2);
01077 snprintf (key, 64, "CRLN-%s", wcscode[proj]);
01078 kstat += check_and_set_key_str (orec, "CTYPE1", key);
01079 snprintf (key, 64, "CRLT-%s", wcscode[proj]);
01080 kstat += check_and_set_key_str (orec, "CTYPE2", key);
01081 kstat += check_and_set_key_str (orec, "CUNIT1", "deg");
01082 kstat += check_and_set_key_str (orec, "CUNIT2", "deg");
01083 kstat += check_and_set_key_float (orec, "CRPIX1", 0.5 * map_cols * rescale + 0.5);
01084 kstat += check_and_set_key_float (orec, "CRPIX2", 0.5 * map_rows * rescale + 0.5);
01085 kstat += check_and_set_key_float (orec, "CRVAL1", clon * degrad);
01086 kstat += check_and_set_key_float (orec, "CRVAL2", clat * degrad);
01087 kstat += check_and_set_key_float (orec, "CDELT1", map_scale/rescale);
01088 kstat += check_and_set_key_float (orec, "CDELT2", map_scale/rescale);
01089 kstat += check_and_set_key_float (orec, "CROTA2", 0.0);
01090 if (map_pa != 0.0) {
01091 kstat += check_and_set_key_float (orec, "PC1_1", cos (map_pa));
01092
01093 kstat += check_and_set_key_float (orec, "PC1_2", sin (map_pa));
01094
01095 kstat += check_and_set_key_float (orec, "PC2_1", sin (map_pa));
01096 kstat += check_and_set_key_float (orec, "PC2_2", cos (map_pa));
01097 }
01098
01099
01100
01101 kstat += check_and_set_key_str (orec, "MapProj", mapname[proj]);
01102 kstat += check_and_set_key_float (orec, "MapScale", map_scale);
01103 kstat += check_and_set_key_float (orec, "Width", map_cols * rescale * map_scale);
01104 kstat += check_and_set_key_float (orec, "Height", map_rows * rescale * map_scale);
01105 kstat += check_and_set_key_float (orec, "Size", sqrt (map_rows * map_cols) * rescale * map_scale);
01106 kstat += check_and_set_key_float (orec, "Map_PA", map_pa / raddeg);
01107 kstat += check_and_set_key_float (orec, "RSunRef", 1.0e-6 * RSUNM);
01108 kstat += check_and_set_key_str (orec, "Interp", interpname[intrpopt]);
01109 kstat += check_and_set_key_str (orec, "Module", module_ident);
01110 kstat += check_and_set_key_str (orec, "BLD_VERS", jsoc_version);
01111
01112 kstat += check_and_set_key_str (orec, "Source", source);
01113 kstat += check_and_set_key_str (orec, "Input", input);
01114
01115 if (kstat) {
01116 fprintf (stderr, "Error writing key value(s) to record %d in series %s\n",
01117 img, outser);
01118 fprintf (stderr, " series may not have appropriate structure\n");
01119 drms_close_records (ods, DRMS_FREE_RECORD);
01120 return 1;
01121 }
01122 tnow = (double)time(NULL);
01123 tnow += UNIX_epoch;
01124 drms_setkey_time(orec, "DATE", tnow);
01125
01126 free(bIncl); free(bTotal); free(bAzim);
01127 drms_free_array(image);
01128 drms_free_array (map);
01129 drms_free_array (outmap);
01130 }
01131 drms_close_records(ids, DRMS_FREE_RECORD);
01132 drms_close_records (ods, DRMS_INSERT_RECORD);
01133 return 0;
01134 }
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156