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