(file) Return to jtsfiddle.c CVS log (file) (dir) Up to [Development] / JSOC / proj / globalhs / apps

   1 tplarson 1.1 /* this JSOC module is a port of an SOI module written by Rasmus Larsen.
   2               * ported by Tim Larson.
   3 tplarson 1.3  * tim doubts this works correctly with nskip or navg
   4 tplarson 1.1  */
   5              
   6              /* 
   7               *  Detrending/gapfilling/differencing module
   8               *  ts_fiddle_rml upgrades ts_fiddle
   9               */
  10              
  11              #include <stdio.h>
  12              #include <stdlib.h>
  13              #include <strings.h>
  14              #include <time.h>
  15              #include <sys/time.h>
  16              #include <sys/resource.h>
  17              #include <math.h>
  18              #include <assert.h>
  19              #include <fftw3.h>
  20              
  21              #include "jsoc_main.h"
  22 kehcheng 1.7 #include "fitsio.h"
  23 tplarson 1.1 
  24              #define ARRLENGTH(ARR)  (sizeof(ARR)/sizeof(ARR[0]))
  25              #define kNOTSPECIFIED "not specified"
  26              
  27              char *module_name = "jtsfiddle";
  28 tplarson 1.15 char *cvsinfo_jtsfiddle = "cvsinfo: $Header: /home/cvsuser/cvsroot/JSOC/proj/globalhs/apps/jtsfiddle.c,v 1.14 2013/04/28 08:05:21 tplarson Exp $";
  29 tplarson 1.1  
  30               /* Command line arguments: */
  31               ModuleArgs_t module_args[] =
  32               {
  33                 {ARG_STRING,   "in", "", "input data records"},
  34 tplarson 1.3    {ARG_STRING,   "tsout", kNOTSPECIFIED, "output dataseries for timeseries"},
  35                 {ARG_STRING,   "powout", kNOTSPECIFIED, "output dataseries for power spectra"},
  36                 {ARG_STRING,   "fftout", kNOTSPECIFIED, "output dataseries for fft's"},
  37                 {ARG_STRING,   "fft1out", kNOTSPECIFIED, "output dataseries for fft's reordered"},
  38                 {ARG_STRING,   "arpowout", kNOTSPECIFIED, "output dataseries for AR power"},
  39                 {ARG_STRING,   "mavgout", kNOTSPECIFIED, "output dataseries for m-averaged power spectra"},
  40               //  {ARG_STRING,   "out", "", "output data series"},
  41 tplarson 1.1    {ARG_STRING,   "segin" , kNOTSPECIFIED, "name of input segment if not using segment 0"},
  42                 {ARG_STRING,   "segout", kNOTSPECIFIED, "name of output segment if not using segment 0"},
  43                 {ARG_STRING,   "histlink", "HISTORY", "name of link to ancillary dataseries for processing metadata"},
  44                 {ARG_STRING,   "srclink",  "SRCDATA", "name of link to source data"},
  45                 {ARG_INT,      "PERM", "1", "set to 0 for transient records, nonzero for permanent records"},
  46                 {ARG_INT,      "VERB", "1",  "option for level of verbosity: 0=only error and warning messages; >0=print messages outside of loop; >1=print messages inside loop; >2=debugging output", NULL},
  47 tplarson 1.13   {ARG_STRING,   "TAG", kNOTSPECIFIED, "this parameter sets a keyword of the same name to the same value, usually used as an additional primekey"},
  48 tplarson 1.15   {ARG_STRING,   "VERSION", kNOTSPECIFIED, "this parameter sets a keyword of the same name to the same value, useful for selecting obsolete records"},
  49 tplarson 1.13 
  50 tplarson 1.1    {ARG_STRING,   "LOGFILE", "stdout", ""},
  51 tplarson 1.2    {ARG_STRING,   "GAPFILE", "", "record or file containing window function"},
  52                 {ARG_STRING,   "SECTIONFILE", kNOTSPECIFIED, "record or file specifying continuous sections of data"},
  53               
  54 tplarson 1.1    {ARG_INT,      "NDT", "-1", "", ""},
  55 tplarson 1.2  //  {ARG_FLOAT,    "TSAMPLE", "60", "", ""},
  56 tplarson 1.1    {ARG_INT,      "IFILL", "1", "", ""},
  57                 {ARG_INT,      "IFIRST", "0", "", ""},
  58 tplarson 1.3  //  {ARG_INT,      "FLIPM", "0", "", ""},
  59 tplarson 1.1    {ARG_INT,      "MAX_AR_ORDER", "360", "", ""},
  60                 {ARG_INT,      "FU_FIT_EDGES", "1", "", ""},
  61                 {ARG_INT,      "FU_ITER", "3", "", ""},
  62                 {ARG_INT,      "FU_MIN_PERCENT", "90", "", ""},
  63                 {ARG_FLOAT,    "CDETREND", "50.0", "", ""},
  64                 {ARG_INT,      "DETREND_LENGTH", "1600", "", ""},
  65                 {ARG_INT,      "DETREND_SKIP", "1440", "", ""},
  66 tplarson 1.3    {ARG_INT,      "DETREND_FIRST", "0", "", ""},
  67               /*
  68 tplarson 1.1    {ARG_INT,      "TSOUT", "0", "", ""},
  69                 {ARG_INT,      "FFTOUT", "0", "", ""},
  70                 {ARG_INT,      "FFT1OUT", "0", "", ""},
  71                 {ARG_INT,      "POWOUT", "0", "", ""},
  72                 {ARG_INT,      "ARPOWOUT", "0", "", ""},
  73                 {ARG_INT,      "MAVGOUT", "0", "", ""},
  74 tplarson 1.3  */
  75 tplarson 1.1    {ARG_INT,      "NAVG", "0", "", ""},
  76                 {ARG_INT,      "NSKIP", "0", "", ""},
  77                 {ARG_INT,      "NOFF", "0", "", ""},
  78                 {ARG_INT,      "IMIN", "0", "", ""},
  79                 {ARG_INT,      "IMAX", "-1", "", ""},
  80                 {ARG_END},
  81               };
  82               
  83               #include "saveparm.c"
  84               #include "timing.c"
  85 tplarson 1.3  #include "set_history.c"
  86 tplarson 1.1  
  87 tplarson 1.12 extern void cdetrend_discontig( int n, _Complex float *data, int *isgood, 
  88               				int degree, int length, int skip, 
  89               				int m, int *sect_last, int detrend_first);
  90               
  91               int cfahlman_ulrych(int n, _Complex float *data, int *isgood, 
  92               		    int minpercentage, int maxorder, int iterations, 
  93               		    int padends, int *order, _Complex float *ar_coeff);
  94               
  95 tplarson 1.14 //char *getdetrendversion(void);
  96               //char *getgapfillversion(void);
  97 tplarson 1.1  
  98               /* global variables holding the values of the command line variables. */
  99               static char *logfile, *gapfile, *sectionfile;
 100               static int lmode, n_sampled_out, ifill, flipm;
 101               static int ar_order, max_ar_order, fu_iter, fu_fit_edges;
 102               static int fu_min_percent;
 103 tplarson 1.3  static int detrend_length, detrend_skip, detrend_first;
 104 tplarson 1.1  static float tsample, detrend_const;
 105               static int ifirst, tsout,fftout, fft1out, powout, arpowout, mavgout;
 106               static int navg, nskip, noff, imin, imax;
 107               
 108               
 109               /* Prototypes for local functions. */
 110               static double splitting(int l, int m);
 111               
 112               /* Prototypes for external functions */
 113               extern void cffti_(int *, float *);
 114               extern void cfftb_(int *, float *, float *);
 115               static int extract_gaps(int n_in, int *gaps_in, int *n_out, int *gaps_out, 
 116               		  float tsample_in, float *tsample_out,
 117               		  int *num_sections, int *sections);
 118               static void extract_data(int n_in, int *gaps, float *data_in, float *data_out);
 119               static int read_section_file(char *filename, int *num_section, int **section);
 120               
 121               /************ Here begins the main module **************/
 122               int DoIt(void)
 123               {
 124                 int i;
 125 tplarson 1.1    int m, n_in, n_sampled_in;
 126                 TIME epoch, step, start, stop;
 127                 int gapsize, istart, istop, data_dim, detrend_order;
 128                 int npow, mshift;
 129                 float tsamplex, df1, c;
 130                 int *agaps;
 131                 int *gaps, *gaps2;
 132                 float *msum, *pow;
 133                 float *data, *out_data, *in_data;
 134                 fftwf_plan plan;
 135                 int num_sections, *sections;
 136                 float *ar_coeff=NULL;
 137 tplarson 1.3    float *datarr, *datptr, *outptr;
 138                 float *datahold;
 139                 char tstartstr[100];
 140                 int lmin, lmax;
 141 tplarson 1.1  
 142                 int fstatus = 0;
 143                 fitsfile *fitsptr;
 144                 long fdims[1];
 145                 long fpixel[]={1};
 146                 int *anynul=0;
 147               
 148 tplarson 1.3    int instart[2], inend[2];
 149 tplarson 1.10   int tslength[2], tsstart[2], tsend[2], tstotal[2];
 150                 int fft1length[2], fft1start[2], fft1end[2], fft1total[2];
 151                 int powlength[2], powstart[2], powend[2], powtotal[2];
 152 tplarson 1.1    int status=DRMS_SUCCESS;
 153                 int newstat=0;
 154               
 155                 DRMS_Segment_t *segin = NULL;
 156                 DRMS_Segment_t *segout = NULL;
 157                 DRMS_Array_t *inarr = NULL;
 158                 DRMS_Array_t *outarr = NULL;
 159                 DRMS_Record_t *inrec = NULL;
 160                 DRMS_Record_t *outrec = NULL;
 161                 DRMS_Type_t usetype = DRMS_TYPE_FLOAT;
 162                 DRMS_RecLifetime_t lifetime;
 163                 long long histrecnum = -1;
 164 tplarson 1.2    DRMS_Segment_t *gapseg = NULL;
 165                 DRMS_Array_t *gaparr = NULL;
 166 tplarson 1.1  
 167                 HIterator_t outKey_list;
 168                 DRMS_Keyword_t *outKey;
 169                 TIME tnow, UNIX_epoch = -220924792.000; /* 1970.01.01_00:00:00_UTC */
 170               
 171                 int errbufstat=setvbuf(stderr, NULL, _IONBF, BUFSIZ);
 172                 int outbufstat=setvbuf(stdout, NULL, _IONBF, BUFSIZ);
 173               
 174 tplarson 1.6    double tstart, tstartsave, tstop, tstopsave, cadence, tstartout, tstopout;
 175 tplarson 1.1    double wt0, wt1, wt2, wt3, wt;
 176                 double ut0, ut1, ut2, ut3, ut;
 177                 double st0, st1, st2, st3, st;
 178                 double ct0, ct1, ct2, ct3, ct;
 179               
 180                 wt0=getwalltime();
 181                 ct0=getcputime(&ut0, &st0);
 182               
 183                 /* Read input parameters. */
 184 tplarson 1.3    logfile     = (char *)cmdparams_save_str    (&cmdparams, "LOGFILE", &newstat);
 185                 gapfile     = (char *)cmdparams_save_str    (&cmdparams, "GAPFILE", &newstat);
 186                 sectionfile = (char *)cmdparams_save_str    (&cmdparams, "SECTIONFILE", &newstat);
 187 tplarson 1.1    n_sampled_out = cmdparams_save_int  (&cmdparams, "NDT", &newstat);
 188 tplarson 1.2  //  tsample     = cmdparams_save_float  (&cmdparams, "TSAMPLE", &newstat);
 189 tplarson 1.1    ifill       = cmdparams_save_int    (&cmdparams, "IFILL", &newstat);
 190                 max_ar_order= cmdparams_save_int    (&cmdparams, "MAX_AR_ORDER", &newstat);
 191                 fu_fit_edges= cmdparams_save_int    (&cmdparams, "FU_FIT_EDGES", &newstat);
 192                 fu_iter     = cmdparams_save_int    (&cmdparams, "FU_ITER", &newstat);
 193                 fu_min_percent = cmdparams_save_int (&cmdparams, "FU_MIN_PERCENT", &newstat);
 194                 ifirst      = cmdparams_save_int    (&cmdparams, "IFIRST", &newstat);
 195 tplarson 1.3  //  flipm       = cmdparams_save_int    (&cmdparams, "FLIPM", &newstat);
 196 tplarson 1.1    detrend_const = cmdparams_save_float(&cmdparams, "CDETREND", &newstat);
 197                 detrend_length = cmdparams_save_int (&cmdparams, "DETREND_LENGTH", &newstat);
 198                 detrend_skip = cmdparams_save_int   (&cmdparams, "DETREND_SKIP", &newstat);
 199 tplarson 1.3    detrend_first = cmdparams_save_int  (&cmdparams, "DETREND_FIRST", &newstat);
 200               /*
 201 tplarson 1.1    tsout       = cmdparams_save_int    (&cmdparams, "TSOUT", &newstat);
 202                 fftout      = cmdparams_save_int    (&cmdparams, "FFTOUT", &newstat);
 203                 fft1out     = cmdparams_save_int    (&cmdparams, "FFT1OUT", &newstat);
 204                 powout      = cmdparams_save_int    (&cmdparams, "POWOUT", &newstat);
 205                 arpowout    = cmdparams_save_int    (&cmdparams, "ARPOWOUT", &newstat);
 206                 mavgout     = cmdparams_save_int    (&cmdparams, "MAVGOUT", &newstat);
 207 tplarson 1.3  */
 208 tplarson 1.1    navg        = cmdparams_save_int    (&cmdparams, "NAVG", &newstat);
 209                 nskip       = cmdparams_save_int    (&cmdparams, "NSKIP", &newstat);
 210                 noff        = cmdparams_save_int    (&cmdparams, "NOFF", &newstat);
 211                 imin        = cmdparams_save_int    (&cmdparams, "IMIN", &newstat);
 212                 imax        = cmdparams_save_int    (&cmdparams, "IMAX", &newstat);
 213               
 214 tplarson 1.3    char *inrecquery = (char *)cmdparams_save_str(&cmdparams, "in", &newstat);
 215               //  char *outseries = (char *)cmdparams_save_str(&cmdparams, "out", &newstat);
 216                 char *segnamein = (char *)cmdparams_save_str(&cmdparams, "segin", &newstat);
 217                 char *segnameout = (char *)cmdparams_save_str(&cmdparams, "segout", &newstat);
 218 tplarson 1.1    int seginflag = strcmp(kNOTSPECIFIED, segnamein);
 219                 int segoutflag = strcmp(kNOTSPECIFIED, segnameout);
 220 tplarson 1.3    char *histlinkname = (char *)cmdparams_save_str(&cmdparams, "histlink", &newstat);
 221                 char *srclinkname = (char *)cmdparams_save_str(&cmdparams, "srclink", &newstat);
 222 tplarson 1.1    int verbflag = cmdparams_save_int(&cmdparams, "VERB", &newstat);
 223                 int permflag = cmdparams_save_int(&cmdparams, "PERM", &newstat);
 224                 if (permflag)
 225                   lifetime = DRMS_PERMANENT;
 226                 else
 227                   lifetime = DRMS_TRANSIENT;
 228               
 229 tplarson 1.13   char *tag = (char *)cmdparams_save_str(&cmdparams, "TAG", &newstat);
 230                 int tagflag = strcmp(kNOTSPECIFIED, tag);
 231 tplarson 1.15   char *version = (char *)cmdparams_save_str(&cmdparams, "VERSION", &newstat);
 232                 int verflag = strcmp(kNOTSPECIFIED, version);
 233 tplarson 1.13 
 234 tplarson 1.3    char *tsseries = (char *)cmdparams_save_str(&cmdparams, "tsout", &newstat);
 235                 tsout = strcmp(kNOTSPECIFIED, tsseries);
 236                 char *powseries = (char *)cmdparams_save_str(&cmdparams, "powout", &newstat);
 237                 powout = strcmp(kNOTSPECIFIED, powseries);
 238                 char *fftseries = (char *)cmdparams_save_str(&cmdparams, "fftout", &newstat);
 239                 fftout = strcmp(kNOTSPECIFIED, fftseries);
 240                 char *fft1series = (char *)cmdparams_save_str(&cmdparams, "fft1out", &newstat);
 241                 fft1out = strcmp(kNOTSPECIFIED, fft1series);
 242                 char *arpowseries = (char *)cmdparams_save_str(&cmdparams, "arpowout", &newstat);
 243                 arpowout = strcmp(kNOTSPECIFIED, arpowseries);
 244                 char *mavgseries = (char *)cmdparams_save_str(&cmdparams, "mavgout", &newstat);
 245                 mavgout = strcmp(kNOTSPECIFIED, mavgseries);
 246               
 247                 char *serieslist[6];
 248                 enum seriesindex  {TSOUT, FFTOUT, FFT1OUT, POWOUT, ARPOWOUT, MAVGOUT};
 249                 int  flagarr[6] = {tsout, fftout, fft1out, powout, arpowout, mavgout};
 250                 int mfliparr[6] = {0, 0, 0, 0, 0, 0};
 251                 int msignarr[6] = {0, 0, 0, 0, 0, 0};
 252                 serieslist[TSOUT]=tsseries;
 253                 serieslist[FFTOUT]=fftseries;
 254                 serieslist[FFT1OUT]=fft1series;
 255 tplarson 1.3    serieslist[POWOUT]=powseries;
 256                 serieslist[ARPOWOUT]=arpowseries;
 257                 serieslist[MAVGOUT]=mavgseries;
 258                 long long histrecnumarr[6]={-1, -1, -1, -1, -1, -1};
 259 tplarson 1.5    DRMS_RecordSet_t *outrecsetarr[6]={NULL, NULL, NULL, NULL, NULL, NULL};
 260                 DRMS_Record_t       *outrecarr[6]={NULL, NULL, NULL, NULL, NULL, NULL};
 261                 DRMS_Segment_t      *segoutarr[6]={NULL, NULL, NULL, NULL, NULL, NULL};
 262 tplarson 1.1  
 263                 /**** Sanity check of input parameters. ****/
 264               
 265                 if ((tsout == 0) && (fftout == 0) && (fft1out == 0) && (powout == 0) && (mavgout == 0) && (arpowout == 0)) 
 266                 {
 267 tplarson 1.3      fprintf(stderr, "ERROR: must specify an output dataseries\n");
 268                   return 1;
 269 tplarson 1.1    }
 270 tplarson 1.3  
 271 tplarson 1.1    if (navg <= 0) 
 272                   navg=1;
 273                 if (nskip <= 0) 
 274                   nskip=1;
 275                 if ((navg != 1) && (nskip != 1))
 276                 {
 277                   fprintf(stderr, "ERROR: one of navg and nskip must equal 1\n");
 278 tplarson 1.3      return 1;
 279 tplarson 1.1    }
 280                 if (noff < 0 || noff >= nskip) 
 281                 {
 282                   fprintf(stderr, "ERROR: noff must be >= 0 and < nskip\n");
 283 tplarson 1.3      return 1;
 284 tplarson 1.1    }
 285 tplarson 1.3    if (arpowout && !ifill)
 286 tplarson 1.1    {
 287                   fprintf(stderr, "ERROR: must have nonzero ifill with arpowout\n");
 288 tplarson 1.3      return 1;
 289                 }
 290                 if (fu_min_percent <= 0 || fu_min_percent > 100)
 291                 {
 292                   fprintf(stderr, "ERROR: FU_MIN_PERCENT must be > 0 and <= 100\n");
 293                   return 1;
 294                 }
 295               
 296                 if (newstat) 
 297                 {
 298                   fprintf(stderr, "ERROR: problem with input arguments, status = %d, diagnosis follows\n", newstat);
 299                   cpsave_decode_error(newstat);
 300                   return 1;
 301                 }  
 302                 else if (savestrlen != strlen(savestr)) 
 303                 {
 304                   fprintf(stderr, "ERROR: problem with savestr, savestrlen = %d, strlen(savestr) = %d\n", savestrlen, (int)strlen(savestr));
 305                   return 1;
 306 tplarson 1.1    }
 307               
 308               
 309 tplarson 1.3   // these must be present in the output dataseries and variable, not links or constants
 310                // the loop is only necessary if the output series don't all link to the same history series, which they usually will, but just in case...
 311 tplarson 1.5    char *outchecklist[] = {"T_START", "QUALITY", "LMIN", "LMAX", "NDT"};
 312 tplarson 1.11   int is, ishold, itest, mflip;
 313 tplarson 1.3    char *holdseries="";
 314 tplarson 1.14 /*
 315 tplarson 1.11   char *cvsinfo;
 316                 cvsinfo = (char *)malloc(1024);
 317 tplarson 1.15   strcpy(cvsinfo,"$Header: /home/cvsuser/cvsroot/JSOC/proj/globalhs/apps/jtsfiddle.c,v 1.14 2013/04/28 08:05:21 tplarson Exp $");
 318 tplarson 1.11   strcat(cvsinfo,"\n");
 319                 strcat(cvsinfo,getdetrendversion());
 320                 strcat(cvsinfo,"\n");
 321                 strcat(cvsinfo,getgapfillversion());
 322 tplarson 1.14 */
 323 tplarson 1.3    for (is=0;is<6;is++)
 324                 {
 325               
 326                   if (!flagarr[is])
 327                     continue;
 328               
 329                   DRMS_Record_t *tempoutrec = drms_create_record(drms_env, 
 330                                                                  serieslist[is],
 331                                                                  DRMS_TRANSIENT, 
 332                                                                  &status);
 333               
 334                   if (status != DRMS_SUCCESS) 
 335                   {
 336                    fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", serieslist[is], status);
 337                    return 1;
 338                   }
 339               
 340                   DRMS_Link_t *histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname);
 341 tplarson 1.1  
 342 tplarson 1.3  
 343                   // set up ancillary dataseries for processing metadata
 344                   if (histlink != NULL) 
 345                   {
 346                     if (strcmp(holdseries, histlink->info->target_series))
 347                     {
 348 tplarson 1.11         ishold=is;
 349 tplarson 1.3          holdseries=strdup(histlink->info->target_series);
 350 tplarson 1.14         histrecnumarr[is]=set_history(histlink);
 351 tplarson 1.3          if (histrecnumarr[is] < 0)
 352                       {
 353                         fprintf(stderr, "ERROR: problem creating record in history dataseries for output dataseries %s\n", serieslist[is]);
 354                         drms_close_record(tempoutrec, DRMS_FREE_RECORD);
 355                         return 1;
 356                       }
 357                     }
 358                     else
 359                     {
 360 tplarson 1.11         histrecnumarr[is]=histrecnumarr[ishold];
 361 tplarson 1.3        }
 362                   }
 363                   else
 364                   {
 365                     fprintf(stderr,"WARNING: could not find history link in output dataseries %s\n", serieslist[is]);
 366                   }
 367               
 368                   for (itest=0; itest < ARRLENGTH(outchecklist); itest++)
 369 tplarson 1.2      {
 370 tplarson 1.3        DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]);
 371                     if (outkeytest == NULL || outkeytest->info->islink || outkeytest->info->recscope == 1)
 372                     {
 373                       fprintf(stderr, "ERROR: output keyword %s in series %s is either missing, constant, or a link\n", outchecklist[itest], serieslist[is]);
 374                       drms_close_record(tempoutrec, DRMS_FREE_RECORD);
 375                       return 1;
 376                     }
 377 tplarson 1.2      }
 378 tplarson 1.1  
 379 tplarson 1.3      mflip = drms_getkey_int(tempoutrec, "MFLIPPED", &status);
 380                   if (status == DRMS_SUCCESS)
 381                     mfliparr[is]=mflip;    
 382 tplarson 1.1  
 383 tplarson 1.3      drms_close_record(tempoutrec, DRMS_FREE_RECORD);
 384                 }
 385 tplarson 1.1  
 386 tplarson 1.3  // for efficiency require that tsseries and fftseries have the same value of MFLIPPED.  this restriction may be lifted as noted below.
 387                 if ((tsout && fftout) && (mfliparr[TSOUT] != mfliparr[FFTOUT]))
 388                 {
 389                   fprintf(stderr, "ERROR: series %s and %s must have the same value of MFLIPPED\n", tsseries, fftseries);
 390                   return 1;
 391                 }
 392 tplarson 1.1  
 393 tplarson 1.2    if (fits_open_file(&fitsptr, gapfile, READONLY, &fstatus))
 394 tplarson 1.1    {
 395 tplarson 1.2      DRMS_RecordSet_t *gaprecset = drms_open_records(drms_env, gapfile, &status);
 396                   if (status != DRMS_SUCCESS || gaprecset == NULL) 
 397                   {
 398                     fprintf(stderr,"ERROR: problem reading gaps: file status = %d, DRMS status = %d\n",fstatus,status);
 399 tplarson 1.3        return 1;
 400 tplarson 1.2      }
 401                   if (gaprecset->n == 0)
 402                   {
 403                     fprintf(stderr,"ERROR: gapfile recordset contains no records\n");
 404 tplarson 1.3        return 1;
 405 tplarson 1.2      }
 406                   if (gaprecset->n > 1)
 407                   {
 408                     fprintf(stderr,"ERROR: gapfile recordset with more than 1 record not yet supported.\n");
 409 tplarson 1.3        return 1;
 410 tplarson 1.2      } 
 411                   gapseg = drms_segment_lookupnum(gaprecset->records[0], 0);
 412                   if (gapseg != NULL)
 413                     gaparr = drms_segment_read(gapseg, DRMS_TYPE_INT, &status);
 414                   if (status != DRMS_SUCCESS || gaparr == NULL || gapseg == NULL)
 415                   {
 416                     fprintf(stderr, "problem reading gaps segment: status = %d\n", status);
 417 tplarson 1.3        return 1;
 418 tplarson 1.2      }
 419                   agaps=(int *)(gaparr->data);
 420                   gapsize=gaparr->axis[0];
 421 tplarson 1.1    }
 422 tplarson 1.2    else
 423 tplarson 1.1    {
 424 tplarson 1.2      fits_get_img_size(fitsptr, 1, fdims, &fstatus);
 425                   gapsize=fdims[0];
 426                   agaps=(int *)(malloc(gapsize*sizeof(int)));
 427                   fits_read_pix(fitsptr, TINT, fpixel, gapsize, NULL, agaps, anynul, &fstatus); 
 428                   fits_close_file(fitsptr, &fstatus);
 429                   if (fstatus) 
 430                   {
 431                     fits_report_error(stderr, fstatus);
 432 tplarson 1.3        return 1;
 433 tplarson 1.2      }
 434 tplarson 1.1    }
 435               
 436 tplarson 1.9    if (verbflag)
 437                   printf("gapfile read, gapsize = %d\n",gapsize);
 438 tplarson 1.1  
 439                 data_dim=gapsize;
 440                 if (n_sampled_out>gapsize) 
 441                   data_dim=n_sampled_out;
 442               
 443 tplarson 1.3    /* allocate temporary storage */
 444                 gaps=(int *)(malloc(gapsize*sizeof(int)));
 445                 gaps2=(int *)(malloc(gapsize*sizeof(int)));
 446                 data=(float *)(fftwf_malloc(2*data_dim*sizeof(float)));
 447                 ar_coeff = (float *)malloc((max_ar_order+1)*2*sizeof(float));
 448               // now done below
 449               //  if (fft1out || powout || mavgout || arpowout)
 450               //    pow=(float *)(malloc(n_sampled_out*sizeof(float)));
 451               
 452 tplarson 1.1    /* Read location of jumps. */
 453 tplarson 1.2    if (!strcmp(sectionfile,kNOTSPECIFIED))
 454 tplarson 1.1    {
 455                   /* No sections file specified. Assume that the whole 
 456                      time series in one section. */
 457                   num_sections=1;
 458                   sections = malloc(2*sizeof(int));
 459                   sections[0] = 0;
 460                   sections[1] = data_dim-1;
 461                 }
 462                 else
 463                 {
 464 tplarson 1.2      int secstat;
 465                   if (secstat=read_section_file(sectionfile, &num_sections, &sections))
 466 tplarson 1.1      {
 467 tplarson 1.2        DRMS_RecordSet_t *secrecset = drms_open_records(drms_env, sectionfile, &status);
 468                     if (status != DRMS_SUCCESS || secrecset == NULL) 
 469                     {
 470                       fprintf(stderr,"ERROR: problem reading sections: file status = %d, DRMS status = %d\n",secstat,status);
 471 tplarson 1.3          return 1;
 472 tplarson 1.2        }
 473                     if (secrecset->n == 0)
 474                     {
 475                       fprintf(stderr,"ERROR: sectionfile recordset contains no records\n");
 476 tplarson 1.3          return 1;
 477 tplarson 1.2        }
 478                     if (secrecset->n > 1)
 479                     {
 480                       fprintf(stderr,"ERROR: sectionfile recordset with more than 1 record not yet supported.\n");
 481 tplarson 1.3          return 1;
 482 tplarson 1.2        }
 483                     num_sections=drms_getkey_int(secrecset->records[0], "NSECS", NULL);
 484                     if (num_sections < 1)
 485                     {
 486                       fprintf(stderr,"ERROR: Invalid NSECS keywords\n");
 487 tplarson 1.3          return 1;
 488 tplarson 1.2        }
 489                     sections = (int *)malloc(2*(num_sections)*sizeof(int));
 490                     char *sectkey=drms_getkey_string(secrecset->records[0], "SECS", NULL);
 491                     sscanf(strtok(sectkey," \n"),"%d",&(sections[0]));
 492                     sscanf(strtok(NULL," \n"),"%d",&(sections[1]));
 493                     int i;
 494                     for (i=2 ;i<2*(num_sections); i+=2)
 495                     {
 496                       sscanf(strtok(NULL," \n"), "%d", &(sections)[i]);
 497                       sscanf(strtok(NULL," \n"), "%d", &(sections)[i+1]);
 498               
 499                       if (sections[i]>sections[i+1] || (i>0 && sections[i]<=sections[i-1]))
 500                       {
 501                         fprintf(stderr,"ERROR: Invalid SECS keyword, sections overlap.\n");
 502 tplarson 1.3            return 1;
 503 tplarson 1.2          }
 504                     }
 505                     free(sectkey);
 506 tplarson 1.1      }
 507                 }
 508               
 509 tplarson 1.9    if (verbflag)
 510                   printf("num_sections = %d\n",num_sections);
 511 tplarson 1.1  
 512 tplarson 1.3    DRMS_RecordSet_t *inrecset = drms_open_records(drms_env, inrecquery, &status);
 513 tplarson 1.2  
 514 tplarson 1.3    if (status != DRMS_SUCCESS || inrecset == NULL) 
 515 tplarson 1.2    {
 516                   fprintf(stderr,"ERROR: problem opening input recordset: status = %d\n",status);
 517 tplarson 1.3      return 1;
 518 tplarson 1.2    }
 519 tplarson 1.3    if (inrecset->n == 0)
 520 tplarson 1.2    {
 521 tplarson 1.4      fprintf(stderr, "ERROR: input recordset contains no records\n");
 522 tplarson 1.3      return 1;
 523 tplarson 1.2    }
 524               
 525 tplarson 1.3    inrec=inrecset->records[0];
 526                 char *inchecklist[] = {"T_START", "T_STOP", "QUALITY", "LMIN", "LMAX", "T_STEP"};
 527 tplarson 1.2    for (itest=0; itest < ARRLENGTH(inchecklist); itest++)
 528                 {
 529                   DRMS_Keyword_t *inkeytest = hcon_lookup_lower(&inrec->keywords, inchecklist[itest]);
 530 tplarson 1.3      if (inkeytest == NULL)
 531 tplarson 1.2      {
 532                     fprintf(stderr, "ERROR: required input keyword %s is missing\n", inchecklist[itest]);
 533 tplarson 1.3        drms_close_records(inrecset, DRMS_FREE_RECORD);
 534                     return 1;
 535 tplarson 1.2      }
 536                 }
 537               
 538 tplarson 1.6    cadence=drms_getkey_float(inrec, "T_STEP", NULL); //assume constant across all input records
 539                 tsample=cadence;
 540                 tstartsave=drms_getkey_time(inrec, "T_START", NULL); //must be constant across all input records unless GAPFILE is implemented differently
 541 tplarson 1.2  
 542 tplarson 1.3    int mflipin=drms_getkey_int(inrec, "MFLIPPED", &status);
 543                 if (status != DRMS_SUCCESS) mflipin=0;
 544 tplarson 1.2  
 545 tplarson 1.3  // already required mfliparr[TSOUT] == mfliparr[FFTOUT] above
 546                 if (tsout && mfliparr[TSOUT] != mflipin)
 547                   flipm=1;
 548                 else if (fftout && mfliparr[FFTOUT] != mflipin)
 549                   flipm=1;
 550                 else
 551                   flipm=0;
 552 tplarson 1.2  
 553 tplarson 1.3    for (is=2;is<5;is++)
 554 tplarson 1.1    {
 555 tplarson 1.3      if (!flagarr[is])
 556                     continue;
 557                   if (mfliparr[is] != (mflipin || flipm))
 558                     msignarr[is]=-1;
 559                   else
 560                     msignarr[is]=1;
 561 tplarson 1.1    }
 562               
 563 tplarson 1.3    if (mflipin)
 564 tplarson 1.8      msignarr[MAVGOUT]=1;
 565                 else
 566 tplarson 1.3      msignarr[MAVGOUT]=-1;
 567 tplarson 1.2  
 568                 // changed n_in to gapsize in following call
 569                 if (extract_gaps(gapsize, agaps, &n_sampled_in, gaps, tsample, &tsamplex, &num_sections, sections))
 570 tplarson 1.1    {
 571                   fprintf(stderr, "ERROR: problem in extract_gaps\n");
 572 tplarson 1.3      return 1;
 573 tplarson 1.1    }
 574               
 575                 /* Adjust detrend parameters according to the number of
 576                    available points. */
 577                 if (n_sampled_in<detrend_length)
 578                 {
 579                   detrend_length = n_sampled_in;
 580                   detrend_skip = detrend_length;
 581 tplarson 1.3    }
 582               
 583                 int idtf;
 584                 if (detrend_first > 0)
 585                 {
 586                   for (idtf=0;idtf<detrend_first;idtf++)
 587                     gaps[idtf]=0;
 588                 }
 589               
 590 tplarson 1.1  
 591                 if (n_sampled_out == -1) 
 592                   n_sampled_out = n_sampled_in;
 593                 df1 = tsamplex*n_sampled_out;
 594               
 595                 if (fftout || fft1out || powout || arpowout || mavgout)     
 596                   plan = fftwf_plan_dft_1d(n_sampled_out, (fftwf_complex *)data, 
 597               			    (fftwf_complex *)data, FFTW_BACKWARD, FFTW_MEASURE);
 598               
 599 tplarson 1.2    /* Set sum to zero before starting */
 600                 if (mavgout) 
 601 tplarson 1.15     msum = (float *)malloc((n_sampled_out/2)*sizeof(float));
 602 tplarson 1.2  
 603 tplarson 1.3    if (fft1out || powout || mavgout || arpowout)
 604 tplarson 1.1    {
 605                   /* Set first and last output index if not set as a parameter. */
 606                   if (imax < imin) 
 607                   {
 608                     imin=0;
 609                     imax=n_sampled_out/2-1;
 610                   }
 611                   npow=imax-imin+1;
 612                   pow=(float *)(malloc(n_sampled_out*sizeof(float)));
 613 tplarson 1.3      datahold=(float *)malloc(2*npow*sizeof(float));
 614                 }
 615 tplarson 1.1  
 616 tplarson 1.3  // needed to implement mfliparr[TSOUT] != mfliparr[FFTOUT] 
 617               //  float *datatemp=(float *)malloc(2*n_sampled_out*sizeof(float));
 618                 float *tmpptr=data;
 619               
 620                 if (tsout || fftout) 
 621                 {
 622 tplarson 1.10     tslength[0]=tstotal[0]=2*n_sampled_out;
 623 tplarson 1.3      tslength[1]=1;
 624                   tsstart[0]=0;
 625                   tsend[0]=2*n_sampled_out-1;
 626                 }
 627                 if (fft1out)
 628                 {
 629 tplarson 1.10     fft1length[0]=fft1total[0]=2*npow;
 630 tplarson 1.3      fft1length[1]=1;
 631                   fft1start[0]=0;
 632                   fft1end[0]=2*npow-1;
 633                 }
 634                 if (powout || arpowout || mavgout)
 635                 {
 636 tplarson 1.10     powlength[0]=powtotal[0]=npow;
 637 tplarson 1.3      powlength[1]=1;
 638                   powstart[0]=0;
 639                   powend[0]=npow-1;
 640                 }
 641                 instart[0]=0;
 642                 inend[0]=2*gapsize - 1;
 643               
 644                 status=drms_stage_records(inrecset, 1, 0);
 645                 if (status != DRMS_SUCCESS)
 646                 {
 647                   fprintf(stderr, "ERROR: drms_stage_records returned status = %d\n", status);
 648                   return 1;
 649                 }
 650               
 651 tplarson 1.5    for (is=0; is<6; is++)
 652                 {
 653                   if (!flagarr[is])
 654                     continue;
 655 tplarson 1.3  
 656 tplarson 1.5      outrecsetarr[is] = drms_create_records(drms_env, inrecset->n, serieslist[is], DRMS_PERMANENT, &status);
 657 tplarson 1.3  
 658 tplarson 1.5      if (status != DRMS_SUCCESS || outrecsetarr[is] == NULL) 
 659                   {
 660                    fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", serieslist[is], status);
 661                    return 1;
 662                   }
 663 tplarson 1.3    }
 664               
 665 tplarson 1.5    int irec;
 666                 for (irec=0;irec<inrecset->n;irec++)
 667 tplarson 1.3    {
 668               
 669 tplarson 1.5      inrec = inrecset->records[irec];
 670 tplarson 1.1  
 671 tplarson 1.5      lmin=drms_getkey_int(inrec, "LMIN", NULL);
 672                   lmax=drms_getkey_int(inrec, "LMAX", NULL);
 673                   if (lmin != lmax)
 674                   {
 675                     fprintf(stderr, "ERROR: lmin != lmax not yet supported.\n");
 676                     return 0;
 677                   }
 678                   lmode=lmin;
 679 tplarson 1.1  
 680 tplarson 1.10     if (verbflag > 1) 
 681                   {
 682                     printf("starting l=%d\n", lmode);
 683                   }
 684               
 685 tplarson 1.6      tstart=drms_getkey_time(inrec, "T_START", NULL);
 686                   tstop =drms_getkey_time(inrec, "T_STOP", NULL);
 687                   cadence=drms_getkey_float(inrec, "T_STEP", NULL);
 688                   if (tstart != tstartsave)
 689                   {
 690               // to lift this restriction must be able to specify multiple gap files/records as input
 691                     sprint_time(tstartstr, tstart, "TAI", 0);
 692                     fprintf(stderr, "ERROR: all input records must have same T_START, record %d has %s\n", irec, tstartstr);
 693                     return 0;
 694                   }
 695 tplarson 1.1  
 696 tplarson 1.6      n_in=(tstop-tstart)/cadence;
 697 tplarson 1.5      if (n_in != gapsize)
 698 tplarson 1.3      {
 699 tplarson 1.5        fprintf(stderr, "ERROR: gaps seem incompatible with timeseries, gapsize=%d, n_in=%d\n", gapsize, n_in);
 700                     return 0;
 701 tplarson 1.3      }
 702               
 703 tplarson 1.5      tstartout=tstart+ifirst*tsample;
 704                   tstopout=tstartout+df1;
 705                   sprint_time(tstartstr, tstartout, "TAI", 0);
 706 tplarson 1.1  
 707 tplarson 1.5      if (seginflag)
 708                     segin = drms_segment_lookup(inrec, segnamein);
 709 tplarson 1.3      else
 710 tplarson 1.5        segin = drms_segment_lookupnum(inrec, 0);
 711                   if (segin == NULL)
 712 tplarson 1.3      {
 713 tplarson 1.5        fprintf(stderr, "ERROR: problem looking up input segment: recnum = %lld\n", inrec->recnum);
 714 tplarson 1.3        return 0;
 715                   }
 716 tplarson 1.1  
 717 tplarson 1.5      for (is=0; is<6; is++)
 718                   {
 719                     if (!flagarr[is])
 720                       continue;
 721               /*
 722                     outrecarr[is] = drms_create_record(drms_env, serieslist[is], DRMS_PERMANENT, &status);
 723                     if (status != DRMS_SUCCESS) 
 724                     {
 725                      fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", serieslist[is], status);
 726                      return 0;
 727                     }
 728               */
 729                     outrec=outrecsetarr[is]->records[irec];
 730                     if (histrecnumarr[is] > 0)
 731                       drms_setlink_static(outrec, histlinkname,  histrecnumarr[is]);
 732                     drms_setlink_static(outrec, srclinkname,  inrec->recnum);
 733               
 734                     if (segoutflag)
 735                       segoutarr[is] = drms_segment_lookup(outrec, segnameout);
 736                     else
 737                       segoutarr[is] = drms_segment_lookupnum(outrec, 0);
 738 tplarson 1.5        if (segoutarr[is] == NULL)
 739                     {
 740                       fprintf(stderr, "ERROR: problem looking up outputput segment in series %s\n", serieslist[is]);
 741                       return 0;
 742                     }
 743               
 744 tplarson 1.3  // the following is not needed if at least one of the first N-1 dimensions are 0 in the jsd, 
 745               // or if the first N-1 dimensions in the jsd are always the dimensions desired.
 746               // it *is* needed any time one must override the jsd defaults
 747               /*
 748 tplarson 1.5        switch(is)
 749                     {
 750                       case TSOUT:
 751                       case FFTOUT:
 752                         segoutarr[is]->axis[0]=2*n_sampled_out;
 753                         segoutarr[is]->axis[1]=lmode+1;
 754                         break;
 755                       case FFT1OUT:
 756                         segoutarr[is]->axis[0]=2*npow;
 757                         segoutarr[is]->axis[1]=2*lmode+1;
 758                         break;
 759                       case POWOUT:
 760                       case ARPOWOUT:
 761                         segoutarr[is]->axis[0]=npow;
 762                         segoutarr[is]->axis[1]=2*lmode+1;
 763                         break;
 764                       case MAVGOUT:
 765                         segoutarr[is]->axis[0]=npow;
 766                         segoutarr[is]->axis[1]=1;
 767                         break;
 768                       default:
 769 tplarson 1.5            ;
 770                     }
 771               */
 772 tplarson 1.10       switch(is)
 773                     {
 774                       case TSOUT:
 775                       case FFTOUT:
 776                         tstotal[1]=lmode+1;
 777                         break;
 778                       case FFT1OUT:
 779                         fft1total[1]=2*lmode+1;
 780                         break;
 781                       case POWOUT:
 782                       case ARPOWOUT:
 783                         powtotal[1]=2*lmode+1;
 784                         break;
 785                       case MAVGOUT:
 786                       default:
 787                         ;
 788                     }
 789               
 790 tplarson 1.3      }
 791 tplarson 1.1  
 792 tplarson 1.15     if (mavgout)
 793                     for (i=0;i<n_sampled_out/2;i++) 
 794                       msum[i] = 0.0;
 795               
 796 tplarson 1.1    /***** Main Loop over m: Detrend, gapfill and/or compute FFT/power spectrum *******/
 797 tplarson 1.5      for (m=0; m<=lmode; m++) 
 798                   {
 799 tplarson 1.3  
 800 tplarson 1.10       if (verbflag > 2) 
 801 tplarson 1.5        {
 802 tplarson 1.10         printf("starting m=%d\n", m);
 803 tplarson 1.5        }
 804 tplarson 1.3  
 805 tplarson 1.5        instart[1]=m;
 806                     inend[1]=m;
 807                     inarr = drms_segment_readslice(segin, usetype, instart, inend, &status);
 808                     if (status != DRMS_SUCCESS || inarr == NULL )
 809                     {
 810                       fprintf(stderr, "ERROR: problem reading input segment: status = %d, recnum = %lld\n", status, inrec->recnum);
 811                       return 0;
 812                     }
 813                     in_data=(float *)(inarr->data);
 814 tplarson 1.1  
 815                   /* Extracts data copy */
 816 tplarson 1.5        extract_data(n_sampled_in, gaps, in_data, data);
 817 tplarson 1.1  
 818                   /* Detrend entire time series if required */
 819 tplarson 1.5        if (detrend_const != 0) 
 820                     {
 821                       detrend_order = floor(detrend_length/detrend_const)+2;
 822                       cdetrend_discontig(n_sampled_in, (_Complex float *)data, gaps, 
 823 tplarson 1.1  			 detrend_order, detrend_length, detrend_skip, 
 824 tplarson 1.3  			 num_sections, sections, detrend_first);
 825 tplarson 1.5        }
 826 tplarson 1.1  
 827                   /* Fill gaps in entire time series if required */
 828 tplarson 1.5        memcpy(gaps2, gaps, n_sampled_in*sizeof(int));
 829                     if (ifill != 0 && max_ar_order > 0) 
 830                     {
 831                       cfahlman_ulrych(n_sampled_in, (_Complex float *)data, gaps2,
 832 tplarson 1.1  		      fu_min_percent, max_ar_order, fu_iter, fu_fit_edges, 
 833               		      &ar_order, (_Complex float *)ar_coeff);
 834 tplarson 1.5        }
 835 tplarson 1.3  
 836 tplarson 1.5        drms_free_array(inarr);
 837 tplarson 1.3  
 838 tplarson 1.5        memmove(data, &data[2*ifirst], 2*(n_sampled_in-ifirst)*sizeof(float));
 839                     if ((ifirst+n_sampled_out) >= n_sampled_in) 
 840                       memset(&data[2*(n_sampled_in-ifirst)], 0, 2*(n_sampled_out+ifirst-n_sampled_in)*sizeof(float));      
 841 tplarson 1.3  
 842 tplarson 1.5        if (tsout)
 843                     {
 844 tplarson 1.3  // code to flip m on this output separately.  in the present code this has already been accomplished by setting flipm.
 845 tplarson 1.2  /*
 846 tplarson 1.5          if (mfliparr[TSOUT] != mflipin)
 847 tplarson 1.3          {
 848 tplarson 1.5            for (i = 0; i < n_sampled_out; i++)
 849                         {
 850                           datatemp[2*i]=data[2*i];
 851                           datatemp[2*i+1]=-data[2*i+1];
 852                         }
 853                         tmpptr=datatemp;
 854 tplarson 1.3          }
 855 tplarson 1.5          else
 856                         tmpptr=data;
 857 tplarson 1.2  */
 858 tplarson 1.5          tsstart[1]=m;
 859                       tsend[1]=m;
 860                       outarr = drms_array_create(usetype, 2, tslength, tmpptr, &status);
 861 tplarson 1.9          outarr->bzero=segoutarr[TSOUT]->bzero;
 862                       outarr->bscale=segoutarr[TSOUT]->bscale;
 863 tplarson 1.10         status=drms_segment_writeslice_ext(segoutarr[TSOUT], outarr, tsstart, tsend, tstotal, 0);
 864 tplarson 1.5          free(outarr);
 865                       if (status != DRMS_SUCCESS)
 866                       {
 867                         fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[TSOUT], status, m, tstartstr, lmode, histrecnumarr[TSOUT]);
 868                         return 0;
 869                       }
 870 tplarson 1.3        }
 871 tplarson 1.1  
 872 tplarson 1.5        if (fftout || fft1out || powout || mavgout)
 873                       fftwf_execute(plan);
 874 tplarson 1.1  
 875 tplarson 1.5        if (fftout)
 876                     {
 877 tplarson 1.3  // code to flip m on this output separately.  in the present code this has already been accomplished by setting flipm.
 878               /*
 879 tplarson 1.5          if (mfliparr[FFTOUT] != mflipin)
 880 tplarson 1.3          {
 881 tplarson 1.5            datatemp[0]=data[0];
 882                         datatemp[1]=-data[1];
 883                         for (i = 1; i < n_sampled_out; i++)
 884                         {
 885                           datatemp[2*i]=data[2*(n_sampled_out-i)];
 886                           datatemp[2*i+1]=-data[2*(n_sampled_out-i)+1];
 887                         }
 888                         tmpptr=datatemp;
 889 tplarson 1.3          }
 890                       else
 891 tplarson 1.5            tmpptr=data;
 892 tplarson 1.3  */
 893 tplarson 1.5          tsstart[1]=m;
 894                       tsend[1]=m;
 895                       outarr = drms_array_create(usetype, 2, tslength, tmpptr, &status);
 896 tplarson 1.9          outarr->bzero=segoutarr[FFTOUT]->bzero;
 897                       outarr->bscale=segoutarr[FFTOUT]->bscale;
 898 tplarson 1.10         status=drms_segment_writeslice_ext(segoutarr[FFTOUT], outarr, tsstart, tsend, tstotal, 0);
 899 tplarson 1.5          free(outarr);
 900                       if (status != DRMS_SUCCESS)
 901                       {
 902                         fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[FFTOUT], status, m, tstartstr, lmode, histrecnumarr[FFTOUT]);
 903                         return 0;
 904                       }
 905 tplarson 1.3        }
 906               
 907 tplarson 1.5        if (fft1out)
 908 tplarson 1.3        {
 909               
 910 tplarson 1.5          fft1start[1]=lmode+m*msignarr[FFT1OUT];
 911                       fft1end[1]=lmode+m*msignarr[FFT1OUT];
 912                       outarr = drms_array_create(usetype, 2, fft1length, data+2*imin, &status);
 913 tplarson 1.9          outarr->bzero=segoutarr[FFT1OUT]->bzero;
 914                       outarr->bscale=segoutarr[FFT1OUT]->bscale;
 915 tplarson 1.10         status=drms_segment_writeslice_ext(segoutarr[FFT1OUT], outarr, fft1start, fft1end, fft1total, 0);
 916 tplarson 1.3          free(outarr);
 917                       if (status != DRMS_SUCCESS)
 918                       {
 919                         fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[FFT1OUT], status, m, tstartstr, lmode, histrecnumarr[FFT1OUT]);
 920                         return 0;
 921                       }
 922 tplarson 1.1  
 923 tplarson 1.5          if (m > 0) 
 924                       {
 925                         /* Do negative m */
 926                         for (i=0; i<npow; i++) 
 927                         {
 928                           /* Conjugate for negative m */
 929                           datahold[2*i] = data[2*(n_sampled_out-imin-i)];
 930                           datahold[2*i+1] = -data[2*(n_sampled_out-imin-i)+1];
 931                         }
 932                         fft1start[1]=lmode-m*msignarr[FFT1OUT];
 933                         fft1end[1]=lmode-m*msignarr[FFT1OUT];
 934                         outarr = drms_array_create(usetype, 2, fft1length, datahold, &status);
 935 tplarson 1.9            outarr->bzero=segoutarr[FFT1OUT]->bzero;
 936                         outarr->bscale=segoutarr[FFT1OUT]->bscale;
 937 tplarson 1.10           status=drms_segment_writeslice_ext(segoutarr[FFT1OUT], outarr, fft1start, fft1end, fft1total, 0);
 938 tplarson 1.5            free(outarr);
 939                         if (status != DRMS_SUCCESS)
 940                         {
 941                           fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[FFT1OUT], status, m, tstartstr, lmode, histrecnumarr[FFT1OUT]);
 942                           return 0;
 943                         }
 944                       }
 945 tplarson 1.3        }
 946 tplarson 1.1  
 947 tplarson 1.5        if (powout || mavgout)
 948                       for (i = 0; i < n_sampled_out; i++) 
 949                         pow[i] = data[2*i]*data[2*i] + data[2*i+1]*data[2*i+1];
 950               
 951                     if (powout)
 952                     {
 953                       powstart[1]=lmode+m*msignarr[POWOUT];
 954                       powend[1]=lmode+m*msignarr[POWOUT];
 955                       outarr = drms_array_create(usetype, 2, powlength, pow+imin, &status);
 956 tplarson 1.9          outarr->bzero=segoutarr[POWOUT]->bzero;
 957                       outarr->bscale=segoutarr[POWOUT]->bscale;
 958 tplarson 1.10         status=drms_segment_writeslice_ext(segoutarr[POWOUT], outarr, powstart, powend, powtotal, 0);
 959 tplarson 1.3          free(outarr);
 960                       if (status != DRMS_SUCCESS)
 961                       {
 962                         fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[POWOUT], status, m, tstartstr, lmode, histrecnumarr[POWOUT]);
 963                         return 0;
 964                       }
 965               
 966 tplarson 1.5          if (m > 0) 
 967                       {
 968                         /* Do negative m */
 969                         if (imin)
 970                           datahold[0] = pow[n_sampled_out-imin];
 971                         else
 972                           datahold[0] = pow[0];
 973                         for (i=1; i<npow;i++) 
 974                           datahold[i] = pow[n_sampled_out-imin-i];
 975               
 976                         powstart[1]=lmode-m*msignarr[POWOUT];
 977                         powend[1]=lmode-m*msignarr[POWOUT];
 978                         outarr = drms_array_create(usetype, 2, powlength, datahold, &status);
 979 tplarson 1.9            outarr->bzero=segoutarr[POWOUT]->bzero;
 980                         outarr->bscale=segoutarr[POWOUT]->bscale;
 981 tplarson 1.10           status=drms_segment_writeslice_ext(segoutarr[POWOUT], outarr, powstart, powend, powtotal, 0);
 982 tplarson 1.5            free(outarr);
 983                         if (status != DRMS_SUCCESS)
 984                         {
 985                           fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[POWOUT], status, m, tstartstr, lmode, histrecnumarr[POWOUT]);
 986                           return 0;
 987                         }
 988                       }
 989 tplarson 1.1        }
 990 tplarson 1.3  
 991 tplarson 1.5        if (mavgout)
 992 tplarson 1.1        {
 993 tplarson 1.5          mshift = floor(df1*splitting(lmode,m*msignarr[MAVGOUT])+0.5f);
 994                       if (mshift >= 0) 
 995                         for (i=0; i<n_sampled_out/2-mshift; i++)
 996                           msum[i] += pow[mshift+i];
 997                       else
 998                         for (i=0; i<n_sampled_out/2+mshift; i++)
 999                           msum[i-mshift] += pow[i];
1000                       if (m > 0) 
1001                       {
1002                         /* Do negative m */
1003                         mshift = floor(df1*splitting(lmode,-m*msignarr[MAVGOUT])+0.5f);
1004                         if (mshift >=0)
1005                           for (i=1; i<n_sampled_out/2-mshift;i++)
1006                             msum[i] += pow[n_sampled_out-mshift-i];
1007                         else
1008                           for (i=1; i<n_sampled_out/2+mshift; i++)
1009                             msum[i-mshift] += pow[n_sampled_out-i];
1010                       }
1011 tplarson 1.1        }
1012 tplarson 1.3  
1013 tplarson 1.5        if (arpowout)
1014 tplarson 1.1        {
1015 tplarson 1.5          memmove(data, ar_coeff, 2*(ar_order+1)*sizeof(float));
1016                       memset(&data[2*(ar_order+1)],0,2*(n_sampled_out-ar_order-1)*sizeof(float));
1017                       fftwf_execute(plan);
1018                       for (i = 0; i < n_sampled_out; i++) 
1019                         pow[i] = 1.0/(data[2*i]*data[2*i] + data[2*i+1]*data[2*i+1]);
1020               
1021                       powstart[1]=lmode+m*msignarr[ARPOWOUT];
1022                       powend[1]=lmode+m*msignarr[ARPOWOUT];
1023                       outarr = drms_array_create(usetype, 2, powlength, pow+imin, &status);
1024 tplarson 1.9          outarr->bzero=segoutarr[ARPOWOUT]->bzero;
1025                       outarr->bscale=segoutarr[ARPOWOUT]->bscale;
1026 tplarson 1.10         status=drms_segment_writeslice_ext(segoutarr[ARPOWOUT], outarr, powstart, powend, powtotal, 0);
1027 tplarson 1.3          free(outarr);
1028                       if (status != DRMS_SUCCESS)
1029                       {
1030                         fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[ARPOWOUT], status, m, tstartstr, lmode, histrecnumarr[ARPOWOUT]);
1031 tplarson 1.5            return 0;
1032                       }
1033               
1034                       if (m > 0) 
1035                       {
1036                         /* Do negative m */
1037                         if (imin)
1038                           datahold[0] = pow[n_sampled_out-imin];
1039                         else
1040                           datahold[0] = pow[0];
1041                         for (i=1; i<npow;i++) 
1042                           datahold[i] = pow[n_sampled_out-imin-i];
1043               
1044                         powstart[1]=lmode-m*msignarr[ARPOWOUT];
1045                         powend[1]=lmode-m*msignarr[ARPOWOUT];
1046                         outarr = drms_array_create(usetype, 2, powlength, datahold, &status);
1047 tplarson 1.9            outarr->bzero=segoutarr[ARPOWOUT]->bzero;
1048                         outarr->bscale=segoutarr[ARPOWOUT]->bscale;
1049 tplarson 1.10           status=drms_segment_writeslice_ext(segoutarr[ARPOWOUT], outarr, powstart, powend, powtotal, 0);
1050 tplarson 1.5            free(outarr);
1051                         if (status != DRMS_SUCCESS)
1052                         {
1053                           fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, m = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[ARPOWOUT], status, m, tstartstr, lmode, histrecnumarr[ARPOWOUT]);
1054                            return 0;
1055                         }
1056 tplarson 1.3          }
1057 tplarson 1.1        }
1058               
1059 tplarson 1.5      } //end of loop over m
1060 tplarson 1.1  
1061 tplarson 1.5      if (mavgout)
1062 tplarson 1.3      {
1063 tplarson 1.5        c=1.0f/(2*lmode+1);
1064                     for (i=0; i<npow; i++) 
1065                       datahold[i] = msum[imin+i] * c;
1066                     outarr = drms_array_create(usetype, 2, powlength, datahold, &status);
1067 tplarson 1.9        outarr->bzero=segoutarr[MAVGOUT]->bzero;
1068                     outarr->bscale=segoutarr[MAVGOUT]->bscale;
1069 tplarson 1.5        status=drms_segment_write(segoutarr[MAVGOUT], outarr, 0);
1070                     free(outarr);
1071                     if (status != DRMS_SUCCESS)
1072                     {
1073                       fprintf(stderr, "ERROR: problem writing output segment in series %s: status = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", serieslist[MAVGOUT], status, tstartstr, lmode, histrecnum);
1074                       return 0;
1075                     }
1076 tplarson 1.3      }
1077 tplarson 1.2  
1078 tplarson 1.5      for (is=0;is<6;is++)
1079                   {
1080                     if (!flagarr[is])
1081                       continue;
1082 tplarson 1.1  
1083 tplarson 1.5        outrec=outrecsetarr[is]->records[irec];
1084                     drms_copykeys(outrec, inrec, 0, kDRMS_KeyClass_Explicit);
1085                     drms_setkey_int(outrec, "QUALITY", 0);
1086                     drms_setkey_time(outrec, "T_START", tstartout);
1087                     drms_setkey_time(outrec, "T_STOP", tstopout);
1088                     drms_setkey_time(outrec, "T_OBS", (tstartout + tstopout)/2);
1089                     drms_setkey_float(outrec, "T_STEP", tsamplex);
1090                     drms_setkey_int(outrec, "NDT", n_sampled_out);
1091 tplarson 1.13       if (tagflag)
1092                       drms_setkey_string(outrec, "TAG", tag);
1093 tplarson 1.15       if (verflag)
1094                        drms_setkey_string(outrec, "VERSION", version);
1095               
1096 tplarson 1.5        tnow = (double)time(NULL);
1097                     tnow += UNIX_epoch;
1098                     drms_setkey_time(outrec, "DATE", tnow);
1099               
1100               //      drms_close_record(outrec, DRMS_INSERT_RECORD);
1101 tplarson 1.3  
1102 tplarson 1.5      }
1103 tplarson 1.1  
1104                 }
1105               
1106 tplarson 1.5    drms_close_records(inrecset, DRMS_FREE_RECORD);
1107                 for (is=0;is<6;is++)
1108 tplarson 1.1    {
1109 tplarson 1.5      if (!flagarr[is])
1110                     continue;
1111                   drms_close_records(outrecsetarr[is], DRMS_INSERT_RECORD);
1112 tplarson 1.1    }
1113               
1114 tplarson 1.5    if(ar_coeff != NULL)
1115 tplarson 1.1      free(ar_coeff);
1116               
1117                 if (fftout || fft1out || powout || arpowout || mavgout)   
1118                   fftwf_destroy_plan(plan); 
1119               
1120                 wt=getwalltime();
1121                 ct=getcputime(&ut, &st);
1122                 if (verbflag) 
1123                 {
1124 tplarson 1.10     printf("total time spent: %.2f ms wall time, %.2f ms cpu time\n", 
1125 tplarson 1.1              wt-wt0, ct-ct0);
1126                 }
1127               
1128 tplarson 1.3    printf("module %s successful completion\n", cmdparams.argv[0]);
1129 tplarson 1.1    return 0;
1130               }
1131               
1132               
1133               static double splitting(int l, int m)
1134               {
1135                 double a1x[] = {406.0,407.0,408.0,410.5,412.0,411.5,409.0,406.0,406.0};
1136                 double a3x[] = {10.0,10.0,15.0,19.5,21.0,21.3,21.3,21.3,21.8};
1137                 double a5x[] = {0.0,0.0,0.0,-1.5,-2.5,-3.5,-4.0,-4.0,-4.5};
1138                 /* f0 is the frequency used for generating the above a-coeff */
1139                 double f0 = 1500.0;
1140                 /* fcol is the frequency for which to optimize the collaps */
1141                 double fcol = 800.0;
1142               
1143                 double ll,x,x3,x5,a1,a2,a3,a5,frac,lx;
1144                 int ix;
1145               
1146                 if (l == 0) 
1147                   ll = 1; 
1148                 else 
1149                   ll = sqrt(l*(l+1.));
1150 tplarson 1.1    x = m/ll;
1151                 x3 = x*x*x;
1152                 x5 = x3*x*x;
1153                 lx = 5*log10(l*f0/fcol)-4;
1154                 ix = floor(lx);
1155                 frac = lx-ix;
1156                 if (lx <= 0) {
1157                   ix = 0;
1158                   frac = 0.0;
1159                 }
1160                 if (lx >=8) {
1161                   ix = 7;
1162                   frac = 1.0;
1163                 }
1164                 a1 = (1.0-frac)*a1x[ix]+frac*a1x[ix+1];
1165                 a2 = 0.0;
1166                 a3 = (1.0-frac)*a3x[ix]+frac*a3x[ix+1];
1167                 a5 = (1.0-frac)*a5x[ix]+frac*a5x[ix+1];
1168               
1169                 return ll*(a1*x+a2*(1.5*x*x-0.5)+a3*(2.5*x3-1.5*x)+a5*(63./8.*x5-70./8.*x3+15./8.*x))/1e9;
1170               }
1171 tplarson 1.1  
1172               
1173               
1174               /* Extract the data samples actually used by skipping or averaging
1175                  data. Replace missing data that are not marked as gaps with zero. */
1176               void extract_data(int n_in, int *gaps, float *data_in, float *data_out)
1177               {
1178                 int i,j, nmiss = 0;
1179 tplarson 1.3  // the following check will be skipped in production executables since they will be built with NDEBUG defined.
1180               // it doesn't matter because the check is already done in DoIt().
1181 tplarson 1.1    assert(nskip==1 || navg==1);
1182                 if ((navg == 1) && (nskip == 1)) 
1183                 {
1184                   for (i=0; i<n_in; i++) 
1185                   {
1186                     if (gaps[i]==0 )
1187                     {
1188               	data_out[2*i] = 0.0f;
1189               	data_out[2*i+1] = 0.0f;
1190                     }
1191                     else
1192                     {
1193               	if (isnan(data_in[2*i]) || isnan(data_in[2*i+1]))
1194               	{
1195               	  data_out[2*i] = 0.0f;
1196               	  data_out[2*i+1] = 0.0f;
1197               	  gaps[i] = 0;
1198               	  nmiss++;
1199               	}
1200               	else
1201               	{
1202 tplarson 1.1  	  data_out[2*i] = data_in[2*i];
1203               	  data_out[2*i+1] = flipm ? -data_in[2*i+1] : data_in[2*i+1];
1204               	}
1205                     }
1206                   }
1207                 }
1208                 else if (nskip != 1) 
1209                 {
1210                   for (i = 0; i<n_in; i++) 
1211                   {
1212                     if (gaps[i]==0 )
1213                     {
1214               	data_out[2*i] = 0.0f;
1215               	data_out[2*i+1] = 0.0f;
1216                     }
1217                     else
1218                     {
1219               	int ix = nskip*i+noff;
1220               	if (isnan(data_in[2*ix]) || isnan(data_in[2*ix+1]))
1221               	{
1222               	  data_out[2*i] = 0.0f;
1223 tplarson 1.1  	  data_out[2*i+1] = 0.0f;
1224               	  gaps[i] = 0;
1225               	  nmiss++;
1226               	}
1227               	else
1228               	{
1229               	  data_out[2*i] = data_in[2*ix];
1230               	  data_out[2*i+1] =  flipm ? -data_in[2*ix+1] : data_in[2*ix+1];
1231               	}
1232                     }
1233                   }
1234                 }
1235                 else if (navg != 1) 
1236                 {
1237                   for (i = 0; i<n_in; i++) 
1238                   {
1239                     if (gaps[i]==0 )
1240                     {
1241               	data_out[2*i] = 0.0f;
1242               	data_out[2*i+1] = 0.0f;
1243                     }
1244 tplarson 1.1        else
1245                     {
1246               	float avgr = 0.0f;
1247               	float avgi = 0.0f;
1248               	for (j=0; j<navg; j++) 
1249               	{
1250               	  int ix = navg*i+j;
1251               	  if (isnan(data_in[2*ix]) || isnan(data_in[2*ix+1]))
1252               	  {
1253               	    data_out[2*i] = 0.0f;
1254               	    data_out[2*i+1] = 0.0f;
1255               	    gaps[i] = 0;
1256               	    nmiss++;
1257               	    break;
1258               	  }
1259               	  else 
1260               	  {
1261               	    avgr += data_in[2*ix];
1262               	    avgi += data_in[2*ix+1];
1263               	  }
1264               	}
1265 tplarson 1.1  	if (j == navg) 
1266               	{
1267               	  data_out[2*i] = avgr/navg;
1268               	  data_out[2*i+1] = avgi/navg;
1269               	}
1270                     }
1271                   }  
1272                 }
1273               }
1274               
1275               /* Extract the windows function for the samples actually used after
1276                  subsampling or averaging. Modify the list of continous sections
1277                  accordingly, and make sure we do not average across section boundaries. */
1278               static int extract_gaps(int n_in, int *gaps_in, int *n_out, int *gaps_out, 
1279               		  float tsample_in, float *tsample_out, 
1280               		  int *num_sections, int *sections)
1281               {
1282 tplarson 1.3  // the following check will be skipped in production executables since they will be built with NDEBUG defined.
1283               // it doesn't matter because the check is already done in DoIt().
1284 tplarson 1.1    assert(nskip==1 || navg==1);
1285                 int i,j,sect, start,stop;
1286               
1287               
1288                 if (*num_sections<1)
1289                 {
1290                   fprintf(stderr,"Apparantly no sections of data available.");
1291                   return 1;
1292                 }
1293                 /* Mask out data that in between sections if this hasn't already been
1294                    done in gapfile. */
1295                 for (i=0; i<sections[0] && i<n_in; i++)
1296                   gaps_in[i] = 0;
1297                 for (sect=1; sect<(*num_sections); sect++)
1298                 {
1299                   for (i=sections[2*sect-1]+1; i<sections[2*sect] && i<n_in; i++)
1300                     gaps_in[i] = 0;
1301                 }
1302                 for (i=sections[2*(*num_sections-1)+1]+1; i<n_in; i++)
1303                   gaps_in[i] = 0;
1304                   
1305 tplarson 1.1  
1306                 if ((navg == 1) && (nskip == 1)) 
1307                 {
1308                   *n_out = n_in;
1309                   *tsample_out = tsample_in;
1310                   for (i=0; i<*n_out; i++) 
1311                     gaps_out[i] = gaps_in[i];
1312                 }
1313                 else if (nskip != 1) 
1314                 {
1315                   *n_out = n_in/nskip;
1316                   *tsample_out = nskip*tsample_in;
1317                   for (i=0; i<*n_out; i++) 
1318                   {
1319                     gaps_out[i] = gaps_in[nskip*i+noff];
1320                   }
1321                   for (i=0; i<2*(*num_sections); i+=2)
1322                   {
1323                     start = (int)ceilf(((float)(sections[i]-noff))/nskip);
1324                     stop = (int)floorf(((float)(sections[i+1]-noff))/nskip);
1325                     if (start <= stop)
1326 tplarson 1.1        {
1327               	sections[i] = start;
1328               	sections[i+1] = stop;
1329                     }
1330                     else 
1331                     {
1332               	/* This section was skipped entirely. */
1333               	for (j=i; j< 2*(*num_sections-1); j+=2) 
1334               	{
1335               	  sections[j] = sections[j+2];
1336               	  sections[j+1] = sections[j+3];
1337               	}
1338               	*num_sections -= 1;
1339                     }
1340                   }
1341                 }
1342                 else  if (navg != 1) 
1343                 {
1344                   sect = 0;
1345                   *n_out = n_in/navg;
1346                   *tsample_out = tsample*navg;
1347 tplarson 1.1      for (i=0; i<*n_out; i++) 
1348                   {      
1349                     int igx = 1;
1350                     while (sect < *num_sections && 
1351               	     !(navg*i >= sections[2*sect] && navg*i >= sections[2*sect+1]))
1352               	sect++;
1353               
1354                     /* Don't allow averaging of data from different sections. */
1355                     if (navg*i >= sections[2*sect] && (navg*i+navg-1)<=sections[2*sect+1])
1356                     {
1357               	for (j=0; j<navg; j++) 
1358               	  igx *= gaps_in[navg*i+j];
1359               	gaps_out[i] = igx;
1360                     }
1361                     else
1362               	gaps_out[i] = 0;
1363                   }
1364                   for (i=0; i<2*(*num_sections); i+=2)
1365                   {
1366                     start = (int)ceilf(((float)sections[i])/navg);
1367                     stop = (int)floorf(((float)sections[i+1])/navg);
1368 tplarson 1.1        if (start <= stop)
1369                     {
1370               	sections[i] = start;
1371               	sections[i+1] = stop;
1372                     }
1373                     else 
1374                     {
1375               	/* This section was skipped entirely. */
1376               	for (j=i; j< 2*(*num_sections-1); j+=2) 
1377               	{
1378               	  sections[j] = sections[j+2];
1379               	  sections[j+1] = sections[j+3];
1380               	}
1381               	*num_sections -= 1;
1382                     }
1383                   }
1384                 }  
1385                 return 0;
1386               }
1387               
1388               
1389 tplarson 1.1  /*
1390                  Read a list of sections [start_sample:end_sample] that should
1391                  contain continuous data. When detrending, jumps are allow to
1392                  occur between sections. The sections file should be a text file 
1393                  of the form:
1394               
1395                  num
1396                  start_1  end_1
1397                  start_2  end_2
1398                  ...
1399                  start_num  end_num
1400               */
1401               static int read_section_file(char *filename, int *num_sections, int **sections)
1402               {
1403                 FILE *fh;
1404                 int i;
1405               
1406                 fh = fopen(filename,"r");
1407                 if (fh!=NULL)
1408                 {
1409                   fscanf(fh,"%d",num_sections);
1410 tplarson 1.1      *sections = (int *)malloc(2*(*num_sections)*sizeof(int));
1411                   
1412                   for (i=0 ;i<2*(*num_sections); i+=2)
1413                   {
1414                     fscanf(fh,"%d",&(*sections)[i]);
1415                     fscanf(fh,"%d",&(*sections)[i+1]);
1416                   
1417                     if ((*sections)[i]>(*sections)[i+1] ||
1418               	  (i>0 && (*sections)[i]<=(*sections)[i-1]))
1419                     {
1420               	fprintf(stderr,"Invalid sections file, sections overlap.\n");
1421 tplarson 1.2  	return 2;
1422 tplarson 1.1        }
1423                   }
1424                   fclose(fh);
1425                   return 0;
1426                 }
1427                 else 
1428                   return 1;
1429               }  
1430               

Karen Tian
Powered by
ViewCVS 0.9.4