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