ATLAS Offline Software
Functions
NTupleSvc.cxx File Reference
#include <EventLoopAlgs/NTupleSvc.h>
#include <fstream>
#include <memory>
#include <TBranchElement.h>
#include <TFile.h>
#include <TLeaf.h>
#include <TRegexp.h>
#include <TTree.h>
#include <EventLoop/Job.h>
#include <EventLoop/StatusCode.h>
#include <EventLoop/IWorker.h>
#include <EventLoopAlgs/WhiteBoardSvc.h>
#include <RootCoreUtils/Assert.h>
#include <RootCoreUtils/ThrowMsg.h>

Go to the source code of this file.

Functions

 ClassImp (EL::NTupleSvc) namespace EL
 

Function Documentation

◆ ClassImp()

ClassImp ( EL::NTupleSvc  )

Definition at line 38 of file NTupleSvc.cxx.

41 {
42  NTupleSvc *getNTupleSvc (IWorker *worker, const std::string& outputStream,
43  const std::string& treeName)
44  {
45  RCU_REQUIRE_SOFT (worker != 0);
46  RCU_REQUIRE_SOFT (!outputStream.empty());
47  NTupleSvc *result = dynamic_cast<NTupleSvc*>
48  (worker->getAlg ("NTupleSvc_" + outputStream + "_" + treeName));
49  if (result == 0)
50  {
51  result = dynamic_cast<NTupleSvc*>
52  (worker->getAlg ("NTupleSvc_" + outputStream));
53  }
54  RCU_ASSERT2_SOFT (result != 0, "output algorithm not found");
55  return result;
56  }
57 
58 
59 
60  void NTupleSvc ::
61  testInvariant () const
62  {
63  RCU_INVARIANT (this != 0);
64  }
65 
66 
67 
69  NTupleSvc (const std::string& val_outputName)
70  : m_file (0), m_tree (0), m_initialized (false),
71  m_whiteboard (0)
72  {
73  RCU_REQUIRE_SOFT (!val_outputName.empty());
74 
75  m_outputName = val_outputName;
76 
77  RCU_NEW_INVARIANT (this);
78  }
79 
80 
81 
82  NTupleSvc ::
83  ~NTupleSvc ()
84  {
85  RCU_DESTROY_INVARIANT (this);
86  }
87 
88 
89 
90  void NTupleSvc ::
91  copyBranch (const std::string& name)
92  {
93  RCU_CHANGE_INVARIANT (this);
94  m_copyBranches.insert (name);
95  }
96 
97 
98 
99  void NTupleSvc ::
100  copyBranchList (const std::string& fileName)
101  {
102  // no invariant used
103 
104  std::ifstream file (fileName.c_str());
105  std::string line;
106  while (getline (file, line))
107  {
108  while (!line.empty() && isspace (line[0]))
109  line = line.substr (1);
110  while (!line.empty() && isspace (line[line.size()-1]))
111  line.pop_back();
112  if (!line.empty() && line[0] != '#')
113  copyBranch (line);
114  }
115  }
116 
117 
118 
119  void NTupleSvc ::
120  addWhiteFloat (const std::string& varName)
121  {
122  RCU_CHANGE_INVARIANT (this);
123  m_whiteFloat.insert (varName);
124  }
125 
126 
127 
128  void NTupleSvc ::
129  addWhiteArray (const std::string& varName)
130  {
131  RCU_CHANGE_INVARIANT (this);
132  m_whiteArray.insert (varName);
133  }
134 
135 
136 
137  TTree *NTupleSvc ::
138  tree () const
139  {
140  RCU_READ_INVARIANT (this);
141  RCU_REQUIRE2_SOFT (m_tree != 0, "initialize() has been called");
142  return m_tree;
143  }
144 
145 
146 
147  bool NTupleSvc ::
148  getFilterPassed () const
149  {
150  RCU_READ_INVARIANT (this);
151  return m_taken;
152  }
153 
154 
155 
156  void NTupleSvc ::
157  setFilterPassed (bool passed)
158  {
159  RCU_CHANGE_INVARIANT (this);
160  if (passed)
161  m_taken = true;
162  }
163 
164 
165 
166  const std::string& NTupleSvc ::
167  treeName () const
168  {
169  RCU_READ_INVARIANT (this);
170  return m_treeName;
171  }
172 
173 
174 
175  void NTupleSvc ::
176  treeName (const std::string& val_treeName)
177  {
178  RCU_CHANGE_INVARIANT (this);
179  m_treeName = val_treeName;
180  }
181 
182 
183 
184  const char *NTupleSvc ::
185  GetName () const
186  {
187  RCU_READ_INVARIANT (this);
188  return m_outputName.c_str();
189  }
190 
191 
192 
193  StatusCode NTupleSvc ::
194  setupJob (Job& job)
195  {
196  RCU_CHANGE_INVARIANT (this);
197  RCU_REQUIRE2_SOFT (job.outputHas (m_outputName), ("output stream " + m_outputName + " not configured. try:\n EL::OutputStream output (\"" + m_outputName + "\");\n job.addOutput (output);").c_str());
198  return EL::StatusCode::SUCCESS;
199  }
200 
201 
202 
203  EL::StatusCode NTupleSvc :: changeInput (bool /*firstFile*/)
204  {
205  RCU_CHANGE_INVARIANT (this);
206 
207  m_connected = false;
208  return EL::StatusCode::SUCCESS;
209  }
210 
211 
212 
214  {
215  RCU_CHANGE_INVARIANT (this);
216 
217  m_file = wk()->getOutputFile (m_outputName);
218  std::string name = m_treeName;
219  if (name.empty()) name = wk()->tree()->GetName();
220  TDirectory *curDir = gDirectory;
221  try
222  {
223  m_file->cd ();
224  m_tree = new TTree (name.c_str(), m_tree_title.c_str());
225  curDir->cd ();
226  } catch (...)
227  {
228  curDir->cd ();
229  }
230 
231  // Turn off auto saving:
232  m_tree->SetAutoSave(10000);
233  // Flush the tree contents after collecting 30 MB in memory:
234  m_tree->SetAutoFlush( -30000000 );
235  TTree::SetBranchStyle(1);
236 
237  return EL::StatusCode::SUCCESS;
238  }
239 
240 
241 
243  {
244  RCU_CHANGE_INVARIANT (this);
245 
246  m_taken = false;
247  return EL::StatusCode::SUCCESS;
248  }
249 
250 
251 
252  EL::StatusCode NTupleSvc :: postExecute ()
253  {
254  RCU_CHANGE_INVARIANT (this);
255 
256  initBranches ();
257 
258  if (!m_taken)
259  return EL::StatusCode::SUCCESS;
260 
261  copyInput ();
262 
263  for (whiteInfoMIter iter = m_whiteInfo.begin(),
264  end = m_whiteInfo.end(); iter != end; ++ iter)
265  {
266  if (iter->array)
267  {
268  std::size_t size;
269  const float *values;
270  m_whiteboard->getArray (iter->name, size, values);
271  std::vector<float>(values,values+size).swap (iter->buffer);
272  } else
273  iter->buffer[0] = m_whiteboard->getFloat (iter->name);
274  }
275 
276  m_tree->Fill ();
277  return EL::StatusCode::SUCCESS;
278  }
279 
280 
281 
282  bool NTupleSvc ::
283  hasName (const std::string& name) const
284  {
285  RCU_READ_INVARIANT (this);
286  return
287  name == "NTupleSvc_" + m_outputName ||
288  name == "NTupleSvc_" + m_outputName + "_" + m_treeName;
289  }
290 
291 
292 
293  void NTupleSvc ::
294  initBranches ()
295  {
296  if (m_initialized == false)
297  {
298  m_initialized = true;
299 
300  std::set<std::string> branchList;
301 
302  findBranches (branchList);
303  initOutput (branchList);
304 
305  for (m_whiteFloatIter iter = m_whiteFloat.begin(),
306  end = m_whiteFloat.end(); iter != end; ++ iter)
307  {
308  WhiteInfo info;
309  info.name = *iter;
310  info.array = false;
311  m_whiteInfo.push_back (info);
312  }
313  for (m_whiteArrayIter iter = m_whiteArray.begin(),
314  end = m_whiteArray.end(); iter != end; ++ iter)
315  {
316  WhiteInfo info;
317  info.name = *iter;
318  info.array = true;
319  m_whiteInfo.push_back (info);
320  }
321  for (whiteInfoMIter iter = m_whiteInfo.begin(),
322  end = m_whiteInfo.end(); iter != end; ++ iter)
323  {
324  if (iter->array)
325  {
326  iter->pointer = &iter->buffer;
327  m_tree->Branch (iter->name.c_str(), &iter->pointer);
328  } else
329  {
330  iter->buffer.resize (1);
331  m_tree->Branch (iter->name.c_str(), &iter->buffer[0], (iter->name + "/F").c_str());
332  }
333  }
334  if (!m_whiteInfo.empty())
335  m_whiteboard = getWhiteBoardSvc (wk());
336  }
337  }
338 
339 
340  void NTupleSvc ::
341  findBranches (std::set<std::string>& branchList)
342  {
343  for (m_copyBranchesIter iter = m_copyBranches.begin(),
344  end = m_copyBranches.end(); iter != end; ++ iter)
345  {
346  std::size_t count = 0;
347  TRegexp pattern (*iter);
348  TObject *object = 0;
349 
350  for (TIter branchIter (wk()->tree()->GetListOfBranches());
351  (object = branchIter());)
352  {
353  TString str (object->GetName());
354  Ssiz_t len = 0;
355 
356  if (pattern.Index (str, &len) == 0 && len == str.Length())
357  {
358  branchList.insert (str.Data());
359  ++ count;
360  }
361  }
362  if (count == 0)
363  RCU_THROW_MSG ("could not find any branch that matches pattern \"" + *iter + "\"");
364  }
365  }
366 
367 
368 
369  void NTupleSvc ::
370  initOutput (const std::string& branchName)
371  {
372  // rationale: this ensures that I am not copying branches twice
373  for (copyInfoMIter branch = m_copyInfo.begin(),
374  end = m_copyInfo.end(); branch != end; ++ branch)
375  {
376  if (branch->name == branchName)
377  return;
378  }
379 
380  CopyInfo info;
381  info.name = branchName;
382  info.source = wk()->tree()->FindBranch (branchName.c_str());
383  if (info.source == 0)
384  RCU_THROW_MSG ("could not find input branch: " + branchName);
385 
386  const char *className = info.source->GetClassName();
387  if (strlen (className) > 0)
388  {
389  info.target = m_tree->Branch (branchName.c_str(), className,
390  static_cast<void*>(0));
391  } else
392  {
393  static std::map<std::string,std::string> types;
394  if (types.empty())
395  {
396  types["Char_t"] = "B";
397  types["UChar_t"] = "b";
398  types["Short_t"] = "S";
399  types["UShort_t"] = "s";
400  types["Int_t"] = "I";
401  types["UInt_t"] = "i";
402  types["Float_t"] = "F";
403  types["Double_t"] = "D";
404  types["Long64_t"] = "L";
405  types["ULong64_t"] = "l";
406  types["Bool_t"] = "O";
407  }
408 
409  std::string leaves;
410  TObject *object;
411  for (TIter iter = info.source->GetListOfLeaves(); (object = iter()); )
412  {
413  TLeaf *myleaf = dynamic_cast<TLeaf*>(object);
414  if (myleaf == 0)
415  RCU_THROW_MSG ("found non-leaf object in leaf list");
416 
417  std::string typeName = myleaf->GetTypeName();
418  std::map<std::string,std::string>::const_iterator type
419  = types.find (typeName);
420  if (type == types.end())
421  RCU_THROW_MSG ("unknown leaf type " + typeName);
422 
423  if (!leaves.empty())
424  leaves += ":";
425  leaves = leaves + myleaf->GetTitle() + "/" + type->second;
426  }
427  if (leaves.empty())
428  RCU_THROW_MSG ("failed to scan leaves of branch " + branchName);
429 
430  for (std::string::size_type pos = 0;
431  (pos = leaves.find ("[", pos)) != std::string::npos; )
432  {
433  ++ pos;
434  std::string::size_type pos2 = leaves.find ("]", pos);
435  if (pos2 == std::string::npos)
436  RCU_THROW_MSG ("failed to scan leaf dimensions for " + leaves);
437  std::string dim = leaves.substr (pos, pos2 - pos);
438  if (!(dim[0] >= '0' && dim[0] <= '9'))
439  initOutput (dim);
440  }
441  info.target = m_tree->Branch (branchName.c_str(), static_cast<void*>(0),
442  leaves.c_str());
443  }
444  m_copyInfo.push_back (info);
445  }
446 
447 
448 
449  void NTupleSvc ::
450  initOutput (const std::set<std::string>& branchList)
451  {
452  for (std::set<std::string>::const_iterator branch = branchList.begin(),
453  end = branchList.end(); branch != end; ++ branch)
454  initOutput (*branch);
455  }
456 
457 
458 
459  void NTupleSvc ::
460  copyInput ()
461  {
462  if (!m_connected)
463  {
464  for (copyInfoMIter info = m_copyInfo.begin(),
465  end = m_copyInfo.end(); info != end; ++ info)
466  {
467  info->source = dynamic_cast<TBranch*>
468  (wk()->tree()->GetBranch (info->name.c_str()));
469  RCU_ASSERT2_SOFT (info->source != 0, ("source branch " + info->name + " not found for copying").c_str());
470  }
471  m_connected = true;
472  }
473 
474  for (copyInfoMIter info = m_copyInfo.begin(),
475  end = m_copyInfo.end(); info != end; ++ info)
476  {
477  void *address = info->source->GetAddress();
478  if (address == 0)
479  {
480  std::size_t size = sizeof (void*);
481  TObject *object;
482  for (TIter iter = info->source->GetListOfLeaves();
483  (object = iter());)
484  {
485  TLeaf *myleaf = dynamic_cast<TLeaf*>(object);
486  RCU_ASSERT (myleaf != 0);
487  Int_t countval;
488  TLeaf *countleaf = myleaf->GetLeafCounter (countval);
489  if (countleaf)
490  countval = countleaf->GetMaximum();
491  if (countval < 0)
492  RCU_THROW_MSG (std::string ("could not determine size of leaf ") + myleaf->GetName() + " in branch " + info->name);
493  if (countval == 0)
494  countval = 1;
495  const std::size_t mysize
496  = myleaf->GetOffset() + myleaf->GetLenType() * countval;
497  if (size < mysize)
498  size = mysize;
499  }
500  info->buffer.resize (size, 0);
501  info->source->SetStatus (1);
502  info->source->SetAddress (address = &info->buffer[0]);
503  }
504  RCU_ASSERT (address != 0);
505  info->target->SetAddress (address);
506  info->source->GetEntry (wk()->treeEntry(), 1);
507  }
508  }
509 }
grepfile.info
info
Definition: grepfile.py:38
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
checkFileSG.line
line
Definition: checkFileSG.py:75
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
get_generator_info.result
result
Definition: get_generator_info.py:21
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
initialize
void initialize()
Definition: run_EoverP.cxx:894
tree
TChain * tree
Definition: tile_monitor.h:30
RunGeantinoStepRecordingITk.outputStream
outputStream
Definition: RunGeantinoStepRecordingITk.py:126
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:797
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
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
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
JetTagCalibConfig.className
string className
Definition: JetTagCalibConfig.py:31
RCU_ASSERT2_SOFT
#define RCU_ASSERT2_SOFT(x, y)
Definition: Assert.h:169
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
RCU_REQUIRE_SOFT
#define RCU_REQUIRE_SOFT(x)
Definition: Assert.h:153
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
PixelAthClusterMonAlgCfg.varName
string varName
end cluster ToT and charge
Definition: PixelAthClusterMonAlgCfg.py:117
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
file
TFile * file
Definition: tile_monitor.h:29
dumpFileToPlots.treeName
string treeName
Definition: dumpFileToPlots.py:20
RCU_INVARIANT
#define RCU_INVARIANT(x)
Definition: Assert.h:201
python.root_lsr_rank.types
types
Definition: root_lsr_rank.py:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
RTTAlgmain.address
address
Definition: RTTAlgmain.py:55
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
RCU_REQUIRE2_SOFT
#define RCU_REQUIRE2_SOFT(x, y)
Definition: Assert.h:155
RTTAlgmain.branch
branch
Definition: RTTAlgmain.py:61
RCU_DESTROY_INVARIANT
#define RCU_DESTROY_INVARIANT(x)
Definition: Assert.h:235
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
EL::getWhiteBoardSvc
WhiteBoardSvc * getWhiteBoardSvc(IWorker *worker)
effects: get the whiteboard service for this worker guarantee: strong failures: formula service not c...
RCU_CHANGE_INVARIANT
#define RCU_CHANGE_INVARIANT(x)
Definition: Assert.h:231
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
pickleTool.object
object
Definition: pickleTool.py:30
str
Definition: BTagTrackIpAccessor.cxx:11
RCU_THROW_MSG
#define RCU_THROW_MSG(message)
Definition: PrintMsg.h:58
test_interactive_athena.job
job
Definition: test_interactive_athena.py:6
RCU_ASSERT
#define RCU_ASSERT(x)
Definition: Assert.h:222
RCU_READ_INVARIANT
#define RCU_READ_INVARIANT(x)
Definition: Assert.h:229
EL::getNTupleSvc
NTupleSvc * getNTupleSvc(IWorker *worker, const std::string &outputStream, const std::string &treeName="")
effects: get the skimming algorithm for the given output for this worker guarantee: strong failures: ...
Lb2Lll.NTupleSvc
NTupleSvc
Definition: Lb2Lll.py:200
RCU_NEW_INVARIANT
#define RCU_NEW_INVARIANT(x)
Definition: Assert.h:233