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
00089
00090 #include <stdio.h>
00091 #include <math.h>
00092 #include <stdlib.h>
00093 #include <time.h>
00094 #include <sys/time.h>
00095 #include <sys/resource.h>
00096 #include <fftw3.h>
00097 #include "jsoc_main.h"
00098 #include "fstats.h"
00099 #include "drms_dsdsapi.h"
00100 #include "errlog.h"
00101 #include "projection.h"
00102 #include "atoinc.h"
00103
00104 #define ARRLENGTH(ARR) (sizeof(ARR)/sizeof(ARR[0]))
00105 #define PI (M_PI)
00106
00107 #define absval(x) (((x) < 0) ? (-(x)) : (x))
00108 #define minval(x,y) (((x) < (y)) ? (x) : (y))
00109 #define maxval(x,y) (((x) < (y)) ? (y) : (x))
00110 #define very_small (1.0e-30)
00111 #define is_very_small(x) (absval(x) < very_small)
00112 #define is_even(x) (!((x)%2))
00113 #define is_odd(x) ((x)%2)
00114
00115 #define RADSINDEG (PI/180)
00116 #define ARCSECSINRAD (3600*180/PI)
00117 #define DAYSINYEAR (365.2425)
00118 #define SECSINDAY (86400)
00119 #define TAU_A (499.004783806) // light travel time in seconds, = 1 AU/c
00120
00121 #define TCARR (25.38) // days
00122 #define RTRUE (6.96000000e8) // meters
00123 #define AU (149597870691) // meters/au
00124
00125
00126 #define QUAL_NODATA (0x80000000)
00127 #define QUAL_MIXEDCALVER (0x00000001)
00128 #define kNOTSPECIFIED "not specified"
00129
00130 char *module_name = "jv2ts";
00131 char *cvsinfo_jv2ts = "cvsinfo: $Header: /home/cvsuser/cvsroot/JSOC/proj/globalhs/apps/jv2ts.c,v 1.28 2017/06/22 23:24:12 tplarson Exp $";
00132
00133 ModuleArgs_t module_args[] =
00134 {
00135
00136 {ARG_STRING, "in", NULL, "input data records"},
00137 {ARG_STRING, "tsout", kNOTSPECIFIED, "output data series"},
00138 {ARG_STRING, "segin", kNOTSPECIFIED, "input data segment"},
00139 {ARG_STRING, "segout", kNOTSPECIFIED, "output data segment"},
00140 {ARG_STRING, "histlink", "HISTORY", "name of link to ancillary dataseries for processing metadata. specify \"none\" to suppress warning messages."},
00141 {ARG_STRING, "srclink", "SRCDATA", "name of link to source data"},
00142 {ARG_STRING, "v2hout", kNOTSPECIFIED, "output data series for jv2helio"},
00143 {ARG_STRING, "h2mout", kNOTSPECIFIED, "output data series for jhelio2mlat"},
00144 {ARG_INT, "PERM", "1", "set to 0 for transient records, nonzero for permanent records"},
00145 {ARG_INT, "VERB", "1", "option for level of verbosity: 0 gives only error and warning messages; >0 prints messages outside of loop; >1 prints messages inside loop; >2 for debugging output"},
00146 {ARG_INT, "FORCEOUTPUT", "0", "option to specify behavior on missing inputs; 0 gives an error on missing or duplicate inputs, >0 makes outputs regardless"},
00147 {ARG_INT, "ABORTONREADFAIL", "1", "set to 0 to skip records whose segment cannot be read; otherwise abort if any segments cannot be read."},
00148 {ARG_STRING, "TAG", "none", "this parameter sets a keyword of the same name to the same value, usually used as an additional primekey"},
00149 {ARG_STRING, "VERSION", kNOTSPECIFIED, "this parameter sets a keyword of the same name to the same value, useful for selecting obsolete records"},
00150 {ARG_INT, "CALVERKEY", "2", "short integer bit mask determining which 4-bit fields of CALVER64 are permitted to change on input. set the bit to disallow change of the corresponding nybble."},
00151
00152 {ARG_INT, "LMIN", "0", "minimum l in output"},
00153
00154 {ARG_INT, "LCHUNK", "0", "increment in l on output, default is lmax+1"},
00155 {ARG_INT, "NORM", "1", "set to nonzero to use cnorm=sinbdelta*sqrt(2) in sgemm call, otherwise use cnorm=1"},
00156 {ARG_TIME, "TSTART", NULL, "start time of first output record"},
00157 {ARG_STRING, "TTOTAL", NULL, "total length of time in output"},
00158 {ARG_STRING, "TCHUNK", kNOTSPECIFIED, "length of output timeseries"},
00159
00160 {ARG_INT, "LMAX", "300", "maximum l (maximum m) in the output, cannot be greater than MAPMMAX", NULL},
00161 {ARG_INT, "SUBMEAN", "0", "nonzero subtracts mean of input image", NULL},
00162 {ARG_INT, "NORMLIZE", "0", "nonzero multiplies by sqrt((fraction nonmissing)/2) for each row", NULL},
00163 {ARG_INT, "CENTLONG", "1", "nonzero centers the longitude Fourier transform on the center of the remapped image", NULL},
00164 {ARG_INT, "ZEROMISS", "0", "zero sets any row containing a NaN to DRMS_MISSING", NULL},
00165 {ARG_INT, "LGAPOD", "0", "nonzero apodizes in longitude", NULL},
00166 {ARG_DOUBLE, "LGAPMIN", "60.0", "start of longitude apodization, degrees", NULL},
00167 {ARG_DOUBLE, "LGAPWIDT", "10.0", "width of longitude apodization, degrees", NULL},
00168
00169 {ARG_INT, "LTAPOD", "0", "nonzero apodizes in latitude", NULL},
00170 {ARG_DOUBLE, "LTAPMIN", "60.0", "start of latitude apodization, degrees", NULL},
00171 {ARG_DOUBLE, "LTAPWIDT", "10.0", "width of latitude apodization, degrees", NULL},
00172
00173
00174 {ARG_INT, "MAPMMAX", "1536", "determines mapcols", ""},
00175 {ARG_INT, "SINBDIVS", "512", "number of increments in sin latitude from 0 to 1", ""},
00176 {ARG_FLOAT, "MAPRMAX", "0.95", "maximum image radius", ""},
00177 {ARG_INT, "NAN_BEYOND_RMAX", "0", "set to nonzero to set output to DRMS_MISSING outside MAPRMAX, otherwise uses 0.0 outside MAPRMAX"},
00178 {ARG_FLOAT, "MAPLGMAX", "72.0", "longitude maximum, degrees", ""},
00179 {ARG_FLOAT, "MAPLGMIN", "-72.0", "longitude minimum, degrees", ""},
00180 {ARG_FLOAT, "MAPBMAX", "72.0", "latitude maximum, degrees, also used for minimum", ""},
00181 {ARG_INT, "LGSHIFT", "0", "option for longitude shift: 0=none; 1=fixed rate; 2=nearest degree; 3=nearest tenth of a degree", ""},
00182 {ARG_TIME, "REF_T0", "1987.01.03_17:31:12_TAI", "reference time for computing fixed rate longitude shift", ""},
00183 {ARG_FLOAT, "REF_L0", "0.0", "reference longitude for computing fixed rate longitude shift ", ""},
00184 {ARG_FLOAT, "SOLAR_P", "999.0", "P-angle; if unset, taken from keywords", ""},
00185 {ARG_FLOAT, "PSIGN", "1.0", "sign of SOLAR_P", ""},
00186 {ARG_FLOAT, "PERR", "0.0", "fixed P-angle error, likely -0.22", ""},
00187 {ARG_FLOAT, "IERR", "0.0", "error in Carrington inclination, likely -0.10", ""},
00188 {ARG_TIME, "REF_TB0", "2001.06.06_06:57:22_TAI", "reference time for computing correction to P and B angles, roughly when B0=0", ""},
00189 {ARG_INT, "INTERPO", "1", "option for interpolation: 0=bilinear; 1=cubic convolution", ""},
00190 {ARG_INT, "APODIZE", "0", "option for apodization: 0=none; 1=use true solar coordinates; 2=use ideal solar coordinates (b0=0)", ""},
00191 {ARG_FLOAT, "APINNER", "0.0", "start of apodization in fractional image radius", ""},
00192 {ARG_FLOAT, "APWIDTH", "0.0", "width of apodization in fractional image radius", ""},
00193 {ARG_INT, "APEL", "0", "set to nonzero for elliptical apodization described by APX and APY", ""},
00194 {ARG_FLOAT, "APX", "1.00", "divide the x position by this before applying apodization", ""},
00195 {ARG_FLOAT, "APY", "1.00", "divide the y position by this before applying apodization", ""},
00196 {ARG_INT, "VCORLEV", "2", "option for velocity correction: 0=none; 1=subtract a model of differential rotation; 2=also divide by line of sight projection factor for purely radial velocities", ""},
00197 {ARG_INT, "MCORLEV", "0", "option for magnetic correction: 0=none; 1=line of sight; 2=radial", ""},
00198 {ARG_INT, "MOFFSETFLAG", "0", "set to nonzero to get BFITZERO from input record and subtract from data before interpolating", ""},
00199 {ARG_FLOAT, "OUTSCALE", "1.0", "bscale to use for output", ""},
00200 {ARG_FLOAT, "OUTBIAS", "0.0", "bzero to use for output", ""},
00201 {ARG_INT, "DISTORT", "0", "option for distortion correction: 0=none; 1=full disk(fd) data; 2=vector-weighted(vw) data", ""},
00202 {ARG_FLOAT, "CUBIC", "7.06E-9", "cubic distortion in fd units", ""},
00203 {ARG_FLOAT, "TILTALPHA", "2.59", "tilt of CCD, degrees", ""},
00204 {ARG_FLOAT, "TILTBETA", "56.0", "direction of CCD tilt, degrees", ""},
00205 {ARG_FLOAT, "TILTFEFF", "12972.629", "effective focal length", ""},
00206 {ARG_INT, "OFLAG", "0", "set to nonzero to force reading orientation from keyword, otherwise \"SESW\" is assumed)", ""},
00207 {ARG_INT, "DATASIGN", "0", "value to multiply data; set to 0 to take DATASIGN from keyword, or 1.0 if not found", ""},
00208 {ARG_INT, "MAXMISSVALS", "0", "if >0, this becomes threshold on MISSVALS from keyword", ""},
00209 {ARG_INT, "CARRSTRETCH", "0", "set to nonzero to correct for differential rotation according to DIFROT_[ABC]", ""},
00210 {ARG_FLOAT, "DIFROT_A", "13.562", "A coefficient in differential rotation adjustment (offset)", ""},
00211 {ARG_FLOAT, "DIFROT_B", "-2.04", "B coefficient (to sin(lat) ^ 2)", ""},
00212 {ARG_FLOAT, "DIFROT_C", "-1.4875", "C coefficient (to sin(lat) ^ 4)", ""},
00213
00214 {ARG_END}
00215 };
00216
00217 #include "saveparm.c"
00218 #include "timing.c"
00219 #include "set_history.c"
00220 #include "calversfunctions.c"
00221
00222 int SetDistort(int dist, double cubic, double alpha, double beta, double feff, LIBPROJECTION_Dist_t *dOut);
00223
00224 int obs2helio(float *V, float *U, int xpixels, int ypixels, double x0, double y0, double BZero, double P,
00225 double S, double rsun, double Rmax, int interpolation, int cols, int rows, double Lmin,
00226 double Ldelta, double Ladjust, double sinBdelta, double smajor, double sminor, double sangle,
00227 double xscale, double yscale, const char *orientation, int mag_correction, int velocity_correction,
00228 double obs_vr, double obs_vw, double obs_vn, double vsign, int NaN_beyond_rmax, int carrStretch,
00229 const LIBPROJECTION_Dist_t *distpars, float diffrotA, float diffrotB, float diffrotC,
00230 LIBPROJECTION_RotRate_t *rRates, int size);
00231
00232 int apodize(float *data, double b0, int cols, int rows, double Lmin, double Ldelta, double sinBdelta,
00233 int apodlevel, double apinner, double apwidth, int apel, double apx, double apy);
00234
00235
00236 int setplm2(int lmin,int lmax,int m,long nx,int *indx,double *x,long nplm,double *plm,double *dplm);
00237
00238
00239
00240
00241 void scopy_(int *, float *, int *, float *, int *);
00242 void setplm_(int *, int *, int *, int *, int *, double *, int *, double *);
00243 void sgemm_();
00244
00245 typedef enum
00246 {
00247 V2HStatus_Success,
00248 V2HStatus_MissingParameter,
00249 V2HStatus_IllegalTimeFormat,
00250 V2HStatus_TimeConvFailed,
00251 V2HStatus_Unimplemented,
00252 V2HStatus_IllegalOrientation
00253 } V2HStatus_t;
00254
00255 static void CheckO(const char *orientation, V2HStatus_t *stat)
00256 {
00257
00258 static char o[16];
00259 char *c = o;
00260
00261 if(!orientation)
00262 {
00263 *stat = V2HStatus_MissingParameter;
00264 }
00265 else if (4 != sscanf(orientation, "%[NS]%[EW]%[NS]%[EW]", c++, c++, c++, c++))
00266 {
00267 *stat = V2HStatus_IllegalOrientation;
00268 }
00269 else if ((o[0] == o[2]) && (o[1] == o[3]))
00270 {
00271 *stat = V2HStatus_IllegalOrientation;
00272 }
00273 else if ((o[0] !=o [2]) && (o[1] != o[3]))
00274 {
00275 *stat = V2HStatus_IllegalOrientation;
00276 }
00277 else
00278 {
00279 *stat = V2HStatus_Success;
00280 }
00281 }
00282
00283 static inline void ParameterDef(int status,
00284 char *pname,
00285 double defaultp,
00286 double *p,
00287 long long recnum,
00288 int verbflag)
00289 {
00290
00291 if (status != 0)
00292 {
00293 *p = defaultp;
00294 if (verbflag)
00295 fprintf(stderr, "WARNING: default value %g used for %s, status = %d, recnum = %lld\n", defaultp, pname, status, recnum);
00296 }
00297 }
00298
00299 #define PARAMETER_ERROR(PNAME) \
00300 if (status != DRMS_SUCCESS) \
00301 { \
00302 fprintf(stderr, "ERROR: problem with required keyword %s, status = %d, T_REC = %s, recnum = %lld, histrecnum = %lld\n", PNAME, status, trecstr, inrec->recnum, histrecnum); \
00303 drms_free_array(inarr); \
00304 return 0; \
00305 }
00306
00307
00308 int DoIt(void)
00309 {
00310 int newstat=0;
00311 DRMS_RecChunking_t chunkstat = kRecChunking_None;
00312 int fetchstat = DRMS_SUCCESS;
00313 int status = DRMS_SUCCESS;
00314 char *inrecquery = NULL;
00315 char *outseries = NULL;
00316 char *segnamein = NULL;
00317 char *segnameout = NULL;
00318 DRMS_RecordSet_t *inrecset = NULL;
00319 DRMS_Record_t *inrec = NULL;
00320 DRMS_Record_t *outrec = NULL;
00321 DRMS_Segment_t *segin = NULL;
00322 DRMS_Segment_t *segout = NULL;
00323 DRMS_Array_t *inarr = NULL;
00324 DRMS_Array_t *outarr = NULL;
00325 DRMS_Type_t usetype = DRMS_TYPE_FLOAT;
00326 DRMS_RecLifetime_t lifetime;
00327 long long histrecnum=-1;
00328 int length[2];
00329
00330 double wt0, wt1, wt2, wt3, wt;
00331 double ut0, ut1, ut2, ut3, ut;
00332 double st0, st1, st2, st3, st;
00333 double ct0, ct1, ct2, ct3, ct;
00334
00335 TIME trec, tnow, UNIX_epoch = -220924792.000;
00336 char trecstr[100], tstartstr[100];
00337
00338 int quality;
00339
00340 float *v2hptr, *h2mptr;
00341
00342
00343 float *oddpart, *evenpart, *inptr, *workptr, *mptr, *outptr;
00344 float *folded, *masks, *real4evenl, *real4oddl, *imag4evenl, *imag4oddl, *outx;
00345
00346
00347 double *plm, *saveplm, *latgrid;
00348 int *indx;
00349
00350 double sinBdelta;
00351 double *plmptr;
00352 float *maskptr;
00353
00354 int nsn, fournsn, snx, maxnsn;
00355 int lchunksize, lchunkfirst, lchunklast, lchunk, l;
00356 int lmin, lmax;
00357 int msize, mx, foldedsize;
00358 int maprows, nlat, imagesize, latx, poslatx, neglatx, moffset, nlatx;
00359 int i, m, modd, meven;
00360 int lfirst, llast, ifirst, ilast, lstart, ldone;
00361 int lfirsteven, llasteven, nevenl, lfirstodd, llastodd, noddl;
00362 int fromoffset, tooffset, imageoffset;
00363
00364 int increment1 = 1;
00365 int increment2 = 2;
00366
00367
00368 char transpose[] = "t";
00369 char normal[] = "n";
00370 float one = 1.0;
00371 float zero = 0.0;
00372 int normflag;
00373 float cnorm;
00374
00375 double tstart, tepoch, tstep, tround, cadence, nseconds, chunksecs, cadence0;
00376 char *ttotal, *tchunk;
00377 int nrecs, irec, trecind, bc, iset, ntimechunks;
00378 int *bad;
00379 int ndt;
00380
00381
00382 double mean, norm=1.0, normx;
00383 int subtract_mean, normalize, cent_long, zero_miss, lgapod, ltapod;
00384 double lgapmin, lgapwidt, lgapmax, lon, ltapmin, ltapwidt, ltapmax, lat;
00385
00386 int row, col;
00387 int lfft, mapped_lmax;
00388 int mapcols2;
00389 int nfft, nmean, nok, nout;
00390
00391 float *buf, *bp, *ip, *inp, *op, *outp, *weight, *wp, *weight2, *wp2;
00392 float *wbuf;
00393 fftwf_plan fftwp;
00394
00395
00396 V2HStatus_t vstat = V2HStatus_Success;
00397 const char *orientationdef = "SESW ";
00398 char *orientation = NULL;
00399 int paramsign;
00400 int longitude_shift, velocity_correction, interpolation, apodization;
00401 int mag_correction;
00402 int mag_offset;
00403 int sinb_divisions, mapcols, nmax, nmin;
00404 int carrStretch = 0;
00405 float diffrotA = 0.0;
00406 float diffrotB = 0.0;
00407 float diffrotC = 0.0;
00408 double tobs, tmearth, tref, trefb0;
00409 double smajor, sminor, sangle;
00410 double xscale, yscale, imagescale;
00411 int xpixels, ypixels, pixels;
00412 double obs_vr, obs_vw, obs_vn;
00413 double b0, bmax, bmin;
00414 double longmax, longmin, longmax_adjusted, longmin_adjusted, longinterval;
00415 double p0, p, rmax;
00416 double ierr, perr, psign;
00417 double x0, y0;
00418 double obsdist, longshift, obsl0, refl0, mapl0, longrate, rtrue, rsun, S;
00419 double rsunDef, rsunobs;
00420 int obsCR;
00421 int apel;
00422 double apinner, apwidth, apx, apy;
00423 double scale, bias;
00424 double colsperdeg;
00425
00426 double satrot, instrot;
00427 double dsignout, vsign;
00428 int distsave;
00429 double cubsave, tiltasave, tiltbsave, tiltfsave;
00430 LIBPROJECTION_Dist_t distP;
00431
00432 int errbufstat=setvbuf(stderr, NULL, _IONBF, BUFSIZ);
00433 int outbufstat=setvbuf(stdout, NULL, _IONBF, BUFSIZ);
00434
00435 wt0=getwalltime();
00436 ct0=getcputime(&ut0, &st0);
00437
00438 inrecquery = (char *)cmdparams_save_str(&cmdparams, "in", &newstat);
00439 outseries = (char *)cmdparams_save_str(&cmdparams, "tsout", &newstat);
00440 int tsflag = strcmp(kNOTSPECIFIED, outseries);
00441 segnamein = (char *)cmdparams_save_str(&cmdparams, "segin", &newstat);
00442 segnameout = (char *)cmdparams_save_str(&cmdparams, "segout", &newstat);
00443 int seginflag = strcmp(kNOTSPECIFIED, segnamein);
00444 int segoutflag = strcmp(kNOTSPECIFIED, segnameout);
00445 int verbflag = cmdparams_save_int(&cmdparams, "VERB", &newstat);
00446 int permflag = cmdparams_save_int(&cmdparams, "PERM", &newstat);
00447 if (permflag)
00448 lifetime = DRMS_PERMANENT;
00449 else
00450 lifetime = DRMS_TRANSIENT;
00451 int forceoutput = cmdparams_save_int(&cmdparams, "FORCEOUTPUT", &newstat);
00452 char *tag = (char *)cmdparams_save_str(&cmdparams, "TAG", &newstat);
00453 char *version = (char *)cmdparams_save_str(&cmdparams, "VERSION", &newstat);
00454 int verflag = strcmp(kNOTSPECIFIED, version);
00455 unsigned short calverkey = (unsigned short)cmdparams_save_int(&cmdparams, "CALVERKEY", &newstat);
00456
00457 char *histlinkname = (char *)cmdparams_save_str(&cmdparams, "histlink", &newstat);
00458 char *srclinkname = (char *)cmdparams_save_str(&cmdparams, "srclink", &newstat);
00459
00460 char *v2hout = (char *)cmdparams_save_str(&cmdparams, "v2hout", &newstat);
00461 char *h2mout = (char *)cmdparams_save_str(&cmdparams, "h2mout", &newstat);
00462 int v2hflag = strcmp(kNOTSPECIFIED, v2hout);
00463 int h2mflag = strcmp(kNOTSPECIFIED, h2mout);
00464 int histflag = strncasecmp("none", histlinkname, 4);
00465
00466 int abortflag = cmdparams_save_int(&cmdparams, "ABORTONREADFAIL", &newstat);
00467
00468
00469 if (!v2hflag && !h2mflag && !tsflag)
00470 {
00471 fprintf(stderr, "ERROR: no outputs specified.\n");
00472 return 1;
00473 }
00474
00475 lmin=cmdparams_save_int(&cmdparams, "LMIN", &newstat);
00476 lmax=cmdparams_save_int(&cmdparams, "LMAX", &newstat);
00477 lchunksize=cmdparams_save_int(&cmdparams, "LCHUNK", &newstat);
00478 normflag=cmdparams_save_int(&cmdparams, "NORM", &newstat);
00479
00480 tstart=cmdparams_save_time(&cmdparams, "TSTART", &newstat);
00481 sprint_time(tstartstr, tstart, "TAI", 0);
00482 ttotal=(char *)cmdparams_save_str(&cmdparams, "TTOTAL", &newstat);
00483 nseconds=atoinc(ttotal);
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 tchunk=(char *)cmdparams_save_str(&cmdparams, "TCHUNK", &newstat);
00502 if (strcmp(kNOTSPECIFIED, tchunk))
00503 {
00504 chunksecs=atoinc(tchunk);
00505
00506
00507
00508
00509
00510 }
00511 else if (!tsflag)
00512 {
00513 fprintf(stderr, "ERROR: TCHUNK must be specified if no tsout is given.\n");
00514 return 1;
00515 }
00516 else
00517 chunksecs=0.0;
00518
00519
00520 subtract_mean = cmdparams_save_int(&cmdparams, "SUBMEAN", &newstat);
00521 normalize = cmdparams_save_int(&cmdparams, "NORMLIZE", &newstat);
00522
00523
00524 cent_long = cmdparams_save_int(&cmdparams, "CENTLONG", &newstat);
00525
00526
00527 zero_miss = cmdparams_save_int(&cmdparams, "ZEROMISS", &newstat);
00528 lgapod = cmdparams_save_int(&cmdparams, "LGAPOD", &newstat);
00529 lgapmin = cmdparams_save_double(&cmdparams, "LGAPMIN", &newstat);
00530 lgapwidt = cmdparams_save_double(&cmdparams, "LGAPWIDT", &newstat);
00531 lgapmax = lgapmin+lgapwidt;
00532
00533 ltapod = cmdparams_save_int(&cmdparams, "LTAPOD", &newstat);
00534 ltapmin = cmdparams_save_double(&cmdparams, "LTAPMIN", &newstat);
00535 ltapwidt = cmdparams_save_double(&cmdparams, "LTAPWIDT", &newstat);
00536 ltapmax = ltapmin+ltapwidt;
00537
00538 int checko = cmdparams_save_int(&cmdparams, "OFLAG", &newstat);
00539 int NaN_beyond_rmax = cmdparams_save_int(&cmdparams, "NAN_BEYOND_RMAX", &newstat);
00540 int maxmissvals = cmdparams_save_int(&cmdparams, "MAXMISSVALS", &newstat);
00541
00542
00543 carrStretch = cmdparams_save_int(&cmdparams, "CARRSTRETCH", &newstat);
00544 diffrotA = cmdparams_save_float(&cmdparams, "DIFROT_A", &newstat);
00545 diffrotB = cmdparams_save_float(&cmdparams, "DIFROT_B", &newstat);
00546 diffrotC = cmdparams_save_float(&cmdparams, "DIFROT_C", &newstat);
00547
00548 longrate = 360.0 / TCARR - 360.0 / DAYSINYEAR;
00549 longrate /= SECSINDAY;
00550
00551 apodization = cmdparams_save_int(&cmdparams, "APODIZE", &newstat);
00552 apinner = cmdparams_save_double(&cmdparams, "APINNER", &newstat);
00553 apwidth = cmdparams_save_double(&cmdparams, "APWIDTH", &newstat);
00554 apel = cmdparams_save_int(&cmdparams, "APEL", &newstat);
00555 apx = cmdparams_save_double(&cmdparams, "APX", &newstat);
00556 apy = cmdparams_save_double(&cmdparams, "APY", &newstat);
00557 longitude_shift = cmdparams_save_int(&cmdparams, "LGSHIFT", &newstat);
00558 mag_correction = cmdparams_save_int(&cmdparams, "MCORLEV", &newstat);
00559 mag_offset = cmdparams_save_int(&cmdparams, "MOFFSETFLAG", &newstat);
00560 velocity_correction = cmdparams_save_int(&cmdparams, "VCORLEV", &newstat);
00561 interpolation = cmdparams_save_int(&cmdparams, "INTERPO", &newstat);
00562 paramsign = cmdparams_save_int(&cmdparams, "DATASIGN", &newstat);
00563 rmax = cmdparams_save_double(&cmdparams, "MAPRMAX", &newstat);
00564 refl0 = cmdparams_save_double(&cmdparams, "REF_L0", &newstat);
00565
00566 distsave = cmdparams_save_int(&cmdparams, "DISTORT", &newstat);
00567 cubsave = cmdparams_save_double(&cmdparams, "CUBIC", &newstat);
00568 tiltasave = cmdparams_save_double(&cmdparams, "TILTALPHA", &newstat);
00569 tiltbsave = cmdparams_save_double(&cmdparams, "TILTBETA", &newstat);
00570 tiltfsave = cmdparams_save_double(&cmdparams, "TILTFEFF", &newstat);
00571
00572 scale = cmdparams_save_double(&cmdparams, "OUTSCALE", &newstat);
00573 bias = cmdparams_save_double(&cmdparams, "OUTBIAS", &newstat);
00574 p0 = cmdparams_save_double(&cmdparams, "SOLAR_P", &newstat);
00575 psign = cmdparams_save_double(&cmdparams, "PSIGN", &newstat);
00576 perr = cmdparams_save_double(&cmdparams, "PERR", &newstat);
00577 ierr = cmdparams_save_double(&cmdparams, "IERR", &newstat);
00578 trefb0 = cmdparams_save_time(&cmdparams, "REF_TB0", &newstat);
00579
00580 SetDistort(distsave, cubsave, tiltasave, tiltbsave, tiltfsave, &distP);
00581
00582 tref = cmdparams_save_time(&cmdparams, "REF_T0", &newstat);
00583
00584
00585 mapped_lmax = cmdparams_save_int(&cmdparams, "MAPMMAX", &newstat);
00586 longmax = cmdparams_save_double(&cmdparams, "MAPLGMAX", &newstat);
00587 longmin = cmdparams_save_double(&cmdparams, "MAPLGMIN", &newstat);
00588 longinterval = (180.0) / mapped_lmax;
00589
00590
00591
00592
00593
00594 nmin = (int)(longmin / longinterval);
00595 nmax = (int)(longmax / longinterval);
00596 colsperdeg = mapped_lmax / 180.0;
00597 nmin = (int)(longmin * colsperdeg);
00598 nmax = (int)(longmax * colsperdeg);
00599 mapcols = nmax - nmin + 1;
00600 longmin_adjusted = nmin * longinterval;
00601 longmax_adjusted = nmax * longinterval;
00602
00603
00604 sinb_divisions = cmdparams_save_int(&cmdparams, "SINBDIVS", &newstat);
00605 sinBdelta = 1.0/sinb_divisions;
00606 bmax = cmdparams_save_double(&cmdparams, "MAPBMAX", &newstat);
00607 bmin = -bmax;
00608 nmax = (int)(sin(RADSINDEG*bmax)*sinb_divisions);
00609 maprows = 2*nmax;
00610
00611 if (normflag == 0)
00612 cnorm=1.0;
00613 else
00614 cnorm = sqrt(2.)*sinBdelta;
00615
00616 if (lmax > mapped_lmax || lmin > lmax)
00617 {
00618 fprintf(stderr, "ERROR: must have MAPMMAX >= LMAX >= LMIN, MAPMMAX = %d, LMAX= %d, LMIN = %d\n", mapped_lmax, lmax, lmin);
00619 return 1;
00620 }
00621
00622 if (newstat)
00623 {
00624 fprintf(stderr, "ERROR: problem with input arguments, status = %d, diagnosis follows\n", newstat);
00625 cpsave_decode_error(newstat);
00626 return 1;
00627 }
00628 else if (savestrlen != strlen(savestr))
00629 {
00630 fprintf(stderr, "ERROR: problem with savestr, savestrlen = %d, strlen(savestr) = %d\n", savestrlen, (int)strlen(savestr));
00631 return 1;
00632 }
00633
00634 DRMS_Record_t *tempoutrec;
00635 DRMS_Link_t *histlink;
00636 int itest;
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 if (tsflag)
00647 {
00648 tempoutrec = drms_create_record(drms_env, outseries, DRMS_TRANSIENT, &status);
00649 if (status != DRMS_SUCCESS)
00650 {
00651 fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", outseries, status);
00652 return 1;
00653 }
00654
00655 DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, "MAPMMAX");
00656 if (outkeytest != NULL && outkeytest->info->recscope == 1)
00657 {
00658 int mapmmaxout=drms_getkey_int(tempoutrec, "MAPMMAX", &status);
00659 if (mapmmaxout != mapped_lmax)
00660 {
00661 fprintf(stderr,"ERROR: output MAPMMAX=%d does not match input parameter MAPMMAX=%d, status = %d\n", mapmmaxout, mapped_lmax, status);
00662 return 1;
00663 }
00664 }
00665
00666 outkeytest = hcon_lookup_lower(&tempoutrec->keywords, "SINBDIVS");
00667 if (outkeytest != NULL && outkeytest->info->recscope == 1)
00668 {
00669 int sinbdivsout=drms_getkey_int(tempoutrec, "SINBDIVS", &status);
00670 if (sinbdivsout != sinb_divisions)
00671 {
00672 fprintf(stderr,"ERROR: output SINBDIVS=%d does not match input parameter SINBDIVS=%d, status = %d\n", sinbdivsout, sinb_divisions, status);
00673 return 1;
00674 }
00675 }
00676
00677 outkeytest = hcon_lookup_lower(&tempoutrec->keywords, "APINNER");
00678 if (outkeytest != NULL && outkeytest->info->recscope == 1)
00679 {
00680 float apinnerout=drms_getkey_float(tempoutrec, "APINNER", &status);
00681 if ((int)(10000*apinnerout) != (int)(10000*apinner))
00682 {
00683 fprintf(stderr,"ERROR: output APINNER=%f does not match input parameter APINNER=%f, status = %d\n", apinnerout, apinner, status);
00684 return 1;
00685 }
00686 }
00687
00688 outkeytest = hcon_lookup_lower(&tempoutrec->keywords, "APWIDTH");
00689 if (outkeytest != NULL && outkeytest->info->recscope == 1)
00690 {
00691 float apwidthout=drms_getkey_float(tempoutrec, "APWIDTH", &status);
00692 if ((int)(10000*apwidth) != (int)(10000*apwidth))
00693 {
00694 fprintf(stderr,"ERROR: output APWIDTH=%f does not match input parameter APWIDTH=%f, status = %d\n", apwidthout, apwidth, status);
00695 return 1;
00696 }
00697 }
00698
00699
00700 if (histflag)
00701 {
00702 histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname);
00703 if (histlink != NULL)
00704 {
00705 histrecnum=set_history(histlink);
00706 if (histrecnum < 0)
00707 {
00708 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00709 return 1;
00710 }
00711 }
00712 else
00713 {
00714 fprintf(stderr,"WARNING: could not find history link in output dataseries\n");
00715 }
00716 }
00717
00718
00719 char *outchecklist[] = {"T_START", "QUALITY", "LMIN", "LMAX", "NDT"};
00720 for (itest=0; itest < ARRLENGTH(outchecklist); itest++)
00721 {
00722 DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]);
00723 if (outkeytest == NULL || outkeytest->info->islink || outkeytest->info->recscope == 1)
00724 {
00725 fprintf(stderr, "ERROR: output keyword %s is either missing, constant, or a link\n", outchecklist[itest]);
00726 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00727 return 1;
00728 }
00729 }
00730
00731 cadence0=drms_getkey_float(tempoutrec, "T_STEP", &status);
00732 tepoch=drms_getkey_time(tempoutrec, "T_START_epoch", &status);
00733 tstep=drms_getkey_float(tempoutrec, "T_START_step", &status);
00734 tround=drms_getkey_float(tempoutrec, "T_START_round", &status);
00735 if (fmod(tstart-tepoch,tstep) > tround/2)
00736 {
00737 sprint_time(trecstr, tepoch, "TAI", 0);
00738 fprintf(stderr, "ERROR: output dataseries seems incompatible with input parameters (tstep must divide tstart-tepoch): TSTART = %s, T_START_epoch = %s, tstep = %f\n",
00739 tstartstr, trecstr, tstep);
00740 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00741 return 1;
00742 }
00743 if (chunksecs == 0.0)
00744 chunksecs = tstep;
00745 else if (fmod(chunksecs,tstep))
00746 {
00747 fprintf(stderr, "ERROR: output dataseries seems incompatible with input parameters (tstep must divide chunksecs): chunksecs = %f, tstep = %f\n", chunksecs, tstep);
00748 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00749 return 1;
00750 }
00751
00752 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00753 }
00754
00755 if (v2hflag)
00756 {
00757 tempoutrec = drms_create_record(drms_env, v2hout, DRMS_TRANSIENT, &status);
00758 if (status != DRMS_SUCCESS)
00759 {
00760 fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", v2hout, status);
00761 return 1;
00762 }
00763
00764
00765 if (histflag && histrecnum < 0)
00766 {
00767 histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname);
00768 if (histlink != NULL)
00769 {
00770 histrecnum=set_history(histlink);
00771 if (histrecnum < 0)
00772 {
00773 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00774 return 1;
00775 }
00776 }
00777 else
00778 {
00779 fprintf(stderr,"WARNING: could not find history link in output dataseries\n");
00780 }
00781 }
00782
00783
00784 char *outchecklist[] = {"T_REC", "QUALITY", "CRPIX1", "CRVAL1", "CDELT1", "CRPIX2", "CROTA2", "CDELT2" };
00785 for (itest=0; itest < ARRLENGTH(outchecklist); itest++)
00786 {
00787 DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]);
00788 if (outkeytest == NULL || outkeytest->info->islink || outkeytest->info->recscope == 1)
00789 {
00790 fprintf(stderr, "ERROR: output keyword %s is either missing, constant, or a link\n", outchecklist[itest]);
00791 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00792 return 1;
00793 }
00794 }
00795
00796 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00797 }
00798
00799 if (h2mflag)
00800 {
00801 tempoutrec = drms_create_record(drms_env, h2mout, DRMS_TRANSIENT, &status);
00802 if (status != DRMS_SUCCESS)
00803 {
00804 fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", h2mout, status);
00805 return 1;
00806 }
00807
00808
00809 if (histflag && histrecnum < 0)
00810 {
00811 histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname);
00812 if (histlink != NULL)
00813 {
00814 histrecnum=set_history(histlink);
00815 if (histrecnum < 0)
00816 {
00817 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00818 return 1;
00819 }
00820 }
00821 else
00822 {
00823 fprintf(stderr,"WARNING: could not find history link in output dataseries\n");
00824 }
00825 }
00826
00827
00828 char *outchecklist[] = {"T_REC", "QUALITY", "CRPIX1", "CDELT1", "CRPIX2", "CDELT2" };
00829 for (itest=0; itest < ARRLENGTH(outchecklist); itest++)
00830 {
00831 DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]);
00832 if (outkeytest == NULL || outkeytest->info->islink || outkeytest->info->recscope == 1)
00833 {
00834 fprintf(stderr, "ERROR: output keyword %s is either missing, constant, or a link\n", outchecklist[itest]);
00835 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00836 return 1;
00837 }
00838 }
00839
00840 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00841 }
00842
00843
00844 if (fmod(nseconds,chunksecs) != 0.0)
00845 {
00846 fprintf(stderr, "ERROR: input parameters seem incompatible (chunksecs must divide totalsecs): totalsecs = %f, chunksecs = %f\n", nseconds, chunksecs);
00847 return 1;
00848 }
00849 ntimechunks=nseconds/chunksecs;
00850
00851 inrecset = drms_open_recordset(drms_env, inrecquery, &status);
00852 if (status != DRMS_SUCCESS || inrecset == NULL)
00853 {
00854 fprintf(stderr, "ERROR: problem opening input recordset: status = %d\n", status);
00855 return 1;
00856 }
00857
00858 int nrecsin = drms_count_records(drms_env, inrecquery, &status);
00859 if (status != DRMS_SUCCESS)
00860 {
00861 fprintf(stderr, "ERROR: problem counting input records: status = %d, nrecs = %d\n", status, nrecsin);
00862 drms_close_records(inrecset, DRMS_FREE_RECORD);
00863 return 1;
00864 }
00865 if (nrecsin == 0)
00866 {
00867 fprintf(stderr, "ERROR: input recordset contains no records. if such was intended use jretile instead.\n");
00868 drms_close_records(inrecset, DRMS_FREE_RECORD);
00869 return 1;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 if (verbflag)
00883 printf("input recordset opened, nrecs = %d\n", nrecsin);
00884
00885 inrec = drms_recordset_fetchnext(drms_env, inrecset, &fetchstat, &chunkstat, NULL);
00886
00887
00888 char *inchecklist[] = {"T_REC", "QUALITY", "T_OBS", "CRLT_OBS", "CRLN_OBS", "CADENCE",
00889
00890 "CDELT1", "CDELT2"};
00891
00892 DRMS_Keyword_t *inkeytest;
00893 for (itest=0; itest < ARRLENGTH(inchecklist); itest++)
00894 {
00895 inkeytest = hcon_lookup_lower(&inrec->keywords, inchecklist[itest]);
00896 if (inkeytest == NULL)
00897 {
00898 fprintf(stderr, "ERROR: required input keyword %s is missing\n", inchecklist[itest]);
00899 drms_close_records(inrecset, DRMS_FREE_RECORD);
00900 return 1;
00901 }
00902 }
00903
00904 int readrsunref=0;
00905 double rsunref;
00906 inkeytest = hcon_lookup_lower(&inrec->keywords, "RSUN_REF");
00907 if (inkeytest == NULL)
00908 rtrue = RTRUE/AU;
00909 else if (inkeytest->info->recscope == 1)
00910 {
00911 rsunref = drms_getkey_double(inrec, "RSUN_REF", &status);
00912 ParameterDef(status, "RSUN_REF", RTRUE, &rsunref, inrec->recnum, 1);
00913 rtrue=rsunref/AU;
00914 }
00915 else
00916 readrsunref=1;
00917
00918 trec = drms_getkey_time(inrec, "T_REC", &status);
00919 if (status != DRMS_SUCCESS)
00920 {
00921 fprintf(stderr, "ERROR: problem with required parameter T_REC: status = %d, recnum = %lld\n", status, inrec->recnum);
00922 drms_close_records(inrecset, DRMS_FREE_RECORD);
00923 return 1;
00924 }
00925 sprint_time(trecstr, trec, "TAI", 0);
00926
00927 cadence=drms_getkey_float(inrec, "CADENCE", &status);
00928 if (status != DRMS_SUCCESS)
00929 {
00930 fprintf(stderr, "ERROR: problem with required parameter CADENCE: status = %d, T_REC = %s, recnum = %lld\n", status, trecstr, inrec->recnum);
00931 drms_close_records(inrecset, DRMS_FREE_RECORD);
00932 return 1;
00933 }
00934
00935 if (!forceoutput)
00936 {
00937 if (nrecsin != nseconds/cadence)
00938 {
00939 fprintf(stderr, "ERROR: input recordset does not contain a record for every slot.\n");
00940 drms_close_records(inrecset, DRMS_FREE_RECORD);
00941 return 1;
00942 }
00943 }
00944
00945 if (tsflag && cadence != cadence0)
00946 {
00947 fprintf(stderr, "ERROR: input CADENCE does not match output T_STEP: status = %d, T_REC = %s, recnum = %lld\n", status, trecstr, inrec->recnum);
00948 drms_close_records(inrecset, DRMS_FREE_RECORD);
00949 return 1;
00950 }
00951
00952 nrecs=chunksecs/cadence;
00953 maxnsn=nsn=nrecs;
00954 fournsn=4*nsn;
00955
00956 if (verbflag)
00957 printf("ntimechunks = %d, recs per timechunk = %d\n", ntimechunks, nrecs);
00958
00959
00960 if (trec >= tstart + nseconds)
00961 {
00962 fprintf(stderr, "ERROR: no records processed: first input record is after last output record: T_REC = %s\n", trecstr);
00963 drms_close_records(inrecset, DRMS_FREE_RECORD);
00964 return 1;
00965 }
00966
00967 while (trec < tstart && chunkstat != kRecChunking_NoMoreRecs)
00968 {
00969 fprintf(stderr, "WARNING: input record will not be included in output: T_REC = %s, TSTART = %s \n", trecstr, tstartstr);
00970 inrec = drms_recordset_fetchnext(drms_env, inrecset, &fetchstat, &chunkstat, NULL);
00971 if (inrec != NULL)
00972 {
00973 trec = drms_getkey_time(inrec, "T_REC", &status);
00974 sprint_time(trecstr, trec, "TAI", 0);
00975 }
00976 }
00977 if (chunkstat == kRecChunking_NoMoreRecs)
00978 {
00979 fprintf(stderr,"ERROR: no records processed: last input record is before first output record: T_REC = %s\n", trecstr);
00980 drms_close_records(inrecset, DRMS_FREE_RECORD);
00981 return 1;
00982 }
00983
00984 msize = lmax+1;
00985 if (lchunksize == 0) lchunksize = msize;
00986
00987 nlat = maprows/2;
00988 imagesize = maprows*2*msize;
00989
00990 nout = 2 * (lmax + 1);
00991
00992 lfft = 2 * mapped_lmax;
00993 nfft = lfft + 2;
00994 mapcols2 = mapcols/2;
00995
00996
00997
00998
00999
01000
01001
01002 if (nlat % 4)
01003 nlatx=4*(nlat/4+1);
01004 else
01005 nlatx=nlat;
01006
01007
01008 DRMS_RecordSet_t *outrecset, *v2hrecset, *h2mrecset;
01009 if (tsflag)
01010 {
01011 real4evenl = (float *)(malloc (nlatx*maxnsn*sizeof(float)));
01012 real4oddl = (float *)(malloc (nlatx*maxnsn*sizeof(float)));
01013 imag4evenl = (float *)(malloc (nlatx*maxnsn*sizeof(float)));
01014 imag4oddl = (float *)(malloc (nlatx*maxnsn*sizeof(float)));
01015 outx = (float *)(malloc (maxnsn*2*lchunksize*sizeof(float)));
01016
01017 plm = (double *)(malloc ((lmax+1)*nlat*sizeof(double)));
01018 saveplm = (double *)(malloc ((lmax+1)*nlat*2*sizeof(double)));
01019 latgrid = (double *)(malloc (nlat*sizeof(double)));
01020 for (i=0; i<nlat; i++) latgrid[i] = (i+0.5)*sinBdelta;
01021
01022 indx = (int *)(malloc ((lmax+1)*sizeof(int)));
01023 for (l=0; l<=lmax; l++) indx[l]=l;
01024
01025 masks = (float *)(malloc (nlat*lchunksize*sizeof(float)));
01026 foldedsize = 4*nlat*(lmax+1)*maxnsn;
01027 folded = (float *)(malloc (foldedsize*sizeof(float)));
01028 oddpart = (float *)(malloc (nlat*sizeof(float)));
01029 evenpart = (float *)(malloc (nlat*sizeof(float)));
01030
01031 lchunkfirst = lmin/lchunksize;
01032 lchunklast = lmax/lchunksize;
01033 int nlchunks = (lchunklast - lchunkfirst) + 1;
01034 int nrecsout = nlchunks*ntimechunks;
01035 outrecset = drms_create_records(drms_env, nrecsout, outseries, lifetime, &status);
01036 if (status != DRMS_SUCCESS || outrecset == NULL)
01037 {
01038 fprintf(stderr,"ERROR: unable to create records in output dataseries %s, status = %d\n", outseries, status);
01039 drms_close_records(inrecset, DRMS_FREE_RECORD);
01040 return 1;
01041 }
01042
01043 }
01044
01045 if (v2hflag)
01046 {
01047 v2hrecset = drms_create_records(drms_env, nrecsin, v2hout, lifetime, &status);
01048 if (status != DRMS_SUCCESS || v2hrecset == NULL)
01049 {
01050 fprintf(stderr,"ERROR: unable to create records in output dataseries %s, status = %d\n", v2hout, status);
01051 drms_close_records(inrecset, DRMS_FREE_RECORD);
01052 return 1;
01053 }
01054 }
01055
01056 if (h2mflag)
01057 {
01058 h2mrecset = drms_create_records(drms_env, nrecsin, h2mout, lifetime, &status);
01059 if (status != DRMS_SUCCESS || h2mrecset == NULL)
01060 {
01061 fprintf(stderr,"ERROR: unable to create records in output dataseries %s, status = %d\n", h2mout, status);
01062 drms_close_records(inrecset, DRMS_FREE_RECORD);
01063 return 1;
01064 }
01065 }
01066
01067
01068 bad = (int *)(malloc (nrecs*sizeof(int)));
01069 v2hptr = (float *)(malloc(maprows*mapcols*sizeof(float)));
01070 h2mptr = (float *)(malloc(maprows*nout*sizeof(float)));
01071
01072
01073 buf = (float *)malloc(nfft * sizeof(float));
01074
01075 wbuf = (float *)malloc(nfft * sizeof(float));
01076 fftwp = fftwf_plan_r2r_1d(lfft, buf, wbuf, FFTW_R2HC, FFTW_ESTIMATE);
01077
01078
01079 weight = (float *)malloc(nfft * sizeof(float));
01080 weight2 = (float *)malloc(maprows * sizeof(float));
01081
01082 wp = weight;
01083 for (col=0; col<mapcols; col++)
01084 {
01085 if (lgapod)
01086 {
01087 lon=abs(col-mapcols2)*360.0/(2*mapped_lmax);
01088 if (lon < lgapmin)
01089 *wp++=1.0;
01090 else if (lon < lgapmax)
01091 *wp++=0.5+0.5*cos(PI*(lon-lgapmin)/lgapwidt);
01092 else
01093 *wp++=0.0;
01094 }
01095 else
01096 *wp++ = 1.0;
01097 }
01098
01099 double latweight;
01100 double sinBbase = 0.5-maprows/2;
01101 wp2 = weight2;
01102
01103 for (row=0; row<maprows; row++)
01104 {
01105 if (ltapod)
01106 {
01107 lat=abs(asin(sinBdelta*(sinBbase + row))*180.0/PI);
01108 if (lat < ltapmin)
01109 *wp2++=1.0;
01110 else if (lat < ltapmax)
01111 *wp2++=0.5+0.5*cos(PI*(lat-ltapmin)/ltapwidt);
01112 else
01113 *wp2++=0.0;
01114 }
01115 else
01116 *wp2++ = 1.0;
01117 }
01118
01119
01120 status=drms_stage_records(inrecset, 1, 0);
01121 if (status != DRMS_SUCCESS)
01122 {
01123 fprintf(stderr, "ERROR: drms_stage_records returned status = %d\n", status);
01124 return 1;
01125 }
01126
01127 unsigned long long calversout, calvers;
01128 int calversunset=1;
01129 unsigned int nybblearrout[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
01130 int fixflagarr[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
01131 for (i=0;i<16;i++)
01132 {
01133 if (getbits(calverkey,i,1))
01134 fixflagarr[i]=1;
01135 }
01136
01137 int mixflag=0;
01138
01139 int nrecords=0;
01140 int nsegments=0;
01141 int error=0;
01142 int nodata=0;
01143 int irecout=0;
01144 int iv2hrec=0;
01145 int ih2mrec=0;
01146 for (iset=0; iset < ntimechunks && chunkstat != kRecChunking_NoMoreRecs; iset++)
01147 {
01148 sprint_time(tstartstr, tstart, "TAI", 0);
01149 if (verbflag)
01150 {
01151 wt1=getwalltime();
01152 ct1=getcputime(&ut1, &st1);
01153 printf("processing timechunk %d, tstart = %s\n", iset, tstartstr);
01154 }
01155
01156 if (trec >= tstart+chunksecs)
01157 {
01158 if (forceoutput)
01159 {
01160 nodata=1;
01161 goto skip_norecs;
01162 }
01163 else
01164 {
01165 fprintf(stderr, "ERROR: no data for timechunk beginning at %s\n", tstartstr);
01166 error++;
01167 tstart+=chunksecs;
01168 continue;
01169 }
01170 }
01171
01172 while (trec < tstart && chunkstat != kRecChunking_NoMoreRecs)
01173 {
01174 inrec = drms_recordset_fetchnext(drms_env, inrecset, &fetchstat, &chunkstat, NULL);
01175 if (inrec != NULL)
01176 {
01177 trec = drms_getkey_time(inrec, "T_REC", &status);
01178 sprint_time(trecstr, trec, "TAI", 0);
01179 }
01180 }
01181
01182 bc=0;
01183 nodata=0;
01184 mixflag=0;
01185 calversunset=1;
01186 trecind=(trec-tstart+cadence/2)/cadence;
01187
01188 for (irec=0; irec < nrecs && chunkstat != kRecChunking_NoMoreRecs; irec++)
01189 {
01190
01191 if (trecind > irec)
01192
01193 {
01194 if (forceoutput)
01195 {
01196 bad[bc++]=irec;
01197 continue;
01198 }
01199 else
01200 {
01201 fprintf(stderr, "ERROR: some input records missing, T_START = %s, T_REC = %s, irec = %d\n", tstartstr, trecstr, irec);
01202 error++;
01203 goto continue_outer_loop;
01204 }
01205 }
01206
01207 while (trecind < irec && chunkstat != kRecChunking_NoMoreRecs)
01208
01209 {
01210 if (forceoutput)
01211 {
01212 inrec = drms_recordset_fetchnext(drms_env, inrecset, &fetchstat, &chunkstat, NULL);
01213 if (inrec != NULL)
01214 {
01215 trec = drms_getkey_time(inrec, "T_REC", &status);
01216 sprint_time(trecstr, trec, "TAI", 0);
01217 trecind=(trec-tstart+cadence/2)/cadence;
01218 }
01219 }
01220 else
01221 {
01222 fprintf(stderr, "ERROR: some input records have duplicate T_REC, T_START = %s, T_REC = %s, irec = %d\n", tstartstr, trecstr, irec);
01223 error++;
01224 goto continue_outer_loop;
01225 }
01226 }
01227
01228 if (verbflag > 1)
01229 {
01230 wt2=getwalltime();
01231 ct2=getcputime(&ut2, &st2);
01232 printf(" processing record %d\n", irec);
01233 }
01234
01235 quality=drms_getkey_int(inrec, "QUALITY", &status);
01236 if (status != DRMS_SUCCESS || (quality & QUAL_NODATA))
01237 {
01238 bad[bc++]=irec;
01239 if (verbflag > 2)
01240 fprintf(stderr, "SKIP: image rejected based on quality: T_REC = %s, quality = %08x\n", trecstr, quality);
01241 goto skip;
01242 }
01243
01244 if (tsflag)
01245 {
01246 if (calversunset)
01247 {
01248 calversout=drms_getkey_longlong(inrec, "CALVER64", &status);
01249 if (status != DRMS_SUCCESS)
01250 calversout = 0;
01251 else
01252 calversout = fixcalver64(calversout);
01253 calversunset=0;
01254
01255 for (i=0;i<16;i++)
01256 nybblearrout[i]=getbits(calversout,4*i+3,4);
01257
01258 }
01259
01260 calvers=drms_getkey_longlong(inrec, "CALVER64", &status);
01261 if (status != DRMS_SUCCESS)
01262 calvers = 0;
01263 else
01264 calvers = fixcalver64(calvers);
01265
01266 for (i=0;i<16;i++)
01267 {
01268 int nybble=getbits(calvers,4*i+3,4);
01269 if (fixflagarr[i])
01270 {
01271 if (nybble != nybblearrout[i])
01272 {
01273 fprintf(stderr, "ERROR: input data has mixed values for field %d of CALVER64: %d and %d, recnum = %lld, histrecnum = %lld\n", i, nybblearrout[i], nybble, inrec->recnum, histrecnum);
01274 error++;
01275 goto continue_outer_loop;
01276 }
01277 }
01278 else
01279 {
01280 if (nybble < nybblearrout[i])
01281 nybblearrout[i]=nybble;
01282 }
01283 }
01284
01285 if (!mixflag && calvers != calversout)
01286 mixflag=1;
01287 }
01288
01289
01290 if (seginflag)
01291 segin = drms_segment_lookup(inrec, segnamein);
01292 else
01293 segin = drms_segment_lookupnum(inrec, 0);
01294 if (segin != NULL)
01295 inarr = drms_segment_read(segin, usetype, &status);
01296
01297 if (segin == NULL || inarr == NULL || status != DRMS_SUCCESS)
01298 {
01299 if (abortflag)
01300 {
01301 fprintf(stderr, "ERROR: problem with input segment or array: status = %d, T_REC = %s, recnum = %lld, histrecnum = %lld\n", status, trecstr, inrec->recnum, histrecnum);
01302 return 0;
01303
01304 }
01305 else
01306 {
01307 bad[bc++]=irec;
01308 if (verbflag)
01309 fprintf(stderr, "SKIP: image segment could not be read: T_REC = %s\n", trecstr);
01310 goto skip;
01311 }
01312 }
01313
01314 if (maxmissvals > 0)
01315 {
01316 int missvals = drms_getkey_int(inrec, "MISSVALS", &status);
01317 PARAMETER_ERROR("MISSVALS")
01318 if (missvals > maxmissvals)
01319 {
01320 bad[bc++]=irec;
01321 if (verbflag > 1)
01322 fprintf(stderr, "SKIP: %d pixels MISSING, max allowed is %d: T_REC = %s, recnum = %lld\n", missvals, maxmissvals, trecstr, inrec->recnum);
01323 drms_free_array(inarr);
01324 goto skip;
01325 }
01326 }
01327
01328 tobs = drms_getkey_time(inrec, "T_OBS", &status);
01329 PARAMETER_ERROR("T_OBS")
01330
01331
01332 b0 = drms_getkey_double(inrec, "CRLT_OBS", &status);
01333 PARAMETER_ERROR("CRLT_OBS")
01334
01335
01336 obsl0 = drms_getkey_double(inrec, "CRLN_OBS", &status);
01337 PARAMETER_ERROR("CRLN_OBS")
01338
01339 if (p0 == 999.0)
01340 {
01341
01342
01343
01344
01345
01346
01347
01348
01349 double crota = drms_getkey_double(inrec, "CROTA2", &status);
01350 PARAMETER_ERROR("CROTA2")
01351 p=-crota;
01352 }
01353 else
01354 {
01355 p = p0;
01356 }
01357
01358 p = psign * p ;
01359 b0 = b0 + ierr * sin((tobs - trefb0) / 31557600. * 2 * PI);
01360 p = p + perr - ierr * cos((tobs - trefb0) / 31557600. * 2 * PI);
01361
01362
01363 smajor = drms_getkey_double(inrec, "S_MAJOR", &status);
01364 ParameterDef(status, "S_MAJOR", 1.0, &smajor, inrec->recnum, 0);
01365
01366 sminor = drms_getkey_double(inrec, "S_MINOR", &status);
01367 ParameterDef(status, "S_MINOR", 1.0, &sminor, inrec->recnum, 0);
01368
01369 sangle = drms_getkey_double(inrec, "S_ANGLE", &status);
01370 ParameterDef(status, "S_ANGLE", 0.0, &sangle, inrec->recnum, 0);
01371
01372
01373
01374
01375
01376
01377 xscale = drms_getkey_double(inrec, "CDELT1", &status);
01378 PARAMETER_ERROR("CDELT1")
01379 yscale = drms_getkey_double(inrec, "CDELT2", &status);
01380 PARAMETER_ERROR("CDELT2")
01381
01382
01383 if (xscale != yscale)
01384 {
01385 fprintf(stderr, "ERROR: CDELT1 != CDELT2 not supported, CDELT1 = %f, CDELT2 = %f: T_REC = %s, recnum = %lld \n", xscale, yscale, trecstr, inrec->recnum);
01386 drms_free_array(inarr);
01387 error++;
01388 goto continue_outer_loop;
01389 }
01390 imagescale=xscale;
01391 xscale=1.0;
01392 yscale=1.0;
01393
01394
01395
01396
01397
01398
01399 if (paramsign != 0)
01400 {
01401 vsign = paramsign;
01402 }
01403 else
01404 {
01405 vsign = drms_getkey_double(inrec, "DATASIGN", &status);
01406 ParameterDef(status, "DATASIGN", 1.0, &vsign, inrec->recnum, 1);
01407 }
01408
01409 if (velocity_correction)
01410 {
01411 obs_vr = drms_getkey_double(inrec, "OBS_VR", &status);
01412 ParameterDef(status, "OBS_VR", 0.0, &obs_vr, inrec->recnum, 1);
01413
01414 obs_vw = drms_getkey_double(inrec, "OBS_VW", &status);
01415 ParameterDef(status, "OBS_VW", 0.0, &obs_vw, inrec->recnum, 1);
01416
01417 obs_vn = drms_getkey_double(inrec, "OBS_VN", &status);
01418 ParameterDef(status, "OBS_VN", 0.0, &obs_vn, inrec->recnum, 1);
01419 }
01420
01421
01422 obsdist = drms_getkey_double(inrec, "DSUN_OBS", &status) / AU;
01423
01424 ParameterDef(status, "OBS_DIST", 1.0, &obsdist, inrec->recnum, 1);
01425 if (readrsunref)
01426 {
01427 rsunref = drms_getkey_double(inrec, "RSUN_REF", &status);
01428 ParameterDef(status, "RSUN_REF", RTRUE, &rsunref, inrec->recnum, 1);
01429 rtrue=rsunref/AU;
01430 }
01431 S = rtrue / obsdist;
01432
01433 rsunobs = drms_getkey_double(inrec, "RSUN_OBS", &status);
01434 if (status == DRMS_SUCCESS)
01435 rsun = rsunobs/imagescale;
01436 else
01437 {
01438 rsun = drms_getkey_double(inrec, "R_SUN", &status);
01439 if (status != DRMS_SUCCESS)
01440 rsun = ARCSECSINRAD * S / sqrt(1.0 - S * S) / imagescale;
01441 }
01442
01443 if (longitude_shift == 1)
01444 {
01445 tmearth = tobs+TAU_A*(1.0-obsdist);
01446 longshift = (obsl0-refl0)+longrate*(tmearth-tref);
01447 while (longshift > 180.0) longshift-=360.0;
01448 while (longshift < -180.0) longshift+=360.0;
01449 }
01450 else if (longitude_shift == 2)
01451 {
01452 longshift = obsl0 - (int)(obsl0);
01453 if (longshift > 0.5) longshift -= 1.0;
01454 }
01455 else if (longitude_shift == 3)
01456 {
01457 longshift = (obsl0 * 10 - (int)(obsl0 * 10)) / 10;
01458 if (longshift > 0.5) longshift -= 1.0;
01459 }
01460 else
01461 {
01462 longshift = 0.0;
01463 }
01464
01465 mapl0 = obsl0 - longshift;
01466
01467 xpixels = inarr->axis[0];
01468 ypixels = inarr->axis[1];
01469 pixels = xpixels * ypixels;
01470
01471
01472 x0 = drms_getkey_double(inrec, "CRPIX1", &status);
01473 ParameterDef(status, "CRPIX1", xpixels / 2, &x0, inrec->recnum, 1);
01474 x0 -= 1.0;
01475
01476
01477 y0 = drms_getkey_double(inrec, "CRPIX2", &status);
01478 ParameterDef(status, "CRPIX2", ypixels / 2, &y0, inrec->recnum, 1);
01479 y0 -= 1.0;
01480
01481 if (mag_offset)
01482 {
01483 float *dat = (float *)inarr->data;
01484 double bfitzero = drms_getkey_double(inrec, "BFITZERO", &status);
01485 PARAMETER_ERROR("BFITZERO")
01486 int i;
01487
01488 if (!isnan(bfitzero))
01489 {
01490 for (i = 0; i < pixels; ++i)
01491 {
01492 dat[i] -= (float)bfitzero;
01493 }
01494
01495 }
01496 }
01497
01498 if (checko)
01499 {
01500 orientation = drms_getkey_string(inrec, "ORIENT", &status);
01501 PARAMETER_ERROR("ORIENT")
01502 CheckO(orientation, &vstat);
01503 if (vstat != V2HStatus_Success)
01504 {
01505 fprintf(stderr,"ERROR: illegal ORIENT: T_REC = %s, recnum = %lld\n", trecstr, inrec->recnum);
01506 drms_free_array(inarr);
01507 free(orientation);
01508 error++;
01509 goto continue_outer_loop;
01510 }
01511 }
01512 else
01513 {
01514 orientation = strdup(orientationdef);
01515 }
01516
01517 if (status = obs2helio((float *)inarr->data,
01518 v2hptr,
01519 xpixels,
01520 ypixels,
01521 x0,
01522 y0,
01523 b0 * RADSINDEG,
01524 p * RADSINDEG,
01525 S,
01526 rsun,
01527 rmax,
01528 interpolation,
01529 mapcols,
01530 maprows,
01531 longmin_adjusted * RADSINDEG,
01532 longinterval * RADSINDEG,
01533 longshift * RADSINDEG,
01534 sinBdelta,
01535 smajor,
01536 sminor,
01537 sangle * RADSINDEG,
01538 xscale,
01539 yscale,
01540 orientation,
01541 mag_correction,
01542 velocity_correction,
01543 obs_vr,
01544 obs_vw,
01545 obs_vn,
01546 vsign,
01547 NaN_beyond_rmax,
01548 carrStretch,
01549 &distP,
01550 diffrotA,
01551 diffrotB,
01552 diffrotC,
01553 NULL,
01554 0))
01555 {
01556 fprintf(stderr, "ERROR: failure in obs2helio: status = %d, T_REC = %s, recnum = %lld\n", status, trecstr, inrec->recnum);
01557 drms_free_array(inarr);
01558 free(orientation);
01559 error++;
01560 goto continue_outer_loop;
01561 }
01562 drms_free_array(inarr);
01563 free(orientation);
01564
01565 if (status = apodize(v2hptr,
01566 b0 * RADSINDEG,
01567 mapcols,
01568 maprows,
01569 longmin_adjusted * RADSINDEG,
01570 longinterval * RADSINDEG,
01571 sinBdelta,
01572 apodization,
01573 apinner,
01574 apwidth,
01575 apel,
01576 apx,
01577 apy))
01578 {
01579 fprintf(stderr, "ERROR: failure in apodize: status = %d, T_REC = %s, recnum = %lld\n", status, trecstr, inrec->recnum);
01580 error++;
01581 goto continue_outer_loop;
01582 }
01583
01584 if (v2hflag)
01585 {
01586
01587 outrec=v2hrecset->records[iv2hrec++];
01588 drms_copykeys(outrec, inrec, 0, kDRMS_KeyClass_Explicit);
01589 DRMS_Link_t *histlink = hcon_lookup_lower(&outrec->links, histlinkname);
01590 DRMS_Link_t *srclink = hcon_lookup_lower(&outrec->links, srclinkname);
01591 if (histlink != NULL)
01592 drms_setlink_static(outrec, histlinkname, histrecnum);
01593 if (srclink != NULL)
01594 drms_setlink_static(outrec, srclinkname, inrec->recnum);
01595 if (segoutflag)
01596 segout = drms_segment_lookup(outrec, segnameout);
01597 else
01598 segout = drms_segment_lookupnum(outrec, 0);
01599 length[0]=mapcols;
01600 length[1]=maprows;
01601 outarr = drms_array_create(usetype, 2, length, v2hptr, &status);
01602 drms_setkey_int(outrec, "TOTVALS", maprows*mapcols);
01603 set_statistics(segout, outarr, 1);
01604 outarr->bzero=segout->bzero;
01605 outarr->bscale=segout->bscale;
01606 status=drms_segment_write(segout, outarr, 0);
01607 free(outarr);
01608
01609 if (status != DRMS_SUCCESS)
01610 {
01611 fprintf(stderr, "ERROR: problem writing output segment: status = %d, T_REC = %s, input recnum = %lld, histrecnum = %lld\n", status, trecstr, inrec->recnum, histrecnum);
01612 return 0;
01613 }
01614
01615
01616 drms_setkey_int(outrec, "QUALITY", quality);
01617 drms_setkey_int(outrec, "MAPMMAX", mapped_lmax);
01618 drms_setkey_int(outrec, "SINBDIVS", sinb_divisions);
01619 drms_setkey_float(outrec, "APINNER", apinner);
01620 drms_setkey_float(outrec, "APWIDTH", apwidth);
01621 drms_setkey_float(outrec, "CRPIX1", mapcols/2.0 + 0.5);
01622 drms_setkey_float(outrec, "CRVAL1", mapl0);
01623 drms_setkey_float(outrec, "CROTA1", 0.0);
01624 drms_setkey_float(outrec, "CDELT1", longinterval);
01625 drms_setkey_float(outrec, "CRPIX2", maprows/2.0 + 0.5);
01626 drms_setkey_float(outrec, "CRVAL2", 0.0);
01627 drms_setkey_float(outrec, "CROTA2", 0.0);
01628 drms_setkey_float(outrec, "CDELT2", sinBdelta);
01629 drms_setkey_string(outrec, "CTYPE1", "CRLN_CEA");
01630 drms_setkey_string(outrec, "CTYPE2", "CRLT_CEA");
01631 drms_setkey_string(outrec, "CUNIT1", "deg");
01632 drms_setkey_string(outrec, "CUNIT2", "sinlat");
01633
01634
01635 drms_setkey_float(outrec, "MAPRMAX", rmax);
01636 drms_setkey_float(outrec, "MAPBMAX", bmax);
01637 drms_setkey_float(outrec, "MAPLGMAX", longmax_adjusted);
01638 drms_setkey_float(outrec, "MAPLGMIN", longmin_adjusted);
01639 drms_setkey_int(outrec, "INTERPO", interpolation);
01640 drms_setkey_int(outrec, "LGSHIFT", longitude_shift);
01641 drms_setkey_int(outrec, "MCORLEV", mag_correction);
01642 drms_setkey_int(outrec, "MOFFSET", mag_offset);
01643 drms_setkey_int(outrec, "CARSTRCH", carrStretch);
01644 drms_setkey_float(outrec, "DIFROT_A", diffrotA);
01645 drms_setkey_float(outrec, "DIFROT_B", diffrotB);
01646 drms_setkey_float(outrec, "DIFROT_C", diffrotC);
01647
01648 dsignout=vsign*drms_getkey_double(inrec, "DATASIGN", &status);
01649 if (status != DRMS_SUCCESS)
01650 dsignout=vsign;
01651 dsignout/=fabs(dsignout);
01652 drms_setkey_int(outrec, "DATASIGN", (int)dsignout);
01653
01654 tnow = (double)time(NULL);
01655 tnow += UNIX_epoch;
01656 drms_setkey_time(outrec, "DATE", tnow);
01657
01658
01659 }
01660
01661
01662 if (verbflag > 1)
01663 {
01664 wt=getwalltime();
01665 ct=getcputime(&ut, &st);
01666 fprintf(stdout,
01667 " remap done, %.2f ms wall time, %.2f ms cpu time\n",
01668 wt-wt2,
01669 ct-ct2);
01670 }
01671
01672 if (!h2mflag && !tsflag)
01673 goto skip;
01674
01675 inp=v2hptr;
01676 outp=h2mptr;
01677
01678 mean = 0.0;
01679 if (subtract_mean)
01680 {
01681 nmean = 0;
01682 ip = inp;
01683 for (row=0; row<maprows; row++)
01684 {
01685 for (col=0; col<mapcols; col++)
01686 {
01687 if (!isnan(*ip))
01688 {
01689 nmean++;
01690 mean += *ip;
01691 }
01692 ip++;
01693 }
01694 }
01695 mean /= (nmean ? nmean : 1);
01696 }
01697
01698 for (row=0; row<maprows; row++)
01699 {
01700 latweight = weight2[row];
01701
01702 if (cent_long == 0)
01703 {
01704
01705
01706
01707 nok = 0;
01708 bp = buf;
01709 wp = weight;
01710 ip = inp + mapcols * row;
01711 for (col=0; col<mapcols; col++)
01712 {
01713 if (!isnan(*ip))
01714 {
01715 *bp++ = latweight * *wp * (*ip - mean);
01716 nok += 1;
01717 }
01718 else
01719 *bp++ = 0.0;
01720 ip++;
01721 wp++;
01722 }
01723
01724
01725 for (i=col; i<nfft; i++)
01726 *bp++ = 0.0;
01727 }
01728 else
01729 {
01730
01731
01732
01733
01734 nok = 0;
01735
01736
01737
01738 bp = buf;
01739 ip = inp + mapcols * row+mapcols2;
01740 wp = weight + mapcols2;
01741 if (subtract_mean)
01742 {
01743 for (col=0; col<=mapcols2; col++)
01744 {
01745 if (!isnan(*ip))
01746 {
01747 *bp++ = latweight * *wp * (*ip - mean);
01748 nok += 1;
01749 }
01750 else
01751 *bp++ = 0.0;
01752 ip++;
01753 wp++;
01754 }
01755 }
01756 else
01757 {
01758 for (col=0; col<=mapcols2; col++)
01759 {
01760 if (!isnan(*ip))
01761 {
01762 *bp++ = latweight * *wp * *ip;
01763 nok += 1;
01764 }
01765 else
01766 *bp++ = 0.0;
01767 ip++;
01768 wp++;
01769 }
01770 }
01771
01772
01773 bp = buf+lfft-mapcols2;
01774 ip = inp + mapcols * row;
01775 wp = weight;
01776 if (subtract_mean)
01777 {
01778 for (col=0; col<mapcols2; col++)
01779 {
01780 if (!isnan(*ip))
01781 {
01782 *bp++ = latweight * *wp * (*ip - mean);
01783 nok += 1;
01784 }
01785 else
01786 *bp++ = 0.0;
01787 ip++;
01788 wp++;
01789 }
01790 }
01791 else
01792 {
01793 for (col=0; col<mapcols2; col++)
01794 {
01795 if (!isnan(*ip))
01796 {
01797 *bp++ = latweight * *wp * *ip;
01798 nok += 1;
01799 }
01800 else
01801 *bp++ = 0.0;
01802 ip++;
01803 wp++;
01804 }
01805 }
01806
01807
01808 bp = buf+mapcols2+1;
01809 for (i=0; i<lfft-mapcols; i++)
01810 *bp++ = 0.0;
01811
01812 }
01813
01814 if ((zero_miss == 0) && (nok != mapcols))
01815 {
01816
01817
01818 for (i=0; i<nout; i++)
01819 {
01820 op = outp + i * maprows + row;
01821 *op = DRMS_MISSING_FLOAT;
01822 }
01823 }
01824 else
01825 {
01826 if (normalize)
01827 norm = 1./sqrt(2*(double)nfft/nok)/lfft;
01828 else
01829 norm = 1./lfft;
01830
01831
01832 fftwf_execute(fftwp);
01833
01834
01835
01836 for (i=0; i<nout/2; i++)
01837 {
01838 op = outp + 2*i * maprows + row;
01839 *op = wbuf[i]*norm;
01840 }
01841
01842
01843 *(outp+row+maprows)=0.0;
01844
01845 normx=-norm;
01846 for (i=1; i<nout/2; i++)
01847 {
01848 op = outp + 2*i * maprows + row + maprows;
01849 *op = wbuf[lfft-i]*normx;
01850 }
01851
01852 }
01853 }
01854
01855 if (h2mflag)
01856 {
01857
01858 outrec=h2mrecset->records[ih2mrec++];
01859 drms_copykeys(outrec, inrec, 0, kDRMS_KeyClass_Explicit);
01860 DRMS_Link_t *histlink = hcon_lookup_lower(&outrec->links, histlinkname);
01861 DRMS_Link_t *srclink = hcon_lookup_lower(&outrec->links, srclinkname);
01862 if (histlink != NULL)
01863 drms_setlink_static(outrec, histlinkname, histrecnum);
01864 if (srclink != NULL)
01865 drms_setlink_static(outrec, srclinkname, inrec->recnum);
01866 if (segoutflag)
01867 segout = drms_segment_lookup(outrec, segnameout);
01868 else
01869 segout = drms_segment_lookupnum(outrec, 0);
01870 length[0]=maprows;
01871 length[1]=nout;
01872 outarr = drms_array_create(usetype, 2, length, h2mptr, &status);
01873 drms_setkey_int(outrec, "TOTVALS", maprows*nout);
01874 set_statistics(segout, outarr, 1);
01875 outarr->bzero=segout->bzero;
01876 outarr->bscale=segout->bscale;
01877 status=drms_segment_write(segout, outarr, 0);
01878 free(outarr);
01879
01880 if (status != DRMS_SUCCESS)
01881 {
01882 fprintf(stderr, "ERROR: problem writing output segment: status = %d, T_REC = %s, input recnum = %lld, histrecnum = %lld\n", status, trecstr, inrec->recnum, histrecnum);
01883 return 0;
01884 }
01885
01886
01887 drms_setkey_int(outrec, "QUALITY", quality);
01888 drms_setkey_int(outrec, "MAPMMAX", mapped_lmax);
01889 drms_setkey_int(outrec, "SINBDIVS", sinb_divisions);
01890 drms_setkey_float(outrec, "APINNER", apinner);
01891 drms_setkey_float(outrec, "APWIDTH", apwidth);
01892 drms_setkey_int(outrec, "LMAX", lmax);
01893 drms_setkey_double(outrec, "CRPIX1", maprows/2.0 + 0.5);
01894 drms_setkey_double(outrec, "CRVAL1", 0.0);
01895 drms_setkey_double(outrec, "CROTA1", 0.0);
01896 drms_setkey_double(outrec, "CDELT1", sinBdelta);
01897 drms_setkey_double(outrec, "CRPIX2", 1.0);
01898 drms_setkey_double(outrec, "CRVAL2", 0.0);
01899 drms_setkey_double(outrec, "CROTA2", 0.0);
01900 drms_setkey_double(outrec, "CDELT2", 1.0);
01901 drms_setkey_string(outrec, "CTYPE1", "CRLT_CEA");
01902 drms_setkey_string(outrec, "CTYPE2", "CRLN_FFT");
01903 drms_setkey_string(outrec, "CUNIT1", "rad");
01904 drms_setkey_string(outrec, "CUNIT2", "m");
01905
01906 tnow = (double)time(NULL);
01907 tnow += UNIX_epoch;
01908 drms_setkey_time(outrec, "DATE", tnow);
01909
01910 }
01911
01912 if (verbflag > 1)
01913 {
01914 wt2=getwalltime();
01915 ct2=getcputime(&ut2, &st2);
01916 fprintf(stdout,
01917 " fft and transpose done, %.2f ms wall time, %.2f ms cpu time\n",
01918 wt2-wt,
01919 ct2-ct);
01920 }
01921
01922 if (!tsflag)
01923 goto skip;
01924
01925 inptr=h2mptr;
01926 imageoffset = imagesize * irec;
01927 for (mx = 0; mx < 2*msize; mx++)
01928 {
01929 moffset = mx * maprows;
01930 mptr = inptr + moffset;
01931 for (latx = 0; latx < nlat; latx++)
01932 {
01933 poslatx = nlat + latx; neglatx = nlat - 1 - latx;
01934 evenpart[latx] = mptr[poslatx] + mptr[neglatx];
01935 oddpart[latx] = mptr[poslatx] - mptr[neglatx];
01936 }
01937 workptr = folded + imageoffset + moffset;
01938 scopy_ (&nlat, evenpart, &increment1, workptr, &increment1);
01939 workptr += nlat;
01940 scopy_ (&nlat, oddpart, &increment1, workptr, &increment1);
01941 }
01942
01943 skip:
01944 inrec = drms_recordset_fetchnext(drms_env, inrecset, &fetchstat, &chunkstat, NULL);
01945
01946 if (inrec != NULL)
01947 {
01948 trec = drms_getkey_time(inrec, "T_REC", &status);
01949 PARAMETER_ERROR("T_REC")
01950 trecind=(trec-tstart+cadence/2)/cadence;
01951 sprint_time(trecstr, trec, "TAI", 0);
01952 }
01953
01954 }
01955
01956 if (verbflag)
01957 printf(" number of bad images = %d\n", bc);
01958
01959 if (!tsflag)
01960 goto continue_outer_loop;
01961
01962
01963 while (irec < nrecs)
01964 {
01965 bad[bc++]=irec;
01966 irec++;
01967 }
01968
01969 if (bc == nrecs)
01970 {
01971 nodata=1;
01972 }
01973 else
01974 {
01975 while (bc > 0)
01976 {
01977 imageoffset=imagesize*bad[--bc];
01978 for (i=0;i<imagesize;i++) folded[imageoffset+i]=0.0;
01979 }
01980 }
01981
01982 if (verbflag)
01983 {
01984 wt2=getwalltime();
01985 ct2=getcputime(&ut2, &st2);
01986 fprintf(stdout,
01987 " images processed, %.2f ms wall time, %.2f ms cpu time\n",
01988 wt2-wt1,
01989 ct2-ct1);
01990 }
01991
01992
01993 skip_norecs:
01994
01995
01996
01997
01998
01999 ldone=-1;
02000
02001
02002 for (lchunk = lchunkfirst; lchunk <= lchunklast; lchunk++)
02003 {
02004 lfirst = lchunk * lchunksize;
02005 llast = lfirst + lchunksize - 1;
02006 lfirst = maxval(lfirst,lmin);
02007 llast = minval(llast,lmax);
02008
02009 ifirst = lfirst*(lfirst+1)/2;
02010 ilast = llast*(llast+1)/2+llast;
02011
02012 if (verbflag > 1)
02013 {
02014 wt3=getwalltime();
02015 ct3=getcputime(&ut3, &st3);
02016 printf(" processing lchunk %d, lmin = %d, lmax = %d\n", lchunk, lfirst, llast);
02017 }
02018
02019
02020 outrec=outrecset->records[irecout++];
02021
02022
02023
02024
02025
02026
02027
02028 if (histlink != NULL)
02029 drms_setlink_static(outrec, histlinkname, histrecnum);
02030
02031 if (nodata)
02032 goto skip_nodata;
02033
02034
02035 length[0]=2*nrecs;
02036 length[1]=(ilast-ifirst+1);
02037
02038 outarr = drms_array_create(usetype, 2, length, NULL, &status);
02039
02040 if (segoutflag)
02041 segout = drms_segment_lookup(outrec, segnameout);
02042 else
02043 segout = drms_segment_lookupnum(outrec, 0);
02044
02045 if (segout == NULL || outarr == NULL || status != DRMS_SUCCESS)
02046 {
02047 fprintf(stderr,"ERROR: problem with output segment or data array: lfirst = %d, llast = %d, length = [%d, %d], status = %d, iset = %d, T_START= %s, histrecnum = %lld",
02048 lfirst, llast, length[0], length[1], status, iset, tstartstr, histrecnum);
02049 return 0;
02050 }
02051
02052 outptr = (float *)(outarr->data);
02053
02054
02055 for (m = 0; m <= llast; m++)
02056 {
02057
02058 modd = is_odd(m);
02059 meven = !modd;
02060 lstart = maxval(lfirst,m);
02061
02062
02063
02064 if ((lstart-1) == ldone)
02065 {
02066
02067 if ((lstart - 2) >= m)
02068 for (latx = 0; latx < nlat; latx++)
02069 plm[(lstart-2)*nlat + latx] = saveplm[m*nlat + latx];
02070 if ((lstart - 1) >= m)
02071 for (latx = 0; latx < nlat; latx++)
02072 plm[(lstart-1)*nlat + latx] = saveplm[msize*nlat + m*nlat + latx];
02073
02074
02075
02076 setplm2(lstart, llast, m, nlat, indx, latgrid, nlat, plm, NULL);
02077 }
02078 else
02079 {
02080
02081
02082 setplm2(m, llast, m, nlat, indx, latgrid, nlat, plm, NULL);
02083 }
02084
02085
02086 if ((llast-1) >= m)
02087 for (latx = 0; latx < nlat; latx++)
02088 saveplm[m*nlat + latx] = plm[(llast - 1)*nlat + latx];
02089 for (latx = 0; latx < nlat; latx++)
02090 saveplm[msize*nlat + m*nlat + latx] = plm[llast*nlat + latx];
02091 ldone=llast;
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 plmptr=plm+nlat*lstart;
02112 maskptr=masks;
02113 latx=nlat*(llast-lstart+1);
02114
02115 int ilatx;
02116 for (ilatx=0;ilatx<latx;ilatx++)
02117 maskptr[ilatx]=plmptr[ilatx];
02118
02119
02120
02121 for (snx=0; snx<nrecs; snx++)
02122 {
02123
02124
02125
02126
02127
02128 scopy_ (&nlat,
02129 folded + nlat*(4*m+modd) + snx*imagesize,
02130 &increment1,
02131 real4evenl + snx*nlatx,
02132 &increment1);
02133 scopy_ (&nlat,
02134 folded + nlat*(4*m+meven) + snx*imagesize,
02135 &increment1,
02136 real4oddl + snx*nlatx,
02137 &increment1);
02138 scopy_ (&nlat,
02139 folded + nlat*(4*m+2+modd) + snx*imagesize,
02140 &increment1,
02141 imag4evenl + snx*nlatx,
02142 &increment1);
02143 scopy_ (&nlat,
02144 folded + nlat*(4*m+2+meven) + snx*imagesize,
02145 &increment1,
02146 imag4oddl + snx*nlatx,
02147 &increment1);
02148 }
02149
02150
02151
02152 lfirsteven = is_even(lstart) ? lstart : lstart+1;
02153 llasteven = is_even(llast) ? llast : llast-1;
02154 nevenl = (llasteven-lfirsteven)/2 + 1;
02155
02156
02157 sgemm_ (transpose,
02158 normal,
02159 &nsn,
02160 &nevenl,
02161 &nlat,
02162 &cnorm,
02163 real4evenl,
02164 &nlatx,
02165 masks + nlat*(lfirsteven-lstart),
02166 &maprows,
02167 &zero,
02168 outx + nsn*2*(lfirsteven-lstart),
02169 &fournsn,
02170 1,
02171 1);
02172
02173 sgemm_ (transpose,
02174 normal,
02175 &nsn,
02176 &nevenl,
02177 &nlat,
02178 &cnorm,
02179 imag4evenl,
02180 &nlatx,
02181 masks + nlat*(lfirsteven-lstart),
02182 &maprows,
02183 &zero,
02184 outx + nsn*(2*(lfirsteven-lstart)+1),
02185 &fournsn,
02186 1,
02187 1);
02188
02189
02190 lfirstodd = is_odd(lstart) ? lstart : lstart+1;
02191 llastodd = is_odd(llast) ? llast : llast-1;
02192 noddl = (llastodd-lfirstodd)/2 + 1;
02193
02194 sgemm_ (transpose,
02195 normal,
02196 &nsn,
02197 &noddl,
02198 &nlat,
02199 &cnorm ,
02200 real4oddl,
02201 &nlatx,
02202 masks + nlat*(lfirstodd-lstart),
02203 &maprows,
02204 &zero,
02205 outx + nsn*2*(lfirstodd-lstart),
02206 &fournsn,
02207 1,
02208 1);
02209
02210 sgemm_ (transpose,
02211 normal,
02212 &nsn,
02213 &noddl,
02214 &nlat,
02215 &cnorm,
02216 imag4oddl,
02217 &nlatx,
02218 masks + nlat*(lfirstodd-lstart),
02219 &maprows,
02220 &zero,
02221 outx + nsn*(2*(lfirstodd-lstart)+1),
02222 &fournsn,
02223 1,
02224 1);
02225
02226
02227
02228 for (l = lstart; l <= llast; l++)
02229 {
02230 fromoffset = 2*nsn*(l-lstart);
02231 tooffset = 2*nsn*(l*(l+1)/2 + m -ifirst);
02232 scopy_ (&nsn,
02233 outx+fromoffset,
02234 &increment1,
02235 outptr+tooffset,
02236 &increment2);
02237 scopy_ (&nsn,
02238 outx+fromoffset+nsn,
02239 &increment1,
02240 outptr+tooffset+1,
02241 &increment2);
02242 }
02243
02244
02245 }
02246
02247
02248 outarr->bzero=segout->bzero;
02249 outarr->bscale=segout->bscale;
02250 status=drms_segment_write(segout, outarr, 0);
02251 drms_free_array(outarr);
02252 nsegments++;
02253
02254 if (status != DRMS_SUCCESS)
02255 {
02256 fprintf(stderr, "ERROR: problem writing output segment: status = %d, T_START = %s, LMIN = %d, LMAX = %d, histrecnum = %lld\n", status, tstartstr, lfirst, llast, histrecnum);
02257 return 0;
02258 }
02259
02260 skip_nodata:
02261
02262 drms_setkey_int(outrec, "LMIN", lfirst);
02263 drms_setkey_int(outrec, "LMAX", llast);
02264 drms_setkey_time(outrec, "T_START", tstart);
02265 drms_setkey_time(outrec, "T_STOP", tstart+chunksecs);
02266 drms_setkey_time(outrec, "T_OBS", tstart+chunksecs/2);
02267 drms_setkey_time(outrec, "DATE__OBS", tstart);
02268 drms_setkey_string(outrec, "TAG", tag);
02269 if (verflag)
02270 drms_setkey_string(outrec, "VERSION", version);
02271
02272 for (i=0;i<16;i++)
02273 setbits(calversout,4*i+3,4,nybblearrout[i]);
02274 drms_setkey_longlong(outrec, "CALVER64", calversout);
02275
02276 if (nodata)
02277 drms_setkey_int(outrec, "QUALITY", QUAL_NODATA);
02278 else if (mixflag)
02279 drms_setkey_int(outrec, "QUALITY", QUAL_MIXEDCALVER);
02280 else
02281 drms_setkey_int(outrec, "QUALITY", 0);
02282
02283
02284 drms_setkey_int(outrec, "MAPMMAX", mapped_lmax);
02285 drms_setkey_int(outrec, "SINBDIVS", sinb_divisions);
02286 drms_setkey_float(outrec, "APINNER", apinner);
02287 drms_setkey_float(outrec, "APWIDTH", apwidth);
02288 drms_setkey_float(outrec, "T_STEP", cadence);
02289
02290 ndt=chunksecs/cadence;
02291 drms_setkey_int(outrec, "NDT", ndt);
02292
02293 tnow = (double)time(NULL);
02294 tnow += UNIX_epoch;
02295 drms_setkey_time(outrec, "DATE", tnow);
02296
02297
02298 nrecords++;
02299
02300 if (verbflag > 1)
02301 {
02302 wt=getwalltime();
02303 ct=getcputime(&ut, &st);
02304 fprintf(stdout,
02305 " %.2f ms wall time, %.2f ms cpu time\n",
02306 wt-wt3,
02307 ct-ct3);
02308 }
02309
02310
02311 }
02312
02313 if (verbflag)
02314 {
02315 wt1=getwalltime();
02316 ct1=getcputime(&ut1, &st1);
02317 fprintf(stdout, "SHT of timechunk %d complete: %.2f ms wall time, %.2f ms cpu time\n", iset,
02318 wt1-wt2, ct1-ct2);
02319 }
02320
02321 continue_outer_loop:
02322 tstart+=chunksecs;
02323 }
02324
02325
02326 if (chunkstat != kRecChunking_LastInRS && chunkstat != kRecChunking_NoMoreRecs)
02327 fprintf(stderr, "WARNING: input records remain after last output record: chunkstat = %d\n", (int)chunkstat);
02328
02329 drms_close_records(inrecset, DRMS_FREE_RECORD);
02330 if (tsflag)
02331 drms_close_records(outrecset, DRMS_INSERT_RECORD);
02332 if (v2hflag)
02333 drms_close_records(v2hrecset, DRMS_INSERT_RECORD);
02334 if (h2mflag)
02335 drms_close_records(h2mrecset, DRMS_INSERT_RECORD);
02336
02337
02338 wt=getwalltime();
02339 ct=getcputime(&ut, &st);
02340 if (verbflag && tsflag)
02341 {
02342 printf("number of records created = %d\n", nrecords);
02343 printf("number of segments created = %d\n", nsegments);
02344 }
02345 if (verbflag)
02346 {
02347 fprintf(stdout, "total time spent: %.2f ms wall time, %.2f ms cpu time\n",
02348 wt-wt0, ct-ct0);
02349 }
02350
02351 if (!error)
02352 printf("module %s successful completion\n", cmdparams.argv[0]);
02353 else
02354 printf("module %s failed to produce %d timechunks: histrecnum = %lld\n", cmdparams.argv[0], error, histrecnum);
02355
02356 return 0;
02357 }