ATLAS Offline Software
Macros | Functions
PerfStats.cxx File Reference
#include <TTree.h>
#include <TFile.h>
#include <TTimeStamp.h>
#include "xAODCore/tools/PerfStats.h"
#include "xAODCore/tools/Utils.h"
#include "xAODCore/tools/IOStats.h"
#include "xAODCore/tools/ReadStats.h"
Include dependency graph for PerfStats.cxx:

Go to the source code of this file.

Macros

#define FWD_CALL(CALL)
 

Functions

 ClassImp (xAOD::PerfStats) namespace xAOD
 

Macro Definition Documentation

◆ FWD_CALL

#define FWD_CALL (   CALL)
Value:
void PerfStats::CALL( TBranch *b, size_t basketNumber ) { \
if( m_otherPerfStats ) m_otherPerfStats->CALL( b, basketNumber ); \
} \
void PerfStats::CALL( size_t bi, size_t basketNumber ) { \
if( m_otherPerfStats ) m_otherPerfStats->CALL( bi, basketNumber ); \
} struct dummyforsemi

Function Documentation

◆ ClassImp()

ClassImp ( xAOD::PerfStats  )

The destructor is a quite important function in this class. it makes sure that the static s_instance variable gets reset, and that all TVirtualPerfStats objects really get deleted.

Everywhere in the code this function should be used to access the one and only PerfStats object in memory.

Returns
A pointer to the PerfStats singleton

The user is supposed to call this function after the initialization of his/her analysis code finished, but before the event processing starts.

Parameters
clearClear the statistics gathered so far

The user is supposed to call this function once his/her analysis code finished with the event processing.

This function does most of the work of the class. It is called every time ROOT does a file I/O operation. The function takes care of registering this operation in its statistics, and checks if a new file was opened since the last I/O operation.

Parameters
fileThe file object that was read from
lenThe number of bytes that were read from the file
startThe time when the read operation started

This function is called by ROOT when it needs to unzip some data from a given inpout file.

Parameters
fileThe file the information was read from
posPosition inside the input file? (Not used.)
startThe time when the unzipping operation started
complenNot sure. (Not used.)
objlenNot sure. (Not used.)

In single process running this function is basically never called. It's only active when running on PROOF, in which case we should not care about the values given to it, but just forward it to TPerfStats. The actual amount of data read for xAOD monitoring is coming in through the FileReadEvent(...) function...

Parameters
numNumber of bytes read in "some operation"

This function is not called with anything meaningful in standalone ROOT analyses, so it just forwards the call to a possible other TVirtualPerfStats object.

Parameters
numNumber of processed events

The function just gets the number of events from the other TVirtualPerfStats object if it exists, otherwise it just returns zero.

Returns
The number of processed events

The constructor needs to do a few things. If there is already another TVirtualPerfStats object defined under gPerfStats, then it stores that pointer in order to be able to forward monitoring information to that object later on. It then overwrites gPerfStats to point to this object.

Note that this is a private function in TVirtualPerfStats, so it is not forwarded to m_otherPerfStats.

Definition at line 16 of file PerfStats.cxx.

