00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <time.h>
00026 #include <ctype.h>
00027 #include <math.h>
00028 #include <errno.h>
00029 #include <unistd.h>
00030 #include <string.h>
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033 #include <assert.h>
00034 #include <fcntl.h>
00035 #include <dirent.h>
00036
00037 #include "common.h"
00038
00039 #define DTMAX1 5.e-3
00040 #define DTMAX2 5.e-6
00041
00042 int fileNameOptions=ADD_CHANNEL_CODE;
00043
00044 char * auxChannelName[] = { "PwrSupply", "IntTemp", "AUX02", "AUX03", "AUX04", "AUX05", "AUX06", "AUX07", "AUX08",
00045 "AUX09", "AUX10", "AUX11", "AUX12", "AUX13", "AUX14", "AUX15" };
00046 char * auxChannelUnit[] = { "0.1V", "0.1°C", "count", "count", "count", "count", "count", "count",
00047 "count", "count", "count", "count", "count", "count", "count", "count" };
00048
00049 int buggyMykerinos=0;
00050 int warnFixBuggyMykerinos=0;
00051
00052 char dayDirPrefix[255];
00053 int timeWarningNow=0;
00054
00055 struct InfoHeaderType infoHeader[MAX_CHANNEL];
00056
00057 struct Titan2TimeType lastExtTime = { 0, 0 };
00058 struct Titan2TimeType lastIntTime = { 0, 0 };
00059 struct Titan2TimeType roundedTime = { 0, 0 };
00060
00061 int knownUSecond=0;
00062 int knownSecond=0;
00063 int knownExtGps=0;
00064 int knownTime=0;
00065
00066 FILE * dtFile=NULL;
00067 char dtFileName[255];
00068 struct Titan2TimeType dtFileTime = { 0, 0 };
00069 int dtUseLine;
00070
00071 double lastDt=1.e16;
00072
00073 int nCached=0;
00074 double *dtCached=NULL;
00075 double *TCached=NULL;
00076 char dtCachedFile[255];
00077
00078 char testForStation[128];
00079
00080 int emptyDir=0;
00081
00087 time_t lastShiftComputation=0;
00088 double lastShiftComputed=0.0;
00089
00092 static int IsTitan1Time(void)
00093 {
00094 if (((knownUSecond==0)||(knownExtGps==0))&&(knownTime==1)&&(knownSecond==1))
00095 {
00096 return(1);
00097 }
00098 return(0);
00099 }
00100
00101
00103 void ResetTimes(void)
00104 {
00105 nCached=0;
00106 if (dtCached) { free(dtCached); dtCached=NULL; };
00107 if (TCached) { free(TCached); TCached=NULL; };
00108
00109 emptyDir=0;
00110 knownTime=0;
00111 knownUSecond=0;
00112 knownSecond=0;
00113 knownExtGps=0;
00114
00115 lastShiftComputation=0;
00116 lastShiftComputed=0.0;
00117
00118 memset(&(HWConfig.digitizer),0,sizeof(struct DigitizerType));
00119
00120 memset(&lastExtTime,0,sizeof(struct Titan2TimeType));
00121 memset(&lastIntTime,0,sizeof(struct Titan2TimeType));
00122 memset(&roundedTime,0,sizeof(struct Titan2TimeType));
00123 memset(¤tTime,0,sizeof(struct Titan2TimeType));
00124 memset(&correctedTime,0,sizeof(struct Titan2TimeType));
00125 memset(&pulseTime,0,sizeof(struct Titan2TimeType));
00126 memset(&gpsExtTime,0,sizeof(struct Titan2TimeType));
00127 memset(&gpsIntTime,0,sizeof(struct Titan2TimeType));
00128 }
00129
00131 int InWindow(void)
00132 {
00133 int bw;
00134 if (onlyTag[0])
00135 {
00136 if (strcmp(currentTag,onlyTag)!=0)
00137 {
00138 return(0);
00139 }
00140 }
00141 if ((skipTime>beginWindow)&&(skipTime<endWindow))
00142 {
00143 bw=skipTime;
00144 }
00145 else
00146 {
00147 bw=beginWindow;
00148 }
00149 if (
00150 (
00151 !(
00152 ((bw>0)&&(correctedTime.usecond>>32<bw))||
00153 ((endWindow>0)&&(correctedTime.usecond>>32>endWindow))
00154 )
00155 )&&
00156 ((currentTime.usecond>0)||(extractTit))
00157 )
00158 {
00159 return(1);
00160 }
00161 return(0);
00162 }
00163
00164
00166 int DtFileSelect(const struct dirent* t)
00167 {
00168 int l;
00169 char s[128];
00170 l=strlen(t->d_name);
00171
00172 if (l<strlen(testForStation)+4)
00173 {
00174 return(0);
00175 }
00176 strcpy(s,testForStation);
00177 strcat(s,".dft");
00178
00179 if (0==strcmp(t->d_name+l-strlen(testForStation)-4,s))
00180 {
00181 return(1);
00182 }
00183 strcpy(s,testForStation);
00184 strcat(s,".flt");
00185
00186 if (0==strcmp(t->d_name+l-strlen(testForStation)-4,s))
00187 {
00188 return(1);
00189 }
00190 #ifndef IGNORE_DT_FILE
00191 strcpy(s,testForStation);
00192 strcat(s,".dt");
00193
00194 if (0==strcmp(t->d_name+l-strlen(testForStation)-3,s))
00195 {
00196 return(1);
00197 }
00198
00199 #endif
00200 return(0);
00201 }
00202
00209 int ReadDtLine(char *line, double *T, double *dt, char *fn)
00210 {
00211 if (6!=str2time(line,T))
00212 {
00213 PrintError("format error in %s: %s",fn,line);
00214 return(-1);
00215 }
00216 if (1!=sscanf(line,"%*s %lf",dt))
00217 {
00218
00219 return(-1);
00220 }
00221 return(0);
00222 }
00223
00228 int TimeFileSort(const void * a, const void * b)
00229 {
00230 struct dirent **e1 = (struct dirent **)a;
00231 struct dirent **e2 = (struct dirent **)b;
00232 int l1,l2;
00233 l1=strlen((*e1)->d_name);
00234 l2=strlen((*e2)->d_name);
00235
00236 if (strcmp((*e1)->d_name+l1-3,(*e2)->d_name+l2-3)==0)
00237 {
00238
00239 return(__alphasort(e1,e2));
00240 }
00241
00242
00243 if (strcmp((*e1)->d_name+l1-3,"dft")==0)
00244 {
00245 return(-1);
00246 }
00247
00248 if (strcmp((*e2)->d_name+l2-2,"dt")==0)
00249 {
00250 return(-1);
00251 }
00252
00253 if (strcmp((*e2)->d_name+l2-3,"dft")==0)
00254 {
00255 return(1);
00256 }
00257
00258 if (strcmp((*e1)->d_name+l1-2,"dt")==0)
00259 {
00260 return(1);
00261 }
00262
00263 return(0);
00264 }
00265
00268 void FillDtCache(char *fileName)
00269 {
00270 FILE *f;
00271 char line[128];
00272 int nalloc=0;
00273 double T,dt;
00274 PrintLog("reading '%s' for dt cache\n",fileName);
00275 strcpy(dtCachedFile,fileName);
00276
00277 if (dtCached) { free(dtCached); dtCached=NULL; };
00278 if (TCached) { free(TCached); TCached=NULL; };
00279 nCached=0;
00280
00281 f=fopen(fileName,"rt");
00282 if (!f)
00283 {
00284 return;
00285 }
00286
00287 while (fgets(line,127,f)!=NULL)
00288 {
00289 if (line[0]=='#')
00290 {
00291 continue;
00292 }
00293 if (nCached>=nalloc-1)
00294 {
00295 nalloc+=4096;
00296 dtCached=(double *)realloc(dtCached,nalloc*sizeof(double));
00297 if (dtCached==0)
00298 {
00299 PrintError("realloc dtCached: %m\n");
00300 }
00301 TCached=(double *)realloc(TCached,nalloc*sizeof(double));
00302 if (TCached==0)
00303 {
00304 PrintError("realloc TCached: %m\n");
00305 }
00306 }
00307
00308 if (0==ReadDtLine(line,&T,&dt,fileName))
00309 {
00310 dtCached[nCached]=dt;
00311 TCached[nCached] =T;
00312 nCached++;
00313 }
00314 }
00315 fclose(f);
00316 }
00317
00324 int GetInterpolatedShift(double t, double *ts, int *age, char *station, char *file)
00325 {
00326 int ok=NO_TIME_CORRECTION,i,l,j;
00327 int nfiles=0;
00328 int notFoundInCache=1;
00329 char line[129];
00330 char dtfilename[255];
00331 FILE *f;
00332 double T1,T2,dt1,dt2,dt;
00333 struct dirent **dtfile=NULL;
00334 T1=-1.;
00335 T2=1.e20;
00336 dt1=dt2=dt=0.0;
00337
00338 if (0!=strcmp(testForStation,station))
00339 {
00340 emptyDir=0;
00341 strcpy(testForStation,station);
00342 }
00343
00344 if (emptyDir!=0)
00345 {
00346 return(ok);
00347 }
00348
00349 if (nCached>0)
00350 {
00351 if ((TCached[0]<=t)&&(TCached[nCached-1]>=t))
00352 {
00353 register int i;
00354
00355 for (i=0; i<nCached; i++)
00356 {
00357 if (TCached[i]>t)
00358 {
00359 if (i) i--;
00360 T1=TCached[i];
00361 dt1=dtCached[i];
00362
00363 for (; i<nCached; i++)
00364 {
00365 if (TCached[i]>t)
00366 {
00367 T2=TCached[i];
00368 dt2=dtCached[i];
00369
00370 notFoundInCache=0;
00371 if (file)
00372 {
00373 strcpy(file,dtCachedFile);
00374 }
00375 i=nCached;
00376 break;
00377 }
00378 }
00379 }
00380 }
00381 }
00382 }
00383
00384 if (notFoundInCache)
00385 {
00386
00387
00388 nfiles=__scandir(TDBPath(TDB_PATH_DFT,station),&dtfile,DtFileSelect,TimeFileSort);
00389 PrintDebug("scanning '%s' for '%s' ...%d\n",TDBPath(TDB_PATH_DFT,station),station,nfiles);
00390 if (nfiles==0)
00391 {
00392 emptyDir=1;
00393 return(ok);
00394 }
00395 for (i=0; i<nfiles; i++)
00396 {
00397 sprintf(dtfilename,"%s/%s",TDBPath(TDB_PATH_DFT,station),dtfile[i]->d_name);
00398
00399 f=fopen(dtfilename,"rt");
00400 if (!f)
00401 {
00402 PrintError("%s: %m\n",dtfilename);
00403 continue;
00404 }
00405 l=0;
00406
00407 for (j=0; (l<5)&&(fgets(line,127,f)!=NULL); )
00408 {
00409 if (line[0]=='#')
00410 {
00411 continue;
00412 }
00413 if (ReadDtLine(line,&T1,&dt1,dtfilename)<0)
00414 {
00415 continue;
00416 }
00417 break;
00418 }
00419
00420 if (T1>t)
00421 {
00422
00423 fclose(f);
00424
00425 break;
00426
00427 }
00428
00429 fseek(f,SEEK_END,-1000);
00430
00431 fgets(line,127,f);
00432
00433 while (fgets(line,127,f)!=NULL)
00434 {
00435 if (line[0]=='#')
00436 {
00437 continue;
00438 }
00439
00440 if (ReadDtLine(line,&T2,&dt,dtfilename)<0)
00441 {
00442 continue;
00443 }
00444 }
00445
00446 fclose(f);
00447
00448 if ((T1<t)&&(T2>t))
00449
00450 {
00451
00452 FillDtCache(dtfilename);
00453
00454
00455
00456 for (i=0; i<nCached; i++)
00457 {
00458 if (TCached[i]>t)
00459 {
00460 if (i) i--;
00461 T1=TCached[i];
00462 dt1=dtCached[i];
00463
00464 for (; i<nCached; i++)
00465 {
00466 if (TCached[i]>t)
00467 {
00468 T2=TCached[i];
00469 dt2=dtCached[i];
00470
00471 notFoundInCache=0;
00472 if (file)
00473 {
00474 strcpy(file,dtCachedFile);
00475 }
00476 i=nCached;
00477 break;
00478 }
00479 }
00480 }
00481 }
00482
00483 break;
00484
00485 }
00486
00487 }
00488
00489 }
00490 PrintDebug("T1=%f t=%f T2=%f\n",T1,t,T2);
00491
00492
00493 if ((T1>0.)&&(T2<1.e18))
00494
00495 {
00496
00497 *ts=dt1+(t-T1)*(dt2-dt1)/(T2-T1);
00498
00499 ok=INTERPOLATION_CORRECTION;
00500 *age=(int)(t-T1);
00501
00502 }
00503 else
00504 {
00505
00506 if (T2<1.e18)
00507 {
00508 ok=EXTENDED_CORRECTION;
00509 *age=(int)(t-T2);
00510 *ts=dt2;
00511 }
00512
00513 if (T1>0.)
00514 {
00515 ok=EXTENDED_CORRECTION;
00516 *age=(int)(T1-t);
00517 *ts=dt1;
00518 }
00519 }
00520
00521 if (nfiles>0)
00522 {
00523 for (i=0; i<nfiles; i++)
00524 {
00525 free(dtfile[i]);
00526 }
00527 free(dtfile);
00528 }
00529 PrintDebug("ok=%d ts=%f age=%d\n",ok,*ts,*age);
00530 return(ok);
00531 }
00532
00533 double GetExtraTcorr(struct InfoHeaderType *ih)
00534 {
00535 char fn[128];
00536 char line[128];
00537 double delay;
00538 FILE *f;
00539
00540 ih->extraTcorrUsed=0;
00541
00542 if (strlen(ih->driftFile)==0)
00543 {
00544 return(0.0);
00545 }
00546
00547
00548 sprintf(line,"%s/extra_tcorr",TDBPath(TDB_PATH_TC,ih->station));
00549
00550 f=fopen(line,"rt");
00551
00552 if (f!=NULL)
00553 {
00554
00555 while (!feof(f))
00556 {
00557
00558 if (NULL==fgets(line,79,f))
00559 {
00560 break;
00561 }
00562
00563
00564 if ((line[0]=='#')||(2!=sscanf(line,"%s %lf",fn,&delay)))
00565 {
00566 continue;
00567 }
00568
00569 if (strcmp(ih->driftFile,fn)==0)
00570 {
00571
00572 fclose(f);
00573
00574 ih->extraTcorrUsed=1;
00575
00576 return(delay);
00577
00578 }
00579
00580 }
00581
00582 }
00583
00584 return(0.0);
00585 }
00586
00587
00588
00589 double GetFrameSkip(double starttime,char * station)
00590 {
00591
00592 double correction=0.0,tdate,c;
00593 char fn[128],line[80],sdate[50];
00594 FILE *f;
00595
00596 sprintf(fn,TDBPath(TDB_PATH_TC,station),"/FrameSkip.%s",station);
00597 f=fopen(fn,"rt");
00598
00599 if (f!=NULL)
00600
00601 {
00602
00603 while (!feof(f))
00604 {
00605
00606 if (NULL==fgets(line,79,f))
00607 {
00608 break;
00609 }
00610
00611 if ((line[0]=='#')||(2!=sscanf(line,"%s %lf",sdate,&c)))
00612 {
00613 continue;
00614 }
00615 tdate=1.e38;
00616
00617 if (3>str2time(sdate, &tdate))
00618 {
00619 continue;
00620 }
00621
00622 if (tdate<starttime)
00623
00624 {
00625
00626 correction=c;
00627
00628 }
00629
00630 }
00631
00632 fclose(f);
00633
00634 }
00635 if (fabs(correction)>0.1)
00636 {
00637 PrintWarning("%s: %.4fs observed delay (%.0f %.0f)\n",
00638 fn,correction,tdate,starttime);
00639 }
00640
00641 return(correction);
00642 }
00643
00648 double ADCDelay(struct DigitizerType *digitizer, int ch)
00649 {
00650
00651 if (ch>=MAX_OSIRIS_CHANNEL)
00652 {
00653 return(0.0);
00654 }
00655 if ((digitizer->ok)&&(!IsTitan1Time()))
00656 {
00657 if (digitizer->adcDelay<0.1)
00658 {
00659
00660 return(2.5/16000.);
00661 }
00662 else
00663 {
00664 return((double)digitizer->adcDelay/(double)digitizer->adcFrequency);
00665 }
00666 }
00667 else
00668 {
00669 int mch=PrimaryChannel(ch);
00670 return(
00671 ((double)digitizer->adcDelay*(double)infoHeader[mch].sr.div)/
00672 (double)infoHeader[mch].sr.base
00673 );
00674 }
00675 }
00676
00680 double Titan1FilterDelayTime(int ch)
00681 {
00682 double fprim;
00683 double delay;
00684 int R;
00685
00686 if (ch>=MAX_OSIRIS_CHANNEL)
00687 {
00688 return(0.0);
00689 }
00690 delay=0.0;
00691 if (ch<6)
00692 {
00693 return(0.0);
00694 }
00695 if (oldHWConfig.srExp[ch-6].div<=0)
00696 {
00697 return(0.0);
00698 }
00699
00700 fprim=(double)oldHWConfig.srExp[ch-6].base/(double)oldHWConfig.srExp[ch-6].div;
00701
00702 R=oldHWConfig.srExp[ch-6].base*oldHWConfig.srExp[ch].div/
00703 (oldHWConfig.srExp[ch-6].div*oldHWConfig.srExp[ch].base);
00704 while ((R!=0)&&((R%2)==0))
00705 {
00706 delay+=(double)(128-1)/(2.*(double)(fprim));
00707 R/=2;
00708 fprim/=2.0;
00709 }
00710 return(delay);
00711 }
00712
00717 double FixBuggyMykerinos(struct DigitizerType *d, double f)
00718 {
00719
00720 if (d->adcDecimationLength!=0)
00721 {
00722
00723 return(0.0);
00724 }
00725
00726 if (buggyMykerinos)
00727 {
00728
00729 if (warnFixBuggyMykerinos==0)
00730
00731 {
00732
00733 PrintWarning("Mykerinos-T generates Titan2 data version (%d.%d.%d) with timing error that have been fixed. The data created by rtitan2 are corrected but the Mykerinos-T should be upgraded.\n",
00734 HWConfig.formatVersion,
00735 HWConfig.formatMajor,
00736 HWConfig.formatMinor);
00737
00738 warnFixBuggyMykerinos=1;
00739
00740 }
00741 return(2.0/f);
00742 }
00743
00744 return(0.0);
00745 }
00746
00749 void SetBuggyMykerinos(int yes)
00750 {
00751 buggyMykerinos=yes;
00752 }
00753
00759 double FilterDelayTime(struct DigitizerType *digitizer, struct Titan2SRType *sr, int ch)
00760 {
00761 #define ONE 1
00762 int fprim,R;
00763 double delay;
00764
00765
00766 if (ch>=MAX_OSIRIS_CHANNEL)
00767 {
00768 return(0.0);
00769 }
00770
00771 if (digitizer->adcFrequency<=0)
00772 {
00773 return(Titan1FilterDelayTime(ch));
00774 }
00775
00776 delay=0.;
00777 if (sr->npts==0)
00778 {
00779 PrintError("cannot compute a filter delay with F=0\n");
00780 timeWarningNow=1;
00781 timeWarning++;
00782 return(0.0);
00783 }
00784
00785
00786 if ((digitizer->adcDecimation)&&(digitizer->adcDecimationLength>1))
00787 {
00788
00789 delay+=(double)(digitizer->adcDecimationLength-ONE)/
00790 (2.*(double)digitizer->adcFrequency);
00791 }
00792
00793
00794
00795
00796
00797 fprim=digitizer->adcFrequency;
00798 if (digitizer->adcDecimation)
00799 {
00800 fprim/=digitizer->adcDecimation;
00801 }
00802
00803
00804
00805
00806 R=fprim/sr->npts;
00807
00808 while ((R!=0)&&((R%5)==0))
00809 {
00810 delay+=(double)(digitizer->secondDecimationLength-ONE)/(2.*(double)(fprim));
00811 delay+=FixBuggyMykerinos(digitizer,fprim);
00812 R/=5;
00813 fprim/=5;
00814 }
00815
00816 while ((R!=0)&&((R%2)==0))
00817 {
00818 delay+=(double)(digitizer->secondDecimationLength-ONE)/(2.*(double)(fprim));
00819 delay+=FixBuggyMykerinos(digitizer,fprim);
00820 R/=2;
00821 fprim/=2;
00822 }
00823 return(delay);
00824 }
00825
00831 unsigned int FilterChain(struct DigitizerType *digitizer, struct Titan2SRType *sr, int ch)
00832 {
00833 int fprim,R;
00834 unsigned int ret;
00835
00836 if (digitizer->adcFrequency<=0)
00837 {
00838 return(0);
00839 }
00840
00841 if (sr->npts==0)
00842 {
00843 return(0);
00844 }
00845
00846 if ((digitizer->adcDecimation)&&(digitizer->adcDecimationLength>1))
00847 {
00848 ret=1;
00849 }
00850 else
00851 {
00852 ret=0;
00853 }
00854 ret<<=8;
00855
00856
00857
00858
00859
00860 fprim=digitizer->adcFrequency;
00861 if (digitizer->adcDecimation)
00862 {
00863 fprim/=digitizer->adcDecimation;
00864 }
00865
00866
00867
00868
00869 R=fprim/sr->npts;
00870
00871 while ((R!=0)&&((R%5)==0))
00872 {
00873 R/=5;
00874 fprim/=5;
00875 ret++;
00876 }
00877 ret<<=8;
00878
00879 while ((R!=0)&&((R%2)==0))
00880 {
00881 R/=2;
00882 fprim/=2;
00883 ret++;
00884 }
00885 return(ret);
00886 }
00887
00888
00893 int CorrectTime(double t, struct InfoHeaderType *header)
00894 {
00895 int ret;
00896
00897 ret=NO_TIME_CORRECTION;
00898 if (header->pulse.usecond<=0)
00899 {
00900
00901 memcpy(&(header->pulse),&pulseTime,sizeof(struct Titan2TimeType));
00902
00903 memcpy(&(header->external),&roundedTime,sizeof(struct Titan2TimeType));
00904 }
00905
00906 if (header->pulse.usecond>0)
00907 {
00908 header->otshift=DiffTimeT2T1(&(header->external),&(header->pulse),NULL);
00909 }
00910 else
00911 {
00912 header->otshift=DiffTimeT2T1(&(header->external),&(header->pulse),NULL);
00913 header->tshift=header->otshift=0.0;
00914 }
00915
00916 switch (header->correctionMethod)
00917 {
00918 case AUTO_CORRECTION:
00919 case INTERPOLATION_CORRECTION:
00920 ret=header->correctionMethod;
00921
00922
00923 if (GetInterpolatedShift(t,
00924 &(header->tshift),
00925 &(header->pulseAge),
00926 header->station,
00927 header->driftFile)!=NO_TIME_CORRECTION)
00928 {
00929 break;
00930 }
00931 else
00932 {
00933 if (header->correctionMethod!=AUTO_CORRECTION)
00934 {
00935 PrintWarning("could not interpolate the time "
00936 "shift, falling back to "
00937 "LAST_PULSE_CORRECTION\n");
00938 }
00939 }
00940
00941 case LAST_PULSE_CORRECTION:
00942
00943 if (header->pulse.usecond>0)
00944 {
00945 ret=header->correctionMethod;
00946 header->tshift=header->otshift;
00947 break;
00948 }
00949 case NO_TIME_CORRECTION:
00950 if (header->correctionMethod!=NO_TIME_CORRECTION)
00951 {
00952 if (extractingData!=0)
00953 {
00954 PrintWarning("no time correction could be performed\n");
00955 }
00956 }
00957 ret=NO_TIME_CORRECTION;
00958 header->tshift=0.0;
00959 }
00960 if ((header->correctionMethod!=ret)&&(header->correctionMethod!=NO_TIME_CORRECTION))
00961 {
00962 if (extractingData!=0)
00963 {
00964 PrintWarning("could not apply the requested correction method\n");
00965 timeWarningNow=1;
00966 timeWarning++;
00967 }
00968 }
00969 return(ret);
00970 }
00971
00974 double GetApproximatedShift(void)
00975 {
00976 struct InfoHeaderType header;
00977 int i;
00978 if (HWConfig.fieldIdent[0]==0)
00979 {
00980 return(0.0);
00981 }
00982 if (abs((currentTime.usecond>>32)-lastShiftComputation)<3600)
00983 {
00984 return(lastShiftComputed);
00985 }
00986 lastShiftComputation=currentTime.usecond>>32;
00987 memset(&header,0,sizeof(struct InfoHeaderType));
00988 if (saveShift)
00989 {
00990 header.correctionMethod=LAST_PULSE_CORRECTION;
00991 }
00992 else
00993 {
00994 header.correctionMethod=AUTO_CORRECTION;
00995 }
00996 strcpy(header.station,HWConfig.fieldIdent);
00997
00998
00999 memcpy(&(header.pulse),&pulseTime,sizeof(struct Titan2TimeType));
01000
01001 memcpy(&(header.external),&roundedTime,sizeof(struct Titan2TimeType));
01002
01003 i=CorrectTime(currentTime.usecond>>32, &header);
01004 lastShiftComputed=header.tshift;
01005 return(header.tshift);
01006 }
01007
01012 double CorrectChannelStartTime(int ch)
01013 {
01014 double T;
01015 T=US2S*(double)infoHeader[ch].uncorrected.usecond;
01016
01017
01018 if (ch<MAX_OSIRIS_CHANNEL)
01019 {
01020
01021 infoHeader[ch].tadc=ADCDelay(&(oldHWConfig.digitizer),ch);
01022
01023
01024 infoHeader[ch].tfilter=FilterDelayTime(&(oldHWConfig.digitizer),&(infoHeader[ch].sr),ch);
01025
01026
01027 infoHeader[ch].correctionMethod=CorrectTime(
01028 (time_t)(infoHeader[ch].uncorrected.usecond>>32),
01029 &(infoHeader[ch]));
01030
01031 T-=infoHeader[ch].tadc;
01032 T-=infoHeader[ch].tfilter;
01033 if (noTimeCorrection==0)
01034 {
01035 T-=infoHeader[ch].tshift;
01036 }
01037 infoHeader[ch].correctedTime=T;
01038 }
01039
01040 else
01041 {
01042 infoHeader[ch].correctedTime=floor(T+0.5);
01043 }
01044 return(T);
01045 }
01046
01047
01048
01049
01050 int PrimaryChannel(int channel)
01051 {
01052 if (IsTitan1Time())
01053 {
01054 return(channel>5)?(channel-6):channel;
01055 }
01056 else
01057 {
01058 return(channel);
01059 }
01060 }
01061
01069 double DiffTimeT2T1(struct Titan2TimeType *t1, struct Titan2TimeType *t2, struct Titan2TimeType *td)
01070 {
01071 double diff;
01072 if (td)
01073 {
01074 td->usecond=t2->usecond-t1->usecond;
01075 diff=US2S*(double)td->usecond;
01076 }
01077 else
01078 {
01079 diff=US2S*(double)(t2->usecond-t1->usecond);
01080 }
01081 return(diff);
01082 }
01083
01091 double TimeAdd(struct Titan2TimeType *t1, struct Titan2TimeType *t2, struct Titan2TimeType *ts)
01092 {
01093 ts->usecond=t1->usecond+t2->usecond;
01094 return(