ATLAS Offline Software
SampleHandler.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 // Please feel free to contact me (krumnack@iastate.edu) for bug
11 // reports, feature suggestions, praise and complaints.
12 
13 
14 //
15 // includes
16 //
17 
18 //protect
20 
21 #include <iostream>
22 #include <sstream>
23 #include <TFile.h>
24 #include <TSystem.h>
25 #include <RootCoreUtils/Assert.h>
28 #include <RootCoreUtils/ThrowMsg.h>
32 #include <SampleHandler/Sample.h>
34 
35 //
36 // method implementations
37 //
38 
40 
41 namespace SH
42 {
43  namespace
44  {
45  /*
46  bool isspace (const std::string& str)
47  {
48  for (std::string::const_iterator iter = str.begin(),
49  end = str.end(); iter != end; ++ iter)
50  {
51  if (!std::isspace (*iter))
52  return false;
53  };
54  return true;
55  }
56  */
57  }
58 
59 
60 
61  std::string dbg (const SampleHandler& obj, unsigned verbosity)
62  {
63  std::ostringstream result;
64  result << "SampleHandler with " << obj.size() << " files";
65  if (verbosity % 10 > 0)
66  {
67  result << "\n";
68  for (SampleHandler::iterator sample = obj.begin(),
69  end = obj.end(); sample != end; ++ sample)
70  {
71  result << dbg (**sample, verbosity / 10) << "\n";
72  };
73  };
74  return result.str();
75  }
76 
77 
78 
79  void swap (SampleHandler& a, SampleHandler& b)
80  {
81  swap (a.m_samples, b.m_samples);
82  swap (a.m_named, b.m_named);
83  }
84 
85 
86 
87  void SampleHandler ::
88  testInvariant () const
89  {
90  }
91 
92 
93 
96  {
98  RCU_NEW_INVARIANT (this);
99  }
100 
101 
102 
104  SampleHandler (const SampleHandler& that)
105  : TObject (that), m_samples (that.m_samples), m_named (that.m_named)
106  {
107  RCU_NEW_INVARIANT (this);
108  }
109 
110 
111 
114  {
115  RCU_DESTROY_INVARIANT (this);
116  }
117 
118 
119 
120  SampleHandler& SampleHandler ::
121  operator = (const SampleHandler& that)
122  {
123  // no invariant used
124  SampleHandler tmp (that);
125  swap (tmp, *this);
126  return *this;
127  }
128 
129 
130 
131  void SampleHandler ::
132  add (Sample *sample)
133  {
134  SamplePtr mysample (sample);
135 
136  // invariant not used
137  RCU_REQUIRE_SOFT (sample != 0);
138 
139  add (mysample);
140  }
141 
142 
143 
144  void SampleHandler ::
145  add (std::unique_ptr<Sample> sample)
146  {
147  // no invariant used
148  add (SamplePtr (std::move (sample)));
149  }
150 
151 
152 
153  void SampleHandler ::
154  add (SamplePtr& sample)
155  {
156  RCU_CHANGE_INVARIANT (this);
157  RCU_REQUIRE_SOFT (!sample.empty());
158  RCU_REQUIRE_SOFT (!sample->name().empty());
159 
160  if (!sample->name().empty() && m_named.find (sample->name()) != m_named.end())
161  RCU_THROW_MSG ("can't add sample of name " + sample->name() + "\na sample with that name already exists\nold sample:\n" + dbg (*m_named.find (sample->name())->second, 9999) + "\nnew sample:\n" + dbg (*sample, 9999));
162 
163  try
164  {
165  m_samples.push_back (sample.get());
166  if (!sample->name().empty())
167  m_named[sample->name()] = sample;
168  } catch (...)
169  {
170  if (m_samples.back() == sample.get())
171  m_samples.pop_back();
172  };
173  }
174 
175 
176 
177  void SampleHandler ::
178  add (SamplePtr&& sample)
179  {
180  add (sample);
181  }
182 
183 
184 
185  void SampleHandler ::
186  add (const SampleHandler& sh)
187  {
188  // invariant not used
189  RCU_REQUIRE_SOFT (this != &sh);
190 
191  for (iterator iter = sh.begin(), end2 = sh.end();
192  iter != end2; ++ iter)
193  {
194  add (*iter);
195  };
196  }
197 
198 
199 
200  void SampleHandler ::
201  addWithPrefix (const SampleHandler& sh, const std::string& prefix)
202  {
203  // invariant not used
204  RCU_REQUIRE_SOFT (this != &sh);
205 
206  for (iterator iter = sh.begin(), end2 = sh.end();
207  iter != end2; ++ iter)
208  {
209  std::unique_ptr<Sample> sample (dynamic_cast<Sample*>((*iter)->Clone ()));
210  RCU_ASSERT (sample != nullptr);
211  sample->name (prefix + (*iter)->name());
212  add (sample.release());
213  };
214  }
215 
216 
217 
218  void SampleHandler ::
219  remove (const std::string& name)
220  {
221  // invariant not used
222  const Sample *sample = get (name);
223  if (sample == 0)
224  RCU_THROW_MSG ("sample " + name + " not found in SampleHandler");
225  remove (sample);
226  }
227 
228 
229 
230  void SampleHandler ::
231  remove (const Sample *sample)
232  {
233  RCU_CHANGE_INVARIANT (this);
234  RCU_REQUIRE_SOFT (sample != 0);
235 
236  NamedMIter nameIter = m_named.find (sample->name());
237  if (nameIter == m_named.end())
238  RCU_THROW_MSG ("sample " + sample->name() + " not found in SampleHandler");
239  if (nameIter->second.get() != sample)
240  RCU_THROW_MSG ("different sample of name " + sample->name() + " found in SampleHandler");
241  SamplesMIter sampleIter = m_samples.end();
242  for (SamplesMIter iter = m_samples.begin(), end2 = m_samples.end();
243  iter != end2; ++ iter)
244  {
245  if (*iter == sample)
246  sampleIter = iter;
247  };
248  m_samples.erase (sampleIter);
249  m_named.erase (nameIter);
250  }
251 
252 
253 
254  Sample *SampleHandler ::
255  get (const std::string& name)
256  {
257  RCU_READ_INVARIANT (this);
258 
259  NamedIter iter = m_named.find (name);
260  if (iter != m_named.end())
261  return iter->second.get();
262  return 0;
263  }
264 
265 
266  const Sample *SampleHandler ::
267  get (const std::string& name) const
268  {
269  RCU_READ_INVARIANT (this);
270 
271  auto iter = m_named.find (name);
272  if (iter != m_named.end())
273  return iter->second.get();
274  return 0;
275  }
276 
277 
278 
279  SampleHandler SampleHandler ::
280  find (const std::string& tags) const
281  {
282  // no invariant used
283  return find (TagList (tags, ','));
284  }
285 
286 
287 
288  SampleHandler SampleHandler ::
289  find (const TagList& tags) const
290  {
291  RCU_READ_INVARIANT (this);
292 
294 
295  for (SamplesIter sample = m_samples.begin(),
296  end = m_samples.end(); sample != end; ++ sample)
297  {
298  bool use = false;
299  for (TagList::iterator iter = tags.begin(),
300  end = tags.end(); !use && iter != end; ++ iter)
301  use = (*sample)->tags().has (*iter);
302  if (use)
303  result.add (*sample);
304  };
305  return result;
306  }
307 
308 
309 
310  Sample *SampleHandler ::
311  findBySource (const std::string& name) const
312  {
313  RCU_READ_INVARIANT (this);
314 
315  std::vector<Sample*> result;
316  for (iterator sample = begin(),
317  end2 = end(); sample != end2; ++ sample)
318  {
319  if (name == (*sample)->meta()->castString (MetaFields::sourceSample, (*sample)->name()))
320  result.push_back ((*sample));
321  };
322  if (result.size() > 1)
323  {
324  std::ostringstream message;
325  message << "multiple samples have " << name << " as a source:";
326  for (std::vector<Sample*>::const_iterator sample = result.begin(),
327  end = result.end(); sample != end; ++ sample)
328  message << " " << (*sample)->name();
329  RCU_THROW_MSG (message.str());
330  };
331  if (result.empty())
332  return 0;
333  return result.front();
334  }
335 
336 
337 
338  SampleHandler SampleHandler ::
339  findByName (const std::string& pattern) const
340  {
341  RCU_READ_INVARIANT (this);
343  boost::regex expr (pattern);
344  for (iterator iter = begin(), end = this->end(); iter != end; ++ iter)
345  {
346  if (RCU::match_expr (expr, (*iter)->name()))
347  result.add (*iter);
348  }
349  return result;
350  }
351 
352 
353 
354  void SampleHandler ::
355  print () const
356  {
357  RCU_READ_INVARIANT (this);
358  std::cout << dbg (*this, 9999) << std::endl;
359  }
360 
361 
362 
363  void SampleHandler ::
364  printContent () const
365  {
366  // not using invariant
367  print ();
368  }
369 
370 
371 
372  void SampleHandler ::
373  save (const std::string& directory) const
374  {
375  RCU_READ_INVARIANT (this);
376 
377  // rationale: not checking the return status, since this is just a
378  // courtesy directory creation that is Ok to fail.
379  gSystem->MakeDirectory (directory.c_str());
380  for (iterator iter = this->begin(),
381  end = this->end(); iter != end; ++ iter)
382  {
383  TFile file ((directory + "/" + (*iter)->name() + ".root").c_str(), "RECREATE");
384  (*iter)->Write ("sample");
385  };
386  }
387 
388 
389 
390  void SampleHandler ::
391  load (const std::string& directory)
392  {
393  RCU_CHANGE_INVARIANT (this);
394 
395  DiskListLocal mydir (directory);
396  while (mydir.next())
397  {
398  const std::string file = mydir.fileName();
399 
400  if (file.size() > 5 &&
401  file.rfind (".root") == file.size() - 5)
402  {
403  TFile myfile (mydir.path().c_str(), "READ");
404  Sample *const sample = dynamic_cast<Sample*>(myfile.Get ("sample"));
405  if (sample != 0)
406  add (sample);
407  };
408  };
409  }
410 
411 
412 
413  void SampleHandler ::
414  updateLocation (const std::string& from, const std::string& to)
415  {
416  // no invariant used
417  RCU_REQUIRE_SOFT (!from.empty());
418  RCU_REQUIRE_SOFT (!to.empty());
419  for (iterator sample = begin(),
420  end = this->end(); sample != end; ++ sample)
421  (*sample)->updateLocation (from, to);
422  }
423 
424 
425 
426  void SampleHandler ::
427  fetch (const SampleHandler& source)
428  {
429  // invariant not used
430 
431  for (iterator sample = begin(),
432  end2 = end(); sample != end2; ++ sample)
433  {
434  const std::string name
435  = (*sample)->meta()->castString (MetaFields::sourceSample, (*sample)->name());
436  const Sample *const mysource = source.get (name);
437  if (mysource)
438  (*sample)->meta()->fetch (*mysource->meta());
439  };
440  }
441 
442 
443 
444  void SampleHandler ::
445  fetchDefaults (const SampleHandler& source)
446  {
447  // invariant not used
448 
449  for (iterator sample = begin(),
450  end2 = end(); sample != end2; ++ sample)
451  {
452  const std::string name
453  = (*sample)->meta()->castString (MetaFields::sourceSample, (*sample)->name());
454  const Sample *const mysource = source.get (name);
455  if (mysource)
456  (*sample)->meta()->fetchDefaults (*mysource->meta());
457  };
458  }
459 
460 
461 
462  bool SampleHandler ::
463  check_complete (const SampleHandler& source) const
464  {
465  // invariant not used
466 
467  std::set<std::string> names;
468  for (iterator sample = begin(),
469  end2 = end(); sample != end2; ++ sample)
470  {
471  names.insert ((*sample)->meta()->castString (MetaFields::sourceSample, (*sample)->name()));
472  };
473 
474  for (iterator sample = source.begin(),
475  end2 = source.end(); sample != end2; ++ sample)
476  {
477  if (names.find ((*sample)->name()) == names.end())
478  return false;
479  };
480  return true;
481  }
482 
483 
484 
485  void SampleHandler ::
486  setMetaDouble (const std::string& name, double value)
487  {
488  // no invariant used
489 
490  for (iterator sample = begin(),
491  end2 = end(); sample != end2; ++ sample)
492  {
493  (*sample)->meta()->setDouble (name, value);
494  };
495  }
496 
497 
498 
499  void SampleHandler ::
500  setMetaString (const std::string& name, const std::string& value)
501  {
502  // no invariant used
503 
504  for (iterator sample = begin(),
505  end2 = end(); sample != end2; ++ sample)
506  {
507  (*sample)->meta()->setString (name, value);
508  };
509  }
510 
511 
512 
513  void SampleHandler ::
514  setMetaDouble (const std::string& pattern, const std::string& name,
515  double value)
516  {
517  // no invariant used
518 
519  boost::regex mypattern (pattern);
520 
521  for (iterator sample = begin(),
522  end2 = end(); sample != end2; ++ sample)
523  {
524  if (RCU::match_expr (mypattern, (*sample)->name()))
525  (*sample)->meta()->setDouble (name, value);
526  };
527  }
528 
529 
530 
531  void SampleHandler ::
532  setMetaString (const std::string& pattern, const std::string& name,
533  const std::string& value)
534  {
535  // no invariant used
536 
537  boost::regex mypattern (pattern);
538 
539  for (iterator sample = begin(),
540  end2 = end(); sample != end2; ++ sample)
541  {
542  if (RCU::match_expr (mypattern, (*sample)->name()))
543  (*sample)->meta()->setString (name, value);
544  };
545  }
546 
547 
548 
550  begin () const
551  {
552  RCU_READ_INVARIANT (this);
553  return m_samples.begin();
554  }
555 
556 
557 
559  end () const
560  {
561  RCU_READ_INVARIANT (this);
562  return m_samples.end();
563  }
564 
565 
566 
567  std::size_t SampleHandler ::
568  size () const
569  {
570  RCU_READ_INVARIANT (this);
571  return m_samples.size();
572  }
573 
574 
575 
576  Sample *SampleHandler ::
577  operator [] (std::size_t index) const
578  {
579  // no invariant used
580  return at (index);
581  }
582 
583 
584 
585  Sample *SampleHandler ::
586  at (std::size_t index) const
587  {
588  RCU_READ_INVARIANT (this);
590  return m_samples[index];
591  }
592 
593 
594 
595  void SampleHandler ::
596  Streamer (TBuffer& b)
597  {
598  if (b.IsReading())
599  {
600  RCU_CHANGE_INVARIANT (this);
602  ULong_t count = 0;
603  b.ReadULong (count);
604  for (ULong_t iter = 0; iter != count; ++ iter)
605  {
606  Sample *sample = 0;
607  b >> sample;
608  sh.add (sample);
609  }
610  swap (*this, sh);
611  } else
612  {
613  RCU_READ_INVARIANT (this);
614  ULong_t count = m_samples.size(), count2 = 0;
615  b.WriteULong (count);
616  for (SamplesIter iter = m_samples.begin(),
617  end = m_samples.end(); iter != end; ++ iter, ++ count2)
618  {
619  Sample *sample = *iter;
620  b << sample;
621  }
622  };
623  }
624 }
SH::SampleHandler::addWithPrefix
void addWithPrefix(const SampleHandler &sh, const std::string &prefix)
add all samples from the given SampleHandler to this one, with prefix prepended to their name
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
SH::SampleHandler::findBySource
Sample * findBySource(const std::string &name) const
find a sample by the name in the source sample handler
SH::SampleHandler::fetchDefaults
void fetchDefaults(const SampleHandler &source)
fetch the meta-data for all that samples that don't have it in this sample.
SH::SampleHandler::iterator
std::vector< Sample * >::const_iterator iterator
the iterator to use
Definition: SampleHandler.h:475
ClassImp
ClassImp(SH::SampleHandler) namespace SH
Definition: SampleHandler.cxx:39
SH::SampleHandler::NamedIter
std::map< std::string, SH::SamplePtr >::iterator NamedIter
the iterator for m_named
Definition: SampleHandler.h:545
DiskListLocal.h
get_generator_info.result
result
Definition: get_generator_info.py:21
SH::SampleHandler::at
Sample * at(std::size_t index) const
the sample with the given index
SH::SampleHandler::add
void add(Sample *sample)
add a sample to the handler
SH::SampleHandler::SamplesMIter
std::vector< SH::Sample * >::iterator SamplesMIter
the mutable iterator for m_samples
Definition: SampleHandler.h:537
SH::SampleHandler::~SampleHandler
~SampleHandler()
standard destructor
CheckRootVersion.h
SH::dbg
std::string dbg(const Meta &, unsigned)
Definition: Meta.cxx:28
index
Definition: index.py:1
SH::SampleHandler::updateLocation
void updateLocation(const std::string &from, const std::string &to)
update all file references starting with from to to
SH::SampleHandler::operator=
SampleHandler & operator=(const SampleHandler &that)
standard assignment operator
SH::SampleHandler::find
SampleHandler find(const TagList &tags) const
find all samples which have at least one of the given tags.
SH::SampleHandler::m_samples
std::vector< SH::Sample * > m_samples
the list of samples managed
Definition: SampleHandler.h:529
SH::SampleHandler::end
iterator end() const
the end iterator to use
athena.value
value
Definition: athena.py:124
SampleHandler.h
SH::SampleHandler::printContent
void printContent() const
print the debugging output to the screen
SH::SampleHandler::size
std::size_t size() const
the number of samples contained
Assert.h
SH::SampleHandler::print
void print() const
print the debugging output to the screen
grl_maker.mydir
mydir
Definition: grl_maker.py:4
ReweightUtils.message
message
Definition: ReweightUtils.py:15
StringUtil.h
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
SH::SampleHandler::save
void save(const std::string &directory) const
save the list of samples to the given directory
SH::SampleHandler::setMetaDouble
void setMetaDouble(const std::string &name, double value)
set the meta-data double with the given name for all samples.
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
SH::SampleHandler::testInvariant
void testInvariant() const
test the invariant of this object
SamplePtr.h
tags
std::vector< std::string > tags
Definition: hcg.cxx:102
MetaObject.h
FullCPAlgorithmsTest_eljob.sh
sh
Definition: FullCPAlgorithmsTest_eljob.py:111
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:113
RCU_REQUIRE_SOFT
#define RCU_REQUIRE_SOFT(x)
Definition: Assert.h:153
DeMoScan.directory
string directory
Definition: DeMoScan.py:80
RCU::Shell
Definition: ShellExec.cxx:28
python.subdetectors.mmg.names
names
Definition: mmg.py:8
RCU::match_expr
bool match_expr(const boost::regex &expr, const std::string &str)
returns: whether we can match the entire string with the regular expression guarantee: strong failure...
Definition: StringUtil.cxx:40
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
file
TFile * file
Definition: tile_monitor.h:29
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
SH::SampleHandler::dbg
std::string dbg(const SampleHandler &obj, unsigned verbosity=0)
the debugging info of this object
SH::SampleHandler::SampleHandler
SampleHandler()
standard constructor
SH::SampleHandler::load
void load(const std::string &directory)
load all the samples from the given directory
SH::SampleHandler::check_complete
bool check_complete(const SampleHandler &source) const
whether we have all samples from the source SampleHandler.
dbg
Definition: SGImplSvc.cxx:69
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
SH::SampleHandler::begin
iterator begin() const
the begin iterator to use
MetaFields.h
ThrowMsg.h
SH::TagList::iterator
std::set< std::string >::const_iterator iterator
the iterator to use
Definition: TagList.h:96
covarianceTool.verbosity
verbosity
Definition: covarianceTool.py:513
SH::MetaFields::sourceSample
static const std::string sourceSample
the original sample from which this sample was derived
Definition: MetaFields.h:49
SH::SampleHandler::setMetaString
void setMetaString(const std::string &name, const std::string &value)
set the meta-data string with the given name for all samples.
SH::SampleHandler::m_named
std::map< std::string, SH::SamplePtr > m_named
the list of samples by name
Definition: SampleHandler.h:541
CxxUtils::to
CONT to(RANGE &&r)
Definition: ranges.h:39
SH::SampleHandler::findByName
SampleHandler findByName(const std::string &pattern) const
find samples by pattern on the name
RCU::check_root_version
void check_root_version()
effects: check whether we are using a consistent root version guarantee: strong failures: version mis...
Definition: CheckRootVersion.cxx:31
DeMoScan.index
string index
Definition: DeMoScan.py:364
a
TList * a
Definition: liststreamerinfos.cxx:10
RCU_DESTROY_INVARIANT
#define RCU_DESTROY_INVARIANT(x)
Definition: Assert.h:235
SH::SampleHandler::operator[]
Sample * operator[](std::size_t index) const
the sample with the given index
RCU_CHANGE_INVARIANT
#define RCU_CHANGE_INVARIANT(x)
Definition: Assert.h:231
SH::SampleHandler::swap
friend void swap(SampleHandler &a, SampleHandler &b)
SH::SampleHandler::NamedMIter
std::map< std::string, SH::SamplePtr >::iterator NamedMIter
the mutable iterator for m_named
Definition: SampleHandler.h:549
SH::SampleHandler::remove
void remove(const std::string &name)
remove the given sample
copySelective.source
string source
Definition: copySelective.py:32
SH::SampleHandler
A class that manages a list of Sample objects.
Definition: SampleHandler.h:60
SH
This module provides a lot of global definitions, forward declarations and includes that are used by ...
Definition: PrunDriver.h:15
RCU_THROW_MSG
#define RCU_THROW_MSG(message)
Definition: PrintMsg.h:58
SH::SampleHandler::fetch
void fetch(const SampleHandler &source)
fetch the meta-data for all samples that are also in the source sample handler.
SH::SampleHandler::get
Sample * get(const std::string &name)
get the sample with the given name
SH::SampleHandler::SamplesIter
std::vector< SH::Sample * >::const_iterator SamplesIter
the iterator for m_samples
Definition: SampleHandler.h:533
python.PyAthena.obj
obj
Definition: PyAthena.py:132
RCU_ASSERT
#define RCU_ASSERT(x)
Definition: Assert.h:222
RCU_READ_INVARIANT
#define RCU_READ_INVARIANT(x)
Definition: Assert.h:229
Sample.h
RCU_NEW_INVARIANT
#define RCU_NEW_INVARIANT(x)
Definition: Assert.h:233