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