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