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