00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <strings.h>
00014 #include <time.h>
00015 #include <sys/time.h>
00016 #include <sys/resource.h>
00017 #include <math.h>
00018 #include <assert.h>
00019 #include <fftw3.h>
00020
00021 #include "jsoc_main.h"
00022 #include "fitsio.h"
00023
00024 #define ARRLENGTH(ARR) (sizeof(ARR)/sizeof(ARR[0]))
00025 #define kNOTSPECIFIED "not specified"
00026
00027 char *module_name = "jtsslice";
00028 char *cvsinfo_jtsslice = "cvsinfo: $Header: /home/cvsuser/cvsroot/JSOC/proj/globalhs/apps/jtsslice.c,v 1.12 2013/04/28 08:05:21 tplarson Exp $";
00029
00030
00031 ModuleArgs_t module_args[] =
00032 {
00033 {ARG_STRING, "in", "", "input data records"},
00034 {ARG_STRING, "out", "", "output data series"},
00035 {ARG_STRING, "segin" , kNOTSPECIFIED, "name of input segment if not using segment 0"},
00036 {ARG_STRING, "segout", kNOTSPECIFIED, "name of output segment if not using segment 0"},
00037 {ARG_STRING, "histlink", "HISTORY", "name of link to ancillary dataseries for processing metadata"},
00038 {ARG_STRING, "srclink", "SRCDATA", "name of link to source data"},
00039 {ARG_INT, "PERM", "1", "set to 0 for transient records, nonzero for permanent records"},
00040 {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},
00041 {ARG_STRING, "GAPFILE", "", "record or file containing window function"},
00042
00043 {ARG_INT, "NDT", "-1", "", ""},
00044 {ARG_STRING, "TTOTAL", NULL, "total length of time in output"},
00045
00046 {ARG_INT, "IFIRST", "0", "", ""},
00047
00048
00049 {ARG_INT, "TSOUT", "0", "", ""},
00050 {ARG_INT, "FFTOUT", "0", "", ""},
00051 {ARG_INT, "FFT1OUT", "0", "", ""},
00052 {ARG_INT, "POWOUT", "0", "", ""},
00053 {ARG_INT, "MAVGOUT", "0", "", ""},
00054 {ARG_INT, "NAVG", "0", "", ""},
00055 {ARG_INT, "NSKIP", "0", "", ""},
00056 {ARG_INT, "NOFF", "0", "", ""},
00057 {ARG_INT, "IMIN", "0", "", ""},
00058 {ARG_INT, "IMAX", "-1", "", ""},
00059 {ARG_END},
00060 };
00061
00062 #include "saveparm.c"
00063 #include "timing.c"
00064 #include "set_history.c"
00065
00066 #define DIE(code) { fprintf(stderr,"jtsslice died with error code %d\n",(code)); return 0;}
00067
00068
00069 static char *gapfile;
00070 static int lmode, n_sampled_out, flipm;
00071 static float tsample;
00072 static int ifirst, tsout,fftout, fft1out, powout, mavgout;
00073 static int navg, nskip, noff, imin, imax;
00074
00075
00076
00077 static double splitting(int l, int m);
00078
00079
00080 extern void cffti_(int *, float *);
00081 extern void cfftb_(int *, float *, float *);
00082 static int extract_gaps(int n_in, int *gaps_in, int *n_out, int *gaps_out,
00083 float tsample_in, float *tsample_out,
00084 int *num_sections, int *sections);
00085 static void extract_data(int n_in, int *gaps, float *data_in, float *data_out);
00086
00087
00088 int DoIt(void)
00089 {
00090 int i;
00091 int start_index[2], counts[2], intervals[2];
00092 int m, n_in, n_sampled_in;
00093 TIME epoch, step, start, stop;
00094 int gapsize, istart, istop, data_dim, detrend_order;
00095 int npow, mshift;
00096 float tsamplex, df1, c;
00097 int *agaps;
00098 int *gaps;
00099 float *msum, *pow;
00100 float *data, *out_data, *in_data;
00101 fftwf_plan plan;
00102 int num_sections, *sections;
00103 char tstartstr[100];
00104
00105 int fstatus = 0;
00106 fitsfile *fitsptr;
00107 long fdims[1];
00108 long fpixel[]={1};
00109 int *anynul=0;
00110
00111 int length[2], startind[2], endind[2];
00112 float *datarr;
00113 int status=DRMS_SUCCESS;
00114 int newstat=0;
00115 char *ttotal;
00116 double nseconds;
00117
00118 DRMS_Segment_t *segin = NULL;
00119 DRMS_Segment_t *segout = NULL;
00120 DRMS_Array_t *inarr = NULL;
00121 DRMS_Array_t *outarr = NULL;
00122 DRMS_Record_t *inrec = NULL;
00123 DRMS_Record_t *outrec = NULL;
00124 DRMS_Type_t usetype = DRMS_TYPE_FLOAT;
00125 DRMS_RecLifetime_t lifetime;
00126 long long histrecnum = -1;
00127 DRMS_Segment_t *gapseg = NULL;
00128 DRMS_Array_t *gaparr = NULL;
00129
00130 HIterator_t outKey_list;
00131 DRMS_Keyword_t *outKey;
00132 TIME tnow, UNIX_epoch = -220924792.000;
00133
00134 int errbufstat=setvbuf(stderr, NULL, _IONBF, BUFSIZ);
00135 int outbufstat=setvbuf(stdout, NULL, _IONBF, BUFSIZ);
00136
00137 double tstart, tstartsave, tstop, tstopsave, cadence, tstartout, tstopout;
00138 double wt0, wt1, wt2, wt3, wt;
00139 double ut0, ut1, ut2, ut3, ut;
00140 double st0, st1, st2, st3, st;
00141 double ct0, ct1, ct2, ct3, ct;
00142
00143 wt0=getwalltime();
00144 ct0=getcputime(&ut0, &st0);
00145
00146
00147 gapfile = (char *)cmdparams_save_str (&cmdparams, "GAPFILE", &newstat);
00148 n_sampled_out = cmdparams_save_int (&cmdparams, "NDT", &newstat);
00149 ifirst = cmdparams_save_int (&cmdparams, "IFIRST", &newstat);
00150
00151 tsout = cmdparams_save_int (&cmdparams, "TSOUT", &newstat);
00152 fftout = cmdparams_save_int (&cmdparams, "FFTOUT", &newstat);
00153 fft1out = cmdparams_save_int (&cmdparams, "FFT1OUT", &newstat);
00154 powout = cmdparams_save_int (&cmdparams, "POWOUT", &newstat);
00155 mavgout = cmdparams_save_int (&cmdparams, "MAVGOUT", &newstat);
00156 navg = cmdparams_save_int (&cmdparams, "NAVG", &newstat);
00157 nskip = cmdparams_save_int (&cmdparams, "NSKIP", &newstat);
00158 noff = cmdparams_save_int (&cmdparams, "NOFF", &newstat);
00159 imin = cmdparams_save_int (&cmdparams, "IMIN", &newstat);
00160 imax = cmdparams_save_int (&cmdparams, "IMAX", &newstat);
00161
00162 char *inrecquery = (char *)cmdparams_save_str(&cmdparams, "in", &newstat);
00163 char *outseries = (char *)cmdparams_save_str(&cmdparams, "out", &newstat);
00164 char *segnamein = (char *)cmdparams_save_str(&cmdparams, "segin", &newstat);
00165 char *segnameout = (char *)cmdparams_save_str(&cmdparams, "segout", &newstat);
00166 int seginflag = strcmp(kNOTSPECIFIED, segnamein);
00167 int segoutflag = strcmp(kNOTSPECIFIED, segnameout);
00168 char *histlinkname = (char *)cmdparams_save_str(&cmdparams, "histlink", &newstat);
00169 char *srclinkname = (char *)cmdparams_save_str(&cmdparams, "srclink", &newstat);
00170 int verbflag = cmdparams_save_int(&cmdparams, "VERB", &newstat);
00171 int permflag = cmdparams_save_int(&cmdparams, "PERM", &newstat);
00172 if (permflag)
00173 lifetime = DRMS_PERMANENT;
00174 else
00175 lifetime = DRMS_TRANSIENT;
00176
00177 ttotal=(char *)cmdparams_save_str(&cmdparams, "TTOTAL", &newstat);
00178 status=drms_names_parseduration(&ttotal, &nseconds, 1);
00179 if (status != DRMS_SUCCESS)
00180 {
00181 fprintf(stderr, "ERROR: problem parsing TTOTAL, = %s\n", ttotal);
00182 return 1;
00183 }
00184
00185 if (newstat)
00186 {
00187 fprintf(stderr, "ERROR: problem with input arguments, status = %d, diagnosis follows\n", newstat);
00188 cpsave_decode_error(newstat);
00189 return 1;
00190 }
00191 else if (savestrlen != strlen(savestr))
00192 {
00193 fprintf(stderr, "ERROR: problem with savestr, savestrlen = %d, strlen(savestr) = %d\n", savestrlen, (int)strlen(savestr));
00194 return 1;
00195 }
00196
00197
00198
00199
00200
00201 if ((tsout == 0) && (fftout == 0) && (fft1out == 0) && (powout == 0) && (mavgout == 0))
00202 tsout=1;
00203
00204 if ((tsout+fftout+fft1out+powout+mavgout) !=1)
00205 {
00206 fprintf(stderr, "ERROR: only one type of output allowed at a time\n");
00207 return 1;
00208 }
00209 if (navg <= 0)
00210 navg=1;
00211 if (nskip <= 0)
00212 nskip=1;
00213 if ((navg != 1) && (nskip != 1))
00214 {
00215 fprintf(stderr, "ERROR: one of navg and nskip must equal 1\n");
00216 return 1;
00217 }
00218 if (noff < 0 || noff >= nskip)
00219 {
00220 fprintf(stderr, "ERROR: noff must be >= 0 and < nskip\n");
00221 return 1;
00222 }
00223
00224
00225 DRMS_Record_t *tempoutrec = drms_create_record(drms_env,
00226 outseries,
00227 DRMS_TRANSIENT,
00228 &status);
00229
00230 if (status != DRMS_SUCCESS)
00231 {
00232 fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", outseries, status);
00233 return 1;
00234 }
00235
00236 DRMS_Link_t *histlink = hcon_lookup_lower(&tempoutrec->links, histlinkname);
00237 DRMS_Link_t *srclink = hcon_lookup_lower(&tempoutrec->links, srclinkname);
00238
00239
00240 if (histlink != NULL)
00241 {
00242 histrecnum=set_history(histlink);
00243 if (histrecnum < 0)
00244 {
00245 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00246 return 1;
00247 }
00248 }
00249 else
00250 {
00251 fprintf(stderr,"WARNING: could not find history link in output dataseries\n");
00252 }
00253
00254
00255 char *outchecklist[] = {"T_START", "QUALITY", "LMIN", "LMAX", "NDT"};
00256
00257 int itest;
00258 for (itest=0; itest < ARRLENGTH(outchecklist); itest++)
00259 {
00260 DRMS_Keyword_t *outkeytest = hcon_lookup_lower(&tempoutrec->keywords, outchecklist[itest]);
00261 if (outkeytest == NULL || outkeytest->info->islink || outkeytest->info->recscope == 1)
00262 {
00263 fprintf(stderr, "ERROR: output keyword %s is either missing, constant, or a link\n", outchecklist[itest]);
00264 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00265 return 1;
00266 }
00267 }
00268
00269 cadence=drms_getkey_float(tempoutrec, "T_STEP", &status);
00270 double chunksecs = n_sampled_out*cadence;
00271 if (fmod(nseconds,chunksecs) != 0.0)
00272 {
00273 fprintf(stderr, "ERROR: input parameters seem incompatible (chunksecs must divide nseconds): nseconds = %f, chunksecs = %f\n", nseconds, chunksecs);
00274 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00275 return 1;
00276 }
00277 int ntimechunks = nseconds/chunksecs;
00278 tsample=cadence;
00279
00280 int mflipout = drms_getkey_int(tempoutrec, "MFLIPPED", &status);
00281 if (status != DRMS_SUCCESS) mflipout=0;
00282
00283 drms_close_record(tempoutrec, DRMS_FREE_RECORD);
00284
00285
00286 if (fits_open_file(&fitsptr, gapfile, READONLY, &fstatus))
00287 {
00288 DRMS_RecordSet_t *gaprecset = drms_open_records(drms_env, gapfile, &status);
00289 if (status != DRMS_SUCCESS || gaprecset == NULL)
00290 {
00291 fprintf(stderr,"ERROR: problem reading gaps: file status = %d, DRMS status = %d\n",fstatus,status);
00292 return 1;
00293 }
00294 if (gaprecset->n == 0)
00295 {
00296 fprintf(stderr,"ERROR: gapfile recordset contains no records\n");
00297 return 1;
00298 }
00299 if (gaprecset->n > 1)
00300 {
00301 fprintf(stderr,"ERROR: gapfile recordset with more than 1 record not yet supported.\n");
00302 return 1;
00303 }
00304 gapseg = drms_segment_lookupnum(gaprecset->records[0], 0);
00305 if (gapseg != NULL)
00306 gaparr = drms_segment_read(gapseg, DRMS_TYPE_INT, &status);
00307 if (status != DRMS_SUCCESS || gaparr == NULL || gapseg == NULL)
00308 {
00309 fprintf(stderr, "ERROR: problem reading gaps segment: status = %d\n", status);
00310 return 1;
00311 }
00312 agaps=(int *)(gaparr->data);
00313 gapsize=gaparr->axis[0];
00314 }
00315 else
00316 {
00317 fits_get_img_size(fitsptr, 1, fdims, &fstatus);
00318 gapsize=fdims[0];
00319 agaps=(int *)(malloc(gapsize*sizeof(int)));
00320 fits_read_pix(fitsptr, TINT, fpixel, gapsize, NULL, agaps, anynul, &fstatus);
00321 fits_close_file(fitsptr, &fstatus);
00322 if (fstatus)
00323 {
00324 fprintf(stderr, "ERROR: ");
00325 fits_report_error(stderr, fstatus);
00326 return 1;
00327 }
00328 }
00329
00330 if (verbflag)
00331 printf("gapfile read, gapsize = %d\n",gapsize);
00332
00333 data_dim=gapsize;
00334 if (n_sampled_out>gapsize)
00335 data_dim=n_sampled_out;
00336
00337 num_sections=1;
00338 sections = malloc(2*sizeof(int));
00339 sections[0] = 0;
00340 sections[1] = data_dim-1;
00341
00342
00343 gaps=(int *)(malloc(gapsize*sizeof(int)));
00344 data=(float *)(fftwf_malloc(2*data_dim*sizeof(float)));
00345
00346 DRMS_RecordSet_t *inrecset = drms_open_records(drms_env, inrecquery, &status);
00347
00348 if (status != DRMS_SUCCESS || inrecset == NULL)
00349 {
00350 fprintf(stderr,"ERROR: problem opening input recordset: status = %d\n",status);
00351 return 1;
00352 }
00353
00354 if (inrecset->n == 0)
00355 {
00356 fprintf(stderr, "ERROR: input recordset contains no records\n");
00357 return 1;
00358 }
00359
00360 inrec=inrecset->records[0];
00361 char *inchecklist[] = {"T_START", "QUALITY", "LMIN", "LMAX", "T_STEP"};
00362
00363 for (itest=0; itest < ARRLENGTH(inchecklist); itest++)
00364 {
00365 DRMS_Keyword_t *inkeytest = hcon_lookup_lower(&inrec->keywords, inchecklist[itest]);
00366 if (inkeytest == NULL)
00367 {
00368 fprintf(stderr, "ERROR: required input keyword %s is missing\n", inchecklist[itest]);
00369 drms_close_records(inrecset, DRMS_FREE_RECORD);
00370 return 1;
00371 }
00372 }
00373
00374 tstartsave=drms_getkey_time(inrec, "T_START", NULL);
00375
00376 int mflipin = drms_getkey_int(inrec, "MFLIPPED", &status);
00377 if (status != DRMS_SUCCESS) mflipin=0;
00378
00379 if (mflipout != mflipin)
00380 flipm=1;
00381 else
00382 flipm=0;
00383
00384
00385 if (extract_gaps(gapsize, agaps, &n_sampled_in, gaps, tsample, &tsamplex, &num_sections, sections))
00386 {
00387 fprintf(stderr, "ERROR: problem in extract_gaps\n");
00388 return 0;
00389 }
00390
00391 if (n_sampled_out == -1)
00392 n_sampled_out = n_sampled_in;
00393 df1 = tsamplex*n_sampled_out;
00394
00395 if (fftout || fft1out || powout || mavgout)
00396 plan = fftwf_plan_dft_1d(n_sampled_out, (fftwf_complex *)data,
00397 (fftwf_complex *)data, FFTW_BACKWARD, FFTW_MEASURE);
00398
00399
00400 if (mavgout)
00401 msum = (float *)calloc(n_sampled_out/2,sizeof(float));
00402
00403 if (fft1out || powout || mavgout)
00404 {
00405
00406 if (imax < imin)
00407 {
00408 imin=0;
00409 imax=n_sampled_out/2-1;
00410 }
00411 npow=imax-imin+1;
00412 pow=(float *)(malloc(n_sampled_out*sizeof(float)));
00413 }
00414
00415
00416 status=drms_stage_records(inrecset, 1, 0);
00417 if (status != DRMS_SUCCESS)
00418 {
00419 fprintf(stderr, "ERROR: drms_stage_records returned status = %d\n", status);
00420 return 1;
00421 }
00422
00423 int nrecsout = ntimechunks * inrecset->n;
00424 DRMS_RecordSet_t *outrecset = drms_create_records(drms_env, nrecsout, outseries, DRMS_PERMANENT, &status);
00425 if (status != DRMS_SUCCESS || outrecset == NULL)
00426 {
00427 fprintf(stderr,"ERROR: couldn't open a record in output dataseries %s, status = %d\n", outseries, status);
00428 return 1;
00429 }
00430
00431 int gapoffset, gapoffset0 = ifirst;
00432 double tstart0 = tstartsave+ifirst*tsample;
00433 int irec;
00434 for (irec=0;irec<inrecset->n;irec++)
00435 {
00436
00437 inrec = inrecset->records[irec];
00438
00439 int lmin=drms_getkey_int(inrec, "LMIN", NULL);
00440 int lmax=drms_getkey_int(inrec, "LMAX", NULL);
00441 if (lmin != lmax)
00442 {
00443 fprintf(stderr, "ERROR: lmin != lmax not yet supported.\n");
00444 return 0;
00445 }
00446 lmode=lmin;
00447
00448 if (verbflag)
00449 printf("starting l=%d\n",lmode);
00450
00451 tstart=drms_getkey_time(inrec, "T_START", NULL);
00452 tstop =drms_getkey_time(inrec, "T_STOP", NULL);
00453 cadence=drms_getkey_float(inrec, "T_STEP", NULL);
00454 if (tstart != tstartsave)
00455 {
00456
00457 sprint_time(tstartstr, tstart, "TAI", 0);
00458 fprintf(stderr, "ERROR: all input records must have same T_START, record %d has %s\n", irec, tstartstr);
00459 return 0;
00460 }
00461
00462 n_in=(tstop-tstart)/cadence;
00463 if (n_in != gapsize)
00464 {
00465 fprintf(stderr, "ERROR: gaps seem incompatible with time-series, gapsize=%d, n_in=%d\n", gapsize, n_in);
00466 return 0;
00467 }
00468
00469
00470 if (tsout || fftout)
00471 {
00472 length[0]=2*n_sampled_out;
00473 length[1]=lmode+1;
00474 }
00475 else
00476 {
00477 if (fft1out)
00478 length[0]=2*npow;
00479 else
00480 length[0]=npow;
00481 if (powout || fft1out)
00482 length[1]=2*lmode+1;
00483 else
00484 length[1]=1;
00485 }
00486
00487 startind[1]=0;
00488 endind[1]=lmode;
00489
00490 if (seginflag)
00491 segin = drms_segment_lookup(inrec, segnamein);
00492 else
00493 segin = drms_segment_lookupnum(inrec, 0);
00494 if (segin == NULL)
00495 {
00496 fprintf(stderr, "ERROR: problem reading input segment: recnum = %ld\n", inrec->recnum);
00497 return 0;
00498 }
00499
00500 int iset;
00501 for (iset=0; iset < ntimechunks; iset++)
00502 {
00503 tstartout=tstart0 + iset * chunksecs;
00504 tstopout=tstartout+chunksecs;
00505 sprint_time(tstartstr, tstartout, "TAI", 0);
00506 gapoffset = gapoffset0 + iset*n_sampled_out;
00507
00508 if (verbflag>1)
00509 {
00510 printf(" starting tstart = %s, ",tstartstr);
00511 if (irec == 0)
00512 {
00513 int ig, gtotal=0;
00514 for (ig=0;ig<n_sampled_out;ig++)
00515 gtotal+=gaps[gapoffset+ig];
00516 float dutycycle = (float)gtotal/n_sampled_out;
00517 printf("dutycycle = %f\n", dutycycle);
00518 }
00519 }
00520
00521
00522 ifirst=gapoffset;
00523 startind[0]=2*(ifirst);
00524 endind[0]=2*(ifirst + n_sampled_out) - 1;
00525
00526 ifirst=0;
00527
00528 inarr = drms_segment_readslice(segin, usetype, startind, endind, &status);
00529 if (status != DRMS_SUCCESS || inarr == NULL)
00530 {
00531 fprintf(stderr, "ERROR: problem reading input segment: recnum = %ld, status = %d\n", inrec->recnum, status);
00532 return 0;
00533 }
00534 datarr=(float *)(inarr->data);
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 outrec = outrecset->records[iset*inrecset->n + irec];
00546
00547 if (histlink != NULL)
00548 drms_setlink_static(outrec, histlinkname, histrecnum);
00549 if (srclink != NULL)
00550 drms_setlink_static(outrec, srclinkname, inrec->recnum);
00551
00552 if (segoutflag)
00553 segout = drms_segment_lookup(outrec, segnameout);
00554 else
00555 segout = drms_segment_lookupnum(outrec, 0);
00556 outarr = drms_array_create(usetype, 2, length, NULL, &status);
00557 if (status != DRMS_SUCCESS || outarr == NULL || segout == NULL)
00558 {
00559 fprintf(stderr,"ERROR: problem creating output array or segment: length = [%d, %d], status = %d", length[0], length[1], status);
00560 return 0;
00561 }
00562 out_data = outarr->data;
00563
00564
00565 for (m=0; m<=lmode; m++)
00566 {
00567
00568 if (verbflag>2)
00569 printf(" starting m=%d\n",m);
00570
00571 in_data=datarr + m*2*n_sampled_out;
00572
00573
00574 extract_data(n_sampled_out, gaps+gapoffset, in_data, data);
00575
00576
00577
00578 memmove(data, &data[2*ifirst], 2*(n_sampled_in-ifirst)*sizeof(float));
00579 if ((ifirst+n_sampled_out) >= n_sampled_in)
00580 memset(&data[2*n_sampled_in], 0, 2*(n_sampled_out+ifirst-n_sampled_in)*sizeof(float));
00581
00582 if (fftout || fft1out || powout || mavgout)
00583 fftwf_execute(plan);
00584
00585 if (tsout || fftout)
00586 memcpy(&out_data[2*m*n_sampled_out], &data[2*ifirst], 2*n_sampled_out*sizeof(float));
00587
00588 else if (fft1out)
00589 {
00590
00591 memcpy(&out_data[2*(lmode+m)*npow], &data[2*imin], 2*npow*sizeof(float));
00592 if (m > 0)
00593 {
00594
00595 for (i=0; i<npow; i++)
00596 {
00597
00598 out_data[2*((lmode-m)*npow+i)] = data[2*(n_sampled_out-imin-i)];
00599 out_data[2*((lmode-m)*npow+i)+1] = -data[2*(n_sampled_out-imin-i)+1];
00600 }
00601 }
00602 }
00603 else
00604 {
00605
00606 for (i = 0; i < n_sampled_out; i++)
00607 pow[i] = data[2*i]*data[2*i] + data[2*i+1]*data[2*i+1];
00608 if (powout)
00609 {
00610
00611 memcpy(&out_data[(lmode+m)*npow], &pow[imin], npow*sizeof(float));
00612 if (m > 0)
00613 {
00614
00615 if (imin)
00616 out_data[(lmode-m)*npow] = pow[n_sampled_out-imin];
00617 else
00618 out_data[(lmode-m)*npow] = pow[0];
00619 for (i=1; i<npow;i++)
00620 out_data[(lmode-m)*npow+i] = pow[n_sampled_out-imin-i];
00621 }
00622 }
00623 else
00624 {
00625
00626
00627
00628
00629 mshift = floor(df1*splitting(lmode,m)+0.5f);
00630 if (mshift >= 0)
00631 for (i=0; i<n_sampled_out/2-mshift; i++)
00632 msum[i] += pow[mshift+i];
00633 else
00634 for (i=0; i<n_sampled_out/2+mshift; i++)
00635 msum[i-mshift] += pow[i];
00636 if (m > 0)
00637 {
00638
00639 mshift = floor(df1*splitting(lmode,-m)+0.5f);
00640 if (mshift >=0)
00641 for (i=1; i<n_sampled_out/2-mshift;i++)
00642 msum[i] += pow[n_sampled_out-mshift-i];
00643 else
00644 for (i=1; i<n_sampled_out/2+mshift; i++)
00645 msum[i-mshift] += pow[n_sampled_out-i];
00646 }
00647 }
00648 }
00649
00650 }
00651
00652 drms_copykeys(outrec, inrec, 0, kDRMS_KeyClass_Explicit);
00653 drms_setkey_int(outrec, "QUALITY", 0);
00654 drms_setkey_time(outrec, "T_START", tstartout);
00655 drms_setkey_time(outrec, "T_STOP", tstopout);
00656 drms_setkey_time(outrec, "T_OBS", (tstartout + tstopout)/2);
00657 drms_setkey_float(outrec, "T_STEP", tsamplex);
00658 drms_setkey_int(outrec, "NDT", n_sampled_out);
00659
00660 tnow = (double)time(NULL);
00661 tnow += UNIX_epoch;
00662 drms_setkey_time(outrec, "DATE", tnow);
00663
00664 if (mavgout)
00665 {
00666 c=1.0f/(2*lmode+1);
00667 for (i=0; i<npow; i++)
00668 out_data[i] = msum[imin+i] * c;
00669 }
00670
00671 outarr->bzero=segout->bzero;
00672 outarr->bscale=segout->bscale;
00673 status=drms_segment_write(segout, outarr, 0);
00674 if (status != DRMS_SUCCESS)
00675 {
00676 fprintf(stderr, "ERROR: problem writing output segment: status = %d, T_START = %s, LMODE = %d, histrecnum = %lld\n", status, tstartstr, lmode, histrecnum);
00677 return 0;
00678 }
00679 drms_free_array(outarr);
00680 drms_free_array(inarr);
00681
00682
00683 }
00684
00685 }
00686
00687 drms_close_records(inrecset, DRMS_FREE_RECORD);
00688 drms_close_records(outrecset, DRMS_INSERT_RECORD);
00689
00690 if (fftout || fft1out || powout || mavgout)
00691 fftwf_destroy_plan(plan);
00692
00693 wt=getwalltime();
00694 ct=getcputime(&ut, &st);
00695 if (verbflag)
00696 {
00697 fprintf(stdout, "total time spent: %.2f ms wall time, %.2f ms cpu time\n",
00698 wt-wt0, ct-ct0);
00699 }
00700
00701 printf("module %s successful completion\n", cmdparams.argv[0]);
00702 return 0;
00703 }
00704
00705
00706 static double splitting(int l, int m)
00707 {
00708 double a1x[] = {406.0,407.0,408.0,410.5,412.0,411.5,409.0,406.0,406.0};
00709 double a3x[] = {10.0,10.0,15.0,19.5,21.0,21.3,21.3,21.3,21.8};
00710 double a5x[] = {0.0,0.0,0.0,-1.5,-2.5,-3.5,-4.0,-4.0,-4.5};
00711
00712 double f0 = 1500.0;
00713
00714 double fcol = 800.0;
00715
00716 double ll,x,x3,x5,a1,a2,a3,a5,frac,lx;
00717 int ix;
00718
00719 if (l == 0)
00720 ll = 1;
00721 else
00722 ll = sqrt(l*(l+1.));
00723 x = m/ll;
00724 x3 = x*x*x;
00725 x5 = x3*x*x;
00726 lx = 5*log10(l*f0/fcol)-4;
00727 ix = floor(lx);
00728 frac = lx-ix;
00729 if (lx <= 0) {
00730 ix = 0;
00731 frac = 0.0;
00732 }
00733 if (lx >=8) {
00734 ix = 7;
00735 frac = 1.0;
00736 }
00737 a1 = (1.0-frac)*a1x[ix]+frac*a1x[ix+1];
00738 a2 = 0.0;
00739 a3 = (1.0-frac)*a3x[ix]+frac*a3x[ix+1];
00740 a5 = (1.0-frac)*a5x[ix]+frac*a5x[ix+1];
00741
00742 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;
00743 }
00744
00745
00746
00747
00748
00749 void extract_data(int n_in, int *gaps, float *data_in, float *data_out)
00750 {
00751 int i,j, nmiss = 0;
00752
00753
00754 assert(nskip==1 || navg==1);
00755 if ((navg == 1) && (nskip == 1))
00756 {
00757 for (i=0; i<n_in; i++)
00758 {
00759 if (gaps[i]==0 )
00760 {
00761 data_out[2*i] = 0.0f;
00762 data_out[2*i+1] = 0.0f;
00763 }
00764 else
00765 {
00766 if (isnan(data_in[2*i]) || isnan(data_in[2*i+1]))
00767 {
00768 data_out[2*i] = 0.0f;
00769 data_out[2*i+1] = 0.0f;
00770 gaps[i] = 0;
00771 nmiss++;
00772 }
00773 else
00774 {
00775 data_out[2*i] = data_in[2*i];
00776 data_out[2*i+1] = flipm ? -data_in[2*i+1] : data_in[2*i+1];
00777 }
00778 }
00779 }
00780 }
00781 else if (nskip != 1)
00782 {
00783 for (i = 0; i<n_in; i++)
00784 {
00785 if (gaps[i]==0 )
00786 {
00787 data_out[2*i] = 0.0f;
00788 data_out[2*i+1] = 0.0f;
00789 }
00790 else
00791 {
00792 int ix = nskip*i+noff;
00793 if (isnan(data_in[2*ix]) || isnan(data_in[2*ix+1]))
00794 {
00795 data_out[2*i] = 0.0f;
00796 data_out[2*i+1] = 0.0f;
00797 gaps[i] = 0;
00798 nmiss++;
00799 }
00800 else
00801 {
00802 data_out[2*i] = data_in[2*ix];
00803 data_out[2*i+1] = flipm ? -data_in[2*ix+1] : data_in[2*ix+1];
00804 }
00805 }
00806 }
00807 }
00808 else if (navg != 1)
00809 {
00810 for (i = 0; i<n_in; i++)
00811 {
00812 if (gaps[i]==0 )
00813 {
00814 data_out[2*i] = 0.0f;
00815 data_out[2*i+1] = 0.0f;
00816 }
00817 else
00818 {
00819 float avgr = 0.0f;
00820 float avgi = 0.0f;
00821 for (j=0; j<navg; j++)
00822 {
00823 int ix = navg*i+j;
00824 if (isnan(data_in[2*ix]) || isnan(data_in[2*ix+1]))
00825 {
00826 data_out[2*i] = 0.0f;
00827 data_out[2*i+1] = 0.0f;
00828 gaps[i] = 0;
00829 nmiss++;
00830 break;
00831 }
00832 else
00833 {
00834 avgr += data_in[2*ix];
00835 avgi += data_in[2*ix+1];
00836 }
00837 }
00838 if (j == navg)
00839 {
00840 data_out[2*i] = avgr/navg;
00841 data_out[2*i+1] = avgi/navg;
00842 }
00843 }
00844 }
00845 }
00846 }
00847
00848
00849
00850
00851 static int extract_gaps(int n_in, int *gaps_in, int *n_out, int *gaps_out,
00852 float tsample_in, float *tsample_out,
00853 int *num_sections, int *sections)
00854 {
00855
00856
00857 assert(nskip==1 || navg==1);
00858 int i,j,sect, start,stop;
00859
00860
00861 if (*num_sections<1)
00862 {
00863 fprintf(stderr,"Apparantly no sections of data available.");
00864 return 1;
00865 }
00866
00867
00868 for (i=0; i<sections[0] && i<n_in; i++)
00869 gaps_in[i] = 0;
00870 for (sect=1; sect<(*num_sections); sect++)
00871 {
00872 for (i=sections[2*sect-1]+1; i<sections[2*sect] && i<n_in; i++)
00873 gaps_in[i] = 0;
00874 }
00875 for (i=sections[2*(*num_sections-1)+1]+1; i<n_in; i++)
00876 gaps_in[i] = 0;
00877
00878
00879 if ((navg == 1) && (nskip == 1))
00880 {
00881 *n_out = n_in;
00882 *tsample_out = tsample_in;
00883 for (i=0; i<*n_out; i++)
00884 gaps_out[i] = gaps_in[i];
00885 }
00886 else if (nskip != 1)
00887 {
00888 *n_out = n_in/nskip;
00889 *tsample_out = nskip*tsample_in;
00890 for (i=0; i<*n_out; i++)
00891 {
00892 gaps_out[i] = gaps_in[nskip*i+noff];
00893 }
00894 for (i=0; i<2*(*num_sections); i+=2)
00895 {
00896 start = (int)ceilf(((float)(sections[i]-noff))/nskip);
00897 stop = (int)floorf(((float)(sections[i+1]-noff))/nskip);
00898 if (start <= stop)
00899 {
00900 sections[i] = start;
00901 sections[i+1] = stop;
00902 }
00903 else
00904 {
00905
00906 for (j=i; j< 2*(*num_sections-1); j+=2)
00907 {
00908 sections[j] = sections[j+2];
00909 sections[j+1] = sections[j+3];
00910 }
00911 *num_sections -= 1;
00912 }
00913 }
00914 }
00915 else if (navg != 1)
00916 {
00917 sect = 0;
00918 *n_out = n_in/navg;
00919 *tsample_out = tsample*navg;
00920 for (i=0; i<*n_out; i++)
00921 {
00922 int igx = 1;
00923 while (sect < *num_sections &&
00924 !(navg*i >= sections[2*sect] && navg*i >= sections[2*sect+1]))
00925 sect++;
00926
00927
00928 if (navg*i >= sections[2*sect] && (navg*i+navg-1)<=sections[2*sect+1])
00929 {
00930 for (j=0; j<navg; j++)
00931 igx *= gaps_in[navg*i+j];
00932 gaps_out[i] = igx;
00933 }
00934 else
00935 gaps_out[i] = 0;
00936 }
00937 for (i=0; i<2*(*num_sections); i+=2)
00938 {
00939 start = (int)ceilf(((float)sections[i])/navg);
00940 stop = (int)floorf(((float)sections[i+1])/navg);
00941 if (start <= stop)
00942 {
00943 sections[i] = start;
00944 sections[i+1] = stop;
00945 }
00946 else
00947 {
00948
00949 for (j=i; j< 2*(*num_sections-1); j+=2)
00950 {
00951 sections[j] = sections[j+2];
00952 sections[j+1] = sections[j+3];
00953 }
00954 *num_sections -= 1;
00955 }
00956 }
00957 }
00958 return 0;
00959 }
00960