ATLAS Offline Software
Init.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2 
3 // System include(s):
4 #include <atomic>
5 #include <iostream>
6 #include <iomanip>
7 #include <cstring>
8 #include <string>
9 #include <cstdlib>
10 #include <sstream>
11 
12 // ROOT include(s):
13 #include <TApplication.h>
14 #include <TClass.h>
15 #include <TError.h>
16 #include <TSystem.h>
17 
18 // Local include(s):
20 #include "xAODRootAccess/Init.h"
21 
22 namespace xAOD {
23 
25  void ErrorHandler ATLAS_NOT_THREAD_SAFE ( Int_t level, Bool_t abort, const char* location,
26  const char* message );
27 
29  static std::atomic<size_t> sMessageSourceWidth = 25;
30 
31  StatusCode Init( const char* appname ) {
32 
33  return Init( appname, 0, 0 );
34  }
35 
36  StatusCode Init( const char* appname, int* argc, char** argv ) {
37 
38  static std::atomic_flag sInitialised ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT;
39 
40  // Check if we need to do anything:
41  if( ! sInitialised.test_and_set() ) {
42 
43  // Set up our own error handler function:
44  ::SetErrorHandler( ErrorHandler );
45 
46  // Create an application. This is needed to ensure the auto-loading
47  // of the xAOD dictionaries.
48  TApplication* app ATLAS_THREAD_SAFE = gApplication; // suppress checker warning (protected above)
49  if( ! app ) {
50  if( argc && argv ) {
51  [[maybe_unused]]
52  static ::TApplication sApplication( appname, argc, argv );
53  } else {
54  ::TApplication::CreateApplication();
55  }
56  }
57 
58  // Load the libraries in a carefully selected order.
59  // This is a temporary work-around (26 Oct 20) until the current
60  // xAOD dictionary issues are worked out.
61  for (const char *name : {
62  "xAOD::TruthParticle_v1",
63  "xAOD::MuonRoI_v1",
64  "xAOD::CaloCluster_v1",
65  "xAOD::TrackParticle_v1",
66  "xAOD::Electron_v1",
67  "xAOD::Muon_v1",
68  "xAOD::Jet_v1",
69  "xAOD::TauJet_v1",
70  "xAOD::PFO_v1",
71  "xAOD::TrigElectron_v1",
72  "xAOD::L2CombinedMuon_v1",
73  "xAOD::Particle_v1"}) {
74  // silently ignore missing classes, because this gets used in
75  // all projects, and not all projects contain all xAOD classes
76  static constexpr Bool_t LOAD = kTRUE;
77  static constexpr Bool_t SILENT = kTRUE;
78  TClass::GetClass( name, LOAD, SILENT );
79  }
80 
81  // Let the user know what happened:
82  ::Info( appname, "Environment initialised for data access" );
83  }
84 
85  // Return gracefully:
86  return StatusCode::SUCCESS;
87  }
88 
89  void SetMessageSourceWidth( size_t value ) {
90 
91  sMessageSourceWidth = value;
92  return;
93  }
94 
105  void ErrorHandler ATLAS_NOT_THREAD_SAFE ( Int_t level, Bool_t abort, const char* location,
106  const char* message ) {
107 
108  // Check if we need to print anything for this level:
109  if( level < gErrorIgnoreLevel ) {
110  return;
111  }
112 
113  // Source of the missing dictionary warnings:
114  static const char* const DICT_WARNING_SOURCE = "TClass::Init";
115 
116  // Filter out warnings about missing dictionaries. As these are relatively
117  // common. In case a problem occurs because of a missing dictionary, some
118  // other piece of code will complain anyway.
119  if( ( level == kWarning ) &&
120  ( ! strcmp( location, DICT_WARNING_SOURCE ) ) ) {
121  return;
122  }
123 
124  // Construct a string version of the message's level:
125  const char* msgLevel = 0;
126  if( level >= kFatal ) {
127  msgLevel = "FATAL ";
128  } else if( level >= kError ) {
129  msgLevel = "ERROR ";
130  } else if( level >= kWarning ) {
131  msgLevel = "WARNING";
132  } else {
133  msgLevel = "INFO ";
134  }
135 
136  // Make sure that the message's source/location is not longer than a
137  // pre-set maximum value:
138  std::string source( location );
139  if( source.size() > sMessageSourceWidth ) {
140  source.resize( sMessageSourceWidth - 3 );
141  source += "...";
142  }
143 
144  // Print the message to stdout/std::cout:
145  std::ostringstream output;
146  output << std::setiosflags( std::ios::left )
147  << std::setw( sMessageSourceWidth ) << source << " " << msgLevel
148  << " " << message;
149  std::cout << output.str() << std::endl;
150 
151  // If we don't need to abort, return now:
152  if( ! abort ) {
153  return;
154  }
155 
156  // Abort with a stack trace if possible:
157  std::cout << std::endl << "Aborting..." << std::endl;
158  if( gSystem ) {
159  gSystem->StackTrace();
160  gSystem->Abort();
161  } else {
162  std::abort();
163  }
164 
165  return;
166  }
167 
168 } // namespace xAOD
xAOD::name
name
Definition: TriggerMenuJson_v1.cxx:29
athena.value
value
Definition: athena.py:122
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
ReweightUtils.message
message
Definition: ReweightUtils.py:15
xAOD::SetMessageSourceWidth
void SetMessageSourceWidth(size_t value)
Set the width of the source strings for the printed messages.
Definition: Init.cxx:89
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
xAOD::ATLAS_NOT_THREAD_SAFE
void ErrorHandler ATLAS_NOT_THREAD_SAFE(Int_t level, Bool_t abort, const char *location, const char *message)
Function filtering the warnings coming from ROOT.
Definition: Init.cxx:105
Analysis::kError
@ kError
Definition: CalibrationDataVariables.h:60
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
python.sizes.location
string location
Definition: sizes.py:11
Init.h
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
merge.output
output
Definition: merge.py:17
gErrorIgnoreLevel
int gErrorIgnoreLevel
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
checker_macros.h
Define macros for attributes used to control the static checker.
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31