![]() ![]() |
![]() |
File: [Development] / JSOC / proj / lev1_hmi / apps / Attic / o2helio.c
(download)
Revision: 1.8, Thu Apr 16 02:52:58 2009 UTC (14 years, 1 month ago) by tplarson Branch: MAIN CVS Tags: Ver_LATEST, Ver_9-9, Ver_8-0, Ver_7-1, Ver_7-0, Ver_6-4, Ver_6-3, Ver_6-2, Ver_6-1, Ver_6-0, Ver_5-9, Ver_5-8, Ver_5-7, Ver_5-6, Ver_5-5, Ver_5-3, Ver_5-2, Ver_5-14, Ver_5-13, Ver_5-12, Ver_5-11, Ver_5-10, Ver_5-1 Changes since 1.7: +70 -42 lines bug fix to now close records written by CreateBlankRecord. change call to SetDistort. no longer multiply RSUN by anything, function Distort now uses scaling info provided on command line. |
/* * v2helio.c ~soi/(version)/src/modules/v2helio.c * * This module interpolates CCD velocity data to estimate values that * would be obtained at specified equal increments of heliographic * longitude and sine of latitude. Apodization and corrections for * solar rotation and limbshift are included. * * Responsible: Kay Leibrand KLeibrand@solar.Stanford.EDU * * Bugs: * This module is under development. Look for ??? in comments. * * Planned updates: * Decide when and where and if default values should be used. * * Revision history is at end of file. */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #include <sys/time.h> #include "jsoc_main.h" #include "astro.h" #include "drms_dsdsapi.h" #define PI (M_PI) #define RADSINDEG (PI/180) #define ARCSECSINRAD (3600*180/PI) #define DAYSINYEAR (365.2425) #define SECSINDAY (86400) #define TAU_A (499.004782) /* light time for unit dist, secs/au */ #define TCARR (25.38) /* days */ #define RTRUE (6.96000000e8) /* meters */ #define AU (1.49597870e11) /* meters/au */ #define MAXLEN (256) #define NO_DATASET (-1) #define NO_IMAGE (-1) #define kMAX_SKIPERRMSG 1024 #define kMAXROWS 65536 /* cmd-line parameters */ #define kRecSetIn "in" #define kSeriesOut "out" #define kSegIn "segin" #define kSegOut "segout" #define kNOTSPECIFIED "not specified" #define kCarrStretch "CARRSTRETCH" #define kMAXMISSVALS "MAXMISSVALS" #define kAPODIZE "APODIZE" #define kAPINNER "APINNER" #define kAPWIDTH "APWIDTH" #define kAPEL "APEL" #define kAPX "APX" #define kAPY "APY" #define kLGSHIFT "LGSHIFT" #define kMCORLEV "MCORLEV" #define kMOFFSET "MOFFSET" #define kVCORLEV "VCORLEV" #define kINTERPO "INTERPO" #define kDATASIGN "DATASIGN" #define kMAPRMAX "MAPRMAX" #define kREF_L0 "REF_L0" #define kOUTTYPE "OUTTYPE" #define kOUTSCALE "OUTSCALE" #define kOUTBIAS "OUTBIAS" #define kSOLAR_P "SOLAR_P" #define kPSIGN "PSIGN" #define kPERR "PERR" #define kIERR "IERR" #define kCHECKO_FLAG "o" #define kRMAX_FLAG "z" #define kREF_T0 "REF_T0" #define kMAPMMAX "MAPMMAX" #define kMAPLGMAX "MAPLGMAX" #define kMAPLGMIN "MAPLGMIN" #define kSINBDIVS "SINBDIVS" #define kMAPBMAX "MAPBMAX" #define kDISTORT "DISTORT" #define kCUBIC "CUBIC" #define kTILTALPHA "TILTALPHA" #define kTILTBETA "TILTBETA" #define kTILTFEFF "TILTFEFF" #define kDEBUGLOGFLAG "d" /* Keywords in the input data */ #define kT_OBS "T_OBS" #define kMISSVALS "MISSVALS" #define kI_DREC "I_DREC" #define kT_REC "T_REC" #define kQUALITY "QUALITY" #define kOBS_B0 "OBS_B0" #define kOBS_L0 "OBS_L0" #define kOBS_CR "OBS_CR" #define kS_MAJOR "S_MAJOR" #define kS_MINOR "S_MINOR" #define kS_ANGLE "S_ANGLE" #define kIM_SCALE "IM_SCALE" #define kX_SCALE "X_SCALE" #define kY_SCALE "Y_SCALE" #define kOBS_VR "OBS_VR" #define kOBS_VW "OBS_VW" #define kOBS_VN "OBS_VN" #define kORIENT "ORIENT" #define kOBS_DIST "OBS_DIST" #define kR_SUN "R_SUN" #define kXSCALE "XSCALE" #define kYSCALE "YSCALE" #define kX0 "X0" #define kY0 "Y0" /* Keywords in the output data */ #define kSN "SN" #define kPIXELS "PIXELS" #define kMAPCOLS "MAPCOLS" #define kMAPROWS "MAPROWS" #define kMAPBMIN "MAPBMIN" #define kSINBDELT "SINBDELT" #define kSHIFTFLG "SHIFTFLG" #define kLSHIFT "LSHIFT" #define kMAP_L0 "MAP_L0" #define kBFITZERO "BFITZERO" #define DPC "DPC" #define DPC_STR "DPC_STR" #define DPC_OBSR "DPC_OBSR" #define DPC_FORM "DPC_FORM" #define DPC_CROP "DPC_CROP" #define DPC_ORGN "DPC_ORGN" #define DPC_RATE "DPC_RATE" #define DPC_SMPL "DPC_SMPL" #define DPC_CONF "DPC_CONF" #define BLDVER00 "BLDVER00" #define BLDVER10 "BLDVER10" #define BLDVER15 "BLDVER15" #define BLDVER18 "BLDVER18" #define FDRADIAL "FDRADIAL" #define CARSTRCH "CARSTRCH" #define DIFROT_A "DIFROT_A" #define DIFROT_B "DIFROT_B" #define DIFROT_C "DIFROT_C" typedef enum { V2HStatus_Success, V2HStatus_MissingParameter, V2HStatus_IllegalTimeFormat, V2HStatus_TimeConvFailed, V2HStatus_Unimplemented, V2HStatus_IllegalOrientation } V2HStatus_t; char *module_name = "v2helio"; ModuleArgs_t module_args[] = { {ARG_STRING, kRecSetIn, "", "Input data records."}, {ARG_STRING, kSeriesOut, "", "Output data series."}, {ARG_STRING, kSegIn, kNOTSPECIFIED, ""}, {ARG_STRING, kSegOut, kNOTSPECIFIED, ""}, {ARG_FLOAT, kMAPRMAX, "0.95", ""}, {ARG_INT, kMAPMMAX, "1536", ""}, /* determines mapcols */ /* default value is 3*512 */ {ARG_FLOAT, kMAPLGMAX, "72.0", ""}, /* degrees */ {ARG_FLOAT, kMAPLGMIN, "-72.0", ""}, {ARG_FLOAT, kMAPBMAX, "72.0", ""}, {ARG_INT, kSINBDIVS, "512", ""}, /* # of = increments in sinB */ /* from sin(0) to sin(PI/2) */ {ARG_STRING, kREF_T0, "1987.01.03_17:31:12", ""}, {ARG_FLOAT, kREF_L0, "0.0", ""}, {ARG_FLOAT, kSOLAR_P, "999.0", ""}, /* can't use D_MISSING here */ {ARG_FLOAT, kPSIGN, "1.0", ""}, /* Sign of P. For MWO data. */ {ARG_FLOAT, kPERR, "0.0", ""}, /* Fixed P-angle error. Maybe -0.22. */ {ARG_FLOAT, kIERR, "0.0", ""}, /* Error in Carrington inclination. Maybe -0.10. */ {ARG_INT, kINTERPO, "1", "0"}, /* 2 methods - see soi_fun.h */ {ARG_INT, kAPODIZE, "0", ""}, /* see soi_fun.h or apodize.c */ {ARG_FLOAT, kAPINNER, "0.90", ""}, /* start of apodization */ {ARG_FLOAT, kAPWIDTH, "0.05", ""}, /* width of apodization */ {ARG_INT, kAPEL, "0", ""}, /* do elliptical apodization */ /* described by apx and apy */ {ARG_FLOAT, kAPX, "1.00", ""}, /* divide the x position by this before applying apodization */ {ARG_FLOAT, kAPY, "1.00", ""}, /* divide the y position by this before applying apodization */ {ARG_INT, kLGSHIFT, "0", ""}, /* 0=none; 1=fixed rate; 2=nearest Degree */ {ARG_INT, kVCORLEV, "2", ""}, /* 3 levels - see soi_fun.h*/ {ARG_INT, kMCORLEV, "0", ""}, /* 2 levels - see soi_fun.h*/ {ARG_INT, kMOFFSET, "0", ""}, /* 1=apply BFITZERO correction*/ {ARG_STRING, kOUTTYPE, "no scaling", ""}, /* bits in scaled output */ {ARG_FLOAT, kOUTSCALE, "1.0", ""}, /* scale for output */ {ARG_FLOAT, kOUTBIAS, "0.0", ""}, /* bias for scaled output */ {ARG_INT, kDISTORT, "0", ""}, /* 0 for none, 1 for FD, 2 for vw */ {ARG_FLOAT, kCUBIC, "7.06E-9", ""}, /* Cubic distortion in FD units */ {ARG_FLOAT, kTILTALPHA,"2.59", ""}, /* TILT of CCD in degrees */ {ARG_FLOAT, kTILTBETA, "56.0", ""}, /* Direction of TILT in degrees */ {ARG_FLOAT, kTILTFEFF, "12972.629", ""}, /* Effective focal length */ {ARG_FLAG, kCHECKO_FLAG, "0", ""}, /* Non 0 skips checko (SESW assumed) */ {ARG_FLAG, kRMAX_FLAG, "0", ""}, /* Non 0 sets data outside RMAX MISSING */ {ARG_FLAG, kDEBUGLOGFLAG, "0", ""}, /* debug messages */ {ARG_INT, kDATASIGN, "0", ""}, /* Non 0 forces datasigh to value*/ {ARG_INT, kMAXMISSVALS, "0", ""}, /* max. allowed MISSING pixels */ {ARG_INT, kCarrStretch, "0", ""}, /* 0 - don't correct for diff rot, 1 - correct */ {ARG_FLOAT, DIFROT_A, "13.562", ""}, /* A coefficient in diff rot adj (offset) */ {ARG_FLOAT, DIFROT_B, "-2.04", ""}, /* B coefficient (to sin(lat) ^ 2) */ {ARG_FLOAT, DIFROT_C, "-1.4875", ""}, /* c coefficient (to sin(lat) ^ 4) */ {ARG_END, "", "", "", ""} }; HContainer_t *gParamCont = NULL; long long gGUID = 0; static double V2Hstr2Time(const char *timestr, V2HStatus_t *stat); static void CheckO(const char *orientation, V2HStatus_t *stat); /* gParamCont holds pointers to data that gets allocated inside the record loop. * Should there be an error during loop execution, SkipErr() gets called, which * frees this allocated data. Otherwise, this memory gets freed at the end of * each loop iteration. */ static void FreeLoopMem() { if (gParamCont) { hcon_destroy(&gParamCont); } } static void FreeLoopMemItem(const void *v) { /* v is a pointer to char * */ void **vv = (void **)v; if (vv && *vv) { free(*vv); } } static void InsertLoopMemItem(const char *keyn, const void *val) { char buf[DRMS_MAXHASHKEYLEN]; if (!gParamCont) { gParamCont = hcon_create(sizeof(void *), DRMS_MAXHASHKEYLEN, FreeLoopMemItem, NULL, NULL, NULL, NULL); } if (gParamCont) { if (hcon_lookup(gParamCont, keyn)) { snprintf(buf, sizeof(buf), "%s%lld", keyn, gGUID); gGUID++; hcon_insert(gParamCont, buf, &val); } else { hcon_insert(gParamCont, keyn, &val); } } } /* drms_getkey_string() allocs mem - so if it is called inside the record loop, * a pointer to the allocated memory must be saved so that if SkipErr() is * called, that allocated memory won't be leaked. */ static const char *V2HGetKeyStrInLoop(DRMS_Record_t *rec, const char *keyn, int *status) { void *mem = (void *)drms_getkey_string(rec, keyn, status); if (mem) { InsertLoopMemItem(keyn, mem); } return (const char *)mem; } /* Non-fatal errors - print out error value */ static inline void SkipErr(int status, DRMS_Record_t *rec, char *msg, ...) { /* logs error */ char buf[kMAX_SKIPERRMSG]; va_list valist; int ds; int rn; va_start(valist, msg); vsnprintf(buf, sizeof(buf), msg, valist); va_end(valist); ds = drms_getkey_int(rec, kDSDS_DS, NULL); rn = drms_getkey_int(rec, kDSDS_RN, NULL); fprintf(stderr, "*** warning %d: %s (skipping record ds=%d, rn=%d)\n", status, buf, ds, rn); FreeLoopMem(); } static inline void ParameterDef(int status, char *pname, double defaultp, double *p, DRMS_Record_t *rec) { /* logs warning and sets parameter to default value */ if (status != 0) { *p = defaultp; int ds = drms_getkey_int(rec, kDSDS_DS, NULL); int rn = drms_getkey_int(rec, kDSDS_RN, NULL); fprintf(stderr, "warning: default value %g used for %s (record ds=%d, rn=%d)\n", defaultp, pname, ds, rn); } } /* Fatal errors - logs error and returns 1 to indicate abort */ #define PARAMETER_ERROR(CHKERR, ERROR, REC, PNAME) \ if (CHKERR) \ { \ int dsint = -1; \ int rnint = -1; \ if (REC) \ { \ dsint = drms_getkey_int(REC, kDSDS_DS, NULL); \ rnint = drms_getkey_int(REC, kDSDS_RN, NULL); \ } \ fprintf(stderr, \ "fatal error %d: parameter %s (record ds=%d, rn=%d)\n", \ (int)ERROR, \ PNAME, \ dsint, \ rnint); \ FreeLoopMem(); \ return 1; \ } /* Segment will be empty, but there will be a record! */ static void CreateBlankRecord(DRMS_Record_t *inrec, DRMS_Record_t *outrec, const char *tobsstr) { /* create 'blank' data */ drms_copykey(outrec, inrec, kI_DREC); drms_copykey(outrec, inrec, kT_REC); drms_copykey(outrec, inrec, kQUALITY); drms_copykey(outrec, inrec, "series_num"); drms_copykey(outrec, inrec, "rn"); drms_setkey_string(outrec, kT_OBS, tobsstr); } int DoIt(void) { int status = DRMS_SUCCESS; int error = 0; const char *tobsstr, *trefstr, *orientation; int rn; int paramsign; int longitude_shift, velocity_correction, interpolation, apodization; int mag_correction; int mag_offset; int row; int mapped_lmax, sinb_divisions, mapcols, maprows, nmax, nmin; int length[2]; int carrStretch = 0; float diffrotA = 0.0; float diffrotB = 0.0; float diffrotC = 0.0; const char *outtypeStr = NULL; DRMS_Type_t outtype = DRMS_TYPE_FLOAT; V2HStatus_t vret = V2HStatus_Success; double tobs, tmearth, tref; double smajor, sminor, sangle; double xscale, yscale, imagescale; int xpixels, ypixels, pixels; double obs_vr, obs_vw, obs_vn, vsign; double b0, bmax, bmin, sinBdelta; double longmax, longmin, longmax_adjusted, longmin_adjusted, longinterval; double p0, p, rmax; double ierr, perr, psign; double x0, y0; double obsdist, longshift, obsl0, refl0, mapl0, longrate, rtrue, rsun, S; double rsunDef; int obsCR; int apel; double apinner, apwidth, apx, apy; double scale, bias; double colsperdeg; LIBASTRO_RotRate_t rRates[kMAXROWS]; int skip_checko = cmdparams_isflagset(&cmdparams, kCHECKO_FLAG); int debugLog = cmdparams_isflagset(&cmdparams, kDEBUGLOGFLAG); int NaN_beyond_rmax = cmdparams_isflagset(&cmdparams, kRMAX_FLAG); int maxmissvals = cmdparams_get_int(&cmdparams, kMAXMISSVALS, &status); LIBASTRO_Dist_t distP; DRMS_Record_t *outrec = NULL; DRMS_Segment_t *segin = NULL; DRMS_Segment_t *segout = NULL; DRMS_Array_t *inarr = NULL; DRMS_Array_t *outarr = NULL; struct timeval tv0; struct timeval tv; /* read Carrington coordinate correction for differential sun rotation */ carrStretch = cmdparams_get_int(&cmdparams, kCarrStretch, &status); diffrotA = cmdparams_get_float(&cmdparams, DIFROT_A, &status); diffrotB = cmdparams_get_float(&cmdparams, DIFROT_B, &status); diffrotC = cmdparams_get_float(&cmdparams, DIFROT_C, &status); longrate = 360.0 / TCARR - 360.0 / DAYSINYEAR; /* degrees per day */ longrate /= SECSINDAY; /* degrees per sec */ rtrue = RTRUE/AU; /* au */ apodization = cmdparams_get_int(&cmdparams, kAPODIZE, &status); apinner = cmdparams_get_double(&cmdparams, kAPINNER, &status); apwidth = cmdparams_get_double(&cmdparams, kAPWIDTH, &status); apel = cmdparams_get_int(&cmdparams, kAPEL, &status); apx = cmdparams_get_double(&cmdparams, kAPX, &status); apy = cmdparams_get_double(&cmdparams, kAPY, &status); longitude_shift = cmdparams_get_int(&cmdparams, kLGSHIFT, &status); mag_correction = cmdparams_get_int(&cmdparams, kMCORLEV, &status); mag_offset = cmdparams_get_int(&cmdparams, kMOFFSET, &status); velocity_correction = cmdparams_get_int(&cmdparams, kVCORLEV, &status); interpolation = cmdparams_get_int(&cmdparams, kINTERPO, &status); paramsign = cmdparams_get_int(&cmdparams, kDATASIGN, &status); rmax = cmdparams_get_double(&cmdparams, kMAPRMAX, &status); refl0 = cmdparams_get_double(&cmdparams, kREF_L0, &status); outtypeStr = cmdparams_get_str(&cmdparams, kOUTTYPE, &status); if (status == DRMS_SUCCESS && strcmp(outtypeStr, "no scaling") != 0) { outtype = drms_str2type(outtypeStr); } scale = cmdparams_get_double(&cmdparams, kOUTSCALE, &status); bias = cmdparams_get_double(&cmdparams, kOUTBIAS, &status); p0 = cmdparams_get_double(&cmdparams, kSOLAR_P, &status); psign = cmdparams_get_double(&cmdparams, kPSIGN, &status); perr = cmdparams_get_double(&cmdparams, kPERR, &status); ierr = cmdparams_get_double(&cmdparams, kIERR, &status); // change call to SetDistort /* SetDistort(&cmdparams, kDISTORT, kCUBIC, kTILTALPHA, kTILTBETA, kTILTFEFF, &distP); */ int distsave = cmdparams_get_int(&cmdparams, kDISTORT, &status); double cubsave = cmdparams_get_double(&cmdparams, kCUBIC, &status); double tiltasave = cmdparams_get_double(&cmdparams, kTILTALPHA, &status); double tiltbsave = cmdparams_get_double(&cmdparams, kTILTBETA, &status); double tiltfsave = cmdparams_get_double(&cmdparams, kTILTFEFF, &status); SetDistort(distsave, cubsave, tiltasave, tiltbsave, tiltfsave, &distP); trefstr = cmdparams_get_str(&cmdparams, kREF_T0, &status); PARAMETER_ERROR(status, status, NULL, kREF_T0) tref = V2Hstr2Time(trefstr, &vret); /* secs */ PARAMETER_ERROR(vret, vret, NULL, kREF_T0) /* determine mapcols and adjust longmin and longmax */ mapped_lmax = cmdparams_get_int(&cmdparams, kMAPMMAX, &status); longmax = cmdparams_get_double(&cmdparams, kMAPLGMAX, &status); /* degrees */ longmin = cmdparams_get_double(&cmdparams, kMAPLGMIN, &status); /* degrees */ longinterval = (180.0) / mapped_lmax; /* degrees */ /* * This does not always handle the case where 1/longinterval is an integer * correctly. */ /* the next two statement do nothing, right? */ /* why do nmin and max keep getting set with different RHSs? */ nmin = (int)(longmin / longinterval); /* round towards 0 */ nmax = (int)(longmax / longinterval); /* round towards 0 */ colsperdeg = mapped_lmax / 180.0; nmin = (int)(longmin * colsperdeg); /* round towards 0 */ nmax = (int)(longmax * colsperdeg); /* round towards 0 */ mapcols = nmax - nmin + 1; longmin_adjusted = nmin * longinterval; longmax_adjusted = nmax * longinterval; /* determine maprows, bmax, bmin, and sinBdelta */ sinb_divisions = cmdparams_get_int(&cmdparams, kSINBDIVS, &status); sinBdelta = 1.0/sinb_divisions; bmax = cmdparams_get_double(&cmdparams, kMAPBMAX, &status); /* degrees */ bmin = -bmax; nmax = (int)(sin(RADSINDEG*bmax)*sinb_divisions); /* round towards 0 */ maprows = 2*nmax; char *inRecQuery = cmdparams_get_str(&cmdparams, kRecSetIn, NULL); DRMS_RecordSet_t *inRecSet = drms_open_records(drms_env, inRecQuery, &status); char *outSeries = cmdparams_get_str(&cmdparams, kSeriesOut, NULL); char *segnamein = cmdparams_get_str(&cmdparams, kSegIn, NULL); char *segnameout = cmdparams_get_str(&cmdparams, kSegOut, NULL); if (status == DRMS_SUCCESS) { int nRecs = inRecSet->n; int iRec; gettimeofday(&tv0, NULL); for (iRec = 0; !error && iRec < nRecs; iRec++) { DRMS_Record_t *inrec = inRecSet->records[iRec]; /* create an out record */ DRMS_RecordSet_t *rs = drms_create_records(drms_env, 1, outSeries, DRMS_PERMANENT, &status); error = (status != DRMS_SUCCESS); if (!error) { outrec = rs->records[0]; } if (!error && outrec && inrec) { if (iRec == 0) { /* XXX Do outseries stuff here. */ } rn = drms_getkey_int(inrec, kDSDS_RN, &status); tobsstr = V2HGetKeyStrInLoop(inrec, kT_OBS, &status); /* v2helio owns string */ if ((!tobsstr) || (!*tobsstr)) { CreateBlankRecord(inrec, outrec, tobsstr); SkipErr(status, inrec, "unable to locate critical keyword %s", kT_OBS); drms_close_records(rs, DRMS_INSERT_RECORD); continue; /* go to next image */ } if (!strcmp(kNOTSPECIFIED, segnamein)) { segin = drms_segment_lookupnum(inrec, 0); } else { segin = drms_segment_lookup(inrec, segnamein); } if (segin) { inarr = drms_segment_read(segin, segin->info->type, &status); } /* segin */ if (!segin || status != DRMS_SUCCESS || !inarr) { CreateBlankRecord(inrec, outrec, tobsstr); SkipErr(status, inrec, "no data to process"); drms_close_records(rs, DRMS_INSERT_RECORD); continue; /* go to next image */ } /* Order is very important - the first will be freed before the second */ InsertLoopMemItem("arrayindata", inarr->data); InsertLoopMemItem("arrayin", inarr); if (maxmissvals > 0) { int missvals = drms_getkey_int(inrec, kMISSVALS, &status); if (status != DRMS_SUCCESS || missvals > maxmissvals) { CreateBlankRecord(inrec, outrec, tobsstr); SkipErr(0, inrec, "%d pixels MISSING, which is more than is allowed", missvals); drms_close_records(rs, DRMS_INSERT_RECORD); continue; } } /* assemble arguments */ tobs = V2Hstr2Time(tobsstr, &vret); /*secs*/ PARAMETER_ERROR(vret, vret, inrec, kT_OBS); b0 = drms_getkey_double(inrec, kOBS_B0, &status); PARAMETER_ERROR(status, V2HStatus_MissingParameter, inrec, kOBS_B0); obsl0 = drms_getkey_double(inrec, kOBS_L0, &status); PARAMETER_ERROR(status, V2HStatus_MissingParameter, inrec, kOBS_L0); obsCR = drms_getkey_int(inrec, kOBS_CR, &status); if (!obsCR || status != DRMS_SUCCESS) { /* May 2, 2005. Commented this out to allow for no OBS_CR in MWO data. Still printes warning. OBS_CR is not used by this program or by helio2mlat. */ fprintf(stderr, "warning: missing OBS_CR.\n"); } if (p0 == 999.0) { p = drms_getkey_double(inrec, kSOLAR_P, &status); PARAMETER_ERROR(status, V2HStatus_MissingParameter, inrec, kSOLAR_P); } else { p = p0; } /* fix for 1988 MWO p = 180.0 - p ; */ p = psign * p ; /* 991839442. corresponds to hour 73878 minute 57 second 22 or 73878.956 or day 3078.2898, roughly when B0 is 0 */ /* b0=b0 * 0.986207; */ /* One way of correcting. */ /* The following is pretty good */ /* b0=b0-0.1*sin((tobs-991839442.)/31557600.*2*PI);*/ b0 = b0 + ierr * sin((tobs - 991839442.) / 31557600. * 2 * PI); /* p=p-0.2; */ /* p=p-0.2+0.1*cos((tobs-991839442.)/31557600.*2*PI); */ p = p + perr - ierr * cos((tobs - 991839442.) / 31557600. * 2 * PI); smajor = drms_getkey_double(inrec, kS_MAJOR, &status); ParameterDef(status, kS_MAJOR, 1.0, &smajor, inrec); sminor = drms_getkey_double(inrec, kS_MINOR, &status); ParameterDef(status, kS_MINOR, 1.0, &sminor, inrec); sangle = drms_getkey_double(inrec, kS_ANGLE, &status); ParameterDef(status, kS_ANGLE, 0.0, &sangle, inrec); xscale = drms_getkey_double(inrec, kX_SCALE, &status); PARAMETER_ERROR(status, V2HStatus_MissingParameter, inrec, kX_SCALE); yscale = drms_getkey_double(inrec, kY_SCALE, &status); PARAMETER_ERROR(status, V2HStatus_MissingParameter, inrec, kY_SCALE); imagescale = drms_getkey_double(inrec, kIM_SCALE, &status); PARAMETER_ERROR(status, V2HStatus_MissingParameter, inrec, kIM_SCALE); if (paramsign != 0) { vsign = paramsign; } else { vsign = drms_getkey_double(inrec, kDATASIGN, &status); ParameterDef(status, kDATASIGN, 1.0, &vsign, inrec); } if (velocity_correction) { obs_vr = drms_getkey_double(inrec, kOBS_VR, &status); ParameterDef(status, kOBS_VR, 0.0, &obs_vr, inrec); obs_vw = drms_getkey_double(inrec, kOBS_VW, &status); ParameterDef(status, kOBS_VW, 0.0, &obs_vw, inrec); obs_vn = drms_getkey_double(inrec, kOBS_VN, &status); ParameterDef(status, kOBS_VN, 0.0, &obs_vn, inrec); } if (!skip_checko) { orientation = V2HGetKeyStrInLoop(inrec, kORIENT, &status); PARAMETER_ERROR(status, status, inrec, kORIENT); CheckO(orientation, &vret); } else { char foo[] = "SESW "; orientation = strdup(foo); InsertLoopMemItem(foo, orientation); } obsdist = drms_getkey_double(inrec, kOBS_DIST, &status); ParameterDef(status, kOBS_DIST, 1.0, &obsdist, inrec); S = rtrue / obsdist; /* radians - approx. arcsin(rtrue/obsdist) */ rsun = drms_getkey_double(inrec, kR_SUN, &status); rsunDef = ARCSECSINRAD * S / sqrt(1.0 - S * S) / imagescale; ParameterDef(status, kR_SUN, rsunDef, &rsun, inrec); if (status == DRMS_SUCCESS) { /* New meaning of R_SUN, change value to old one if X_SCALE == Y_SCALE otherwise give up */ if (xscale == yscale) { // rsun = rsun * xscale; /* another change. now vw or fd scale is specified using command line option DISTORT. inside obs2helio rsun is divided by xscale and yscale, so just set them to 1 and don't multiply by them here. rsun is now multiplied appropriately inside function Distort. */ xscale=1.0; yscale=1.0; } else { PARAMETER_ERROR(1, V2HStatus_Unimplemented, inrec, "X_SCALE != Y_SCALE") } } if (longitude_shift == 1) { tmearth = tobs+TAU_A*(1.0-obsdist); longshift = (obsl0-refl0)+longrate*(tmearth-tref); /* degrees */ while (longshift > 180.0) longshift-=360.0; while (longshift < -180.0) longshift+=360.0; } else if (longitude_shift == 2) /* Shift center to nearest Carrington Degree */ { longshift = obsl0 - (int)(obsl0); if (longshift > 0.5) longshift -= 1.0; } else if (longitude_shift == 3) /* Shift center to nearest tenth of a degree */ { longshift = (obsl0 * 10 - (int)(obsl0 * 10)) / 10; if (longshift > 0.5) longshift -= 1.0; } else { longshift = 0.0; } mapl0 = obsl0 - longshift; xpixels = inarr->axis[0]; ypixels = inarr->axis[1]; pixels = xpixels * ypixels; x0 = drms_getkey_double(inrec, kX0, &status); ParameterDef(status, kX0, xpixels / 2, &x0, inrec); y0 = drms_getkey_double(inrec, kY0, &status); ParameterDef(status, kY0, ypixels / 2, &y0, inrec); /* construct the output array */ length[0] = mapcols; length[1] = maprows; outarr = drms_array_create(DRMS_TYPE_FLOAT, 2, length, NULL, &status); if (status != DRMS_SUCCESS) { CreateBlankRecord(inrec, outrec, tobsstr); SkipErr(status, inrec, "unable to create output array"); drms_close_records(rs, DRMS_INSERT_RECORD); continue; } if (outarr) { /* Order is very important - the first will be freed before the second */ InsertLoopMemItem("arrayoutdata", outarr->data); InsertLoopMemItem("arrayout", outarr); } /* ??? how many of these attributes do we really need? */ /* ??? what attributes are missing ??? */ drms_setkey_string(outrec, kT_OBS, tobsstr); drms_copykey(outrec, inrec, kI_DREC); drms_copykey(outrec, inrec, kT_REC); drms_copykey(outrec, inrec, kQUALITY); drms_copykey(outrec, inrec, kMISSVALS); drms_setkey_int(outrec, kSN, rn); drms_setkey_int(outrec, kPIXELS, pixels); drms_setkey_double(outrec, kOBS_B0, b0); drms_setkey_double(outrec, kOBS_L0, obsl0); drms_setkey_int(outrec, kOBS_CR, obsCR); drms_setkey_double(outrec, kSOLAR_P, p); drms_setkey_double(outrec, kX0, x0); drms_setkey_double(outrec, kY0, y0); drms_setkey_int(outrec, kMAPMMAX, mapped_lmax); drms_setkey_int(outrec, kMAPCOLS, mapcols); drms_setkey_int(outrec, kMAPROWS, maprows); drms_setkey_double(outrec, kMAPLGMAX, longmax_adjusted); drms_setkey_double(outrec, kMAPLGMIN, longmin_adjusted); drms_setkey_double(outrec, kMAPBMAX, bmax); drms_setkey_double(outrec, kMAPBMIN, bmin); drms_setkey_double(outrec, kSINBDELT, sinBdelta); drms_setkey_double(outrec, kMAPRMAX, rmax); drms_setkey_int(outrec, kAPODIZE, apodization); drms_setkey_double(outrec, kAPINNER, apinner); drms_setkey_double(outrec, kAPWIDTH, apwidth); drms_setkey_int(outrec, kAPEL, apel); drms_setkey_double(outrec, kAPX, apx); drms_setkey_double(outrec, kAPY, apy); drms_setkey_int(outrec, kMCORLEV, mag_correction); drms_setkey_int(outrec, kVCORLEV, velocity_correction); drms_setkey_int(outrec, kINTERPO, interpolation); drms_setkey_int(outrec, kSHIFTFLG, longitude_shift); drms_setkey_double(outrec, kLSHIFT, longshift); drms_setkey_double(outrec, kMAP_L0, mapl0); /* Need to know whether the input was a 1-minute or 5-minute magnetogram */ drms_copykey(outrec, inrec, DPC); drms_copykey(outrec, inrec, DPC_STR); drms_copykey(outrec, inrec, DPC_OBSR); drms_copykey(outrec, inrec, DPC_FORM); drms_copykey(outrec, inrec, DPC_CROP); drms_copykey(outrec, inrec, DPC_ORGN); drms_copykey(outrec, inrec, DPC_RATE); drms_copykey(outrec, inrec, DPC_SMPL); drms_copykey(outrec, inrec, DPC_CONF); /* magsynop needs to know the build version of the fits files used. */ drms_copykey(outrec, inrec, BLDVER00); drms_copykey(outrec, inrec, BLDVER10); drms_copykey(outrec, inrec, BLDVER15); drms_copykey(outrec, inrec, BLDVER18); /* magsynop needs to know whether the fits file contains radial values or not. */ drms_copykey(outrec, inrec, FDRADIAL); drms_copykey(outrec, inrec, "series_num"); drms_copykey(outrec, inrec, "rn"); /* save the differential rotation correction parameters */ if (carrStretch) { int csVal = 1; drms_setkey_int(outrec, CARSTRCH, csVal); drms_setkey_float(outrec, DIFROT_A, diffrotA); drms_setkey_float(outrec, DIFROT_B, diffrotB); drms_setkey_float(outrec, DIFROT_C, diffrotC); } if (mag_offset) { float *dat = (float *)inarr->data; double bfitzero = drms_getkey_double(inrec, kBFITZERO, &status); int i; if (status == DRMS_SUCCESS || isnan(bfitzero)) { #if 0 /* XXX - not sure what to do with history. */ sds_append_history(out_sds, "MDI magnetogram zero level correction was requested but\n"); sds_append_history(out_sds, "BFITZERO keyword was not found. No correction was made.\n"); #endif } else { for (i = 0; i < pixels; ++i) { dat[i] -= (float)bfitzero; } #if 0 /* XXX - not sure what to do with history. */ sprintf(str, "An MDI magnetogram zero level correction of %.4g Gauss\n", bfitzero); sds_append_history(out_sds,str); sprintf(str, "was subtracted from the input image before remapping.\n"); sds_append_history(out_sds,str); #endif } } if (status = Obs2helio((float *)inarr->data, (float *)outarr->data, xpixels, ypixels, x0, y0, b0 * RADSINDEG, p * RADSINDEG, S, rsun, rmax, interpolation, mapcols, maprows, longmin_adjusted * RADSINDEG, longinterval * RADSINDEG, longshift * RADSINDEG, sinBdelta, smajor, sminor, sangle * RADSINDEG, xscale, yscale, orientation, mag_correction, velocity_correction, obs_vr, obs_vw, obs_vn, vsign, NaN_beyond_rmax, carrStretch, &distP, diffrotA, diffrotB, diffrotC, rRates, sizeof(rRates))) { CreateBlankRecord(inrec, outrec, tobsstr); SkipErr(status, inrec, "Failure in obs2helio"); drms_close_records(rs, DRMS_INSERT_RECORD); continue; /* go to next image */ } /* Output to log rotation rate (deg/day) vs. latitude */ if (debugLog) { fprintf(stdout, "latitude\tsidereal rotation rate (deg/day)\n"); for (row = 0; row < maprows && row < sizeof(rRates); row++) { fprintf(stdout, "%10f\t%32f\n", rRates[row].lat / RADSINDEG, rRates[row].r); } } if (status = apodize((float *)outarr->data, b0 * RADSINDEG, mapcols, maprows, longmin_adjusted * RADSINDEG, longinterval * RADSINDEG, sinBdelta, apodization, apinner, apwidth, apel, apx, apy)) { CreateBlankRecord(inrec, outrec, tobsstr); SkipErr(status, inrec, "Failure in apodize"); drms_close_records(rs, DRMS_INSERT_RECORD); continue; /* go to next image */ } if (outtype != DRMS_TYPE_FLOAT && outtype != DRMS_TYPE_RAW) { drms_array_convert_inplace(outtype, bias, scale, outarr); } /* Write to the out record */ if (!strcmp(kNOTSPECIFIED, segnameout)) { segout = drms_segment_lookupnum(outrec, 0); } else { segout = drms_segment_lookup(outrec, segnameout); } if (segout) { /* copy global keywords to out */ #if 0 /* XXX */ sds_append_attrs(out_vds->global_attributes, in_vds->global_attributes); vds_setkey_str(out_vds, "CONFORMS", "TS_EQ"); #endif drms_segment_write(segout, outarr, 0); drms_close_records(rs, DRMS_INSERT_RECORD); } gettimeofday(&tv, NULL); fprintf(stdout, "rn %d done (%f ms elapsed)\n", rn, (float)((tv.tv_sec * 1000000.0 + tv.tv_usec - (tv0.tv_sec * 1000000.0 + tv0.tv_usec)) / 1000.0)); FreeLoopMem(); } /* outrec && inrec */ } /* iRec */ } if (inRecSet) { drms_close_records(inRecSet, DRMS_FREE_RECORD); } gettimeofday(&tv, NULL); fprintf(stdout, "Total time spent %f ms\n", (float)((tv.tv_sec * 1000000.0 + tv.tv_usec - (tv0.tv_sec * 1000000.0 + tv0.tv_usec)) / 1000.0)); return error; } /* end v2helio_strategy */ static double V2Hstr2Time(const char *timestr, V2HStatus_t *stat) { /* convert keyword time format to UNIX time_t -- no fractional seconds */ time_t return_t = 0; static struct tm t; t.tm_isdst = 0; /* t.tm_gmtoff = 0; t.tm_zone = NULL;*/ if(!timestr) { *stat = V2HStatus_MissingParameter; } else if (sscanf(timestr,"%d.%d.%d_%d:%d:%d", &(t.tm_year), &(t.tm_mon), &(t.tm_mday), &(t.tm_hour), &(t.tm_min), &(t.tm_sec)) != 6) { *stat = V2HStatus_IllegalTimeFormat; } else { t.tm_mon -= 1; t.tm_year -= 1900; return_t = mktime(&t); *stat = (return_t == (time_t)-1) ? V2HStatus_TimeConvFailed : V2HStatus_Success; } return (double)return_t; } static void CheckO(const char *orientation, V2HStatus_t *stat) { /* check for legal orientation string */ static char o[MAXLEN]; char *c = o; if(!orientation) { *stat = V2HStatus_MissingParameter; } else if (4 != sscanf(orientation, "%[NS]%[EW]%[NS]%[EW]", c++, c++, c++, c++)) { *stat = V2HStatus_IllegalOrientation; } else if ((o[0] == o[2]) && (o[1] == o[3])) { *stat = V2HStatus_IllegalOrientation; } else if ((o[0] !=o [2]) && (o[1] != o[3])) { *stat = V2HStatus_IllegalOrientation; } else { *stat = V2HStatus_Success; } }
Karen Tian |
Powered by ViewCVS 0.9.4 |