Coding convention: RN13 rule violation -> suppression
[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//
a4f7a3a1 38// The Julian Epoch (JE) indicates the fractional elapsed Julian year count
39// since the start of the Gregorian year count.
40// A Julian year is defined to be 365.25 days and starts at 01-jan 12:00:00 UT.
41// As such, the integer part of JE corresponds to the usual Gregorian year count,
42// apart from 01-jan before 12:00:00 UT.
43// So, 01-jan-1965 12:00:00 UT corresponds to JE=1965.0
44//
45// The Besselian Epoch (BE) indicates the fractional elapsed Besselian year count
46// since the start of the Gregorian year count.
47// A Besselian (or tropical) year is defined to be 365.242198781 days.
48//
49// The Besselian and Julian epochs are used in astronomical catalogs
50// to denote values of time varying observables like e.g. right ascension.
3ea81e9c 51//
52// Because of the fact that the Julian date indicators are all w.r.t. UT
53// they provide an absolute timescale irrespective of timezone or daylight
54// saving time (DST).
55//
a4f7a3a1 56// In view of astronomical observations and positioning it is convenient
57// to have also a UT equivalent related to stellar meridian transitions.
58// This is achieved by the Greenwich Sidereal Time (GST).
59// The GST is defined as the right ascension of the objects passing
60// the Greenwich meridian at 00:00:00 UT.
61// Due to the rotation of the Earth around the Sun, a sidereal day
62// lasts 86164.09 seconds (23h 56m 04.09s) compared to the mean solar
63// day of 86400 seconds (24h).
64// Furthermore, precession of the earth's spin axis results in the fact
65// that the zero point of right ascension (vernal equinox) gradually
66// moves along the celestial equator.
67// In addition, tidal friction and ocean and atmospheric effects will
68// induce seasonal variations in the earth's spin rate and polar motion
69// of the earth's spin axis.
70// To obtain a sidereal time measure, the above efects are taken
71// into account via corrections in the UT to GST conversion.
72//
a7dc0627 73// This AliTimestamp facility allows for picosecond precision, in view
74// of time of flight analyses for particle physics experiments.
75// For normal date/time indication the standard nanosecond precision
76// will in general be sufficient.
77// Note that when the fractional JD, MJD and TJD counts are used instead
3ea81e9c 78// of the integer (days,sec,ns) specification, the nanosecond precision
79// may be lost due to computer accuracy w.r.t. floating point operations.
80//
81// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
82// which corresponds to JD=2440587.5 or the start of MJD=40587 or TJD=587.
83// Using the corresponding MJD of this EPOCH allows construction of
84// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input (M/T)JD and time.
85// Obviously this TTimeStamp implementation would prevent usage of values
86// smaller than JD=2440587.5 or MJD=40587 or TJD=587.
0cfe76b5 87// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
88// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 89// However, this AliTimestamp facility provides support for the full range
90// of (M/T)JD values, but the setting of the corresponding TTimeStamp parameters
91// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 92// For these earlier/later (M/T)JD values, the standard TTimeStamp parameters will
3ea81e9c 93// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 94// This implies that for these earlier/later (M/T)JD values the TTimeStamp parameters
3ea81e9c 95// do not match the Julian parameters of AliTimestamp.
96// As such the standard TTimeStamp parameters do not appear on the print output
0cfe76b5 97// when invoking the Date() memberfunction for these earlier/later (M/T)JD values.
3ea81e9c 98//
99// Examples :
100// ==========
101//
102// Note : All TTimeStamp functionality is available as well.
103//
104// AliTimestamp t;
105//
106// t.Date();
107//
108// // Retrieve Julian Date
109// Int_t jd,jsec,jns;
110// t.GetJD(jd,jsec,jns);
111//
112// // Retrieve fractional Truncated Julian Date
113// Double_t tjd=t.GetTJD();
114//
115// // Retrieve fractional Julian Epoch
116// Double_t je=t.GetJE();
117//
118// // Set to a specific Modified Julian Date
119// Int_t mjd=50537;
120// Int_t mjsec=1528;
121// Int_t mjns=185643;
122// t.SetMJD(mjd,mjsec,mjns);
123//
124// t.Date();
125//
95cfc777 126// // Time intervals for e.g. trigger or TOF analysis
127// AliEvent evt;
ee26083f 128// AliTrack* tx=evt.GetTrack(5);
129// AliTimestamp* timex=tx->GetTimestamp();
130// Double_t dt=evt.GetDifference(timex,"ps");
131// AliTimestamp trig((AliTimestamp)evt);
132// trig.Add(0,0,2,173);
133// AliSignal* sx=evt.GetHit(23);
134// AliTimestamp* timex=sx->GetTimestamp();
135// Double_t dt=trig.GetDifference(timex,"ps");
95cfc777 136// Int_t d,s,ns,ps;
ee26083f 137// trig.GetDifference(timex,d,s,ns,ps);
95cfc777 138//
3ea81e9c 139// // Some practical conversion facilities
140// // Note : They don't influence the actual date/time settings
141// // and as such can also be invoked as AliTimestamp::Convert(...) etc...
142// Int_t y=1921;
143// Int_t m=7;
144// Int_t d=21;
145// Int_t hh=15;
146// Int_t mm=23;
147// Int_t ss=47;
148// Int_t ns=811743;
149// Double_t jdate=t.GetJD(y,m,d,hh,mm,ss,ns);
150//
151// Int_t days,secs,nsecs;
152// Double_t date=421.1949327;
153// t.Convert(date,days,secs,nsecs);
154//
155// days=875;
156// secs=23;
157// nsecs=9118483;
158// date=t.Convert(days,secs,nsecs);
159//
160// Double_t mjdate=40563.823744;
161// Double_t epoch=t.GetJE(mjdate,"mjd");
162//
163//--- Author: Nick van Eijndhoven 28-jan-2005 Utrecht University.
164//- Modified: NvE $Date$ Utrecht University.
165///////////////////////////////////////////////////////////////////////////
166
167#include "AliTimestamp.h"
168#include "Riostream.h"
4ccbc0d8 169#include <cmath>
3ea81e9c 170
171ClassImp(AliTimestamp) // Class implementation to enable ROOT I/O
172
173AliTimestamp::AliTimestamp() : TTimeStamp()
174{
175// Default constructor
176// Creation of an AliTimestamp object and initialisation of parameters.
177// All attributes are initialised to the current date/time as specified
178// in the docs of TTimeStamp.
179
180 FillJulian();
a7dc0627 181 fJps=0;
3ea81e9c 182}
183///////////////////////////////////////////////////////////////////////////
184AliTimestamp::AliTimestamp(TTimeStamp& t) : TTimeStamp(t)
185{
186// Creation of an AliTimestamp object and initialisation of parameters.
187// All attributes are initialised to the values of the input TTimeStamp.
188
189 FillJulian();
a7dc0627 190 fJps=0;
3ea81e9c 191}
192///////////////////////////////////////////////////////////////////////////
193AliTimestamp::~AliTimestamp()
194{
195// Destructor to delete dynamically allocated memory.
196}
197///////////////////////////////////////////////////////////////////////////
198AliTimestamp::AliTimestamp(const AliTimestamp& t) : TTimeStamp(t)
199{
200// Copy constructor
201
202 fMJD=t.fMJD;
203 fJsec=t.fJsec;
204 fJns=t.fJns;
a7dc0627 205 fJps=t.fJps;
3ea81e9c 206 fCalcs=t.fCalcs;
207 fCalcns=t.fCalcns;
208}
209///////////////////////////////////////////////////////////////////////////
210void AliTimestamp::Date(Int_t mode)
211{
212// Print date/time info.
213//
a4f7a3a1 214// mode = 1 ==> Only the TTimeStamp yy-mm-dd hh:mm:ss:ns and GMST info is printed
3ea81e9c 215// 2 ==> Only the Julian parameter info is printed
a4f7a3a1 216// 3 ==> Both the TTimeStamp, GMST and Julian parameter info is printed
3ea81e9c 217//
218// The default is mode=3.
219//
220// Note : In case the (M/T)JD falls outside the TTimeStamp range,
a4f7a3a1 221// the TTimeStamp info will be replaced by UT hh:mm:ss:ns:ps info.
222
223 Int_t mjd,mjsec,mjns,mjps;
224 GetMJD(mjd,mjsec,mjns);
225 mjps=GetPs();
3ea81e9c 226
a4f7a3a1 227 Int_t hh,mm,ss,ns,ps;
0cfe76b5 228
a4f7a3a1 229 if (mode==1 || mode==3)
0cfe76b5 230 {
a4f7a3a1 231 if (mjd>=40587 && (mjd<65442 || (mjd==65442 && mjsec<8047)))
232 {
233 cout << " " << AsString() << endl;
234 }
235 else
236 {
237 GetUT(hh,mm,ss,ns,ps);
238 cout << " UT : " << setfill('0') << setw(2) << hh << ":"
239 << setw(2) << mm << ":" << setw(2) << ss
240 << " ns : " << ns << " ps : " << ps << " ";
241 }
242 GetGST(hh,mm,ss,ns,ps);
243 cout << " GST : " << setfill('0') << setw(2) << hh << ":"
244 << setw(2) << mm << ":" << setw(2) << ss
245 << " ns : " << ns << " ps : " << ps << endl;
0cfe76b5 246 }
3ea81e9c 247 if (mode==2 || mode==3)
248 {
249 Int_t jd,jsec,jns;
250 GetJD(jd,jsec,jns);
251 Int_t tjd,tjsec,tjns;
252 GetTJD(tjd,tjsec,tjns);
a4f7a3a1 253 cout << " Julian Epoch : " << setprecision(25) << GetJE()
254 << " Besselian Epoch : " << setprecision(25) << GetBE() << endl;
95cfc777 255 cout << " JD : " << jd << " sec : " << jsec << " ns : " << jns << " ps : " << fJps
3ea81e9c 256 << " Fractional : " << setprecision(25) << GetJD() << endl;
95cfc777 257 cout << " MJD : " << mjd << " sec : " << mjsec << " ns : " << mjns << " ps : " << fJps
3ea81e9c 258 << " Fractional : " << setprecision(25) << GetMJD() << endl;
95cfc777 259 cout << " TJD : " << tjd << " sec : " << tjsec << " ns : " << tjns << " ps : " << fJps
3ea81e9c 260 << " Fractional : " << setprecision(25) << GetTJD() << endl;
261 }
262}
263///////////////////////////////////////////////////////////////////////////
264Double_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
265{
266// Provide the (fractional) Julian Date (JD) corresponding to the UT date
267// and time in the Gregorian calendar as specified by the input arguments.
268//
269// The input arguments represent the following :
270// y : year in UT (e.g. 1952, 2003 etc...)
271// m : month in UT (1=jan 2=feb etc...)
272// d : day in UT (1-31)
273// hh : elapsed hours in UT (0-23)
274// mm : elapsed minutes in UT (0-59)
275// ss : elapsed seconds in UT (0-59)
276// ns : remaining fractional elapsed second of UT in nanosecond
277//
278// This algorithm is valid for all AD dates in the Gregorian calendar
279// following the recipe of R.W. Sinnott Sky & Telescope 82, (aug. 1991) 183.
280// See also http://scienceworld.wolfram.com/astronomy/JulianDate.html
281//
282// In case of invalid input, a value of -1 is returned.
283//
284// Note :
285// ------
286// This memberfunction only provides the JD corresponding to the
287// UT input arguments. It does NOT set the corresponding Julian parameters
288// for the current AliTimestamp instance.
289// As such the TTimeStamp limitations do NOT apply to this memberfunction.
290// To set the Julian parameters for the current AliTimestamp instance,
291// please use the corresponding SET() memberfunctions of either AliTimestamp
292// or TTimeStamp.
293
294 if (y<0 || m<1 || m>12 || d<1 || d>31) return -1;
295 if (hh<0 || hh>23 || mm<0 || mm>59 || ss<0 || ss>59 || ns<0 || ns>1e9) return -1;
296
297 // The UT daytime in fractional hours
298 Double_t ut=double(hh)+double(mm)/60.+(double(ss)+double(ns)*1.e-9)/3600.;
299
300 Double_t JD=0;
301
302 JD=367*y-int(7*(y+int((m+9)/12))/4)
303 -int(3*(int((y+(m-9)/7)/100)+1)/4)
304 +int(275*m/9)+d+1721028.5+ut/24.;
305
306 return JD;
307}
308///////////////////////////////////////////////////////////////////////////
309Double_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
310{
311// Provide the (fractional) Modified Julian Date corresponding to the UT
312// date and time in the Gregorian calendar as specified by the input arguments.
313//
314// The input arguments represent the following :
315// y : year in UT (e.g. 1952, 2003 etc...)
316// m : month in UT (1=jan 2=feb etc...)
317// d : day in UT (1-31)
318// hh : elapsed hours in UT (0-23)
319// mm : elapsed minutes in UT (0-59)
320// ss : elapsed seconds in UT (0-59)
321// ns : remaining fractional elapsed second of UT in nanosecond
322//
323// This algorithm is valid for all AD dates in the Gregorian calendar
324// following the recipe of R.W. Sinnott Sky & Telescope 82, (aug. 1991) 183.
325// See also http://scienceworld.wolfram.com/astronomy/JulianDate.html
326//
327// In case of invalid input, a value of -1 is returned.
328//
329// Note :
330// ------
331// This memberfunction only provides the MJD corresponding to the
332// UT input arguments. It does NOT set the corresponding Julian parameters
333// for the current AliTimestamp instance.
334// As such the TTimeStamp limitations do NOT apply to this memberfunction.
335// To set the Julian parameters for the current AliTimestamp instance,
336// please use the corresponding SET() memberfunctions of either AliTimestamp
337// or TTimeStamp.
338
339 Double_t JD=GetJD(y,m,d,hh,mm,ss,ns);
340
341 if (JD<0) return JD;
342
343 Double_t MJD=JD-2400000.5;
344
345 return MJD;
346}
347///////////////////////////////////////////////////////////////////////////
348Double_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
349{
350// Provide the (fractional) Truncated Julian Date corresponding to the UT
351// date and time in the Gregorian calendar as specified by the input arguments.
352//
353// The input arguments represent the following :
354// y : year in UT (e.g. 1952, 2003 etc...)
355// m : month in UT (1=jan 2=feb etc...)
356// d : day in UT (1-31)
357// hh : elapsed hours in UT (0-23)
358// mm : elapsed minutes in UT (0-59)
359// ss : elapsed seconds in UT (0-59)
360// ns : remaining fractional elapsed second of UT in nanosecond
361//
362// This algorithm is valid for all AD dates in the Gregorian calendar
363// following the recipe of R.W. Sinnott Sky & Telescope 82, (aug. 1991) 183.
364// See also http://scienceworld.wolfram.com/astronomy/JulianDate.html
365//
366// In case of invalid input, a value of -1 is returned.
367//
368// Note :
369// ------
370// This memberfunction only provides the TJD corresponding to the
371// UT input arguments. It does NOT set the corresponding Julian parameters
372// for the current AliTimestamp instance.
373// As such the TTimeStamp limitations do NOT apply to this memberfunction.
374// To set the Julian parameters for the current AliTimestamp instance,
375// please use the corresponding SET() memberfunctions of either AliTimestamp
376// or TTimeStamp.
377
378 Double_t JD=GetJD(y,m,d,hh,mm,ss,ns);
379
380 if (JD<0) return JD;
381
382 Double_t TJD=JD-2440000.5;
383
384 return TJD;
385}
386///////////////////////////////////////////////////////////////////////////
387Double_t AliTimestamp::GetJE(Double_t date,TString mode) const
388{
389// Provide the Julian Epoch (JE) corresponding to the specified date.
390// The argument "mode" indicates the type of the argument "date".
391//
392// Available modes are :
393// mode = "jd" ==> date represents the Julian Date
394// = "mjd" ==> date represents the Modified Julian Date
395// = "tjd" ==> date represents the Truncated Julian Date
396//
397// The default is mode="jd".
398//
399// In case of invalid input, a value of -99999 is returned.
400//
401// Note :
402// ------
403// This memberfunction only provides the JE corresponding to the
404// input arguments. It does NOT set the corresponding Julian parameters
405// for the current AliTimestamp instance.
406// As such the TTimeStamp limitations do NOT apply to this memberfunction.
407// To set the Julian parameters for the current AliTimestamp instance,
408// please use the corresponding SET() memberfunctions of either AliTimestamp
409// or TTimeStamp.
410
411 if ((mode != "jd") && (mode != "mjd") && (mode != "tjd")) return -99999;
412
413 Double_t jd=date;
414 if (mode=="mjd") jd=date+2400000.5;
415 if (mode=="tjd") jd=date+2440000.5;
416
417 Double_t je=2000.+(jd-2451545.)/365.25;
418
419 return je;
420}
421///////////////////////////////////////////////////////////////////////////
a4f7a3a1 422Double_t AliTimestamp::GetBE(Double_t date,TString mode) const
423{
424// Provide the Besselian Epoch (JE) corresponding to the specified date.
425// The argument "mode" indicates the type of the argument "date".
426//
427// Available modes are :
428// mode = "jd" ==> date represents the Julian Date
429// = "mjd" ==> date represents the Modified Julian Date
430// = "tjd" ==> date represents the Truncated Julian Date
431//
432// The default is mode="jd".
433//
434// In case of invalid input, a value of -99999 is returned.
435//
436// Note :
437// ------
438// This memberfunction only provides the BE corresponding to the
439// input arguments. It does NOT set the corresponding Julian parameters
440// for the current AliTimestamp instance.
441// As such the TTimeStamp limitations do NOT apply to this memberfunction.
442// To set the Julian parameters for the current AliTimestamp instance,
443// please use the corresponding SET() memberfunctions of either AliTimestamp
444// or TTimeStamp.
445
446 if ((mode != "jd") && (mode != "mjd") && (mode != "tjd")) return -99999;
447
448 Double_t jd=date;
449 if (mode=="mjd") jd=date+2400000.5;
450 if (mode=="tjd") jd=date+2440000.5;
451
452 Double_t be=1900.+(jd-2415020.31352)/365.242198781;
453
454 return be;
455}
456///////////////////////////////////////////////////////////////////////////
3ea81e9c 457void AliTimestamp::Convert(Double_t date,Int_t& days,Int_t& secs,Int_t& ns) const
458{
459// Convert date as fractional day count into integer days, secs and ns.
460//
461// Note : Due to computer accuracy the ns value may become inaccurate.
462//
463// The arguments represent the following :
464// date : The input date as fractional day count
465// days : Number of elapsed days
466// secs : Remaining number of elapsed seconds
467// ns : Remaining fractional elapsed second in nanoseconds
468//
469// Note :
470// ------
471// This memberfunction only converts the input date into the corresponding
472// integer parameters. It does NOT set the corresponding Julian parameters
473// for the current AliTimestamp instance.
474// As such the TTimeStamp limitations do NOT apply to this memberfunction.
475// To set the Julian parameters for the current AliTimestamp instance,
476// please use the corresponding SET() memberfunctions of either AliTimestamp
477// or TTimeStamp.
478
479 days=int(date);
480 date=date-double(days);
481 Int_t daysecs=24*3600;
482 date=date*double(daysecs);
483 secs=int(date);
484 date=date-double(secs);
485 ns=int(date*1.e9);
486}
487///////////////////////////////////////////////////////////////////////////
488Double_t AliTimestamp::Convert(Int_t days,Int_t secs,Int_t ns) const
489{
490// Convert date in integer days, secs and ns into fractional day count.
491//
492// Note : Due to computer accuracy the ns precision may be lost.
493//
494// The input arguments represent the following :
495// days : Number of elapsed days
496// secs : Remaining number of elapsed seconds
497// ns : Remaining fractional elapsed second in nanoseconds
498//
499// Note :
500// ------
501// This memberfunction only converts the input integer parameters into the
502// corresponding fractional day count. It does NOT set the corresponding
503// Julian parameters for the current AliTimestamp instance.
504// As such the TTimeStamp limitations do NOT apply to this memberfunction.
505// To set the Julian parameters for the current AliTimestamp instance,
506// please use the corresponding SET() memberfunctions of either AliTimestamp
507// or TTimeStamp.
508
509 Double_t frac=double(secs)+double(ns)*1.e-9;
510 Int_t daysecs=24*3600;
511 frac=frac/double(daysecs);
512 Double_t date=double(days)+frac;
513 return date;
514}
515///////////////////////////////////////////////////////////////////////////
a4f7a3a1 516void AliTimestamp::Convert(Double_t h,Int_t& hh,Int_t& mm,Int_t& ss,Int_t& ns,Int_t& ps) const
517{
518// Convert fractional hour count h into hh:mm:ss:ns:ps.
519//
520// Note : Due to computer accuracy the ps value may become inaccurate.
521//
522// Note :
523// ------
524// This memberfunction only converts the input "h" into the corresponding
525// integer parameters. It does NOT set the corresponding Julian parameters
526// for the current AliTimestamp instance.
527// As such the TTimeStamp limitations do NOT apply to this memberfunction.
528// To set the Julian parameters for the current AliTimestamp instance,
529// please use the corresponding SET() memberfunctions of either AliTimestamp
530// or TTimeStamp.
531
532 hh=int(h);
533 h=h-double(hh);
534 h=h*3600.;
535 ss=int(h);
536 h=h-double(ss);
537 h=h*1.e9;
538 ns=int(h);
539 h=h-double(ns);
540 h=h*1000.;
541 ps=int(h);
542}
543///////////////////////////////////////////////////////////////////////////
544Double_t AliTimestamp::Convert(Int_t hh,Int_t mm,Int_t ss,Int_t ns,Int_t ps) const
545{
546// Convert hh:mm:ss:ns:ps into fractional hour count.
547//
548// Note : Due to computer accuracy the ps precision may be lost.
549//
550// Note :
551// ------
552// This memberfunction only converts the input integer parameters into the
553// corresponding fractional hour count. It does NOT set the corresponding
554// Julian parameters for the current AliTimestamp instance.
555// As such the TTimeStamp limitations do NOT apply to this memberfunction.
556// To set the Julian parameters for the current AliTimestamp instance,
557// please use the corresponding SET() memberfunctions of either AliTimestamp
558// or TTimeStamp.
559
560 Double_t h=hh;
561 h+=double(mm)/60.+(double(ss)+double(ns)*1.e-9+double(ps)*1.e-12)/3600.;
562
563 return h;
564}
565///////////////////////////////////////////////////////////////////////////
3ea81e9c 566void AliTimestamp::FillJulian()
567{
568// Calculation and setting of the Julian date/time parameters corresponding
569// to the current TTimeStamp date/time parameters.
570
571 UInt_t y,m,d,hh,mm,ss;
572
573 GetDate(kTRUE,0,&y,&m,&d);
574 GetTime(kTRUE,0,&hh,&mm,&ss);
575 Int_t ns=GetNanoSec();
576
577 Double_t mjd=GetMJD(y,m,d,hh,mm,ss,ns);
578
579 fMJD=int(mjd);
580 fJsec=GetSec()%(24*3600); // Daytime in elapsed seconds
581 fJns=ns; // Remaining fractional elapsed second in nanoseconds
582
583 // Store the TTimeStamp seconds and nanoseconds values
584 // for which this Julian calculation was performed.
585 fCalcs=GetSec();
586 fCalcns=GetNanoSec();
587}
588///////////////////////////////////////////////////////////////////////////
0cfe76b5 589void AliTimestamp::GetMJD(Int_t& mjd,Int_t& sec,Int_t& ns)
3ea81e9c 590{
591// Provide the Modified Julian Date (MJD) and time corresponding to the
592// currently stored AliTimestamp date/time parameters.
593//
594// The returned arguments represent the following :
595// mjd : The modified Julian date.
596// sec : The number of seconds elapsed within the MJD.
597// ns : The remaining fractional number of seconds (in ns) elapsed within the MJD.
598
599 if (fCalcs != GetSec() || fCalcns != GetNanoSec()) FillJulian();
600
601 mjd=fMJD;
602 sec=fJsec;
603 ns=fJns;
604}
605///////////////////////////////////////////////////////////////////////////
606Double_t AliTimestamp::GetMJD()
607{
608// Provide the (fractional) Modified Julian Date (MJD) corresponding to the
609// currently stored AliTimestamp date/time parameters.
610//
611// Due to computer accuracy the ns precision may be lost.
612// It is advised to use the (mjd,sec,ns) getter instead.
613
614 Int_t mjd=0;
615 Int_t sec=0;
616 Int_t ns=0;
617 GetMJD(mjd,sec,ns);
618
619 Double_t date=Convert(mjd,sec,ns);
620
621 return date;
622}
623///////////////////////////////////////////////////////////////////////////
624void AliTimestamp::GetTJD(Int_t& tjd,Int_t& sec, Int_t& ns)
625{
626// Provide the Truncated Julian Date (TJD) and time corresponding to the
627// currently stored AliTimestamp date/time parameters.
628//
629// The returned arguments represent the following :
630// tjd : The modified Julian date.
631// sec : The number of seconds elapsed within the MJD.
632// ns : The remaining fractional number of seconds (in ns) elapsed within the MJD.
633
634 Int_t mjd=0;
635 GetMJD(mjd,sec,ns);
636
637 tjd=mjd-40000;
638}
639///////////////////////////////////////////////////////////////////////////
640Double_t AliTimestamp::GetTJD()
641{
642// Provide the (fractional) Truncated Julian Date (TJD) corresponding to the
643// currently stored AliTimestamp date/time parameters.
644//
645// Due to computer accuracy the ns precision may be lost.
646// It is advised to use the (mjd,sec,ns) getter instead.
647
648 Int_t tjd=0;
649 Int_t sec=0;
650 Int_t ns=0;
651 GetTJD(tjd,sec,ns);
652
653 Double_t date=Convert(tjd,sec,ns);
654
655 return date;
656}
657///////////////////////////////////////////////////////////////////////////
658void AliTimestamp::GetJD(Int_t& jd,Int_t& sec, Int_t& ns)
659{
660// Provide the Julian Date (JD) and time corresponding to the currently
661// stored AliTimestamp date/time parameters.
662//
663// The returned arguments represent the following :
664// jd : The Julian date.
665// sec : The number of seconds elapsed within the JD.
666// ns : The remaining fractional number of seconds (in ns) elapsed within the JD.
667
668 Int_t mjd=0;
669 GetMJD(mjd,sec,ns);
670
671 jd=mjd+2400000;
672 sec+=12*3600;
673 if (sec >= 24*3600)
674 {
675 sec-=24*3600;
676 jd+=1;
677 }
678}
679///////////////////////////////////////////////////////////////////////////
680Double_t AliTimestamp::GetJD()
681{
682// Provide the (fractional) Julian Date (JD) corresponding to the currently
683// stored AliTimestamp date/time parameters.
684//
685// Due to computer accuracy the ns precision may be lost.
686// It is advised to use the (jd,sec,ns) getter instead.
687
688 Int_t jd=0;
689 Int_t sec=0;
690 Int_t ns=0;
691 GetJD(jd,sec,ns);
692
693 Double_t date=Convert(jd,sec,ns);
694
695 return date;
696}
697///////////////////////////////////////////////////////////////////////////
698Double_t AliTimestamp::GetJE()
699{
700// Provide the Julian Epoch (JE) corresponding to the currently stored
701// AliTimestamp date/time parameters.
702
703 Double_t jd=GetJD();
704 Double_t je=GetJE(jd);
705 return je;
706}
707///////////////////////////////////////////////////////////////////////////
a4f7a3a1 708Double_t AliTimestamp::GetBE()
709{
710// Provide the Besselian Epoch (BE) corresponding to the currently stored
711// AliTimestamp date/time parameters.
712
713 Double_t jd=GetJD();
714 Double_t be=GetBE(jd);
715 return be;
716}
717///////////////////////////////////////////////////////////////////////////
a7dc0627 718void AliTimestamp::SetMJD(Int_t mjd,Int_t sec,Int_t ns,Int_t ps)
3ea81e9c 719{
720// Set the Modified Julian Date (MJD) and time and update the TTimeStamp
721// parameters accordingly (if possible).
722//
723// Note :
724// ------
725// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
726// which corresponds to the start of MJD=40587.
727// Using the corresponding MJD of this EPOCH allows construction of
728// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
729// Obviously this TTimeStamp implementation would prevent usage of MJD values
730// smaller than 40587.
0cfe76b5 731// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
732// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 733// However, this AliTimestamp facility provides support for the full range
734// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
735// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 736// For these earlier/later MJD values, the standard TTimeStamp parameters will
3ea81e9c 737// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 738// This implies that for these earlier/later MJD values the TTimeStamp parameters
3ea81e9c 739// do not match the Julian parameters of AliTimestamp.
740//
741// The input arguments represent the following :
742// mjd : The modified Julian date.
743// sec : The number of seconds elapsed within the MJD.
744// ns : The remaining fractional number of seconds (in ns) elapsed within the MJD.
a7dc0627 745// ps : The remaining fractional number of nanoseconds (in ps) elapsed within the MJD.
746//
747// Note : ps=0 is the default value.
3ea81e9c 748
a7dc0627 749 if (sec<0 || sec>=24*3600 || ns<0 || ns>=1e9 || ps<0 || ps>=1000)
3ea81e9c 750 {
751 cout << " *AliTimestamp::SetMJD* Invalid input."
752 << " sec : " << sec << " ns : " << ns << endl;
753 return;
754 }
755
756 fMJD=mjd;
757 fJsec=sec;
758 fJns=ns;
a7dc0627 759 fJps=ps;
3ea81e9c 760
0cfe76b5 761 Int_t epoch=40587; // MJD of the start of the epoch
762 Int_t limit=65442; // MJD of the latest possible TTimeStamp date/time
3ea81e9c 763
0cfe76b5 764 Int_t date,time;
765 if (mjd<epoch || (mjd>=limit && sec>=8047))
3ea81e9c 766 {
767 Set(0,kFALSE,0,kFALSE);
0cfe76b5 768 date=GetDate();
769 time=GetTime();
770 Set(date,time,0,kTRUE,0);
3ea81e9c 771 }
772 else
773 {
774 // The elapsed time since start of EPOCH
775 Int_t days=mjd-epoch;
776 UInt_t secs=days*24*3600;
777 secs+=sec;
778 Set(secs,kFALSE,0,kFALSE);
0cfe76b5 779 date=GetDate();
780 time=GetTime();
3ea81e9c 781 Set(date,time,ns,kTRUE,0);
782 }
783
784 // Denote that the Julian and TTimeStamp parameters are synchronised,
785 // even in the case the MJD falls outside the TTimeStamp validity range.
786 // The latter still allows retrieval of Julian parameters for these
787 // earlier times.
788 fCalcs=GetSec();
789 fCalcns=GetNanoSec();
790}
791///////////////////////////////////////////////////////////////////////////
792void AliTimestamp::SetMJD(Double_t mjd)
793{
794// Set the Modified Julian Date (MJD) and time and update the TTimeStamp
795// parameters accordingly (if possible).
796//
797// Note :
798// ------
799// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
800// which corresponds to the start of MJD=40587.
801// Using the corresponding MJD of this EPOCH allows construction of
802// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
803// Obviously this TTimeStamp implementation would prevent usage of MJD values
804// smaller than 40587.
0cfe76b5 805// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
806// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 807// However, this AliTimestamp facility provides support for the full range
808// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
809// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 810// For these earlier/later MJD values, the standard TTimeStamp parameters will
3ea81e9c 811// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 812// This implies that for these earlier/later MJD values the TTimeStamp parameters
3ea81e9c 813// do not match the Julian parameters of AliTimestamp.
814//
815// Due to computer accuracy the ns precision may be lost.
816// It is advised to use the (mjd,sec,ns) setting instead.
817//
818// The input argument represents the following :
819// mjd : The modified Julian date as fractional day count.
820
821 Int_t days=0;
822 Int_t secs=0;
823 Int_t ns=0;
824 Convert(mjd,days,secs,ns);
825 SetMJD(days,secs,ns);
826}
827///////////////////////////////////////////////////////////////////////////
a7dc0627 828void AliTimestamp::SetJD(Int_t jd,Int_t sec,Int_t ns,Int_t ps)
3ea81e9c 829{
830// Set the Julian Date (JD) and time and update the TTimeStamp
831// parameters accordingly (if possible).
832//
833// Note :
834// ------
835// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
836// which corresponds to JD=2440587.5 or the start of MJD=40587.
837// Using the corresponding MJD of this EPOCH allows construction of
838// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
839// Obviously this TTimeStamp implementation would prevent usage of values
840// smaller than JD=2440587.5.
0cfe76b5 841// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
842// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 843// However, this AliTimestamp facility provides support for the full range
844// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
845// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 846// For these earlier/later JD values, the standard TTimeStamp parameters will
3ea81e9c 847// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 848// This implies that for these earlier/later (M)JD values the TTimeStamp parameters
3ea81e9c 849// do not match the Julian parameters of AliTimestamp.
850//
851// The input arguments represent the following :
852// jd : The Julian date.
853// sec : The number of seconds elapsed within the JD.
854// ns : The remaining fractional number of seconds (in ns) elapsed within the JD.
a7dc0627 855// ps : The remaining fractional number of nanoseconds (in ps) elapsed within the JD.
856//
857// Note : ps=0 is the default value.
3ea81e9c 858
859 Int_t mjd=jd-2400000;
860 sec-=12*3600;
861 if (sec<0)
862 {
863 sec+=24*3600;
864 mjd-=1;
865 }
866
a7dc0627 867 SetMJD(mjd,sec,ns,ps);
3ea81e9c 868}
869///////////////////////////////////////////////////////////////////////////
870void AliTimestamp::SetJD(Double_t jd)
871{
872// Set the Julian Date (JD) and time and update the TTimeStamp
873// parameters accordingly (if possible).
874//
875// Note :
876// ------
877// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
878// which corresponds to JD=2440587.5 or the start of MJD=40587.
879// Using the corresponding MJD of this EPOCH allows construction of
880// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
881// Obviously this TTimeStamp implementation would prevent usage of values
882// smaller than JD=2440587.5.
0cfe76b5 883// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
884// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 885// However, this AliTimestamp facility provides support for the full range
886// of (M)JD values, but the setting of the corresponding TTimeStamp parameters
887// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 888// For these earlier/later JD values, the standard TTimeStamp parameters will
3ea81e9c 889// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 890// This implies that for these earlier/later (M)JD values the TTimeStamp parameters
3ea81e9c 891// do not match the Julian parameters of AliTimestamp.
892//
893// Due to computer accuracy the ns precision may be lost.
894// It is advised to use the (jd,sec,ns) setting instead.
895//
896// The input argument represents the following :
897// jd : The Julian date as fractional day count.
898
899 Int_t days=0;
900 Int_t secs=0;
901 Int_t ns=0;
902 Convert(jd,days,secs,ns);
903
904 SetJD(days,secs,ns);
905}
906///////////////////////////////////////////////////////////////////////////
a7dc0627 907void AliTimestamp::SetTJD(Int_t tjd,Int_t sec,Int_t ns,Int_t ps)
3ea81e9c 908{
909// Set the Truncated Julian Date (TJD) and time and update the TTimeStamp
910// parameters accordingly (if possible).
911//
912// Note :
913// ------
914// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
915// which corresponds to JD=2440587.5 or the start of TJD=587.
916// Using the corresponding MJD of this EPOCH allows construction of
917// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
918// Obviously this TTimeStamp implementation would prevent usage of values
919// smaller than TJD=587.
0cfe76b5 920// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
921// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 922// However, this AliTimestamp facility provides support for the full range
923// of (T)JD values, but the setting of the corresponding TTimeStamp parameters
924// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 925// For these earlier/later JD values, the standard TTimeStamp parameters will
3ea81e9c 926// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 927// This implies that for these earlier/later (T)JD values the TTimeStamp parameters
3ea81e9c 928// do not match the Julian parameters of AliTimestamp.
929//
930// The input arguments represent the following :
931// tjd : The Truncated Julian date.
932// sec : The number of seconds elapsed within the JD.
933// ns : The remaining fractional number of seconds (in ns) elapsed within the JD.
a7dc0627 934// ps : The remaining fractional number of nanoseconds (in ps) elapsed within the JD.
935//
936// Note : ps=0 is the default value.
3ea81e9c 937
938 Int_t mjd=tjd+40000;
939
5481c137 940 SetMJD(mjd,sec,ns,ps);
3ea81e9c 941}
942///////////////////////////////////////////////////////////////////////////
943void AliTimestamp::SetTJD(Double_t tjd)
944{
945// Set the Truncated Julian Date (TJD) and time and update the TTimeStamp
946// parameters accordingly (if possible).
947//
948// Note :
949// ------
950// The TTimeStamp EPOCH starts at 01-jan-1970 00:00:00 UTC
951// which corresponds to JD=2440587.5 or the start of TJD=587.
952// Using the corresponding MJD of this EPOCH allows construction of
953// the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
954// Obviously this TTimeStamp implementation would prevent usage of values
955// smaller than TJD=587.
0cfe76b5 956// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
957// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
3ea81e9c 958// However, this AliTimestamp facility provides support for the full range
959// of (T)JD values, but the setting of the corresponding TTimeStamp parameters
960// is restricted to the values allowed by the TTimeStamp implementation.
0cfe76b5 961// For these earlier/later JD values, the standard TTimeStamp parameters will
3ea81e9c 962// be set corresponding to the start of the TTimeStamp EPOCH.
0cfe76b5 963// This implies that for these earlier/later (T)JD values the TTimeStamp parameters
3ea81e9c 964// do not match the Julian parameters of AliTimestamp.
965//
966// Due to computer accuracy the ns precision may be lost.
967// It is advised to use the (jd,sec,ns) setting instead.
968//
969// The input argument represents the following :
970// tjd : The Truncated Julian date as fractional day count.
971
972 Int_t days=0;
973 Int_t secs=0;
974 Int_t ns=0;
975 Convert(tjd,days,secs,ns);
976
977 SetTJD(days,secs,ns);
978}
979///////////////////////////////////////////////////////////////////////////
95cfc777 980void AliTimestamp::SetNs(Int_t ns)
981{
982// Set the remaining fractional number of seconds in nanosecond precision.
983// Notes :
984// -------
985// 1) The allowed range for the argument "ns" is [0,99999999].
986// Outside that range no action is performed.
987// 2) The ns fraction can also be entered directly via SetMJD() etc...
988// 3) For additional accuracy see SetPs().
989
990 if (ns>=0 && ns<=99999999) fJns=ns;
991}
992///////////////////////////////////////////////////////////////////////////
993Int_t AliTimestamp::GetNs() const
994{
995// Provide the remaining fractional number of seconds in nanosecond precision.
996// This function allows trigger/timing analysis for (astro)particle physics
997// experiments.
998// Note : For additional accuracy see also GetPs().
999
1000 return fJns;
1001}
1002///////////////////////////////////////////////////////////////////////////
1003void AliTimestamp::SetPs(Int_t ps)
1004{
1005// Set the remaining fractional number of nanoseconds in picoseconds.
1006// Notes :
1007// -------
1008// 1) The allowed range for the argument "ps" is [0,999].
1009// Outside that range no action is performed.
1010// 2) The ps fraction can also be entered directly via SetMJD() etc...
1011
1012 if (ps>=0 && ps<=999) fJps=ps;
1013}
1014///////////////////////////////////////////////////////////////////////////
1015Int_t AliTimestamp::GetPs() const
a7dc0627 1016{
1017// Provide remaining fractional number of nanoseconds in picoseconds.
95cfc777 1018// This function allows time of flight analysis for particle physics
a7dc0627 1019// experiments.
1020
1021 return fJps;
1022}
1023///////////////////////////////////////////////////////////////////////////
95cfc777 1024void AliTimestamp::Add(Int_t d,Int_t s,Int_t ns,Int_t ps)
1025{
1026// Add (or subtract) a certain time difference to the current timestamp.
ee26083f 1027// Subtraction can be achieved by entering negative values as input arguments.
95cfc777 1028//
25eefd00 1029// The time difference is entered via the following input arguments :
1030//
95cfc777 1031// d : elapsed number of days
25eefd00 1032// s : (remaining) elapsed number of seconds
1033// ns : (remaining) elapsed number of nanoseconds
1034// ps : (remaining) elapsed number of picoseconds
1035//
1036// The specified d, s, ns and ps values will be used in an additive
1037// way to determine the time difference.
1038// So, specification of d=1, s=100, ns=0, ps=0 will result in the
1039// same time difference addition as d=0, s=24*3600+100, ns=0, ps=0.
1040// However, by making use of the latter the user should take care
1041// of possible integer overflow problems in the input arguments,
1042// which obviously will provide incorrect results.
95cfc777 1043//
1044// Note : ps=0 is the default value.
1045
ee26083f 1046 Int_t days=0;
1047 Int_t secs=0;
1048 Int_t nsec=0;
1049 // Use Get functions to ensure updated Julian parameters.
1050 GetMJD(days,secs,nsec);
1051 Int_t psec=GetPs();
95cfc777 1052
25eefd00 1053 psec+=ps%1000;
1054 nsec+=ps/1000;
1055 while (psec<0)
95cfc777 1056 {
1057 nsec-=1;
1058 psec+=1000;
1059 }
25eefd00 1060 while (psec>999)
95cfc777 1061 {
1062 nsec+=1;
1063 psec-=1000;
1064 }
1065
25eefd00 1066 nsec+=ns%1000000000;
1067 secs+=ns/1000000000;
1068 while (nsec<0)
95cfc777 1069 {
1070 secs-=1;
1071 nsec+=1000000000;
1072 }
25eefd00 1073 while (nsec>999999999)
95cfc777 1074 {
1075 secs+=1;
1076 nsec-=1000000000;
1077 }
1078
25eefd00 1079 secs+=s%(24*3600);
1080 days+=s/(24*3600);
1081 while (secs<0)
95cfc777 1082 {
1083 days-=1;
1084 secs+=24*3600;
1085 }
25eefd00 1086 while (secs>=24*3600)
95cfc777 1087 {
1088 days+=1;
1089 secs-=24*3600;
1090 }
1091
1092 days+=d;
1093
6a7b0c73 1094 SetMJD(days,secs,nsec,psec);
95cfc777 1095}
1096///////////////////////////////////////////////////////////////////////////
ee26083f 1097Int_t AliTimestamp::GetDifference(AliTimestamp* t,Int_t& d,Int_t& s,Int_t& ns,Int_t& ps)
a7dc0627 1098{
1099// Provide the time difference w.r.t the AliTimestamp specified on the input.
1100// This memberfunction supports both very small (i.e. time of flight analysis
1101// for particle physics experiments) and very long (i.e. investigation of
1102// astrophysical phenomena) timescales.
1103//
1104// The time difference is returned via the following output arguments :
1105// d : elapsed number of days
1106// s : remaining elapsed number of seconds
1107// ns : remaining elapsed number of nanoseconds
1108// ps : remaining elapsed number of picoseconds
1109//
95cfc777 1110// Note :
1111// ------
1112// The calculated time difference is the absolute value of the time interval.
1113// This implies that the values of d, s, ns and ps are always positive or zero.
1114//
a7dc0627 1115// The integer return argument indicates whether the AliTimestamp specified
1116// on the input argument occurred earlier (-1), simultaneously (0) or later (1).
1117
ee26083f 1118 if (!t) return 0;
1119
1120 // Ensure updated Julian parameters for this AliTimestamp instance
1121 if (fCalcs != GetSec() || fCalcns != GetNanoSec()) FillJulian();
1122
1123 // Use Get functions to ensure updated Julian parameters.
1124 t->GetMJD(d,s,ns);
1125 ps=t->GetPs();
1126
1127 d-=fMJD;
1128 s-=fJsec;
1129 ns-=fJns;
1130 ps-=fJps;
a7dc0627 1131
1132 if (!d && !s && !ns && !ps) return 0;
1133
1134 Int_t sign=0;
1135
95cfc777 1136 if (d>0) sign=1;
1137 if (d<0) sign=-1;
1138
1139 if (!sign && s>0) sign=1;
1140 if (!sign && s<0) sign=-1;
a7dc0627 1141
1142 if (!sign && ns>0) sign=1;
1143 if (!sign && ns<0) sign=-1;
1144
1145 if (!sign && ps>0) sign=1;
1146 if (!sign && ps<0) sign=-1;
1147
1148 // In case the input stamp was earlier, take the reverse difference
1149 // to simplify the algebra.
1150 if (sign<0)
1151 {
95cfc777 1152 d=-d;
a7dc0627 1153 s=-s;
1154 ns=-ns;
1155 ps=-ps;
1156 }
1157
1158 // Here we always have a positive time difference
95cfc777 1159 // and can now unambiguously correct for other negative values.
a7dc0627 1160 if (ps<0)
1161 {
1162 ns-=1;
1163 ps+=1000;
1164 }
1165
1166 if (ns<0)
1167 {
1168 s-=1;
95cfc777 1169 ns+=1000000000;
a7dc0627 1170 }
1171
95cfc777 1172 if (s<0)
1173 {
1174 d-=1;
1175 s+=24*3600;
1176 }
a7dc0627 1177
1178 return sign;
1179}
1180///////////////////////////////////////////////////////////////////////////
ee26083f 1181Int_t AliTimestamp::GetDifference(AliTimestamp& t,Int_t& d,Int_t& s,Int_t& ns,Int_t& ps)
1182{
1183// Provide the time difference w.r.t the AliTimestamp specified on the input.
1184// This memberfunction supports both very small (i.e. time of flight analysis
1185// for particle physics experiments) and very long (i.e. investigation of
1186// astrophysical phenomena) timescales.
1187//
1188// The time difference is returned via the following output arguments :
1189// d : elapsed number of days
1190// s : remaining elapsed number of seconds
1191// ns : remaining elapsed number of nanoseconds
1192// ps : remaining elapsed number of picoseconds
1193//
1194// Note :
1195// ------
1196// The calculated time difference is the absolute value of the time interval.
1197// This implies that the values of d, s, ns and ps are always positive or zero.
1198//
1199// The integer return argument indicates whether the AliTimestamp specified
1200// on the input argument occurred earlier (-1), simultaneously (0) or later (1).
1201
1202 return GetDifference(&t,d,s,ns,ps);
1203}
1204///////////////////////////////////////////////////////////////////////////
1205Double_t AliTimestamp::GetDifference(AliTimestamp* t,TString u,Int_t mode)
95cfc777 1206{
1207// Provide the time difference w.r.t the AliTimestamp specified on the input
1208// argument in the units as specified by the TString argument.
1209// A positive return value means that the AliTimestamp specified on the input
1210// argument occurred later, whereas a negative return value indicates an
1211// earlier occurence.
1212//
1213// The units may be specified as :
1214// u = "d" ==> Time difference returned as (fractional) day count
1215// "s" ==> Time difference returned as (fractional) second count
1216// "ns" ==> Time difference returned as (fractional) nanosecond count
1217// "ps" ==> Time difference returned as picosecond count
1218//
1219// It may be clear that for a time difference of several days, the picosecond
1220// and even the nanosecond accuracy may be lost.
1221// To cope with this, the "mode" argument has been introduced to allow
1222// timestamp comparison on only the specified units.
1223//
1224// The following operation modes are supported :
1225// mode = 1 : Full time difference is returned in specified units
1226// 2 : Time difference is returned in specified units by
1227// neglecting the elapsed time for the larger units than the
1228// ones specified.
1229// 3 : Time difference is returned in specified units by only
1230// comparing the timestamps on the level of the specified units.
1231//
1232// Example :
1233// ---------
1234// AliTimestamp t1; // Corresponding to days=3, secs=501, ns=31, ps=7
1235// AliTimestamp t2; // Corresponding to days=5, secs=535, ns=12, ps=15
1236//
1237// The statement : Double_t val=t1.GetDifference(t2,....)
1238// would return the following values :
1239// val=(2*24*3600)+34-(19*1e-9)+(8*1e-12) for u="s" and mode=1
1240// val=34-(19*1e-9)+(8*1e-12) for u="s" and mode=2
1241// val=34 for u="s" and mode=3
1242// val=-19 for u="ns" and mode=3
1243//
1244// The default is mode=1.
1245
ee26083f 1246 if (!t || mode<1 || mode>3) return 0;
95cfc777 1247
1248 Double_t dt=0;
1249
ee26083f 1250 // Ensure updated Julian parameters for this AliTimestamp instance
1251 if (fCalcs != GetSec() || fCalcns != GetNanoSec()) FillJulian();
1252
1253 Int_t dd=0;
1254 Int_t ds=0;
1255 Int_t dns=0;
1256 Int_t dps=0;
1257
1258 // Use Get functions to ensure updated Julian parameters.
1259 t->GetMJD(dd,ds,dns);
1260 dps=t->GetPs();
1261
1262 dd-=fMJD;
1263 ds-=fJsec;
1264 dns-=fJns;
1265 dps-=fJps;
95cfc777 1266
1267 // Time difference for the specified units only
1268 if (mode==3)
1269 {
1270 if (u=="d") dt=dd;
1271 if (u=="s") dt=ds;
1272 if (u=="ns") dt=dns;
1273 if (u=="ps") dt=dps;
1274 return dt;
1275 }
1276
1277 // Suppress elapsed time for the larger units than specified
1278 if (mode==2)
1279 {
1280 if (u=="s") dd=0;
1281 if (u=="ns")
1282 {
1283 dd=0;
1284 ds=0;
1285 }
1286 if (u=="ps")
1287 {
1288 dd=0;
1289 ds=0;
1290 dns=0;
1291 }
1292 }
1293
1294 // Compute the time difference as requested
1295 if (u=="s" || u=="d")
1296 {
1297 // The time difference in (fractional) seconds
1298 dt=double(dd*24*3600+ds)+(double(dns)*1e-9)+(double(dps)*1e-12);
1299 if (u=="d") dt=dt/double(24*3600);
1300 }
1301 if (u=="ns") dt=(double(dd*24*3600+ds)*1e9)+double(dns)+(double(dps)*1e-3);
1302 if (u=="ps") dt=(double(dd*24*3600+ds)*1e12)+(double(dns)*1e3)+double(dps);
1303
1304 return dt;
1305}
1306///////////////////////////////////////////////////////////////////////////
ee26083f 1307Double_t AliTimestamp::GetDifference(AliTimestamp& t,TString u,Int_t mode)
1308{
1309// Provide the time difference w.r.t the AliTimestamp specified on the input
1310// argument in the units as specified by the TString argument.
1311// A positive return value means that the AliTimestamp specified on the input
1312// argument occurred later, whereas a negative return value indicates an
1313// earlier occurence.
1314//
1315// The units may be specified as :
1316// u = "d" ==> Time difference returned as (fractional) day count
1317// "s" ==> Time difference returned as (fractional) second count
1318// "ns" ==> Time difference returned as (fractional) nanosecond count
1319// "ps" ==> Time difference returned as picosecond count
1320//
1321// It may be clear that for a time difference of several days, the picosecond
1322// and even the nanosecond accuracy may be lost.
1323// To cope with this, the "mode" argument has been introduced to allow
1324// timestamp comparison on only the specified units.
1325//
1326// The following operation modes are supported :
1327// mode = 1 : Full time difference is returned in specified units
1328// 2 : Time difference is returned in specified units by
1329// neglecting the elapsed time for the larger units than the
1330// ones specified.
1331// 3 : Time difference is returned in specified units by only
1332// comparing the timestamps on the level of the specified units.
1333//
1334// Example :
1335// ---------
1336// AliTimestamp t1; // Corresponding to days=3, secs=501, ns=31, ps=7
1337// AliTimestamp t2; // Corresponding to days=5, secs=535, ns=12, ps=15
1338//
1339// The statement : Double_t val=t1.GetDifference(t2,....)
1340// would return the following values :
1341// val=(2*24*3600)+34-(19*1e-9)+(8*1e-12) for u="s" and mode=1
1342// val=34-(19*1e-9)+(8*1e-12) for u="s" and mode=2
1343// val=34 for u="s" and mode=3
1344// val=-19 for u="ns" and mode=3
1345//
1346// The default is mode=1.
1347
1348 return GetDifference(&t,u,mode);
1349}
1350///////////////////////////////////////////////////////////////////////////
0cfe76b5 1351void AliTimestamp::SetUT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns,Int_t ps)
1352{
1353// Set the AliTimestamp parameters corresponding to the UT date and time
1354// in the Gregorian calendar as specified by the input arguments.
1355// This facility is exact upto picosecond precision and as such is
1356// for scientific observations preferable above the corresponding
1357// Set function(s) of TTimestamp.
1358// The latter has a random spread in the sub-second part, which
1359// might be of use in generating distinguishable timestamps while
1360// still keeping second precision.
1361//
1362// The input arguments represent the following :
1363// y : year in UT (e.g. 1952, 2003 etc...)
1364// m : month in UT (1=jan 2=feb etc...)
1365// d : day in UT (1-31)
1366// hh : elapsed hours in UT (0-23)
1367// mm : elapsed minutes in UT (0-59)
1368// ss : elapsed seconds in UT (0-59)
1369// ns : remaining fractional elapsed second of UT in nanosecond
1370// ps : remaining fractional elapsed nanosecond of UT in picosecond
1371//
1372// Note : ns=0 and ps=0 are the default values.
1373//
1374// This facility first determines the elapsed days, seconds etc...
1375// since the beginning of the specified UT year on bais of the
1376// input arguments. Subsequently it invokes the SetUT memberfunction
1377// for the elapsed timespan.
1378// As such this facility is valid for all AD dates in the Gregorian
1379// calendar with picosecond precision.
1380
1381 Int_t day=GetDayOfYear(d,m,y);
1382 Int_t secs=hh*3600+mm*60+ss;
1383 SetUT(y,day-1,secs,ns,ps);
1384}
1385///////////////////////////////////////////////////////////////////////////
1386void AliTimestamp::SetUT(Int_t y,Int_t d,Int_t s,Int_t ns,Int_t ps)
1387{
1388// Set the AliTimestamp parameters corresponding to the specified elapsed
1389// timespan since the beginning of the new UT year.
1390// This facility is exact upto picosecond precision and as such is
1391// for scientific observations preferable above the corresponding
1392// Set function(s) of TTimestamp.
1393// The latter has a random spread in the sub-second part, which
1394// might be of use in generating distinguishable timestamps while
1395// still keeping second precision.
1396//
1397// The UT year and elapsed time span is entered via the following input arguments :
1398//
1399// y : year in UT (e.g. 1952, 2003 etc...)
1400// d : elapsed number of days
1401// s : (remaining) elapsed number of seconds
1402// ns : (remaining) elapsed number of nanoseconds
1403// ps : (remaining) elapsed number of picoseconds
1404//
1405// The specified d, s, ns and ps values will be used in an additive
1406// way to determine the elapsed timespan.
1407// So, specification of d=1, s=100, ns=0, ps=0 will result in the
1408// same elapsed time span as d=0, s=24*3600+100, ns=0, ps=0.
1409// However, by making use of the latter the user should take care
1410// of possible integer overflow problems in the input arguments,
1411// which obviously will provide incorrect results.
1412//
1413// Note : ns=0 and ps=0 are the default values.
1414//
1415// This facility first sets the (M)JD corresponding to the start (01-jan 00:00:00)
1416// of the specified UT year following the recipe of R.W. Sinnott
1417// Sky & Telescope 82, (aug. 1991) 183.
1418// Subsequently the day and (sub)second parts are added to the AliTimestamp.
1419// As such this facility is valid for all AD dates in the Gregorian calendar.
1420
1421 Double_t jd=GetJD(y,1,1,0,0,0,0);
1422 SetJD(jd);
1423
1424 Int_t mjd,sec,nsec;
1425 GetMJD(mjd,sec,nsec);
1426 SetMJD(mjd,0,0,0);
1427 Add(d,s,ns,ps);
1428}
1429///////////////////////////////////////////////////////////////////////////
a4f7a3a1 1430void AliTimestamp::GetUT(Int_t& hh,Int_t& mm,Int_t& ss,Int_t& ns,Int_t& ps)
1431{
1432// Provide the corrresponding UT as hh:mm:ss:ns:ps.
1433// This facility is based on the MJD, so the TTimeStamp limitations
1434// do not apply here.
1435
1436 Int_t mjd,sec,nsec,psec;
1437
1438 GetMJD(mjd,sec,nsec);
1439 psec=GetPs();
1440
1441 hh=sec/3600;
1442 sec=sec%3600;
1443 mm=sec/60;
1444 ss=sec%60;
1445 ns=nsec;
1446 ps=psec;
1447}
1448///////////////////////////////////////////////////////////////////////////
1449Double_t AliTimestamp::GetUT()
1450{
1451// Provide the corrresponding UT in fractional hours.
1452// This facility is based on the MJD, so the TTimeStamp limitations
1453// do not apply here.
1454
1455 Int_t hh,mm,ss,ns,ps;
1456
1457 GetUT(hh,mm,ss,ns,ps);
1458
1459 Double_t ut=Convert(hh,mm,ss,ns,ps);
1460
1461 return ut;
1462}
1463///////////////////////////////////////////////////////////////////////////
1464void AliTimestamp::GetGST(Int_t& hh,Int_t& mm,Int_t& ss,Int_t& ns,Int_t& ps)
1465{
1466// Provide the corrresponding Greenwich Sideral Time (GST).
1467// The algorithm used is the one described at p. 83 of the book
1468// Astronomy Methods by Hale Bradt.
1469// This facility is based on the MJD, so the TTimeStamp limitations
1470// do not apply here.
1471
1472 Int_t mjd,sec,nsec,psec;
1473
1474 // The current UT based timestamp data
1475 GetMJD(mjd,sec,nsec);
1476 psec=fJps;
1477
1478 // The basis for the daily corrections in units of Julian centuries w.r.t. J2000.
1479 // Note : Epoch J2000 starts at 01-jan-2000 12:00:00 UT.
1480 Double_t tau=(GetJD()-2451545.)/36525.;
1481
1482 // Syncronise sidereal time with current timestamp
1483 AliTimestamp sid;
1484 sid.SetMJD(mjd,sec,nsec,psec);
1485
1486 // Add offset for GST start value defined as 06:41:50.54841 at 01-jan 00:00:00 UT
1487 sec=6*3600+41*60+50;
1488 nsec=548410000;
1489 psec=0;
1490 sid.Add(0,sec,nsec,psec);
1491
1492 // Daily correction for precession and polar motion
1493 Double_t addsec=8640184.812866*tau+0.093104*pow(tau,2)-6.2e-6*pow(tau,3);
1494 sec=int(addsec);
1495 addsec-=double(sec);
1496 nsec=int(addsec*1.e9);
1497 addsec-=double(nsec)*1.e-9;
1498 psec=int(addsec*1.e12);
1499 sid.Add(0,sec,nsec,psec);
1500
1501 sid.GetMJD(mjd,sec,nsec);
1502 psec=sid.GetPs();
1503
1504 hh=sec/3600;
1505 sec=sec%3600;
1506 mm=sec/60;
1507 ss=sec%60;
1508 ns=nsec;
1509 ps=psec;
1510}
1511///////////////////////////////////////////////////////////////////////////
1512Double_t AliTimestamp::GetGST()
1513{
1514// Provide the corrresponding Greenwich Sideral Time (GMST)
1515// in fractional hours.
1516// This facility is based on the MJD, so the TTimeStamp limitations
1517// do not apply here.
1518
1519 Int_t hh,mm,ss,ns,ps;
1520
1521 GetGST(hh,mm,ss,ns,ps);
1522
1523 Double_t gst=Convert(hh,mm,ss,ns,ps);
1524
1525 return gst;
1526}
1527///////////////////////////////////////////////////////////////////////////
1528Double_t AliTimestamp::GetJD(Double_t e,TString mode) const
1529{
1530// Provide the fractional Julian Date from epoch e.
1531// The sort of epoch may be specified via the "mode" parameter.
1532//
1533// mode = "J" ==> Julian epoch
1534// "B" ==> Besselian epoch
1535//
1536// The default value is mode="J".
1537
1538 Double_t jd=0;
1539
1540 if (mode=="J" || mode=="j") jd=(e-2000.0)*365.25+2451545.0;
1541
1542 if (mode=="B" || mode=="b") jd=(e-1900.0)*365.242198781+2415020.31352;
1543
1544 return jd;
1545}
1546///////////////////////////////////////////////////////////////////////////
1547Double_t AliTimestamp::GetMJD(Double_t e,TString mode) const
1548{
1549// Provide the fractional Modified Julian Date from epoch e.
1550// The sort of epoch may be specified via the "mode" parameter.
1551//
1552// mode = "J" ==> Julian epoch
1553// "B" ==> Besselian epoch
1554//
1555// The default value is mode="J".
1556
1557 Double_t mjd=GetJD(e,mode)-2400000.5;
1558
1559 return mjd;
1560}
1561///////////////////////////////////////////////////////////////////////////
1562Double_t AliTimestamp::GetTJD(Double_t e,TString mode) const
1563{
1564// Provide the fractional Truncated Julian Date from epoch e.
1565// The sort of epoch may be specified via the "mode" parameter.
1566//
1567// mode = "J" ==> Julian epoch
1568// "B" ==> Besselian epoch
1569//
1570// The default value is mode="J".
1571
1572 Double_t tjd=GetJD(e,mode)-2440000.5;
1573
1574 return tjd;
1575}
1576///////////////////////////////////////////////////////////////////////////