18  {
19 
20  // Initialize the static variable(s):
21  PerfStats* PerfStats::s_instance = nullptr;
23 
28  PerfStats::~PerfStats() {
29 
30  lock_t lock (s_mutex);
31  // Since this object can only be deleted by deleting the global
32  // gPerfStats object, make sure that all the objects get deleted
33  // if the user asked for it...
34  s_instance = nullptr;
35  if( m_otherPerfStats ) {
36  delete m_otherPerfStats;
37  }
38  }
39 
45  PerfStats& PerfStats::instance() {
46 
47  lock_t lock (s_mutex);
48  // Construct the object if it is now available at the moment:
49  if( ! s_instance ) {
50  s_instance = new PerfStats();
51  }
52 
53  return *s_instance;
54  }
55 
61  void PerfStats::start( bool clear ) {
62 
63  lock_t lock (s_mutex);
64  // Return right away if we are running already:
65  if( m_running ) return;
66 
67  // Clear the statistics collected so far if required:
68  if( clear ) IOStats::instance().stats().Clear();
69 
70  // Let the user know what we're doing:
71  Info( "start", "Starting performance monitoring" );
72 
73  // Record the starting time:
74  m_startTime = TTimeStamp();
75  // Remember that we are running:
76  m_running = true;
77 
78  return;
79  }
80 
84  void PerfStats::stop() {
85 
86  lock_t lock (s_mutex);
87  // Return right away if we are not running:
88  if( ! m_running ) return;
89 
90  // Calculate the time elapsed from when the analysis started:
91  const ::Double_t elapsed = TTimeStamp().AsDouble() -
92  m_startTime;
93  // Save it:
94  ReadStats& stats = IOStats::instance().stats();
95  stats.setProcessTime( stats.processTime() + elapsed );
96 
97  // Remember that we are stopped:
98  m_running = false;
99 
100  // Let the user know what we've done:
101  Info( "stop", "Performance monitoring stopped after %s",
102  Utils::timeToString( elapsed ).c_str() );
103 
104  return;
105  }
106 
107  void PerfStats::SimpleEvent( EEventType type ) {
108 
109  // Forward the call if possible:
110  if( m_otherPerfStats ) {
111  m_otherPerfStats->SimpleEvent( type );
112  }
113 
114  return;
115  }
116 
117  void PerfStats::PacketEvent( const char* slave, const char* slavename,
118  const char* filename,
119  ::Long64_t eventsprocessed,
120  ::Double_t latency,
121  ::Double_t proctime, ::Double_t cputime,
122  ::Long64_t bytesRead ) {
123 
124  // Forward the call if possible:
125  if( m_otherPerfStats ) {
126  m_otherPerfStats->PacketEvent( slave, slavename, filename,
127  eventsprocessed, latency, proctime,
128  cputime, bytesRead );
129  }
130 
131  return;
132  }
133 
134  void PerfStats::FileEvent( const char* slave, const char* slavename,
135  const char* nodename, const char* filename,
136  ::Bool_t isStart ) {
137 
138  // Forward the call if possible:
139  if( m_otherPerfStats ) {
140  m_otherPerfStats->FileEvent( slave, slavename, nodename, filename,
141  isStart );
142  }
143 
144  return;
145  }
146 
147  void PerfStats::FileOpenEvent( ::TFile* file, const char* filename,
148  ::Double_t start ) {
149 
150  // Forward the call if possible:
151  if( m_otherPerfStats ) {
152  m_otherPerfStats->FileOpenEvent( file, filename, start );
153  }
154 
155  return;
156  }
157 
167  void PerfStats::FileReadEvent( ::TFile* file, ::Int_t len,
168  ::Double_t start ) {
169 
170  // Do the calculation without delay:
171  const ::Double_t tnow = TTimeStamp();
172  const ::Double_t dtime = tnow - start;
173 
174  // Accumulate the reading time statistics:
175  ReadStats& stats = IOStats::instance().stats();
176  stats.setReadTime( stats.readTime() + dtime );
177 
178  // Accumulate the amount of read data:
179  stats.setBytesRead( stats.bytesRead() + len );
180  stats.setFileReads( stats.fileReads() + 1 );
181 
182  // Forward the call if possible:
183  if( m_otherPerfStats ) {
184  m_otherPerfStats->FileReadEvent( file, len, start );
185  }
186 
187  return;
188  }
189 
199  void PerfStats::UnzipEvent( ::TObject* tree, ::Long64_t pos,
200  ::Double_t start, ::Int_t complen,
201  ::Int_t objlen ) {
202 
203  // Do the calculation without delay:
204  const ::Double_t tnow = TTimeStamp();
205  const ::Double_t dtime = tnow - start;
206 
207  // Just accumulate the zipping time statistics:
208  ReadStats& stats = IOStats::instance().stats();
209  stats.setUnzipTime( stats.unzipTime() + dtime );
210 
211  // Get the cache size from the tree:
212  ::TTree* t = dynamic_cast< ::TTree* >( tree );
213  if( ! t ) {
214  Warning( "UnzipEvent", "Couldn't cast object to TTree" );
215  } else {
216  stats.setCacheSize( t->GetCacheSize() );
217  }
218 
219  // Forward the call if possible:
220  if( m_otherPerfStats ) {
221  m_otherPerfStats->UnzipEvent( tree, pos, start, complen, objlen );
222  }
223 
224  return;
225  }
226 
227  void PerfStats::RateEvent( ::Double_t proctime, ::Double_t deltatime,
228  ::Long64_t eventsprocessed,
229  ::Long64_t bytesRead ) {
230 
231  // Forward the call if possible:
232  if( m_otherPerfStats ) {
233  m_otherPerfStats->RateEvent( proctime, deltatime, eventsprocessed,
234  bytesRead );
235  }
236 
237  return;
238  }
239 
248  void PerfStats::SetBytesRead( ::Long64_t num ) {
249 
250  // Forward the call if possible:
251  if( m_otherPerfStats ) {
252  m_otherPerfStats->SetBytesRead( num );
253  }
254 
255  return;
256  }
257 
258  ::Long64_t PerfStats::GetBytesRead() const {
259 
260  // Forward the call if possible:
261  if( m_otherPerfStats ) {
262  return m_otherPerfStats->GetBytesRead();
263  } else {
264  return IOStats::instance().stats().bytesRead();
265  }
266  }
267 
274  void PerfStats::SetNumEvents( ::Long64_t num ) {
275 
276  // Forward the call if possible:
277  if( m_otherPerfStats ) {
278  m_otherPerfStats->SetNumEvents( num );
279  }
280 
281  return;
282  }
283 
290  ::Long64_t PerfStats::GetNumEvents() const {
291 
292  // Forward the call if possible:
293  if( m_otherPerfStats ) {
294  return m_otherPerfStats->GetNumEvents();
295  }
296 
297  return 0;
298  }
299 
300  /* Some methods that are pure virtual in the basaclass and need
301  a definition - forwarding them to the actuall ROOT TPerfStats
302  new in ROOT 6.14
303  */
304  void PerfStats::PrintBasketInfo( Option_t *option ) const {
305  if( m_otherPerfStats ) m_otherPerfStats->PrintBasketInfo( option );
306  }
307 
308  void PerfStats::UpdateBranchIndices( TObjArray *branches ) {
309  if( m_otherPerfStats ) m_otherPerfStats->UpdateBranchIndices( branches );
310  }
311 
312  #define FWD_CALL(CALL) \
313  void PerfStats::CALL( TBranch *b, size_t basketNumber ) { \
314  if( m_otherPerfStats ) m_otherPerfStats->CALL( b, basketNumber ); \
315  } \
316  void PerfStats::CALL( size_t bi, size_t basketNumber ) { \
317  if( m_otherPerfStats ) m_otherPerfStats->CALL( bi, basketNumber ); \
318  } struct dummyforsemi
319 
320  FWD_CALL(SetLoaded);
321  FWD_CALL(SetLoadedMiss);
322  FWD_CALL(SetMissed);
323  FWD_CALL(SetUsed);
324  #undef FWD_CALL
325 
332  PerfStats::PerfStats()
333  : m_otherPerfStats( nullptr ), m_running( false ), m_startTime( 0.0 ),
334  m_tree( nullptr ), m_file( nullptr ), m_treeWarningPrinted( false ) {
335 
336  // locked via instance().
337 
338  // Remember a possible former performance monitoring object:
339  if( gPerfStats && ( gPerfStats != this ) ) {
340  m_otherPerfStats = gPerfStats;
341  Info( "PerfStats",
342  "Will forward calls to former gPerfStats object" );
343  }
344 
345  // This object is now the performance monitoring object:
346  gPerfStats = this;
347  }
348 
349 #if ROOT_VERSION_CODE >= ROOT_VERSION( 6, 23, 2 )
350  void PerfStats::SetFile( TFile* file ) {
354 
355  m_file = file;
356  }
357 #endif // ROOT version
358 
359 } // namespace xAOD
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
tree
TChain * tree
Definition: tile_monitor.h:30
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
trigbs_dumpHLTContentInBS.stats
stats
Definition: trigbs_dumpHLTContentInBS.py:91
ZDCMsg::Info
@ Info
Definition: ZDCMsg.h:20
FPEAudit::lock_t
std::lock_guard< std::mutex > lock_t
Definition: FPEAuditor.cxx:44
CALL
#define CALL(x, y)
Definition: TH1D_LW.cxx:23
m_file
std::unique_ptr< TFile > m_file
description: this is a custom writer for the old-school drivers that don't use an actual writer
Definition: OutputStreamData.cxx:52
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
runLayerRecalibration.branches
list branches
Definition: runLayerRecalibration.py:98
file
TFile * file
Definition: tile_monitor.h:29
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
FPEAudit::s_mutex
std::mutex s_mutex
Definition: FPEAuditor.cxx:43
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
xAOD::Utils::timeToString
std::string timeToString(::Double_t secs)
Function creating a human-readable elapsed time printout.
Definition: Event/xAOD/xAODCore/Root/Utils.cxx:99
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
FWD_CALL
#define FWD_CALL(CALL)