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