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