ATLAS Offline Software
Tools.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 #include "TopAnalysis/Tools.h"
6 
9 
10 #include "TopEvent/Event.h"
11 #include "TopEvent/EventTools.h"
12 
14 
15 #include <cmath>
16 #include <cstdlib>
17 #include <fstream>
18 #include <iostream>
19 #include <memory>
20 #include <sstream>
21 #include <utility>
22 
23 #include "TTree.h"
24 #include "TFile.h"
25 #include "TSystem.h"
26 #include "TROOT.h"
27 
28 #include "xAODRootAccess/Init.h"
29 //#include "xAODRootAccess/LoadDictionaries.h"
30 
33 
37 
38 #ifndef ROOTCORE
40 #endif
41 
43 using namespace TopAnalysis;
44 
45 namespace top {
46  void xAODInit(bool failOnUnchecked) {
47  if (!xAOD::Init()) {
48  throw std::runtime_error("Failed xAOD::Init - no idea what to do, exiting");
49  }
50  //if (xAOD::LoadDictionaries().isFailure()) {
51  // ATH_MSG_WARNING("Failiure in xAOD::LoadDictionaries(). The job will "
52  // "likely not run correctly.");
53  //}
54 
55  //fail on unchecked error codes
56  if (failOnUnchecked) {
57  StatusCode::enableFailure();
59  }
60  }
61 
62  std::string getDerivationStream(TFile* inputFile) {
63  TTree* metaData = dynamic_cast<TTree*> (inputFile->Get("MetaData"));
64 
65  if (metaData) {
66  metaData->LoadTree(0);
67 
68  TObjArray* ar = metaData->GetListOfBranches();
69  for (int i = 0; i < ar->GetEntries(); ++i) {
70  TBranch* b = (TBranch*) ar->At(i);
71  std::string name = std::string(b->GetName());
72  // Find a variable name with Stream, then split off from DAOD
73  // If we only need TOPQX, we just find "_", add 1 and substring from there instead
74  if (name.find("Stream") != std::string::npos) {
75  auto cursor = name.find('_');
76  std::string stream = name.substr(cursor + 1);
77  return stream;
78  }
79  }
80  } else {
81  throw std::runtime_error("getDerivationStream: MetaData tree"
82  " missing from input file.");
83  }
84 
85  // If we don't already return, something unexpected has happened and we need to fix it!
86  throw std::runtime_error("Cannot determine the derivation stream. Please report.");
87  }
88 
89  void parseCutBookkeepers(xAOD::TEvent& xaodEvent, const std::size_t size,
90  std::vector<std::string> &names, std::vector<float>& sumW) {
91 
92  // workaround for PMGTruthWeightTool returning ZERO weights, when sample has ONLY ONE weight...
93  const std::size_t modifiedSize = (size == 0) ? 1 : size;
94 
95  std::vector<int> maxCycle;
96 
97  for (std::size_t icbk = 0; icbk < modifiedSize; ++icbk) {
98  const std::string cbkName = (icbk == 0) ? "CutBookkeepers" : "CutBookkeepers_weight_" + std::to_string(icbk);
99  const xAOD::CutBookkeeperContainer* cutBookKeepers = nullptr;
100  top::check(xaodEvent.retrieveMetaInput(cutBookKeepers, cbkName), "Cannot retrieve CutBookkeepers: " + cbkName);
101 
102  for (const xAOD::CutBookkeeper *cbk : *cutBookKeepers) {
103  // skip RDO and ESD numbers, which are nonsense; and
104  // skip the derivation number, which is the one after skimming
105  // we want the primary xAOD numbers
106  if ((cbk->inputStream() != "StreamAOD"))
107  continue;
108  if (cbk->name() != "AllExecutedEvents") continue;
109  const std::string name = cbk->name() + "_weight_" + std::to_string(icbk);
110  auto pos_name = std::find(names.begin(), names.end(), name);
111  // is it a previously unencountered bookkeeper? If yes append its name to the vector of names
112  // if not no need, but we must check the corresponding entry for the sum of weights exist
113  if (pos_name == names.end()) {
114  names.push_back(name);
115  maxCycle.push_back(cbk->cycle());
116  sumW.push_back(cbk->sumOfEventWeights());
117  } else if (cbk->cycle() > maxCycle.at(pos_name - names.begin())) {
118  maxCycle.at(pos_name - names.begin()) = cbk->cycle();
119  sumW.at(pos_name - names.begin()) = cbk->sumOfEventWeights();
120  }
121  }
122  }
123  }
124 
125  ULong64_t getRawEventsBookkeeper(const xAOD::CutBookkeeperContainer *cutBookKeepers) {
126  int maxCycle = -1;
127  ULong64_t rawEntries = 0;
128  // search for "AllExecutedEvents" bookkeeper -- this one should always exist
129  for (const xAOD::CutBookkeeper *cbk : *cutBookKeepers) {
130  if ((cbk->inputStream() != "StreamAOD"))
131  continue;
132  if (cbk->name() != "AllExecutedEvents")
133  continue;
134  if (cbk->cycle() > maxCycle) {
135  rawEntries = cbk->nAcceptedEvents();
136  maxCycle = cbk->cycle();
137  }
138  }
139 
140  return rawEntries;
141  }
142 
143  void renameCutBookkeepers(std::vector<std::string>& bookkeeper_names,
144  const std::vector<std::string>& pmg_weight_names) {
145 
146  // prefix in the bookkeeper names to remove
147  static const std::string name_prefix = "AllExecutedEvents_weight_";
148 
149  // check if we have more than one MC generator weight, in that case we have to do the renaming
150  if (pmg_weight_names.size() > 1) {
151  if (bookkeeper_names.size() != pmg_weight_names.size()) {
152  // The number of AllExecutedEvents_ bookkeepers does not match the number of weights retrieved by PMGTool
153  // we cannot match the bookkeepers to weights by indices in this case
154  throw std::runtime_error("ERROR: The number of CutBookkeepers does not match the number of MC generator weights in metadata! Cannot match nominal MC weight to nominal sum of weights!");
155  }
156 
157  // rename the bookkeepers based on the weight names from PMGTool
158  // this names are then also written into the sumWeights TTree in output files
159  for (std::string &name : bookkeeper_names) {
160  // erase "AllExecutedEvents_weight_" prefix
161  int index = std::stoi(name.erase(0, name_prefix.size()));
162  name = pmg_weight_names.at(index);
163  }
164  } else {
165  // expect only one MC weight in this sample, hence only one AllExecutedEvents* bookeeeper
166  if (bookkeeper_names.size() == 1) {
167  bookkeeper_names[0] = "nominal";
168  } else {
169  ATH_MSG_INFO("WARNING: PMGTruthWeightTool reports no extra MC generator weight variations, "
170  << "but this sample does not have exactly one AllExecutedEvents* bookkeeper!\n"
171  << "This means we can't guarantee that the correct CutBookkeeper "
172  << "is used for the sum of weights!");
173  }
174  }
175  }
176 
177  std::vector<std::string> loadCuts(const std::string& filename) {
178  std::vector<std::string> v;
179 
180  std::fstream in(filename.c_str());
181 
182  if (!in.is_open()) {
183  throw std::runtime_error("Problem opening " + filename);
184  }
185 
186  std::string str;
187  while (std::getline(in, str)) {
188  std::string newstring(str);
189 
190  if (str.find('#') != std::string::npos) newstring = str.substr(0, str.find('#'));
191 
192  //leading and trailing white space removal
193  while (std::isspace(*newstring.begin()))
194  newstring.erase(newstring.begin());
195 
196  while (std::isspace(*newstring.rbegin()))
197  newstring.erase(newstring.length() - 1);
198 
199  //make sure it contains something
200  if (newstring.size() > 0) v.push_back(newstring);
201  }
202 
203  return v;
204  }
205 
206  size_t checkFiles(const std::vector<std::string>& filenames) {
207  ATH_MSG_INFO("Input filenames:\n");
208  size_t i = 0;
209  size_t totalYield = 0;
210 
211  for (const auto& filename : filenames) {
212  std::unique_ptr<TFile> f(TFile::Open(filename.c_str()));
213  ATH_MSG_INFO(i + 1 << "/" << filenames.size() << " File: " << filename);
214 
215  if (!f.get()) {
216  throw std::runtime_error("Did not manage to open " + filename);
217  }
218 
219  const TTree* const t = dynamic_cast<TTree* > (f->Get("CollectionTree"));
220 
221  //some files made by the derivation framework have no events passing the
222  //cuts -> which means no collection tree.
223  //the old behaviour was to end execution on this problem
224  //not any more!
225  int entries = 0;
226  std::string note;
227  if (t) entries = t->GetEntries();
228  else note = " (No CollectionTree)";
229 
230  ATH_MSG_INFO("Entries: " << entries << note);
231  totalYield += entries;
232 
233  ++i;
234  }
235 
236  return totalYield;
237  }
238 
239  std::vector<std::string> fileList(const std::string& filename) {
240  std::ifstream ifs(filename.c_str());
241 
242  if (!ifs) {
243  throw std::runtime_error("File does not exist " + filename
244  + "\nThis should contain a list - comma separated list of input files.");
245  }
246 
247  //loop over the lines in the file
248  std::stringstream wholefile;
249 
250  //read the file, and replace new lines with commas
251  //if the line already has comma separated filenames (a la the grid)
252  //these will be included automagically.
253  std::string line;
254  while (!ifs.eof()) {
255  std::getline(ifs, line);
256  wholefile << line << ',';
257  }
258 
259  //somewhere to save the filenames
260  std::vector<std::string> fileList;
261 
262  //now zoom through the whole file string and split at the comma
263  std::string to;
264  while (std::getline(wholefile, to, ',')) {
265  if (to.size() > 0) fileList.push_back(to);
266  }
267 
268  if (fileList.size() == 0) {
269  throw std::runtime_error("Could not get a list of input files from " + filename);
270  }
271 
272  return fileList;
273  }
274 
275  void loadLibraries(const std::string& libraryNames) {
276  std::vector<std::string> tokens;
277 
278  std::stringstream ss(libraryNames);
279  std::string item;
280  char delim = ' ';
281  while (std::getline(ss, item, delim))
282  tokens.push_back(item);
283 
284  std::vector<std::unique_ptr<top::ToolLoaderBase> > toolLoaders;
285  for (const auto& toolLoaderName : tokens) {
286  ATH_MSG_INFO("Attempting to load library: " << toolLoaderName << ".so");
287  gSystem->Load((toolLoaderName + ".so").c_str());
288  }
289  }
290 
291  top::TopObjectSelection* loadObjectSelection(const std::shared_ptr<top::TopConfig>& config) {
292  ATH_MSG_INFO("Attempting to load ObjectSelection: " << config->objectSelectionName());
293  TClass* c = ::TClass::GetClass(config->objectSelectionName().c_str());
294 
295  if (c == nullptr) {
296  throw std::runtime_error("Didn't manage to load " + config->objectSelectionName());
297  }
298 
299  top::ObjectLoaderBase* bc = static_cast<top::ObjectLoaderBase*> (c->New());
300 
301  if (bc == nullptr) {
302  throw std::runtime_error("Didn't manage to cast it to top::ObjectLoaderBase");
303  }
304 
305  top::TopObjectSelection* objectSelection = bc->init(config);
306 
307  if (objectSelection == nullptr) {
308  throw std::runtime_error("Didn't manage to make a top::ObjectSelection class");
309  }
310 
311  return objectSelection;
312  }
313 
314  top::EventSaverBase* loadEventSaver(const std::shared_ptr<top::TopConfig>& config) {
315  ATH_MSG_INFO("Attempting to load OutputFormat: " << config->outputFormat());
316  TClass* c = ::TClass::GetClass(config->outputFormat().c_str());
317 
318  if (c == nullptr) {
319  throw std::runtime_error("Didn't manage to load " + config->outputFormat());
320  }
321 
322  top::EventSaverBase* bc = static_cast<top::EventSaverBase*> (c->New());
323 
324  if (bc == nullptr) {
325  throw std::runtime_error("Didn't manage to cast it to top::EventSaverBase ");
326  }
327 
328  return bc;
329  }
330 
331  bool readMetaData(TFile* inputFile, const std::shared_ptr<top::TopConfig>& config) {
332  // Load the file into a TEvent
334  top::check(xaodEvent.readFrom(inputFile), "Cannot load inputFile");
335  xaodEvent.getEntry(0);
336 
337  // Magical metadata tool to access FileMetaData object
338  asg::AsgMetadataTool ATMetaData("OurNewMetaDataObject");
339 
340  // Check it exists, and if it does we will work with it
341  if (ATMetaData.inputMetaStore()->contains<xAOD::FileMetaData>("FileMetaData")) {
342 
343  ATH_MSG_INFO("Trying to read FileMetaData");
344 
345  // Create pointer for FileMetaData which we will load
346  const xAOD::FileMetaData* FMD = 0;
347  top::check(ATMetaData.inputMetaStore()->retrieve(FMD, "FileMetaData"),
348  "Failed to retrieve metadata from AsgMetadataTool");
349  readMetaData(FMD, config);
350 
351  } else {
352  ATH_MSG_ERROR("Could not read FileMetaData inside MetaData tree.");
353  return false;
354  }
355 
356  return true;
357  }
358 
359  void readMetaData(const xAOD::FileMetaData* FMD, const std::shared_ptr<top::TopConfig>& config) {
360  int mcChannelNumber = -1;
361  std::string dataType="?", simFlavour="?";
362  float mcProcID = -1;
363  bool isDataOverlay = false;
364  bool isMC = false;
365 
366  // get dataType and parse the derivation stream
368  if (dataType.find("StreamDAOD") != std::string::npos) {
369  auto cursor = dataType.find('_'); // split DAOD_BLALBA
370  std::string stream = dataType.substr(cursor + 1);
371  config->setDerivationStream(stream);
372  config->setIsTruthDxAOD((stream.find("TRUTH") != std::string::npos));
373  } else {
374  ATH_MSG_WARNING("DataType: " << dataType
375  << " does not appear to be a StreamDAOD_*, so we cannot determine derivation type.");
376  }
377 
378  // If this is data overlay or not
379  FMD->value(xAOD::FileMetaData::isDataOverlay, isDataOverlay);
380  config->setIsDataOverlay(isDataOverlay);
381 
383  FMD->value(xAOD::FileMetaData::mcProcID, mcProcID);
384  mcChannelNumber = mcProcID;
385  config->setDSID(mcChannelNumber);
386  isMC = (mcChannelNumber > 0);
387  config->setIsMC(isMC);
388 
390  FMD->value(xAOD::FileMetaData::simFlavour, simFlavour);
391  if (isMC) {
392  if (simFlavour == "FullG4") {
393  config->setIsAFII(false);
394  } else if (simFlavour == "FullG4_QS") {
395  config->setIsAFII(false);
396  } else if (simFlavour == "FullG4_LongLived") {
397  config->setIsAFII(false);
398  } else if (simFlavour == "ATLFASTII") {
399  config->setIsAFII(true);
400  } else if (simFlavour == "ATLFAST3_QS") {
401  config->setIsAFII(false);
402  } else if (config->isTruthDxAOD()) {
403  config->setIsAFII(false);
404  } else {
405  ATH_MSG_ERROR("Unsupported simFlavour detected in xAOD::FileMetaData: " << simFlavour);
406  throw std::runtime_error("Unsupported simFlavour detected, exiting");
407  }
408  }
409 
411  ATH_MSG_INFO("Reading the following options from FileMetaData:\n"
412  << "dataType -> " << dataType << "\n"
413  << "mcProcID -> " << mcChannelNumber << "\n"
414  << "isMC -> " << isMC << "\n"
415  << "simFlavour -> " << simFlavour << "\n"
416  << "isDataOverlay -> " << isDataOverlay);
417  }
418 }
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
checkFileSG.line
line
Definition: checkFileSG.py:75
top::readMetaData
void readMetaData(const xAOD::FileMetaData *FMD, const std::shared_ptr< top::TopConfig > &config)
Retrieve metadata from xAOD::FileMetaData object, to be stored in the TopConfig instance.
Definition: Tools.cxx:359
top::loadLibraries
void loadLibraries(const std::string &libraryNames)
So that we can load external libraries with (1) extra event selection tools in, (2) user defined obje...
Definition: Tools.cxx:275
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
top::ObjectLoaderBase
People seem to want to be able to configure the objects used in their anaysis for some reason.
Definition: ObjectLoaderBase.h:22
index
Definition: index.py:1
CP::CorrectionCode::enableFailure
static void enableFailure() noexcept
Definition: CorrectionCode.h:64
Tools.h
xAOD::CutBookkeeper_v1
Description of the class that is used to keep track of event counts.
Definition: CutBookkeeper_v1.h:29
top::loadCuts
std::vector< std::string > loadCuts(const std::string &filename)
Load the file and make a vector of the cuts to pass on to the selection tool.
Definition: Tools.cxx:177
EventSaverBase.h
top::ObjectLoaderBase::init
virtual top::TopObjectSelection * init(std::shared_ptr< top::TopConfig > topConfig)=0
Must implement this to load your own object selection.
top::checkFiles
size_t checkFiles(const std::vector< std::string > &filenames)
Open each file in the vector and get the number of events in it.
Definition: Tools.cxx:206
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
asg::AsgMetadataTool::inputMetaStore
MetaStorePtr_t inputMetaStore() const
Accessor for the input metadata store.
Definition: AsgMetadataTool.cxx:88
top::loadObjectSelection
top::TopObjectSelection * loadObjectSelection(const std::shared_ptr< top::TopConfig > &config)
Users may want to define (and load!) their own object selection.
Definition: Tools.cxx:291
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
beamspotman.tokens
tokens
Definition: beamspotman.py:1284
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:97
xAOD::mcChannelNumber
mcChannelNumber
Definition: EventInfo_v1.cxx:197
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
top::fileList
std::vector< std::string > fileList(const std::string &filename)
Given a filename for a text file, parse it and extract a list of root files.
Definition: Tools.cxx:239
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
EventTools.h
A few functions for doing operations on particles / events. Currently holds code for dR,...
TruthMetaData.h
xAOD::FileMetaData_v1::value
bool value(MetaDataType type, std::string &val) const
Get a pre-defined string value out of the object.
Definition: FileMetaData_v1.cxx:195
xAOD::FileMetaData_v1::simFlavour
@ simFlavour
Fast or Full sim [string].
Definition: FileMetaData_v1.h:76
top::getDerivationStream
std::string getDerivationStream(TFile *inputFile)
Function to determine the derivation type using string manipulation.
Definition: Tools.cxx:62
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
PyPoolBrowser.item
item
Definition: PyPoolBrowser.py:129
MsgCategory.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CaloCondBlobAlgs_fillNoiseFromASCII.inputFile
string inputFile
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:17
lumiFormat.i
int i
Definition: lumiFormat.py:92
top::TopObjectSelection
Configure the object selection used in the analysis.
Definition: TopObjectSelection.h:66
python.subdetectors.mmg.names
names
Definition: mmg.py:8
xAOD::TEvent::getEntry
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0)
Function loading a given entry of the input TTree.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1324
top::xAODInit
void xAODInit(bool failOnUnchecked)
A little wrapper for the xAOD tools.
Definition: Tools.cxx:46
top::EventSaverBase
A base class so users can write their own event saving stuff.
Definition: EventSaverBase.h:26
top::check
void check(bool thingToCheck, const std::string &usefulFailureMessage)
Print an error message and terminate if thingToCheck is false.
Definition: EventTools.cxx:15
top::parseCutBookkeepers
void parseCutBookkeepers(xAOD::TEvent &xaodEvent, const std::size_t size, std::vector< std::string > &names, std::vector< float > &sumW)
Search bookkeepers for ones matching AllExecutedEvents, and which originate from AOD before skimming.
Definition: Tools.cxx:89
Init.h
xAOD::CutBookkeeperContainer_v1
Container that holds the Container of all CutBookkeepers.
Definition: CutBookkeeperContainer_v1.h:27
xAOD::FileMetaData_v1::mcProcID
@ mcProcID
Same as mc_channel_number [float].
Definition: FileMetaData_v1.h:74
Event.h
xAOD::FileMetaData_v1
Class holding file-level metadata about an xAOD file.
Definition: FileMetaData_v1.h:34
StatusCode.h
top::getRawEventsBookkeeper
ULong64_t getRawEventsBookkeeper(const xAOD::CutBookkeeperContainer *cutBookKeepers)
Get raw number of events before skimming from "AllExecutedEvents" bookkeeper.
Definition: Tools.cxx:125
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
xAOD::TEvent::retrieveMetaInput
StatusCode retrieveMetaInput(const T *&obj, const std::string &key)
Retrieve an input metadata object.
item
Definition: ItemListSvc.h:43
CxxUtils::to
CONT to(RANGE &&r)
Definition: ranges.h:32
grepfile.filenames
list filenames
Definition: grepfile.py:34
AthAnalysisHelper.h
python.PyAthena.v
v
Definition: PyAthena.py:157
query_example.cursor
cursor
Definition: query_example.py:21
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
asg::AsgMetadataTool
Base class for dual-use tools that provide file metadata access.
Definition: AsgMetadataTool.h:48
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AsgMetadataTool.h
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
entries
double entries
Definition: listroot.cxx:49
EventInfoRead.isMC
isMC
Definition: EventInfoRead.py:11
top::renameCutBookkeepers
void renameCutBookkeepers(std::vector< std::string > &bookkeeper_names, const std::vector< std::string > &pmg_weight_names)
Rename CutBookkeeper names according to MC generator weight names reported by PMGTruthWeightTool.
Definition: Tools.cxx:143
xAOD::TEvent::readFrom
StatusCode readFrom(::TFile *file, Bool_t useTreeCache=kTRUE, const char *treeName=EVENT_TREE_NAME)
Connect the object to a new input file.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:364
CorrectionCode.h
str
Definition: BTagTrackIpAccessor.cxx:11
ToolLoaderBase.h
xAOD::FileMetaData_v1::isDataOverlay
@ isDataOverlay
Used data overlay for backgrounds [bool].
Definition: FileMetaData_v1.h:78
TruthMetaDataContainer.h
python.compressB64.c
def c
Definition: compressB64.py:93
top::loadEventSaver
top::EventSaverBase * loadEventSaver(const std::shared_ptr< top::TopConfig > &config)
Users may also want to write out custom ntuples / xAODs.
Definition: Tools.cxx:314
ObjectLoaderBase.h
xAOD::FileMetaData_v1::dataType
@ dataType
Data type that's in the file [string].
Definition: FileMetaData_v1.h:64
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:81
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31