Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Measurement.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id$
2// Author: Kyle Cranmer, George Lewis
3/*************************************************************************
4 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11/** \class RooStats::HistFactory::Measurement
12 * \ingroup HistFactory
13The RooStats::HistFactory::Measurement class can be used to construct a model
14by combining multiple RooStats::HistFactory::Channel objects. It also allows
15to set some general properties like the integrated luminosity, its relative
16uncertainty or the functional form of constraints on nuisance parameters.
17*/
18
19
22
23#include "HFMsgService.h"
24
25#include <TFile.h>
26#include <TSystem.h>
27#include <TTimeStamp.h>
28
29#include <ctime>
30#include <iostream>
31#include <algorithm>
32#include <sys/stat.h>
33
34using std::ofstream;
35
36
37/// Standard constructor
39 : fLumi(1.0), fLumiRelErr(.10), fBinLow(0), fBinHigh(1)
40{
41
42}
43
44/*
45RooStats::HistFactory::Measurement::Measurement(const Measurement& other) :
46 POI( other.POI ), Lumi( other.Lumi ), LumiRelErr( other.LumiRelErr ),
47 BinLow( other.BinLow ), BinHigh( other.BinHigh ), ExportOnly( other.ExportOnly ),
48 channels( other.channels ), OutputFilePrefix( other.outputFilePrefix ),
49 constantParams( other.constantParams ), { ; }
50*/
51
52/// Standard constructor specifying name and title of measurement
53RooStats::HistFactory::Measurement::Measurement(const char *Name, const char *Title)
54 : TNamed(Name, Title), fLumi(1.0), fLumiRelErr(.10), fBinLow(0), fBinHigh(1)
55{
56
57}
58
59
60/// Set a parameter in the model to be constant.
61/// the parameter does not have to exist yet, the information will be used when
62/// the model is actually created.
63///
64/// Also checks if the parameter is already set constant.
65/// We don't need to set it constant twice,
66/// and we issue a warning in case this is a hint
67/// of a possible bug
69{
70
71
72 if( std::find(fConstantParams.begin(), fConstantParams.end(), param) != fConstantParams.end() ) {
73 cxcoutWHF << "Warning: Setting parameter: " << param
74 << " to constant, but it is already listed as constant. "
75 << "You may ignore this warning."
76 << std::endl;
77 return;
78 }
79
80 fConstantParams.push_back( param );
81
82}
83
84
85/// Set parameter of the model to given value
86void RooStats::HistFactory::Measurement::SetParamValue( const std::string& param, double value )
87{
88 // Check if this parameter is already set to a value
89 // If so, issue a warning
90 // (Not sure if we want to throw an exception here, or
91 // issue a warning and move along. Thoughts?)
92 if( fParamValues.find(param) != fParamValues.end() ) {
93 cxcoutWHF << "Warning: Chainging parameter: " << param
94 << " value from: " << fParamValues[param]
95 << " to: " << value
96 << std::endl;
97 }
98
99 // Store the parameter and its value
100 cxcoutIHF << "Setting parameter: " << param
101 << " value to " << value
102 << std::endl;
103
104 fParamValues[param] = value;
105
106}
107
108
109/// Add a preprocessed function by giving the function a name,
110/// a functional expression, and a string with a bracketed list of dependencies (eg "SigXsecOverSM[0,3]")
111void RooStats::HistFactory::Measurement::AddPreprocessFunction( std::string name, std::string expression, std::string dependencies )
112{
113
114
115 PreprocessFunction func(name, expression, dependencies);
116 AddFunctionObject(func);
117
118}
119
120/// Returns a list of defined preprocess function expressions
122{
123
124
125 std::vector<std::string> PreprocessFunctionExpressions;
126 for( unsigned int i = 0; i < fFunctionObjects.size(); ++i ) {
127 std::string expression = fFunctionObjects.at(i).GetCommand();
128 PreprocessFunctionExpressions.push_back( expression );
129 }
131}
132
133/// Set constraint term for given systematic to Gamma distribution
135{
136 fGammaSyst[syst] = uncert;
137}
138
139/// Set constraint term for given systematic to LogNormal distribution
141{
142 fLogNormSyst[syst] = uncert;
143}
144
145/// Set constraint term for given systematic to uniform distribution
147{
148 fUniformSyst[syst] = 1.0; // Is this parameter simply a dummy?
149}
150
151/// Define given systematics to have no external constraint
153{
154 fNoSyst[syst] = 1.0; // dummy value
155}
156
157/// Check if the given channel is part of this measurement
159{
160
161
162 for( unsigned int i = 0; i < fChannels.size(); ++i ) {
163
164 Channel& chan = fChannels.at(i);
165 if( chan.GetName() == ChanName ) {
166 return true;
167 }
168
169 }
170
171 return false;
172
173}
174
175
176/// Get channel with given name from this measurement
177/// throws an exception in case the channel is not found
179{
180 for( unsigned int i = 0; i < fChannels.size(); ++i ) {
181
182 Channel& chan = fChannels.at(i);
183 if( chan.GetName() == ChanName ) {
184 return chan;
185 }
186
187 }
188
189 // If we get here, we didn't find the channel
190
191 cxcoutEHF << "Error: Did not find channel: " << ChanName
192 << " in measurement: " << GetName() << std::endl;
193 throw hf_exc();
194
195 // No Need to return after throwing exception
196 // return RooStats::HistFactory::BadChannel;
197
198
199}
200
201/*
202 void RooStats::HistFactory::Measurement::Print( Option_t* option ) const {
203 RooStats::HistFactory::Measurement::Print( std::cout );
204 return;
205 }
206*/
207
208/// Print information about measurement object in tree-like structure to given stream
210{
211
212
213 stream << "Measurement Name: " << GetName()
214 << "\t OutputFilePrefix: " << fOutputFilePrefix
215 << "\t POI: ";
216 for(unsigned int i = 0; i < fPOI.size(); ++i) {
217 stream << fPOI.at(i);
218 }
219 stream << "\t Lumi: " << fLumi
220 << "\t LumiRelErr: " << fLumiRelErr
221 << "\t BinLow: " << fBinLow
222 << "\t BinHigh: " << fBinHigh
223 << "\t ExportOnly: " << fExportOnly
224 << std::endl;
225
226
227 if( !fConstantParams.empty() ) {
228 stream << "Constant Params: ";
229 for( unsigned int i = 0; i < fConstantParams.size(); ++i ) {
230 stream << " " << fConstantParams.at(i);
231 }
232 stream << std::endl;
233 }
234
235 if( !fFunctionObjects.empty() ) {
236 stream << "Preprocess Functions: ";
237 for( unsigned int i = 0; i < fFunctionObjects.size(); ++i ) {
238 stream << " " << fFunctionObjects.at(i).GetCommand();
239 }
240 stream << std::endl;
241 }
242
243 if( !fChannels.empty() ) {
244 stream << "Channels:" << std::endl;
245 for( unsigned int i = 0; i < fChannels.size(); ++i ) {
246 fChannels.at(i).Print( stream );
247 }
248 }
249
250 cxcoutIHF << "End Measurement: " << GetName() << std::endl;
251
252}
253
254
255/// Create XML files for this measurement in the given directory.
256/// XML files can be configured with a different output prefix
257/// Create an XML file for this measurement
258/// First, create the XML driver
259/// Then, create xml files for each channel
261{
262 // First, check that the directory exists:
263 auto testExists = [](const std::string& theDirectory) {
264 void* dir = gSystem->OpenDirectory(theDirectory.c_str());
265 bool exists = dir != nullptr;
266 if (exists)
268
269 return exists;
270 };
271
272 if ( !directory.empty() && !testExists(directory) ) {
273 int success = gSystem->MakeDirectory(directory.c_str() );
274 if( success != 0 ) {
275 cxcoutEHF << "Error: Failed to make directory: " << directory << std::endl;
276 throw hf_exc();
277 }
278 }
279
280 // If supplied new Prefix, use that one:
281
282 cxcoutPHF << "Printing XML Files for measurement: " << GetName() << std::endl;
283
284 std::string XMLName = std::string(GetName()) + ".xml";
285 if( !directory.empty() ) XMLName = directory + "/" + XMLName;
286
287 ofstream xml( XMLName.c_str() );
288
289 if( ! xml.is_open() ) {
290 cxcoutEHF << "Error opening xml file: " << XMLName << std::endl;
291 throw hf_exc();
292 }
293
294
295 // Add the time
296 xml << "<!--" << std::endl;
297 xml << "This xml file created automatically on: " << std::endl;
298/*
299 time_t t = time(0); // get time now
300 struct tm * now = localtime( &t );
301 xml << (now->tm_year + 1900) << '-'
302 << (now->tm_mon + 1) << '-'
303 << now->tm_mday
304 << std::endl;
305*/
306 // LM: use TTimeStamp
307 TTimeStamp t;
308 UInt_t year = 0;
309 UInt_t month = 0;
310 UInt_t day = 0;
311 t.GetDate(true, 0, &year, &month, &day);
312 xml << year << '-'
313 << month << '-'
314 << day
315 << std::endl;
316
317 xml << "-->" << std::endl;
318
319 // Add the doctype
320 xml << "<!DOCTYPE Combination SYSTEM 'HistFactorySchema.dtd'>" << std::endl << std::endl;
321
322 // Add the combination name
323 if (newOutputPrefix.empty() ) newOutputPrefix = fOutputFilePrefix;
324 xml << "<Combination OutputFilePrefix=\"" << newOutputPrefix /*OutputFilePrefix*/ << "\" >" << std::endl << std::endl;
325
326 // Add the Preprocessed Functions
327 for( unsigned int i = 0; i < fFunctionObjects.size(); ++i ) {
328 RooStats::HistFactory::PreprocessFunction func = fFunctionObjects.at(i);
329 func.PrintXML(xml);
330 /*
331 xml << "<Function Name=\"" << func.GetName() << "\" "
332 << "Expression=\"" << func.GetExpression() << "\" "
333 << "Dependents=\"" << func.GetDependents() << "\" "
334 << "/>" << std::endl;
335 */
336 }
337
338 xml << std::endl;
339
340 // Add the list of channels
341 for( unsigned int i = 0; i < fChannels.size(); ++i ) {
342 xml << " <Input>" << "./";
343 if (!directory.empty() ) xml << directory << "/";
344 xml << GetName() << "_" << fChannels.at(i).GetName() << ".xml" << "</Input>" << std::endl;
345 }
346
347 xml << std::endl;
348
349 // Open the Measurement, Set Lumi
350 xml << " <Measurement Name=\"" << GetName() << "\" "
351 << "Lumi=\"" << fLumi << "\" "
352 << "LumiRelErr=\"" << fLumiRelErr << "\" "
353 //<< "BinLow=\"" << fBinLow << "\" "
354 // << "BinHigh=\"" << fBinHigh << "\" "
355 << "ExportOnly=\"" << (fExportOnly ? std::string("True") : std::string("False")) << "\" "
356 << " >" << std::endl;
357
358
359 // Set the POI
360 xml << " <POI>" ;
361 for(unsigned int i = 0; i < fPOI.size(); ++i) {
362 if(i==0) xml << fPOI.at(i);
363 else xml << " " << fPOI.at(i);
364 }
365 xml << "</POI> " << std::endl;
366
367 // Set the Constant Parameters
368 if(!fConstantParams.empty()) {
369 xml << " <ParamSetting Const=\"True\">";
370 for( unsigned int i = 0; i < fConstantParams.size(); ++i ) {
371 if (i==0) xml << fConstantParams.at(i);
372 else xml << " " << fConstantParams.at(i);
373 }
374 xml << "</ParamSetting>" << std::endl;
375 }
376
377 // Set the Parameters with new Constraint Terms
378 std::map<std::string, double>::iterator ConstrItr;
379
380 // Gamma
381 for( ConstrItr = fGammaSyst.begin(); ConstrItr != fGammaSyst.end(); ++ConstrItr ) {
382 xml << "<ConstraintTerm Type=\"Gamma\" RelativeUncertainty=\""
383 << ConstrItr->second << "\">" << ConstrItr->first
384 << "</ConstraintTerm>" << std::endl;
385 }
386 // Uniform
387 for( ConstrItr = fUniformSyst.begin(); ConstrItr != fUniformSyst.end(); ++ConstrItr ) {
388 xml << "<ConstraintTerm Type=\"Uniform\" RelativeUncertainty=\""
389 << ConstrItr->second << "\">" << ConstrItr->first
390 << "</ConstraintTerm>" << std::endl;
391 }
392 // LogNormal
393 for( ConstrItr = fLogNormSyst.begin(); ConstrItr != fLogNormSyst.end(); ++ConstrItr ) {
394 xml << "<ConstraintTerm Type=\"LogNormal\" RelativeUncertainty=\""
395 << ConstrItr->second << "\">" << ConstrItr->first
396 << "</ConstraintTerm>" << std::endl;
397 }
398 // NoSyst
399 for( ConstrItr = fNoSyst.begin(); ConstrItr != fNoSyst.end(); ++ConstrItr ) {
400 xml << "<ConstraintTerm Type=\"NoSyst\" RelativeUncertainty=\""
401 << ConstrItr->second << "\">" << ConstrItr->first
402 << "</ConstraintTerm>" << std::endl;
403 }
404
405
406 // Close the Measurement
407 xml << " </Measurement> " << std::endl << std::endl;
408
409 // Close the combination
410 xml << "</Combination>" << std::endl;
411
412 xml.close();
413
414 // Now, make the xml files
415 // for the individual channels:
416
417 std::string prefix = std::string(GetName()) + "_";
418
419 for( unsigned int i = 0; i < fChannels.size(); ++i ) {
420 fChannels.at(i).PrintXML( directory, prefix );
421 }
422
423
424 cxcoutPHF << "Finished printing XML files" << std::endl;
425
426}
427
428
429/// A measurement, once fully configured, can be saved into a ROOT
430/// file. This will persitify the Measurement object, along with any
431/// channels and samples that have been added to it. It can then be
432/// loaded, potentially modified, and used to create new models.
433///
434/// Write every histogram to the file.
435/// Edit the measurement to point to this file
436/// and to point to each histogram in this file
437/// Then write the measurement itself.
439{
440
441 // Create a temporary measurement
442 // (This is the one that is actually written)
444
445 std::string OutputFileName = file->GetName();
446
447 // Collect all histograms from file:
448 // HistCollector collector;
449
450
451 for( unsigned int chanItr = 0; chanItr < outMeas.fChannels.size(); ++chanItr ) {
452
453 // Go to the main directory
454 // in the file
455 file->cd();
456 file->Flush();
457
458 // Get the name of the channel:
459 RooStats::HistFactory::Channel& channel = outMeas.fChannels.at( chanItr );
460 std::string chanName = channel.GetName();
461
462
463 if( ! channel.CheckHistograms() ) {
464 cxcoutEHF << "Measurement.writeToFile(): Channel: " << chanName
465 << " has uninitialized histogram pointers" << std::endl;
466 throw hf_exc();
467 return;
468 }
469
470 // Get and cache the histograms for this channel:
471 //collector.CollectHistograms( channel );
472 // Do I need this...?
473 // channel.CollectHistograms();
474
475 // Make a directory to store the histograms
476 // for this channel
477
478 TDirectory* chanDir = file->mkdir( (chanName + "_hists").c_str() );
479 if( chanDir == nullptr ) {
480 cxcoutEHF << "Error: Cannot create channel " << (chanName + "_hists")
481 << std::endl;
482 throw hf_exc();
483 }
484 chanDir->cd();
485
486 // Save the data:
487 TDirectory* dataDir = chanDir->mkdir( "data" );
488 if( dataDir == nullptr ) {
489 cxcoutEHF << "Error: Cannot make directory " << chanDir << std::endl;
490 throw hf_exc();
491 }
492 dataDir->cd();
493
494 channel.fData.writeToFile( OutputFileName, GetDirPath(dataDir) );
495
496 /*
497 // Write the data file to this directory
498 TH1* hData = channel.data.GetHisto();
499 hData->Write();
500
501 // Set the location of the data
502 // in the output measurement
503
504 channel.data.InputFile = OutputFileName;
505 channel.data.HistoName = hData->GetName();
506 channel.data.HistoPath = GetDirPath( dataDir );
507 */
508
509 // Loop over samples:
510
511 for( unsigned int sampItr = 0; sampItr < channel.GetSamples().size(); ++sampItr ) {
512
514 std::string sampName = sample.GetName();
515
516 cxcoutPHF << "Writing sample: " << sampName << std::endl;
517
518 file->cd();
519 chanDir->cd();
520 TDirectory* sampleDir = chanDir->mkdir( sampName.c_str() );
521 if( sampleDir == nullptr ) {
522 cxcoutEHF << "Error: Directory " << sampName << " not created properly" << std::endl;
523 throw hf_exc();
524 }
525 std::string sampleDirPath = GetDirPath( sampleDir );
526
527 if( ! sampleDir ) {
528 cxcoutEHF << "Error making directory: " << sampName
529 << " in directory: " << chanName
530 << std::endl;
531 throw hf_exc();
532 }
533
534 // Write the data file to this directory
535 sampleDir->cd();
536
537 sample.writeToFile( OutputFileName, sampleDirPath );
538 /*
539 TH1* hSample = sample.GetHisto();
540 if( ! hSample ) {
541 std::cout << "Error getting histogram for sample: "
542 << sampName << std::endl;
543 throw -1;
544 }
545 sampleDir->cd();
546 hSample->Write();
547
548 sample.InputFile = OutputFileName;
549 sample.HistoName = hSample->GetName();
550 sample.HistoPath = sampleDirPath;
551 */
552
553 // Write the histograms associated with
554 // systematics
555
556 /* THIS IS WHAT I"M COMMENTING
557 sample.GetStatError().writeToFile( OutputFileName, sampleDirPath );
558
559 // Must write all systematics that contain internal histograms
560 // (This is not all systematics)
561
562 for( unsigned int i = 0; i < sample.GetHistoSysList().size(); ++i ) {
563 sample.GetHistoSysList().at(i).writeToFile( OutputFileName, sampleDirPath );
564 }
565 for( unsigned int i = 0; i < sample.GetHistoFactorList().size(); ++i ) {
566 sample.GetHistoFactorList().at(i).writeToFile( OutputFileName, sampleDirPath );
567 }
568 for( unsigned int i = 0; i < sample.GetShapeSysList().size(); ++i ) {
569 sample.GetShapeSysList().at(i).writeToFile( OutputFileName, sampleDirPath );
570 }
571 END COMMENT */
572 /*
573 sample.statError.writeToFile( OutputFileName, sampleDirPath );
574
575 // Now, get the Stat config histograms
576 if( sample.statError.HistoName != "" ) {
577 TH1* hStatError = sample.statError.GetErrorHist();
578 if( ! hStatError ) {
579 std::cout << "Error getting stat error histogram for sample: "
580 << sampName << std::endl;
581 throw -1;
582 }
583 hStatError->Write();
584
585 sample.statError.InputFile = OutputFileName;
586 sample.statError.HistoName = hStatError->GetName();
587 sample.statError.HistoPath = sampleDirPath;
588
589 }
590 */
591
592 }
593
594 }
595
596
597 // Finally, write the measurement itself:
598
599 cxcoutPHF << "Saved all histograms" << std::endl;
600
601 file->cd();
602 outMeas.Write();
603
604 cxcoutPHF << "Saved Measurement" << std::endl;
605
606}
607
608/// Return the directory's path,
609/// stripped of unnecessary prefixes
611{
612
613
614 std::string path = dir->GetPath();
615
616 if( path.find(':') != std::string::npos ) {
617 size_t index = path.find(':');
618 path.replace( 0, index+1, "" );
619 }
620
621 path = path + "/";
622
623 return path;
624
625 /*
626 if( path.find(":") != std::string::npos ) {
627 size_t index = path.find(":");
628 SampleName.replace( 0, index, "" );
629 }
630
631 // Remove the file:
632 */
633
634}
635
636
637/// The most common way to add histograms to channels is to have them
638/// stored in ROOT files and to give HistFactory the location of these
639/// files. This means providing the path to the ROOT file and the path
640/// and name of the histogram within that file. When providing these
641/// in a script, HistFactory doesn't load the histogram from the file
642/// right away. Instead, once all such histograms have been supplied,
643/// one should run this method to open all ROOT files and to copy and
644/// save all necessary histograms.
646
647
648 for( unsigned int chanItr = 0; chanItr < fChannels.size(); ++chanItr) {
649
651
652 chan.CollectHistograms();
653
654 }
655
656}
657
658
659
#define cxcoutPHF
#define cxcoutIHF
#define cxcoutWHF
#define cxcoutEHF
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:110
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
const_iterator begin() const
const_iterator end() const
This class encapsulates all information for the statistical interpretation of one experiment.
Definition Channel.h:30
HistFactory::Data fData
Definition Channel.h:91
std::vector< RooStats::HistFactory::Sample > & GetSamples()
get vector of samples for this channel
Definition Channel.h:76
std::string GetName() const
get name of channel
Definition Channel.h:42
void writeToFile(std::string FileName, std::string DirName)
Definition Data.cxx:44
The RooStats::HistFactory::Measurement class can be used to construct a model by combining multiple R...
Definition Measurement.h:31
void writeToFile(TFile *file)
A measurement, once fully configured, can be saved into a ROOT file.
void AddGammaSyst(std::string syst, double uncert)
Set constraint term for given systematic to Gamma distribution.
std::string GetDirPath(TDirectory *dir)
Return the directory's path, stripped of unnecessary prefixes.
void AddLogNormSyst(std::string syst, double uncert)
Set constraint term for given systematic to LogNormal distribution.
void PrintXML(std::string Directory="", std::string NewOutputPrefix="")
Print to a stream.
RooStats::HistFactory::Channel & GetChannel(std::string)
Get channel with given name from this measurement throws an exception in case the channel is not foun...
void SetParamValue(const std::string &param, double value)
Set a parameter to a specific value (And optionally fix it)
void CollectHistograms()
The most common way to add histograms to channels is to have them stored in ROOT files and to give Hi...
bool HasChannel(std::string)
Check if the given channel is part of this measurement.
void AddUniformSyst(std::string syst)
Set constraint term for given systematic to uniform distribution.
void PrintTree(std::ostream &=std::cout)
Print information about measurement object in tree-like structure to given stream.
Measurement()
Standard constructor.
void AddNoSyst(std::string syst)
Define given systematics to have no external constraint.
void AddConstantParam(const std::string &param)
Add a parameter to be set as constant (Similar to ParamSetting method below)
void AddPreprocessFunction(std::string name, std::string expression, std::string dependencies)
Add a preprocessed function by giving the function a name, a functional expression,...
std::vector< std::string > GetPreprocessFunctions() const
Returns a list of defined preprocess function expressions.
Bool_t cd() override
Change current directory to "this" directory.
TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE) override
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
Describe directory structure in memory.
Definition TDirectory.h:45
virtual const char * GetPath() const
Returns the full path of the directory.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:131
virtual void Flush()
Synchronize a file's in-memory and on-disk states.
Definition TFile.cxx:1146
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual int MakeDirectory(const char *name)
Make a directory.
Definition TSystem.cxx:827
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition TTimeStamp.h:45
UInt_t GetDate(Bool_t inUTC=kTRUE, Int_t secOffset=0, UInt_t *year=nullptr, UInt_t *month=nullptr, UInt_t *day=nullptr) const
Return date in form of 19971224 (i.e.