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
00081
00082
00083
00084
00085
00086
00087 #include <jsoc_main.h>
00088 #include "fstats.h"
00089 #include "cartography.h"
00090 #include "magutils.h"
00091
00092 #define RECTANGULAR (0)
00093 #define CASSINI (1)
00094 #define MERCATOR (2)
00095 #define CYLEQA (3)
00096 #define SINEQA (4)
00097 #define GNOMONIC (5)
00098 #define POSTEL (6)
00099 #define STEREOGRAPHIC (7)
00100 #define ORTHOGRAPHIC (8)
00101 #define LAMBERT (9)
00102
00103 #define RSUNM (6.96e8)
00104 #define INTERP_NEAREST_NEIGHBOR (1)
00105 #define INTERP_BILINEAR (2)
00106
00107
00108
00109 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);
00110
00111
00112 extern int synop_plane2sphere (double x, double y, double latc, double lonc, double *lat, double *lon, int projection);
00113 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);
00114 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);
00115 extern int synop_sphere2plane(double lat, double lon, double latc, double lonc, double *x, double *y, int projection);
00116
00117 void do_boxcar(float *image_in, float *image_out, int in_nx, int in_ny, float fscale, int power);
00118
00119
00120
00121 char *module_name = "maprojlonat02deg";
00122 char *module_desc = "mapping from solar images";
00123 char *version_id = "1.1";
00124
00125 ModuleArgs_t module_args[] = {
00126 {ARG_DATASET, "in", "", "input data set"},
00127 {ARG_DATASERIES, "out", "", "output data series"},
00128 {ARG_DOUBLE, "clat", "Not Specified", "heliographic latitude of map center [deg]"},
00129 {ARG_DOUBLE, "clon", "Not Specified", "Carrington longitude of map center [deg]"},
00130 {ARG_DOUBLE, "scale", "Not specified", "map scale at center [deg/pxl]"},
00131 {ARG_NUME, "map", "orthographic", "map projection",
00132 "carree, Cassini, Mercator, cyleqa, sineqa, gnomonic, Postel, stereographic, orthographic, Lambert"},
00133 {ARG_NUME, "interp", "cubiconv", "interpolation option",
00134 "cubiconv, nearest, bilinear"},
00135 {ARG_FLOAT, "grid", "Not Specified",
00136 "if specified, spacing of grid overlay [deg]"},
00137 {ARG_INT, "cols", "0", "columns in output map"},
00138 {ARG_INT, "rows", "0", "rows in output map"},
00139 {ARG_FLOAT, "map_pa", "0.0", "position angle of north on output map [deg]"},
00140 {ARG_FLOAT, "bscale", "0.0", "output scaling factor"},
00141 {ARG_FLOAT, "bzero", "Default", "output offset"},
00142 {ARG_FLOAT, "RESCALE", "0.1", "Scale factor."},
00143 {ARG_STRING, "clon_key", "CRLN_OBS", "keyname for image central longitude"},
00144 {ARG_STRING, "clat_key", "CRLT_OBS", "keyname for image central latitude"},
00145 {ARG_STRING, "rsun_key", "R_SUN", "keyname for image semi-diameter (pixel)"},
00146 {ARG_STRING, "apsd_key", "RSUN_OBS", "keyname for apparent solar semi-diameter (arcsec)"},
00147 {ARG_STRING, "dsun_key", "DSUN_OBS", "keyname for observer distance"},
00148 {ARG_STRING, "RequestID", "none", "RequestID for jsoc export management"},
00149 {ARG_FLAG, "c", "", "center map at center of image"},
00150 {ARG_FLAG, "s", "", "clon is Stonyhurst longitude"},
00151 {ARG_FLAG, "v", "", "verbose mode"},
00152 {ARG_FLAG, "M", "", "correct for MDI distortion"},
00153 {ARG_FLAG, "R", "",
00154 "convert scalars assuming line-of-sight components of radial vectors"},
00155 {}
00156 };
00157
00158
00159 float missing_val;
00160
00161
00162
00163 void do_boxcar(float *image_in, float *image_out, int in_nx, int in_ny, float fscale, int power)
00164 {
00165 int iscale, nvector, vec_half;
00166 int inx, iny, outx, outy, i, j;
00167 float val;
00168
00169 iscale = 1.0/fscale + 0.5;
00170 nvector = iscale;
00171 vec_half = nvector/2;
00172
00173 int in_go = (iscale-1)/2.0 + 0.5;
00174 int out_nx = in_nx * fscale + 0.5;
00175 int out_ny = in_ny * fscale + 0.5;
00176
00177 for (outy = 0; outy < out_ny; outy += 1)
00178 for (outx = 0; outx < out_nx; outx += 1)
00179 {
00180 double total = 0.0;
00181 double weight = 0.0;
00182 int nn = 0;
00183 for (j = 0; j < nvector; j += 1)
00184 {
00185 iny = outy*iscale + in_go + j - vec_half;
00186 for (i = 0; i < nvector; i += 1)
00187 {
00188 inx = outx*iscale + in_go + i - vec_half;
00189 if (inx >= 0 && inx < in_nx && iny >=0 && iny < in_ny)
00190 {
00191 val = image_in[in_nx*(iny) + inx];
00192 if (!drms_ismissing_float(val))
00193 {
00194 double w = 1.0;
00195 total += pow(w*val, power);
00196 weight += w;
00197 nn++;
00198 }
00199 }
00200 }
00201 }
00202 if (power == 2) total = sqrt(total);
00203 image_out[out_nx*outy + outx] = (nn > 0 ? total/weight : DRMS_MISSING_FLOAT);
00204 }
00205
00206 }
00207
00208
00209
00210
00211
00212 void ccker (double *u, double s) {
00213 double s2, s3;
00214
00215 s2= s * s;
00216 s3= s2 * s;
00217 u[0] = s2 - 0.5 * (s3 + s);
00218 u[1] = 1.5*s3 - 2.5*s2 + 1.0;
00219 u[2] = -1.5*s3 + 2.0*s2 + 0.5*s;
00220 u[3] = 0.5 * (s3 - s2);
00221 }
00222
00223 float ccint2 (float *f, int nx, int ny, double x, double y) {
00224 double ux[4], uy[4];
00225 double sum;
00226 int ix, iy, ix1, iy1, i, j;
00227
00228 if (x < 1.0 || x >= (float)(nx-2) || y < 1.0 || y >= (float)(ny-2))
00229 return missing_val;
00230
00231 ix = (int)x;
00232 ccker (ux, x - (double)ix);
00233 iy = (int)y;
00234 ccker (uy, y - (double)iy);
00235
00236 ix1 = ix - 1;
00237 iy1 = iy - 1;
00238 sum = 0.;
00239 for (i = 0; i < 4; i++)
00240 for (j = 0; j < 4; j++)
00241 sum = sum + f[(iy1+i) * nx + ix1 + j] * uy[i] * ux[j];
00242 return (float)sum;
00243 }
00244
00245 float linint2 (float *f, int cols, int rows, double x, double y) {
00246 double p, q, val;
00247 int col = (int)x, row = (int)y;
00248 int onerow = cols * row;
00249 int colp1 = col + 1, onerowp1 = onerow + cols;
00250
00251 if (x < 0.0 || x > cols || y < 0.0 || y >= rows)
00252 return missing_val;
00253 p = x - col;
00254 q = y - row;
00255 val = (1 - p) * (1 - q) * f[col + onerow]
00256 + p * (1 - q) * f[colp1 + onerow]
00257 + (1 - p) * q * f[col + onerowp1]
00258 + p * q * f[colp1 + onerowp1];
00259 return val;
00260 }
00261
00262 float nearest_val (float *f, int cols, int rows, double x, double y) {
00263 int col, row;
00264 if (x < -0.5 || x >= (cols - 0.5) || y < -0.5 || y >= (rows - 0.5))
00265 return missing_val;
00266 col = x + 0.5;
00267 row = y + 0.5;
00268 return f[col + row * cols];
00269 }
00270
00271 float array_imaginterp (DRMS_Array_t *img, double x, double y,
00272 int schema) {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 double xs, ys;
00298 int cols, rows, mdim;
00299
00300 cols = img->axis[0];
00301 rows = img->axis[1];
00302 mdim = (cols > rows) ? cols : rows;
00303 xs = 0.5 * (x + 1.0) * mdim - 0.5;
00304 ys = 0.5 * (y + 1.0) * mdim - 0.5;
00305 if (schema == INTERP_NEAREST_NEIGHBOR)
00306 return nearest_val (img->data, cols, rows, xs, ys);
00307 else if (schema == INTERP_BILINEAR)
00308 return linint2 (img->data, cols, rows, xs, ys);
00309 else return ccint2 (img->data, cols, rows, xs, ys);
00310 }
00311
00312 void perform_mapping (DRMS_Array_t *img, float *map,
00313 double *maplat, double *maplon, double *map_coslat, double *map_sinlat,
00314 int pixct, unsigned char *offsun, double latc, double lonc,
00315 double xc, double yc, double radius, double pa, double ellipse_e,
00316 double ellipse_pa, int x_invrt, int y_invrt, int interpolator,
00317 int cvlostor, int MDI_correct_distort) {
00318
00319
00320
00321
00322
00323 static double sin_asd = 0.004660, cos_asd = 0.99998914;
00324
00325 double r, cos_cang, xr, yr;
00326 double cos_lat, sin_lat, lon, cos_lat_lon;
00327 double xx, yy;
00328 double cosrho, sinrho;
00329 float interpval;
00330 int n;
00331
00332 double cos_pa = cos (pa);
00333 double sin_pa = sin (pa);
00334 double cos_latc = cos (latc);
00335 double sin_latc = sin (latc);
00336 int plate_cols = img->axis[0];
00337 int plate_rows = img->axis[1];
00338 double plate_width = (plate_cols > plate_rows) ? plate_cols : plate_rows;
00339
00340 xc *= 2.0 / plate_width;
00341 yc *= 2.0 / plate_width;
00342 radius *= 2.0 / plate_width;
00343
00344 for (n = 0; n < pixct; n++) {
00345
00346 if (offsun[n]) {
00347 map[n] = missing_val;
00348 continue;
00349 }
00350 sin_lat = map_sinlat[n];
00351 cos_lat = map_coslat[n];
00352 lon = maplon[n];
00353 cos_lat_lon = cos_lat * cos (lon - lonc);
00354 cos_cang = sin_lat * sin_latc + cos_latc * cos_lat_lon;
00355 if (cos_cang < 0.0) {
00356 map[n] = missing_val;
00357 continue;
00358 }
00359 r = radius * cos_asd / (1.0 - cos_cang * sin_asd);
00360 xr = r * cos_lat * sin (lon - lonc);
00361 yr = r * (sin_lat * cos_latc - sin_latc * cos_lat_lon);
00362 xx = xr * cos_pa - yr * sin_pa;
00363 yy = xr * sin_pa + yr * cos_pa;
00364 yy += yc;
00365 xx += xc;
00366
00367 if (plate_cols > plate_rows) yy -= 1.0 - plate_rows / plate_width;
00368 if (plate_rows > plate_cols) xx -= 1.0 - plate_cols / plate_width;
00369 interpval = array_imaginterp (img, xx, yy, interpolator);
00370 if (cvlostor) {
00371 sinrho = sqrt (xr * xr + yr * yr);
00372 cosrho = sqrt (1.0 - sinrho * sinrho);
00373 interpval /= cosrho;
00374 }
00375
00376
00377 if (MDI_correct_distort) {
00378 mtrack_MDI_image_tip (&xx, &yy, 1, 1);
00379 mtrack_MDI_image_stretch (&xx, &yy, 1, 1);
00380 }
00381 map[n] = (isnan (interpval)) ? missing_val : interpval;
00382 }
00383 }
00384
00385 int near_grid_line (double lon, double lat, double grid, double near) {
00386
00387
00388
00389
00390 static double degrad = 180.0 / M_PI;
00391 double g2 = 0.5 * grid;
00392
00393 lon *= degrad;
00394 lat *= degrad;
00395
00396 while (lon < 0.0) lon += grid;
00397 while (lon > g2) lon -= grid;
00398 if (fabs (lon) < near) return 1;
00399 while (lat < 0.0) lat += grid;
00400 while (lat > g2) lat -= grid;
00401 if (fabs (lat) < near) return 1;
00402 return 0;
00403 }
00404
00405 int DoIt (void) {
00406 CmdParams_t *params = &cmdparams;
00407 DRMS_RecordSet_t *ids, *ods;
00408 DRMS_Record_t *irec, *orec;
00409 DRMS_Segment_t *iseg, *oseg;
00410 DRMS_Array_t *image = NULL, *map = NULL, *outmap = NULL;
00411 double *maplat, *maplon, *map_coslat, *map_sinlat;
00412 double x, y, x0, y0, xstp, ystp, xrot, yrot;
00413 double lat, lon, cos_phi, sin_phi;
00414 double img_lat, img_lon;
00415 double img_xscl, img_yscl, img_xc, img_yc, img_radius, img_pa;
00416 double grid_width;
00417 double ellipse_e, ellipse_pa;
00418 float *data, *outdata;
00419 int axes[2], outaxes[2];
00420 int img, imgct, pixct, segct;
00421 int isegnum, osegnum;
00422 int found, kstat, status;
00423 int need_ephem, need_lat, need_lon;
00424 int x_invrt, y_invrt;
00425 int n, col, row;
00426 int MDI_correct, MDI_correct_distort;
00427 unsigned char *offsun, *ongrid;
00428 char *input, *isegname, *osegname;
00429 char source[DRMS_MAXQUERYLEN], recid[DRMS_MAXQUERYLEN];
00430 char module_ident[64], key[64], tbuf[64];
00431
00432 double raddeg = M_PI / 180.0;
00433 double degrad = 1.0 / raddeg;
00434 char *mapname[] = {"PlateCarree", "Cassini-Soldner", "Mercator",
00435 "LambertCylindrical", "Sanson-Flamsteed", "gnomonic", "Postel",
00436 "stereographic", "orthographic", "LambertAzimuthal"};
00437 char *interpname[] = {"Cubic Convolution", "Nearest Neighbor", "Bilinear"};
00438 char *wcscode[] = {"CAR", "CAS", "MER", "CEA", "GLS", "TAN", "ARC", "STG",
00439 "SIN", "ZEA"};
00440 missing_val = 0.0 / 0.0;
00441 float bblank = -1.0 / 0.0;
00442 float wblank = 1.0 / 0.0;
00443
00444 char *inset = strdup (params_get_str (params, "in"));
00445 char *outser = strdup (params_get_str (params, "out"));
00446 double clat = params_get_double (params, "clat") * raddeg;
00447 double clon = params_get_double (params, "clon") * raddeg;
00448 double map_scale = params_get_double (params, "scale");
00449 double map_pa = params_get_double (params, "map_pa") * raddeg;
00450 float bscale = params_get_float (params, "bscale");
00451 float bzero = params_get_float (params, "bzero");
00452 float grid_spacing = params_get_float (params, "grid");
00453 float rescale = params_get_float (params, "RESCALE");
00454 int map_cols = params_get_int (params, "cols");
00455 int map_rows = params_get_int (params, "rows");
00456 int proj = params_get_int (params, "map");
00457 int intrpopt = params_get_int (params, "interp");
00458 char *clon_key = strdup (params_get_str (params, "clon_key"));
00459 char *clat_key = strdup (params_get_str (params, "clat_key"));
00460 char *rsun_key = strdup (params_get_str (params, "rsun_key"));
00461 char *apsd_key = strdup (params_get_str (params, "apsd_key"));
00462 char *dsun_key = strdup (params_get_str (params, "dsun_key"));
00463 char *RequestID = strdup (params_get_str (params, "RequestID"));
00464 int center = params_isflagset (params, "c");
00465 int stonyhurst = params_isflagset (params, "s");
00466 int verbose = params_isflagset (params, "v");
00467 int overlay = (isfinite (grid_spacing));
00468 int MDI_proc = params_isflagset (params, "M");
00469 int cvlostor = params_isflagset (params, "R");
00470
00471 snprintf (module_ident, 64, "%s v %s", module_name, version_id);
00472 if (verbose) printf ("%s: JSOC version %s\n", module_ident, jsoc_version);
00473
00474 if (map_cols < 1) map_cols = map_rows;
00475 if (map_rows < 1) map_rows = map_cols;
00476 if (map_rows < 1) {
00477 fprintf (stderr, "Error: at least one of \"cols\" or \"rows\" must be set\n");
00478 return 1;
00479 }
00480 if (isnan (map_scale) || map_scale == 0.0) {
00481 fprintf (stderr,
00482 "Error: auto scaling from image resolution not implemented;\n");
00483 fprintf (stderr, " scale parameter must be set.\n");
00484 return 1;
00485 }
00486 need_lat = center || isnan (clat);
00487 need_lon = center || isnan (clon);
00488 MDI_correct = MDI_correct_distort = MDI_proc;
00489 cos_phi = cos (map_pa);
00490 sin_phi = sin (map_pa);
00491 xstp = ystp = map_scale * raddeg;
00492 x0 = 0.5 * (1.0 - map_cols) * xstp;
00493 y0 = 0.5 * (1.0 - map_rows) * ystp;
00494 grid_width = 0.01 * grid_spacing;
00495
00496 if (!(ids = drms_open_records (drms_env, inset, &status))) {
00497 fprintf (stderr, "Error: (%s) unable to open input data set \"%s\"\n",
00498 module_ident, inset);
00499 fprintf (stderr, " status = %d\n", status);
00500 return 1;
00501 }
00502 if ((imgct = ids->n) < 1) {
00503 fprintf (stderr, "Error: (%s) no records in selected input set\n",
00504 module_ident);
00505 fprintf (stderr, " %s\n", inset);
00506 drms_close_records (ids, DRMS_FREE_RECORD);
00507 return 1;
00508 }
00509 input = strdup (inset);
00510
00511 irec = ids->records[0];
00512 segct = drms_record_numsegments (irec);
00513 isegnum = 0;
00514 if (segct) {
00515 found = 0;
00516 for (n = 0; n < segct; n++) {
00517 iseg = drms_segment_lookupnum (irec, n);
00518 if (iseg->info->naxis != 2) continue;
00519 if (!found) {
00520 isegname = strdup (iseg->info->name);
00521 isegnum = n;
00522 }
00523 found++;
00524 }
00525 if (found > 1) {
00526 fprintf (stderr,
00527 "Warning: multiple data segments of dimension 2 in input series %s\n",
00528 input);
00529 fprintf (stderr, " using \"%s\"\n", isegname);
00530 }
00531 iseg = drms_segment_lookupnum (irec, isegnum);
00532 } else {
00533 fprintf (stderr, "Error: no data segments in input series %s\n", input);
00534 drms_close_records (ids, DRMS_FREE_RECORD);
00535 return 1;
00536 }
00537 if (found < 1 || iseg->info->naxis != 2) {
00538 fprintf (stderr,
00539 "Error: no data segment of dimension 2 in input series %s\n", input);
00540 drms_close_records (ids, DRMS_FREE_RECORD);
00541 return 1;
00542 }
00543
00544 if (verbose) printf ("creating %d records in series %s\n", imgct, outser);
00545 if (!(ods = drms_create_records (drms_env, imgct, outser, DRMS_PERMANENT,
00546 &status))) {
00547 fprintf (stderr, "Error: unable to create %d records in series %s\n",
00548 imgct, outser);
00549 fprintf (stderr, " drms_create_records() returned status %d\n",
00550 status);
00551 return 1;
00552 }
00553
00554 orec = ods->records[0];
00555 segct = drms_record_numsegments (orec);
00556 found = 0;
00557 for (n = 0; n < segct; n++) {
00558 oseg = drms_segment_lookupnum (orec, n);
00559 if (oseg->info->naxis != 2) continue;
00560 if (oseg->info->scope == DRMS_CONSTANT) continue;
00561 if (oseg->info->scope == DRMS_VARIABLE) {
00562 if (oseg->axis[0] != map_cols ||
00563 oseg->axis[1] != map_rows) continue;
00564 }
00565 if (!found) {
00566 osegname = strdup (oseg->info->name);
00567 osegnum = n;
00568 }
00569 found++;
00570 }
00571 if (found < 1) {
00572 fprintf (stderr,
00573 "Error: no data segment of dimension 2 and appropriate size in output series %s\n", outser);
00574 drms_close_records (ods, DRMS_FREE_RECORD);
00575 return 1;
00576 }
00577 if (found > 1) {
00578 fprintf (stderr,
00579 "Warning: multiple data segments of dimension 2 and appropriate size in output series %s\n",
00580 outser);
00581 fprintf (stderr, " using \"%s\"\n", osegname);
00582 }
00583
00584 axes[0] = map_cols;
00585 axes[1] = map_rows;
00586 outaxes[0] = map_cols * rescale + 0.5;
00587 outaxes[1] = map_rows * rescale + 0.5;
00588
00589 map = drms_array_create (DRMS_TYPE_FLOAT, 2, axes, NULL, &status);
00590 if (status) {
00591 fprintf (stderr, "Error: couldn't create output array\n");
00592 return 1;
00593 }
00594
00595 outmap = drms_array_create (DRMS_TYPE_FLOAT, 2, outaxes, NULL, &status);
00596
00597
00598 pixct = map_cols * map_rows;
00599 maplat = (double *)malloc (pixct * sizeof (double));
00600 maplon = (double *)malloc (pixct * sizeof (double));
00601 map_coslat = (double *)malloc (pixct * sizeof (double));
00602 map_sinlat = (double *)malloc (pixct * sizeof (double));
00603 offsun = (unsigned char *)malloc (pixct * sizeof (char));
00604 if (overlay) ongrid = (unsigned char *)malloc (pixct * sizeof (char));
00605
00606 if (bscale == 0.0) {
00607 bscale = oseg->bscale;
00608 if (verbose) printf ("bscale set to output default: %g\n", bscale);
00609 }
00610 if (isnan (bzero)) {
00611 bzero = oseg->bzero;
00612 if (verbose) printf ("bzero set to output default: %g\n", bzero);
00613 }
00614 map->bscale = bscale;
00615 map->bzero = bzero;
00616 if (need_lat || need_lon) {
00617 if (need_lon) {
00618 img_lon = drms_getkey_double (irec, clon_key, &status);
00619 if (status || isnan (img_lon)) fprintf (stderr,
00620 "Error: no valid value for key %s in first input record\n", clon_key);
00621 else if (!center) need_lon = 0;
00622 clon = img_lon * raddeg;
00623 }
00624 if (need_lat) {
00625 img_lat = drms_getkey_double (irec, clat_key, &status);
00626 if (status || isnan (img_lat)) fprintf (stderr,
00627 "Error: no valid value for key %s in first input record\n", clat_key);
00628 else if (!center) need_lat = 0;
00629 clat = img_lat * raddeg;
00630 }
00631 if (verbose) printf ("map(s) centred at latitude %+.2f, longitude %.2f\n",
00632 clat / raddeg, clon/raddeg);
00633 }
00634
00635 for (n=0, row=0, y=y0; row < map_rows; row++, y += ystp) {
00636 for (col=0, x=x0; col < map_cols; col++, x += xstp, n++) {
00637 xrot = x * cos_phi - y * sin_phi;
00638 yrot = y * cos_phi + x * sin_phi;
00639 offsun[n] = synop_plane2sphere (xrot, yrot, clat, clon, &lat, &lon, proj);
00640 maplat[n] = lat;
00641 maplon[n] = lon;
00642 map_coslat[n] = cos (lat);
00643 map_sinlat[n] = sin (lat);
00644 if (overlay) ongrid[n] =
00645 near_grid_line (maplon[n], maplat[n], grid_spacing, grid_width);
00646 }
00647 }
00648
00649 data = (float *)map->data;
00650
00651 for (img = 0; img < imgct; img++) {
00652
00653 irec = ids->records[img];
00654 drms_sprint_rec_query (source, irec);
00655 iseg = drms_segment_lookupnum (irec, isegnum);
00656 image = drms_segment_read (iseg, DRMS_TYPE_FLOAT, &status);
00657
00658
00659 img_lon = drms_getkey_double (irec, clon_key, &status);
00660 img_lat = drms_getkey_double (irec, clat_key, &status);
00661
00662
00663
00664
00665 clon = img_lon * raddeg;
00666 if (verbose) printf ("map centred at latitude %+.2f, longitude %.2f\n",
00667 clat / raddeg, clon/raddeg);
00668
00669 for (n=0, row=0, y=y0; row < map_rows; row++, y += ystp) {
00670 for (col=0, x=x0; col < map_cols; col++, x += xstp, n++) {
00671 xrot = x * cos_phi - y * sin_phi;
00672 yrot = y * cos_phi + x * sin_phi;
00673 offsun[n] = synop_plane2sphere (xrot, yrot, clat, clon, &lat, &lon, proj);
00674 maplat[n] = lat;
00675 maplon[n] = lon;
00676 map_coslat[n] = cos (lat);
00677 map_sinlat[n] = sin (lat);
00678 if (overlay) ongrid[n] =
00679 near_grid_line (maplon[n], maplat[n], grid_spacing, grid_width);
00680 }
00681 }
00682
00683
00684 status = synop_solar_image_info (irec, &img_xscl, &img_yscl, &img_xc, &img_yc,
00685 &img_radius, rsun_key, apsd_key, &img_pa, &ellipse_e, &ellipse_pa,
00686 &x_invrt, &y_invrt, &need_ephem, 0);
00687 if (status & NO_SEMIDIAMETER) {
00688 int keystat = 0;
00689 double dsun_obs = drms_getkey_double (irec, dsun_key, &keystat);
00690 if (keystat) {
00691 fprintf (stderr, "Error: one or more essential keywords or values missing; skipped\n");
00692 fprintf (stderr, "solar_image_info() returned %08x :\n", status);
00693 if (status & NO_DATA_DICT)
00694 fprintf (stderr, " internal data dictionary for platform\n");
00695 if (status & NO_SEMIDIAMETER) fprintf (stderr, " semidiameter\n");
00696 if (status & NO_XSCALE) fprintf (stderr, " x-scale\n");
00697 if (status & NO_YSCALE) fprintf (stderr, " y-scale\n");
00698 if (status & NO_XCENTERLOC) fprintf (stderr, " x-center\n");
00699 if (status & NO_YCENTERLOC) fprintf (stderr, " y-center\n");
00700 if (status & NO_HELIO_LATC) fprintf (stderr, " disc-center latitude\n");
00701 if (status & NO_HELIO_LONC) fprintf (stderr, " disc-center longitude\n");
00702 if (status & NO_XUNITS) fprintf (stderr, " x units\n");
00703 if (status & NO_YUNITS) fprintf (stderr, " y units\n");
00704 continue;
00705 }
00706
00707 img_radius = asin (RSUNM / dsun_obs);
00708 img_radius *= 3600.0 * degrad;
00709 img_radius /= (img_xscl <= img_yscl) ? img_xscl : img_yscl;
00710 status &= ~NO_SEMIDIAMETER;
00711 }
00712 if (status == KEYSCOPE_VARIABLE) {
00713 fprintf (stderr, "Warning: one or more keywords expected constant are variable\n");
00714 } else if (status) {
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 if (status & NO_DATA_DICT)
00718 fprintf (stderr, " internal data dictionary for platform\n");
00719 if (status & NO_SEMIDIAMETER) fprintf (stderr, " semidiameter\n");
00720 if (status & NO_XSCALE) fprintf (stderr, " x-scale\n");
00721 if (status & NO_YSCALE) fprintf (stderr, " y-scale\n");
00722 if (status & NO_XCENTERLOC) fprintf (stderr, " x-center\n");
00723 if (status & NO_YCENTERLOC) fprintf (stderr, " y-center\n");
00724 if (status & NO_HELIO_LATC) fprintf (stderr, " disc-center latitude\n");
00725 if (status & NO_HELIO_LONC) fprintf (stderr, " disc-center longitude\n");
00726 if (status & NO_XUNITS) fprintf (stderr, " x units\n");
00727 if (status & NO_YUNITS) fprintf (stderr, " y units\n");
00728 continue;
00729 }
00730 if (MDI_correct) {
00731 mtrack_MDI_correct_imgctr (&img_xc, &img_yc, img_radius);
00732 mtrack_MDI_correct_pa (&img_pa);
00733 }
00734 img_xc -= 0.5 * (image->axis[0] - 1);
00735 img_yc -= 0.5 * (image->axis[1] - 1);
00736
00737
00738
00739 img_lon = 0.2 * round(10.0 * img_lon/2.0);
00740 printf("lon=%f\n", img_lon);
00741 img_lon *= raddeg; clon = img_lon;
00742 img_lat *= raddeg;
00743
00744
00745
00746
00747 orec = ods->records[img];
00748 oseg = drms_segment_lookup (orec, osegname);
00749
00750 perform_mapping (image, data, maplat, maplon, map_coslat, map_sinlat,
00751 pixct, offsun, img_lat, img_lon, img_xc, img_yc, img_radius, img_pa,
00752 ellipse_e, ellipse_pa, x_invrt, y_invrt, intrpopt, cvlostor,
00753 MDI_correct_distort);
00754 if (overlay) {
00755 for (n = 0; n < pixct; n++)
00756 if (ongrid[n]) data[n] = (isfinite (data[n])) ? bblank : wblank;
00757 }
00758
00759 outdata = (float *)outmap->data;
00760 do_boxcar(data, outdata, axes[0], axes[1], rescale, 1);
00761 outmap->israw = 0;
00762 outmap->bzero = oseg->bzero;
00763 outmap->bscale = oseg->bscale;
00764
00765
00766 status = drms_segment_write (oseg, outmap, 0);
00767 if (status) {
00768 drms_sprint_rec_query (recid, orec);
00769 fprintf (stderr, "Error writing data to record %s\n", recid);
00770 fprintf (stderr, " series may not have appropriate structure\n");
00771 return 1;
00772 }
00773 drms_copykeys (orec, irec, 0, kDRMS_KeyClass_Explicit);
00774
00775
00776 double statMin, statMax, statMedn, statMean, statSig, statSkew, statKurt;
00777 int statNgood, ipixels;
00778 if (fstats2(outaxes[0] * outaxes[1], outdata, &statMin, &statMax, &statMedn, &statMean, &statSig,
00779 &statSkew, &statKurt, &statNgood)) printf("\n Statistics computation failed\n");
00780
00781 ipixels = outaxes[0] * outaxes[1];
00782 drms_setkey_int(orec, "TOTVALS", ipixels);
00783 drms_setkey_int(orec, "DATAVALS", statNgood);
00784 ipixels = outaxes[0] * outaxes[1]-statNgood;
00785 drms_setkey_int(orec, "MISSVALS", ipixels);
00786 drms_setkey_double(orec, "DATAMIN", statMin);
00787 drms_setkey_double(orec, "DATAMAX", statMax);
00788 drms_setkey_double(orec, "DATAMEDN", statMedn);
00789 drms_setkey_double(orec, "DATAMEAN", statMean);
00790 drms_setkey_double(orec, "DATARMS", statSig);
00791 drms_setkey_double(orec, "DATASKEW", statSkew);
00792 drms_setkey_double(orec, "DATAKURT", statKurt);
00793
00794
00795
00796 kstat = 0;
00797 kstat += check_and_set_key_str (orec, "WCSNAME", "Carrington Heliographic");
00798 kstat += check_and_set_key_int (orec, "WCSAXES", 2);
00799 snprintf (key, 64, "CRLN-%s", wcscode[proj]);
00800 kstat += check_and_set_key_str (orec, "CTYPE1", key);
00801 snprintf (key, 64, "CRLT-%s", wcscode[proj]);
00802 kstat += check_and_set_key_str (orec, "CTYPE2", key);
00803 kstat += check_and_set_key_str (orec, "CUNIT1", "deg");
00804 kstat += check_and_set_key_str (orec, "CUNIT2", "deg");
00805 kstat += check_and_set_key_float (orec, "CRPIX1", 0.5 * map_cols * rescale + 0.5);
00806 kstat += check_and_set_key_float (orec, "CRPIX2", 0.5 * map_rows * rescale + 0.5);
00807 kstat += check_and_set_key_float (orec, "CRVAL1", clon * degrad);
00808 kstat += check_and_set_key_float (orec, "CRVAL2", clat * degrad);
00809 kstat += check_and_set_key_float (orec, "CDELT1", map_scale/rescale);
00810 kstat += check_and_set_key_float (orec, "CDELT2", map_scale/rescale);
00811 kstat += check_and_set_key_float (orec, "CROTA2", 0.0);
00812 if (map_pa != 0.0) {
00813 kstat += check_and_set_key_float (orec, "PC1_1", cos (map_pa));
00814
00815 kstat += check_and_set_key_float (orec, "PC1_2", sin (map_pa));
00816
00817 kstat += check_and_set_key_float (orec, "PC2_1", sin (map_pa));
00818 kstat += check_and_set_key_float (orec, "PC2_2", cos (map_pa));
00819 }
00820
00821 kstat += check_and_set_key_float (orec, "LonHG", clon * degrad);
00822 kstat += check_and_set_key_float (orec, "LatHG", clat * degrad);
00823 kstat += check_and_set_key_str (orec, "MapProj", mapname[proj]);
00824 kstat += check_and_set_key_float (orec, "MapScale", map_scale);
00825 kstat += check_and_set_key_float (orec, "Width", map_cols * rescale * map_scale);
00826 kstat += check_and_set_key_float (orec, "Height", map_rows * rescale * map_scale);
00827 kstat += check_and_set_key_float (orec, "Size", sqrt (map_rows * map_cols) * rescale * map_scale);
00828 kstat += check_and_set_key_float (orec, "Map_PA", map_pa / raddeg);
00829 kstat += check_and_set_key_float (orec, "RSunRef", 1.0e-6 * RSUNM);
00830 kstat += check_and_set_key_str (orec, "Interp", interpname[intrpopt]);
00831 kstat += check_and_set_key_short (orec, "MDICorr", MDI_proc);
00832 kstat += check_and_set_key_short (orec, "LoS2Rad", cvlostor);
00833
00834 kstat += check_and_set_key_str (orec, "Module", module_ident);
00835 kstat += check_and_set_key_str (orec, "BLD_VERS", jsoc_version);
00836 kstat += check_and_set_key_time (orec, "Created", CURRENT_SYSTEM_TIME);
00837 kstat += check_and_set_key_time (orec, "DATE", CURRENT_SYSTEM_TIME);
00838 kstat += check_and_set_key_str (orec, "Source", source);
00839 kstat += check_and_set_key_str (orec, "Input", input);
00840 kstat += check_and_set_key_str (orec, "RequestID", RequestID);
00841
00842 if (kstat) {
00843 fprintf (stderr, "Error writing key value(s) to record %d in series %s\n",
00844 img, outser);
00845 fprintf (stderr, " series may not have appropriate structure\n");
00846 drms_close_records (ods, DRMS_FREE_RECORD);
00847 return 1;
00848 }
00849 drms_free_array (image);
00850 }
00851 drms_close_records (ods, DRMS_INSERT_RECORD);
00852 drms_free_array (outmap);
00853 drms_free_array (map);
00854 return 0;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887