Developping framework for real electronic mapping for rawdata & fixing some bugs...
[u/mrichter/AliRoot.git] / RALICE / AliTimestamp.cxx
CommitLineData
3ea81e9c 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16// $Id$
17
18///////////////////////////////////////////////////////////////////////////
19// Class AliTimestamp
20// Handling of timestamps for (astro)particle physics reserach.
21//
22// This class is derived from TTimeStamp and provides additional
23// facilities (e.g. Julian date) which are commonly used in the
24// field of (astro)particle physics.
25//
26// The Julian Date (JD) indicates the number of days since noon (UT) on
27// 01 jan -4712 (i.e. noon 01 jan 4713 BC), being day 0 of the Julian calendar.
28//
29// The Modified Julian Date (MJD) indicates the number of days since midnight
30// (UT) on 17-nov-1858, which corresponds to 2400000.5 days after day 0 of the
31// Julian calendar.
32//
33// The Truncated Julian Date (TJD) corresponds to 2440000.5 days after day 0
34// of the Julian calendar and consequently TJD=MJD-40000.
35// This TJD date indication was used by the Vela and Batse missions in
36// view of Gamma Ray Burst investigations.
37//
38// The Julian Epoch (JE) indicates the fractional elapsed year count since
39// midnight (UT) on 01-jan at the start of the Gregorian year count.
40// A year is defined to be 365.25 days, so the integer part of JE corresponds
41// to the usual Gregorian year count.
42// So, 01-jan-1965 00:00:00 UT corresponds to JE=1965.0
43//
44// Because of the fact that the Julian date indicators are all w.r.t. UT
45// they provide an absolute timescale irrespective of timezone or daylight
46// saving time (DST).
47//
a7dc0627 48// This AliTimestamp facility allows for picosecond precision, in view
49// of time of flight analyses for particle physics experiments.
50// For normal date/time indication the standard nanosecond precision
51// will in general be sufficient.
52// Note that when the fractional JD, MJD and TJD counts are used instead
3ea81e9c 53// of the integer (days,sec,ns) specification, the nanosecond precision
54// may be lost due to computer accuracy w.r.t. floating point operations.
55//
56// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
57// which corresponds to JD=2440587.5 or the start of MJD=40587 or TJD=587.
58// Using the corresponding MJD of this EPOCH allows construction of
59// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input (M/T)JD and time.
60// Obviously this TTimeStamp implementation would prevent usage of values
61// smaller than JD=2440587.5 or MJD=40587 or TJD=587.
62// However, this AliTimestamp facility provides support for the full range
63// of (M/T)JD values, but the setting of the corresponding TTimeStamp parameters
64// is restricted to the values allowed by the TTimeStamp implementation.
65// For these earlier (M/T)JD values, the standard TTimeStamp parameters will
66// be set corresponding to the start of the TTimeStamp EPOCH.
67// This implies that for these earlier (M/T)JD values the TTimeStamp parameters
68// do not match the Julian parameters of AliTimestamp.
69// As such the standard TTimeStamp parameters do not appear on the print output
70// when invoking the Date() memberfunction for these earlier (M/T)JD values.
71//
72// Examples :
73// ==========
74//
75// Note : All TTimeStamp functionality is available as well.
76//
77// AliTimestamp t;
78//
79// t.Date();
80//
81// // Retrieve Julian Date
82// Int_t jd,jsec,jns;
83// t.GetJD(jd,jsec,jns);
84//
85// // Retrieve fractional Truncated Julian Date
86// Double_t tjd=t.GetTJD();
87//
88// // Retrieve fractional Julian Epoch
89// Double_t je=t.GetJE();
90//
91// // Set to a specific Modified Julian Date
92// Int_t mjd=50537;
93// Int_t mjsec=1528;
94// Int_t mjns=185643;
95// t.SetMJD(mjd,mjsec,mjns);
96//
97// t.Date();
98//
95cfc777 99// // Time intervals for e.g. trigger or TOF analysis
100// AliEvent evt;
101// AliTimestamp hit((AliTimestamp)evt);
102// hit.Add(0,0,2,173);
103// Double_t dt=evt.GetDifference(hit,"ps");
104// Int_t d,s,ns,ps;
105// evt.GetDifference(hit,d,s,ns,ps);
106//
3ea81e9c 107// // Some practical conversion facilities
108// // Note : They don't influence the actual date/time settings
109// // and as such can also be invoked as AliTimestamp::Convert(...) etc...
110// Int_t y=1921;
111// Int_t m=7;
112// Int_t d=21;
113// Int_t hh=15;
114// Int_t mm=23;
115// Int_t ss=47;
116// Int_t ns=811743;
117// Double_t jdate=t.GetJD(y,m,d,hh,mm,ss,ns);
118//
119// Int_t days,secs,nsecs;
120// Double_t date=421.1949327;
121// t.Convert(date,days,secs,nsecs);
122//
123// days=875;
124// secs=23;
125// nsecs=9118483;
126// date=t.Convert(days,secs,nsecs);
127//
128// Double_t mjdate=40563.823744;
129// Double_t epoch=t.GetJE(mjdate,"mjd");
130//
131//--- Author: Nick van Eijndhoven 28-jan-2005 Utrecht University.
132//- Modified: NvE $Date$ Utrecht University.
133///////////////////////////////////////////////////////////////////////////
134
135#include "AliTimestamp.h"
136#include "Riostream.h"
137
138ClassImp(AliTimestamp) // Class implementation to enable ROOT I/O
139
140AliTimestamp::AliTimestamp() : TTimeStamp()
141{
142// Default constructor
143// Creation of an AliTimestamp object and initialisation of parameters.
144// All attributes are initialised to the current date/time as specified
145// in the docs of TTimeStamp.
146
147 FillJulian();
a7dc0627 148 fJps=0;
3ea81e9c 149}
150///////////////////////////////////////////////////////////////////////////
151AliTimestamp::AliTimestamp(TTimeStamp& t) : TTimeStamp(t)
152{
153// Creation of an AliTimestamp object and initialisation of parameters.
154// All attributes are initialised to the values of the input TTimeStamp.
155
156 FillJulian();
a7dc0627 157 fJps=0;
3ea81e9c 158}
159///////////////////////////////////////////////////////////////////////////
160AliTimestamp::~AliTimestamp()
161{
162// Destructor to delete dynamically allocated memory.
163}
164///////////////////////////////////////////////////////////////////////////
165AliTimestamp::AliTimestamp(const AliTimestamp& t) : TTimeStamp(t)
166{
167// Copy constructor
168
169 fMJD=t.fMJD;
170 fJsec=t.fJsec;
171 fJns=t.fJns;
a7dc0627 172 fJps=t.fJps;
3ea81e9c 173 fCalcs=t.fCalcs;
174 fCalcns=t.fCalcns;
175}
176///////////////////////////////////////////////////////////////////////////
177void AliTimestamp::Date(Int_t mode)
178{
179// Print date/time info.
180//
181// mode = 1 ==> Only the TTimeStamp yy-mm-dd hh:mm:ss:ns info is printed
182// 2 ==> Only the Julian parameter info is printed
183// 3 ==> Both the TTimeStamp and Julian parameter info is printed
184//
185// The default is mode=3.
186//
187// Note : In case the (M/T)JD falls outside the TTimeStamp range,
188// the TTimeStamp info will not be printed.
189
190 Int_t mjd,mjsec,mjns;
191 GetMJD(mjd,mjsec,mjns);
192
193 if ((mode==1 || mode==3) && mjd>=40587) cout << " " << AsString() << endl;
194 if (mode==2 || mode==3)
195 {
196 Int_t jd,jsec,jns;
197 GetJD(jd,jsec,jns);
198 Int_t tjd,tjsec,tjns;
199 GetTJD(tjd,tjsec,tjns);
200 cout << " Julian Epoch : " << setprecision(25) << GetJE() << endl;
95cfc777 201 cout << " JD : " << jd << " sec : " << jsec << " ns : " << jns << " ps : " << fJps
3ea81e9c 202 << " Fractional : " << setprecision(25) << GetJD() << endl;
95cfc777 203 cout << " MJD : " << mjd << " sec : " << mjsec << " ns : " << mjns << " ps : " << fJps
3ea81e9c 204 << " Fractional : " << setprecision(25) << GetMJD() << endl;
95cfc777 205 cout << " TJD : " << tjd << " sec : " << tjsec << " ns : " << tjns << " ps : " << fJps
3ea81e9c 206 << " Fractional : " << setprecision(25) << GetTJD() << endl;
207 }
208}
209///////////////////////////////////////////////////////////////////////////
210Double_t AliTimestamp::GetJD(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns) const
211{
212// Provide the (fractional) Julian Date (JD) corresponding to the UT date
213// and time in the Gregorian calendar as specified by the input arguments.
214//
215// The input arguments represent the following :
216// y : year in UT (e.g. 1952, 2003 etc...)
217// m : month in UT (1=jan 2=feb etc...)
218// d : day in UT (1-31)
219// hh : elapsed hours in UT (0-23)
220// mm : elapsed minutes in UT (0-59)
221// ss : elapsed seconds in UT (0-59)
222// ns : remaining fractional elapsed second of UT in nanosecond
223//
224// This algorithm is valid for all AD dates in the Gregorian calendar
225// following the recipe of R.W. Sinnott Sky & Telescope 82, (aug. 1991) 183.
226// See also http://scienceworld.wolfram.com/astronomy/JulianDate.html
227//
228// In case of invalid input, a value of -1 is returned.
229//
230// Note :
231// ------
232// This memberfunction only provides the JD corresponding to the
233// UT input arguments. It does NOT set the corresponding Julian parameters
234// for the current AliTimestamp instance.
235// As such the TTimeStamp limitations do NOT apply to this memberfunction.
236// To set the Julian parameters for the current AliTimestamp instance,
237// please use the corresponding SET() memberfunctions of either AliTimestamp
238// or TTimeStamp.
239
240 if (y<0 || m<1 || m>12 || d<1 || d>31) return -1;
241 if (hh<0 || hh>23 || mm<0 || mm>59 || ss<0 || ss>59 || ns<0 || ns>1e9) return -1;
242
243 // The UT daytime in fractional hours
244 Double_t ut=double(hh)+double(mm)/60.+(double(ss)+double(ns)*1.e-9)/3600.;
245
246 Double_t JD=0;
247
248 JD=367*y-int(7*(y+int((m+9)/12))/4)
249 -int(3*(int((y+(m-9)/7)/100)+1)/4)
250 +int(275*m/9)+d+1721028.5+ut/24.;
251
252 return JD;
253}
254///////////////////////////////////////////////////////////////////////////
255Double_t AliTimestamp::GetMJD(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns) const
256{
257// Provide the (fractional) Modified Julian Date corresponding to the UT
258// date and time in the Gregorian calendar as specified by the input arguments.
259//
260// The input arguments represent the following :
261// y : year in UT (e.g. 1952, 2003 etc...)
262// m : month in UT (1=jan 2=feb etc...)
263// d : day in UT (1-31)
264// hh : elapsed hours in UT (0-23)
265// mm : elapsed minutes in UT (0-59)
266// ss : elapsed seconds in UT (0-59)
267// ns : remaining fractional elapsed second of UT in nanosecond
268//
269// This algorithm is valid for all AD dates in the Gregorian calendar
270// following the recipe of R.W. Sinnott Sky & Telescope 82, (aug. 1991) 183.
271// See also http://scienceworld.wolfram.com/astronomy/JulianDate.html
272//
273// In case of invalid input, a value of -1 is returned.
274//
275// Note :
276// ------
277// This memberfunction only provides the MJD corresponding to the
278// UT input arguments. It does NOT set the corresponding Julian parameters
279// for the current AliTimestamp instance.
280// As such the TTimeStamp limitations do NOT apply to this memberfunction.
281// To set the Julian parameters for the current AliTimestamp instance,
282// please use the corresponding SET() memberfunctions of either AliTimestamp
283// or TTimeStamp.
284
285 Double_t JD=GetJD(y,m,d,hh,mm,ss,ns);
286
287 if (JD<0) return JD;
288
289 Double_t MJD=JD-2400000.5;
290
291 return MJD;
292}
293///////////////////////////////////////////////////////////////////////////
294Double_t AliTimestamp::GetTJD(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns) const
295{
296// Provide the (fractional) Truncated Julian Date corresponding to the UT
297// date and time in the Gregorian calendar as specified by the input arguments.
298//
299// The input arguments represent the following :
300// y : year in UT (e.g. 1952, 2003 etc...)
301// m : month in UT (1=jan 2=feb etc...)
302// d : day in UT (1-31)
303// hh : elapsed hours in UT (0-23)
304// mm : elapsed minutes in UT (0-59)
305// ss : elapsed seconds in UT (0-59)
306// ns : remaining fractional elapsed second of UT in nanosecond
307//
308// This algorithm is valid for all AD dates in the Gregorian calendar
309// following the recipe of R.W. Sinnott Sky & Telescope 82, (aug. 1991) 183.
310// See also http://scienceworld.wolfram.com/astronomy/JulianDate.html
311//
312// In case of invalid input, a value of -1 is returned.
313//
314// Note :
315// ------
316// This memberfunction only provides the TJD corresponding to the
317// UT input arguments. It does NOT set the corresponding Julian parameters
318// for the current AliTimestamp instance.
319// As such the TTimeStamp limitations do NOT apply to this memberfunction.
320// To set the Julian parameters for the current AliTimestamp instance,
321// please use the corresponding SET() memberfunctions of either AliTimestamp
322// or TTimeStamp.
323
324 Double_t JD=GetJD(y,m,d,hh,mm,ss,ns);
325
326 if (JD<0) return JD;
327
328 Double_t TJD=JD-2440000.5;
329
330 return TJD;
331}
332///////////////////////////////////////////////////////////////////////////
333Double_t AliTimestamp::GetJE(Double_t date,TString mode) const
334{
335// Provide the Julian Epoch (JE) corresponding to the specified date.
336// The argument "mode" indicates the type of the argument "date".
337//
338// Available modes are :
339// mode = "jd" ==> date represents the Julian Date
340// = "mjd" ==> date represents the Modified Julian Date
341// = "tjd" ==> date represents the Truncated Julian Date
342//
343// The default is mode="jd".
344//
345// In case of invalid input, a value of -99999 is returned.
346//
347// Note :
348// ------
349// This memberfunction only provides the JE corresponding to the
350// input arguments. It does NOT set the corresponding Julian parameters
351// for the current AliTimestamp instance.
352// As such the TTimeStamp limitations do NOT apply to this memberfunction.
353// To set the Julian parameters for the current AliTimestamp instance,
354// please use the corresponding SET() memberfunctions of either AliTimestamp
355// or TTimeStamp.
356
357 if ((mode != "jd") && (mode != "mjd") && (mode != "tjd")) return -99999;
358
359 Double_t jd=date;
360 if (mode=="mjd") jd=date+2400000.5;
361 if (mode=="tjd") jd=date+2440000.5;
362
363 Double_t je=2000.+(jd-2451545.)/365.25;
364
365 return je;
366}
367///////////////////////////////////////////////////////////////////////////
368void AliTimestamp::Convert(Double_t date,Int_t& days,Int_t& secs,Int_t& ns) const
369{
370// Convert date as fractional day count into integer days, secs and ns.
371//
372// Note : Due to computer accuracy the ns value may become inaccurate.
373//
374// The arguments represent the following :
375// date : The input date as fractional day count
376// days : Number of elapsed days
377// secs : Remaining number of elapsed seconds
378// ns : Remaining fractional elapsed second in nanoseconds
379//
380// Note :
381// ------
382// This memberfunction only converts the input date into the corresponding
383// integer parameters. It does NOT set the corresponding Julian parameters
384// for the current AliTimestamp instance.
385// As such the TTimeStamp limitations do NOT apply to this memberfunction.
386// To set the Julian parameters for the current AliTimestamp instance,
387// please use the corresponding SET() memberfunctions of either AliTimestamp
388// or TTimeStamp.
389
390 days=int(date);
391 date=date-double(days);
392 Int_t daysecs=24*3600;
393 date=date*double(daysecs);
394 secs=int(date);
395 date=date-double(secs);
396 ns=int(date*1.e9);
397}
398///////////////////////////////////////////////////////////////////////////
399Double_t AliTimestamp::Convert(Int_t days,Int_t secs,Int_t ns) const
400{
401// Convert date in integer days, secs and ns into fractional day count.
402//
403// Note : Due to computer accuracy the ns precision may be lost.
404//
405// The input arguments represent the following :
406// days : Number of elapsed days
407// secs : Remaining number of elapsed seconds
408// ns : Remaining fractional elapsed second in nanoseconds
409//
410// Note :
411// ------
412// This memberfunction only converts the input integer parameters into the
413// corresponding fractional day count. It does NOT set the corresponding
414// Julian parameters for the current AliTimestamp instance.
415// As such the TTimeStamp limitations do NOT apply to this memberfunction.
416// To set the Julian parameters for the current AliTimestamp instance,
417// please use the corresponding SET() memberfunctions of either AliTimestamp
418// or TTimeStamp.
419
420 Double_t frac=double(secs)+double(ns)*1.e-9;
421 Int_t daysecs=24*3600;
422 frac=frac/double(daysecs);
423 Double_t date=double(days)+frac;
424 return date;
425}
426///////////////////////////////////////////////////////////////////////////
427void AliTimestamp::FillJulian()
428{
429// Calculation and setting of the Julian date/time parameters corresponding
430// to the current TTimeStamp date/time parameters.
431
432 UInt_t y,m,d,hh,mm,ss;
433
434 GetDate(kTRUE,0,&y,&m,&d);
435 GetTime(kTRUE,0,&hh,&mm,&ss);
436 Int_t ns=GetNanoSec();
437
438 Double_t mjd=GetMJD(y,m,d,hh,mm,ss,ns);
439
440 fMJD=int(mjd);
441 fJsec=GetSec()%(24*3600); // Daytime in elapsed seconds
442 fJns=ns; // Remaining fractional elapsed second in nanoseconds
443
444 // Store the TTimeStamp seconds and nanoseconds values
445 // for which this Julian calculation was performed.
446 fCalcs=GetSec();
447 fCalcns=GetNanoSec();
448}
449///////////////////////////////////////////////////////////////////////////
450void AliTimestamp::GetMJD(Int_t& mjd,Int_t& sec, Int_t& ns)
451{
452// Provide the Modified Julian Date (MJD) and time corresponding to the
453// currently stored AliTimestamp date/time parameters.
454//
455// The returned arguments represent the following :
456// mjd : The modified Julian date.
457// sec : The number of seconds elapsed within the MJD.
458// ns : The remaining fractional number of seconds (in ns) elapsed within the MJD.
459
460 if (fCalcs != GetSec() || fCalcns != GetNanoSec()) FillJulian();
461
462 mjd=fMJD;
463 sec=fJsec;
464 ns=fJns;
465}
466///////////////////////////////////////////////////////////////////////////
467Double_t AliTimestamp::GetMJD()
468{
469// Provide the (fractional) Modified Julian Date (MJD) corresponding to the
470// currently stored AliTimestamp date/time parameters.
471//
472// Due to computer accuracy the ns precision may be lost.
473// It is advised to use the (mjd,sec,ns) getter instead.
474
475 Int_t mjd=0;
476 Int_t sec=0;
477 Int_t ns=0;
478 GetMJD(mjd,sec,ns);
479
480 Double_t date=Convert(mjd,sec,ns);
481
482 return date;
483}
484///////////////////////////////////////////////////////////////////////////
485void AliTimestamp::GetTJD(Int_t& tjd,Int_t& sec, Int_t& ns)
486{
487// Provide the Truncated Julian Date (TJD) and time corresponding to the
488// currently stored AliTimestamp date/time parameters.
489//
490// The returned arguments represent the following :
491// tjd : The modified Julian date.
492// sec : The number of seconds elapsed within the MJD.
493// ns : The remaining fractional number of seconds (in ns) elapsed within the MJD.
494
495 Int_t mjd=0;
496 GetMJD(mjd,sec,ns);
497
498 tjd=mjd-40000;
499}
500///////////////////////////////////////////////////////////////////////////
501Double_t AliTimestamp::GetTJD()
502{
503// Provide the (fractional) Truncated Julian Date (TJD) corresponding to the
504// currently stored AliTimestamp date/time parameters.
505//
506// Due to computer accuracy the ns precision may be lost.
507// It is advised to use the (mjd,sec,ns) getter instead.
508
509 Int_t tjd=0;
510 Int_t sec=0;
511 Int_t ns=0;
512 GetTJD(tjd,sec,ns);
513
514 Double_t date=Convert(tjd,sec,ns);
515
516 return date;
517}
518///////////////////////////////////////////////////////////////////////////
519void AliTimestamp::GetJD(Int_t& jd,Int_t& sec, Int_t& ns)
520{
521// Provide the Julian Date (JD) and time corresponding to the currently
522// stored AliTimestamp date/time parameters.
523//
524// The returned arguments represent the following :
525// jd : The Julian date.
526// sec : The number of seconds elapsed within the JD.
527// ns : The remaining fractional number of seconds (in ns) elapsed within the JD.
528
529 Int_t mjd=0;
530 GetMJD(mjd,sec,ns);
531
532 jd=mjd+2400000;
533 sec+=12*3600;
534 if (sec >= 24*3600)
535 {
536 sec-=24*3600;
537 jd+=1;
538 }
539}
540///////////////////////////////////////////////////////////////////////////
541Double_t AliTimestamp::GetJD()
542{
543// Provide the (fractional) Julian Date (JD) corresponding to the currently
544// stored AliTimestamp date/time parameters.
545//
546// Due to computer accuracy the ns precision may be lost.
547// It is advised to use the (jd,sec,ns) getter instead.
548
549 Int_t jd=0;
550 Int_t sec=0;
551 Int_t ns=0;
552 GetJD(jd,sec,ns);
553
554 Double_t date=Convert(jd,sec,ns);
555
556 return date;
557}
558///////////////////////////////////////////////////////////////////////////
559Double_t AliTimestamp::GetJE()
560{
561// Provide the Julian Epoch (JE) corresponding to the currently stored
562// AliTimestamp date/time parameters.
563
564 Double_t jd=GetJD();
565 Double_t je=GetJE(jd);
566 return je;
567}
568///////////////////////////////////////////////////////////////////////////
a7dc0627 569void AliTimestamp::SetMJD(Int_t mjd,Int_t sec,Int_t ns,Int_t ps)
3ea81e9c 570{
571// Set the Modified Julian Date (MJD) and time and update the TTimeStamp
572// parameters accordingly (if possible).
573//
574// Note :
575// ------
576// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
577// which corresponds to the start of MJD=40587.
578// Using the corresponding MJD of this EPOCH allows construction of
579// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
580// Obviously this TTimeStamp implementation would prevent usage of MJD values
581// smaller than 40587.
582// However, this AliTimestamp facility provides support for the full range
583// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
584// is restricted to the values allowed by the TTimeStamp implementation.
585// For these earlier MJD values, the standard TTimeStamp parameters will
586// be set corresponding to the start of the TTimeStamp EPOCH.
587// This implies that for these earlier MJD values the TTimeStamp parameters
588// do not match the Julian parameters of AliTimestamp.
589//
590// The input arguments represent the following :
591// mjd : The modified Julian date.
592// sec : The number of seconds elapsed within the MJD.
593// ns : The remaining fractional number of seconds (in ns) elapsed within the MJD.
a7dc0627 594// ps : The remaining fractional number of nanoseconds (in ps) elapsed within the MJD.
595//
596// Note : ps=0 is the default value.
3ea81e9c 597
a7dc0627 598 if (sec<0 || sec>=24*3600 || ns<0 || ns>=1e9 || ps<0 || ps>=1000)
3ea81e9c 599 {
600 cout << " *AliTimestamp::SetMJD* Invalid input."
601 << " sec : " << sec << " ns : " << ns << endl;
602 return;
603 }
604
605 fMJD=mjd;
606 fJsec=sec;
607 fJns=ns;
a7dc0627 608 fJps=ps;
3ea81e9c 609
610 Int_t epoch=40587;
611
612 if (mjd<epoch)
613 {
614 Set(0,kFALSE,0,kFALSE);
615 }
616 else
617 {
618 // The elapsed time since start of EPOCH
619 Int_t days=mjd-epoch;
620 UInt_t secs=days*24*3600;
621 secs+=sec;
622 Set(secs,kFALSE,0,kFALSE);
623 Int_t date=GetDate();
624 Int_t time=GetTime();
625 Set(date,time,ns,kTRUE,0);
626 }
627
628 // Denote that the Julian and TTimeStamp parameters are synchronised,
629 // even in the case the MJD falls outside the TTimeStamp validity range.
630 // The latter still allows retrieval of Julian parameters for these
631 // earlier times.
632 fCalcs=GetSec();
633 fCalcns=GetNanoSec();
634}
635///////////////////////////////////////////////////////////////////////////
636void AliTimestamp::SetMJD(Double_t mjd)
637{
638// Set the Modified Julian Date (MJD) and time and update the TTimeStamp
639// parameters accordingly (if possible).
640//
641// Note :
642// ------
643// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
644// which corresponds to the start of MJD=40587.
645// Using the corresponding MJD of this EPOCH allows construction of
646// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
647// Obviously this TTimeStamp implementation would prevent usage of MJD values
648// smaller than 40587.
649// However, this AliTimestamp facility provides support for the full range
650// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
651// is restricted to the values allowed by the TTimeStamp implementation.
652// For these earlier MJD values, the standard TTimeStamp parameters will
653// be set corresponding to the start of the TTimeStamp EPOCH.
654// This implies that for these earlier MJD values the TTimeStamp parameters
655// do not match the Julian parameters of AliTimestamp.
656//
657// Due to computer accuracy the ns precision may be lost.
658// It is advised to use the (mjd,sec,ns) setting instead.
659//
660// The input argument represents the following :
661// mjd : The modified Julian date as fractional day count.
662
663 Int_t days=0;
664 Int_t secs=0;
665 Int_t ns=0;
666 Convert(mjd,days,secs,ns);
667 SetMJD(days,secs,ns);
668}
669///////////////////////////////////////////////////////////////////////////
a7dc0627 670void AliTimestamp::SetJD(Int_t jd,Int_t sec,Int_t ns,Int_t ps)
3ea81e9c 671{
672// Set the Julian Date (JD) and time and update the TTimeStamp
673// parameters accordingly (if possible).
674//
675// Note :
676// ------
677// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
678// which corresponds to JD=2440587.5 or the start of MJD=40587.
679// Using the corresponding MJD of this EPOCH allows construction of
680// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
681// Obviously this TTimeStamp implementation would prevent usage of values
682// smaller than JD=2440587.5.
683// However, this AliTimestamp facility provides support for the full range
684// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
685// is restricted to the values allowed by the TTimeStamp implementation.
686// For these earlier JD values, the standard TTimeStamp parameters will
687// be set corresponding to the start of the TTimeStamp EPOCH.
688// This implies that for these earlier (M)JD values the TTimeStamp parameters
689// do not match the Julian parameters of AliTimestamp.
690//
691// The input arguments represent the following :
692// jd : The Julian date.
693// sec : The number of seconds elapsed within the JD.
694// ns : The remaining fractional number of seconds (in ns) elapsed within the JD.
a7dc0627 695// ps : The remaining fractional number of nanoseconds (in ps) elapsed within the JD.
696//
697// Note : ps=0 is the default value.
3ea81e9c 698
699 Int_t mjd=jd-2400000;
700 sec-=12*3600;
701 if (sec<0)
702 {
703 sec+=24*3600;
704 mjd-=1;
705 }
706
a7dc0627 707 SetMJD(mjd,sec,ns,ps);
3ea81e9c 708}
709///////////////////////////////////////////////////////////////////////////
710void AliTimestamp::SetJD(Double_t jd)
711{
712// Set the Julian Date (JD) and time and update the TTimeStamp
713// parameters accordingly (if possible).
714//
715// Note :
716// ------
717// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
718// which corresponds to JD=2440587.5 or the start of MJD=40587.
719// Using the corresponding MJD of this EPOCH allows construction of
720// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
721// Obviously this TTimeStamp implementation would prevent usage of values
722// smaller than JD=2440587.5.
723// However, this AliTimestamp facility provides support for the full range
724// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
725// is restricted to the values allowed by the TTimeStamp implementation.
726// For these earlier JD values, the standard TTimeStamp parameters will
727// be set corresponding to the start of the TTimeStamp EPOCH.
728// This implies that for these earlier (M)JD values the TTimeStamp parameters
729// do not match the Julian parameters of AliTimestamp.
730//
731// Due to computer accuracy the ns precision may be lost.
732// It is advised to use the (jd,sec,ns) setting instead.
733//
734// The input argument represents the following :
735// jd : The Julian date as fractional day count.
736
737 Int_t days=0;
738 Int_t secs=0;
739 Int_t ns=0;
740 Convert(jd,days,secs,ns);
741
742 SetJD(days,secs,ns);
743}
744///////////////////////////////////////////////////////////////////////////
a7dc0627 745void AliTimestamp::SetTJD(Int_t tjd,Int_t sec,Int_t ns,Int_t ps)
3ea81e9c 746{
747// Set the Truncated Julian Date (TJD) and time and update the TTimeStamp
748// parameters accordingly (if possible).
749//
750// Note :
751// ------
752// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
753// which corresponds to JD=2440587.5 or the start of TJD=587.
754// Using the corresponding MJD of this EPOCH allows construction of
755// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
756// Obviously this TTimeStamp implementation would prevent usage of values
757// smaller than TJD=587.
758// However, this AliTimestamp facility provides support for the full range
759// of (T)JD values, but the setting of the corresponding TTimeStamp parameters
760// is restricted to the values allowed by the TTimeStamp implementation.
761// For these earlier JD values, the standard TTimeStamp parameters will
762// be set corresponding to the start of the TTimeStamp EPOCH.
763// This implies that for these earlier (T)JD values the TTimeStamp parameters
764// do not match the Julian parameters of AliTimestamp.
765//
766// The input arguments represent the following :
767// tjd : The Truncated Julian date.
768// sec : The number of seconds elapsed within the JD.
769// ns : The remaining fractional number of seconds (in ns) elapsed within the JD.
a7dc0627 770// ps : The remaining fractional number of nanoseconds (in ps) elapsed within the JD.
771//
772// Note : ps=0 is the default value.
3ea81e9c 773
774 Int_t mjd=tjd+40000;
775
776 SetMJD(mjd,sec,ns);
777}
778///////////////////////////////////////////////////////////////////////////
779void AliTimestamp::SetTJD(Double_t tjd)
780{
781// Set the Truncated Julian Date (TJD) and time and update the TTimeStamp
782// parameters accordingly (if possible).
783//
784// Note :
785// ------
786// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
787// which corresponds to JD=2440587.5 or the start of TJD=587.
788// Using the corresponding MJD of this EPOCH allows construction of
789// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
790// Obviously this TTimeStamp implementation would prevent usage of values
791// smaller than TJD=587.
792// However, this AliTimestamp facility provides support for the full range
793// of (T)JD values, but the setting of the corresponding TTimeStamp parameters
794// is restricted to the values allowed by the TTimeStamp implementation.
795// For these earlier JD values, the standard TTimeStamp parameters will
796// be set corresponding to the start of the TTimeStamp EPOCH.
797// This implies that for these earlier (T)JD values the TTimeStamp parameters
798// do not match the Julian parameters of AliTimestamp.
799//
800// Due to computer accuracy the ns precision may be lost.
801// It is advised to use the (jd,sec,ns) setting instead.
802//
803// The input argument represents the following :
804// tjd : The Truncated Julian date as fractional day count.
805
806 Int_t days=0;
807 Int_t secs=0;
808 Int_t ns=0;
809 Convert(tjd,days,secs,ns);
810
811 SetTJD(days,secs,ns);
812}
813///////////////////////////////////////////////////////////////////////////
95cfc777 814void AliTimestamp::SetNs(Int_t ns)
815{
816// Set the remaining fractional number of seconds in nanosecond precision.
817// Notes :
818// -------
819// 1) The allowed range for the argument "ns" is [0,99999999].
820// Outside that range no action is performed.
821// 2) The ns fraction can also be entered directly via SetMJD() etc...
822// 3) For additional accuracy see SetPs().
823
824 if (ns>=0 && ns<=99999999) fJns=ns;
825}
826///////////////////////////////////////////////////////////////////////////
827Int_t AliTimestamp::GetNs() const
828{
829// Provide the remaining fractional number of seconds in nanosecond precision.
830// This function allows trigger/timing analysis for (astro)particle physics
831// experiments.
832// Note : For additional accuracy see also GetPs().
833
834 return fJns;
835}
836///////////////////////////////////////////////////////////////////////////
837void AliTimestamp::SetPs(Int_t ps)
838{
839// Set the remaining fractional number of nanoseconds in picoseconds.
840// Notes :
841// -------
842// 1) The allowed range for the argument "ps" is [0,999].
843// Outside that range no action is performed.
844// 2) The ps fraction can also be entered directly via SetMJD() etc...
845
846 if (ps>=0 && ps<=999) fJps=ps;
847}
848///////////////////////////////////////////////////////////////////////////
849Int_t AliTimestamp::GetPs() const
a7dc0627 850{
851// Provide remaining fractional number of nanoseconds in picoseconds.
95cfc777 852// This function allows time of flight analysis for particle physics
a7dc0627 853// experiments.
854
855 return fJps;
856}
857///////////////////////////////////////////////////////////////////////////
95cfc777 858void AliTimestamp::Add(Int_t d,Int_t s,Int_t ns,Int_t ps)
859{
860// Add (or subtract) a certain time difference to the current timestamp.
861//
862// The time difference is entered via the following output arguments :
863// d : elapsed number of days
864// s : remaining elapsed number of seconds
865// ns : remaining elapsed number of nanoseconds
866// ps : remaining elapsed number of picoseconds
867//
868// Note : ps=0 is the default value.
869
870 Int_t days=fMJD;
871 Int_t secs=fJsec;
872 Int_t nsec=fJns;
873 Int_t psec=fJps;
874
875 psec+=ps;
876 if (psec<0)
877 {
878 nsec-=1;
879 psec+=1000;
880 }
881 if (psec>999)
882 {
883 nsec+=1;
884 psec-=1000;
885 }
886
887 nsec+=ns;
888 if (nsec<0)
889 {
890 secs-=1;
891 nsec+=1000000000;
892 }
893 if (nsec>999999999)
894 {
895 secs+=1;
896 nsec-=1000000000;
897 }
898
899 secs+=s;
900 if (secs<0)
901 {
902 days-=1;
903 secs+=24*3600;
904 }
905 if (secs>=24*3600)
906 {
907 days+=1;
908 secs-=24*3600;
909 }
910
911 days+=d;
912
913 fMJD=days;
914 fJsec=secs;
915 fJns=nsec;
916 fJps=psec;
917}
918///////////////////////////////////////////////////////////////////////////
a7dc0627 919Int_t AliTimestamp::GetDifference(AliTimestamp& t,Int_t& d,Int_t& s,Int_t& ns,Int_t& ps) const
920{
921// Provide the time difference w.r.t the AliTimestamp specified on the input.
922// This memberfunction supports both very small (i.e. time of flight analysis
923// for particle physics experiments) and very long (i.e. investigation of
924// astrophysical phenomena) timescales.
925//
926// The time difference is returned via the following output arguments :
927// d : elapsed number of days
928// s : remaining elapsed number of seconds
929// ns : remaining elapsed number of nanoseconds
930// ps : remaining elapsed number of picoseconds
931//
95cfc777 932// Note :
933// ------
934// The calculated time difference is the absolute value of the time interval.
935// This implies that the values of d, s, ns and ps are always positive or zero.
936//
a7dc0627 937// The integer return argument indicates whether the AliTimestamp specified
938// on the input argument occurred earlier (-1), simultaneously (0) or later (1).
939
95cfc777 940 d=t.fMJD-fMJD;
941 s=t.fJsec-fJsec;
942 ns=t.fJns-fJns;
943 ps=t.fJps-fJps;
a7dc0627 944
945 if (!d && !s && !ns && !ps) return 0;
946
947 Int_t sign=0;
948
95cfc777 949 if (d>0) sign=1;
950 if (d<0) sign=-1;
951
952 if (!sign && s>0) sign=1;
953 if (!sign && s<0) sign=-1;
a7dc0627 954
955 if (!sign && ns>0) sign=1;
956 if (!sign && ns<0) sign=-1;
957
958 if (!sign && ps>0) sign=1;
959 if (!sign && ps<0) sign=-1;
960
961 // In case the input stamp was earlier, take the reverse difference
962 // to simplify the algebra.
963 if (sign<0)
964 {
95cfc777 965 d=-d;
a7dc0627 966 s=-s;
967 ns=-ns;
968 ps=-ps;
969 }
970
971 // Here we always have a positive time difference
95cfc777 972 // and can now unambiguously correct for other negative values.
a7dc0627 973 if (ps<0)
974 {
975 ns-=1;
976 ps+=1000;
977 }
978
979 if (ns<0)
980 {
981 s-=1;
95cfc777 982 ns+=1000000000;
a7dc0627 983 }
984
95cfc777 985 if (s<0)
986 {
987 d-=1;
988 s+=24*3600;
989 }
a7dc0627 990
991 return sign;
992}
993///////////////////////////////////////////////////////////////////////////
95cfc777 994Double_t AliTimestamp::GetDifference(AliTimestamp& t,TString u,Int_t mode) const
995{
996// Provide the time difference w.r.t the AliTimestamp specified on the input
997// argument in the units as specified by the TString argument.
998// A positive return value means that the AliTimestamp specified on the input
999// argument occurred later, whereas a negative return value indicates an
1000// earlier occurence.
1001//
1002// The units may be specified as :
1003// u = "d" ==> Time difference returned as (fractional) day count
1004// "s" ==> Time difference returned as (fractional) second count
1005// "ns" ==> Time difference returned as (fractional) nanosecond count
1006// "ps" ==> Time difference returned as picosecond count
1007//
1008// It may be clear that for a time difference of several days, the picosecond
1009// and even the nanosecond accuracy may be lost.
1010// To cope with this, the "mode" argument has been introduced to allow
1011// timestamp comparison on only the specified units.
1012//
1013// The following operation modes are supported :
1014// mode = 1 : Full time difference is returned in specified units
1015// 2 : Time difference is returned in specified units by
1016// neglecting the elapsed time for the larger units than the
1017// ones specified.
1018// 3 : Time difference is returned in specified units by only
1019// comparing the timestamps on the level of the specified units.
1020//
1021// Example :
1022// ---------
1023// AliTimestamp t1; // Corresponding to days=3, secs=501, ns=31, ps=7
1024// AliTimestamp t2; // Corresponding to days=5, secs=535, ns=12, ps=15
1025//
1026// The statement : Double_t val=t1.GetDifference(t2,....)
1027// would return the following values :
1028// val=(2*24*3600)+34-(19*1e-9)+(8*1e-12) for u="s" and mode=1
1029// val=34-(19*1e-9)+(8*1e-12) for u="s" and mode=2
1030// val=34 for u="s" and mode=3
1031// val=-19 for u="ns" and mode=3
1032//
1033// The default is mode=1.
1034
1035 if (mode<1 || mode>3) return 0;
1036
1037 Double_t dt=0;
1038
1039 Int_t dd=t.fMJD-fMJD;
1040 Int_t ds=t.fJsec-fJsec;
1041 Int_t dns=t.fJns-fJns;
1042 Int_t dps=t.fJps-fJps;
1043
1044 // Time difference for the specified units only
1045 if (mode==3)
1046 {
1047 if (u=="d") dt=dd;
1048 if (u=="s") dt=ds;
1049 if (u=="ns") dt=dns;
1050 if (u=="ps") dt=dps;
1051 return dt;
1052 }
1053
1054 // Suppress elapsed time for the larger units than specified
1055 if (mode==2)
1056 {
1057 if (u=="s") dd=0;
1058 if (u=="ns")
1059 {
1060 dd=0;
1061 ds=0;
1062 }
1063 if (u=="ps")
1064 {
1065 dd=0;
1066 ds=0;
1067 dns=0;
1068 }
1069 }
1070
1071 // Compute the time difference as requested
1072 if (u=="s" || u=="d")
1073 {
1074 // The time difference in (fractional) seconds
1075 dt=double(dd*24*3600+ds)+(double(dns)*1e-9)+(double(dps)*1e-12);
1076 if (u=="d") dt=dt/double(24*3600);
1077 }
1078 if (u=="ns") dt=(double(dd*24*3600+ds)*1e9)+double(dns)+(double(dps)*1e-3);
1079 if (u=="ps") dt=(double(dd*24*3600+ds)*1e12)+(double(dns)*1e3)+double(dps);
1080
1081 return dt;
1082}
1083///////////////////////////////////////////////////////////////////////////