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