00001 #include "drms.h"
00002 #include "cartography.h"
00003
00004
00005
00006 static double lookup (DRMS_Record_t *rec, ParamDef key, int *status) {
00007 double value = key.defval;
00008 int lookupstat = 0;
00009
00010 value = drms_getkey_double (rec, key.name, &lookupstat);
00011 value = value * key.scale + key.offset;
00012 if (lookupstat) *status |= key.statusbit;
00013 if (isnan (value)) *status |= key.statusbit;
00014 return value;
00015 }
00016
00017 static char *lookup_str (DRMS_Record_t *rec, ParamDef key, int *status) {
00018 DRMS_Keyword_t *keywd;
00019 char *value;;
00020
00021 value = drms_getkey_string (rec, key.name, status);
00022 if (*status) *status |= key.statusbit;
00023
00024 if ((keywd = drms_keyword_lookup (rec, key.name, 1))) {
00025 if (keywd->info->recscope != 1) *status |= KEYSCOPE_VARIABLE;
00026 } else *status |= key.statusbit;
00027 return value;
00028 }
00029
00030 int synop_solar_image_info (DRMS_Record_t *img, double *xscl, double *yscl,
00031 double *ctrx, double *ctry, double *apsd, const char *rsun_key,
00032 const char *apsd_key, double *pang, double *ellipse_e, double *ellipse_pa,
00033 int *x_invrt, int *y_invrt, int *need_ephem, int AIPS_convention) {
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 enum param {
00065 XSCL, YSCL, XUNI, YUNI, LATC, LONC, CTRX, CTRY, PANG, APSD, RSUN,
00066 ESMA, ESMI, EECC, EANG, XASP, YASP, PCT
00067 };
00068 enum known_plat {
00069 UNKNOWN
00070 };
00071 static ParamDef param[PCT];
00072 static double raddeg = M_PI / 180.0;
00073 static double degrad = 180.0 / M_PI;
00074 double ella, ellb;
00075 int n, status = 0;
00076 static int scale_avail, xinv_type, yinv_type;
00077 static int hdrtype = UNKNOWN, lasthdr = UNKNOWN - 1;
00078 char *strval;
00079
00080
00081
00082 if (lasthdr != hdrtype) {
00083 if (lasthdr >= UNKNOWN)
00084 fprintf (stderr,
00085 "Warning from solar_image_info(): record keywords may change\n");
00086 for (n = 0; n < PCT; n++) {
00087 sprintf (param[n].name, "No Keyword");
00088 param[n].scale = 1.0;
00089 param[n].offset = 0.0;
00090 param[n].defval = NAN;
00091 param[n].statusbit = 0;
00092 }
00093 param[RSUN].statusbit = NO_SEMIDIAMETER;
00094 param[APSD].statusbit = NO_SEMIDIAMETER;
00095 param[XSCL].statusbit = NO_XSCALE;
00096 param[YSCL].statusbit = NO_YSCALE;
00097 param[XUNI].statusbit = NO_XUNITS;
00098 param[YUNI].statusbit = NO_YUNITS;
00099 param[CTRX].statusbit = NO_XCENTERLOC;
00100 param[CTRY].statusbit = NO_YCENTERLOC;
00101 param[CTRX].statusbit = NO_XCENTERLOC;
00102 param[CTRY].statusbit = NO_YCENTERLOC;
00103 param[LATC].statusbit = NO_HELIO_LATC;
00104 param[LONC].statusbit = NO_HELIO_LONC;
00105 param[PANG].statusbit = NO_HELIO_PA;
00106 param[EECC].defval = 0.0;
00107 param[EANG].defval = 0.0;
00108 param[XASP].defval = 1.0;
00109 param[YASP].defval = 1.0;
00110
00111 switch (hdrtype) {
00112 default:
00113
00114 scale_avail = 1;
00115 xinv_type = yinv_type = 0;
00116 sprintf (param[XUNI].name, "CUNIT1");
00117 sprintf (param[YUNI].name, "CUNIT2");
00118 sprintf (param[XSCL].name, "CDELT1");
00119 sprintf (param[YSCL].name, "CDELT2");
00120 sprintf (param[CTRX].name, "CRPIX1");
00121 param[CTRX].offset = -1.0;
00122 sprintf (param[CTRY].name, "CRPIX2");
00123 param[CTRY].offset = -1.0;
00124 *need_ephem = 0;
00125 strval = lookup_str (img, param[XUNI], &status);
00126 if (!(status & NO_XUNITS)) {
00127 if (!strcmp (strval, "arcsec")) param[XSCL].scale = 1.0;
00128 else if (!strcmp (strval, "arcmin")) param[XSCL].scale = 1.0 / 60.0;
00129 else if (!strcmp (strval, "deg")) param[XSCL].scale = 1.0 / 3600.0;
00130 else if (!strcmp (strval, "mas")) param[XSCL].scale = 1000.0;
00131 else if (!strcmp (strval, "rad")) param[XSCL].scale = degrad * 3600.0;
00132
00133
00134
00135 }
00136 if (strval) free (strval);
00137 strval = lookup_str (img, param[YUNI], &status);
00138 if (!(status & NO_YUNITS)) {
00139 if (!strcmp (strval, "arcsec")) param[YSCL].scale = 1.0;
00140 else if (!strcmp (strval, "arcmin")) param[YSCL].scale = 1.0 / 60.0;
00141 else if (!strcmp (strval, "deg")) param[YSCL].scale = 1.0 / 3600.0;
00142 else if (!strcmp (strval, "mas")) param[YSCL].scale = 1000.0;
00143 else if (!strcmp (strval, "rad")) param[YSCL].scale = degrad * 3600.0;
00144
00145
00146
00147 }
00148 if (strval) free (strval);
00149
00150
00151
00152
00153
00154 strncpy (param[RSUN].name, rsun_key, 31);
00155 strncpy (param[APSD].name, apsd_key, 31);
00156 sprintf (param[APSD].name, "OBS_ASD");
00157 sprintf (param[PANG].name, "CROTA2");
00158 param[PANG].scale = -raddeg;
00159 if (AIPS_convention) param[PANG].scale *= -1;
00160 sprintf (param[ESMA].name, "S_MAJOR");
00161 sprintf (param[ESMI].name, "S_MINOR");
00162 sprintf (param[EANG].name, "S_ANGLE");
00163 param[EANG].scale = raddeg;
00164 }
00165 }
00166 lasthdr = hdrtype;
00167
00168 *apsd = lookup (img, param[RSUN], &status);
00169 if (scale_avail) {
00170 *xscl = lookup (img, param[XSCL], &status);
00171 *yscl = lookup (img, param[YSCL], &status);
00172 if (status & NO_SEMIDIAMETER) {
00173 status &= ~NO_SEMIDIAMETER;
00174 *apsd = lookup (img, param[APSD], &status);
00175 if (status & NO_SEMIDIAMETER) {
00176 *need_ephem = 1;
00177 } else {
00178 if (!(status & (NO_XSCALE | NO_YSCALE))) {
00179 *apsd /= (*xscl <= *yscl) ? *xscl : *yscl;
00180 status &= ~NO_SEMIDIAMETER;
00181 }
00182 }
00183 }
00184 }
00185 ella = lookup (img, param[ESMA], &status);
00186 ellb = lookup (img, param[ESMI], &status);
00187 *ellipse_e = sqrt ((ella - ellb) * (ella + ellb)) / ella;
00188 *ellipse_pa = lookup (img, param[EANG], &status);
00189
00190 *ctrx = lookup (img, param[CTRX], &status);
00191 *ctry = lookup (img, param[CTRY], &status);
00192
00193 *pang = lookup (img, param[PANG], &status);
00194
00195 *x_invrt = xinv_type;
00196 *y_invrt = yinv_type;
00197
00198 return status;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219