LDMX Software
Bus.h
1#ifndef FRAMEWORK_BUS_H
2#define FRAMEWORK_BUS_H
3
4#include <iostream>
5#include <map>
6#include <memory>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
11// ROOT
12#include "TBranchElement.h"
13#include "TTree.h"
14
15namespace framework {
16
29class Bus {
30 public:
42 template <typename BaggageType>
43 const BaggageType& get(const std::string& name) {
44 return getRef<BaggageType>(name).get();
45 }
46
64 template <typename BaggageType>
65 void board(const std::string& name) {
66 passengers_[name] = std::make_unique<Passenger<BaggageType>>();
67 passengers_[name]->clear(); // make sure 'default' state is well defined
68 }
69
82 template <typename BaggageType>
83 void update(const std::string& name, const BaggageType& obj) {
84 getRef<BaggageType>(name).update(obj);
85 }
86
107 TBranch* attach(TTree* tree, const std::string& name, bool can_create) {
108 return passengers_[name]->attach(tree, name, can_create);
109 }
110
117 bool isOnBoard(const std::string& name) {
118 return passengers_.find(name) != passengers_.end();
119 }
120
126 void clear() {
127 for (auto& [n, handle] : passengers_) handle->clear();
128 }
129
140 void everybodyOff() { passengers_.clear(); }
141
150 void stream(std::ostream& s) const {
151 for (auto& [n, handle] : passengers_)
152 s << n << " : " << handle << std::endl;
153 }
154
164 friend std::ostream& operator<<(std::ostream& s, const framework::Bus& b) {
165 b.stream(s);
166 return s;
167 }
168
169 private:
180 class Seat {
181 public:
188 virtual ~Seat() {}
189
205 virtual TBranch* attach(TTree* tree, const std::string& branch_name,
206 bool can_create) = 0;
207
216 virtual void clear() = 0;
217
223 virtual void stream(std::ostream& s) const = 0;
224
238 friend std::ostream& operator<<(
239 std::ostream& s, const std::unique_ptr<framework::Bus::Seat>& seat) {
240 seat->stream(s);
241 return s;
242 }
243
244 }; // Seat
245
246 private:
286 template <typename BaggageType>
287 class Passenger : public Seat {
288 public:
299 Passenger() : Seat(), baggage_{new BaggageType} {}
300
318 virtual ~Passenger() { delete baggage_; }
319
343 virtual TBranch* attach(TTree* tree, const std::string& branch_name,
344 bool can_create) {
345 return attach(the_type<BaggageType>{}, tree, branch_name, can_create);
346 }
347
352 const BaggageType& get() const { return *baggage_; }
353
365 void update(const BaggageType& updated_obj) {
366 *baggage_ = updated_obj;
368 }
369
377 virtual void clear() { clear(the_type<BaggageType>{}); }
378
386 virtual void stream(std::ostream& s) const {
388 }
389
400 friend std::ostream& operator<<(
401 std::ostream& s, const framework::Bus::Passenger<BaggageType>& p) {
402 p.stream(s);
403 return s;
404 }
405
406 private:
411 template <typename>
412 struct the_type {};
413
414 private: // specializations of attach
425 class DeleteObjectStatus : public TBranchElement {
426 DeleteObjectStatus() = delete;
427 DeleteObjectStatus(const DeleteObjectStatus&) = delete;
428
429 public:
430 static int bit() { return TBranchElement::EStatusBits::kDeleteObject; }
431 };
432
457 template <typename T>
458 TBranch* attach(the_type<T> t, TTree* tree, const std::string& branch_name,
459 bool can_create) {
460 TBranch* branch = tree->GetBranch(branch_name.c_str());
461 if (branch) {
475 if (dynamic_cast<TBranchElement*>(branch)) {
476 branch->SetBit(DeleteObjectStatus::bit(), false);
477 }
478 branch->SetObject(baggage_);
479 } else if (can_create) {
484 branch = tree->Branch(branch_name.c_str(), baggage_, 100000, 3);
485 }
486 return branch;
487 }
488
513 TBranch* attachBasic(TTree* tree, const std::string& branch_name,
514 bool can_create) {
515 TBranch* branch = tree->GetBranch(branch_name.c_str());
516 if (branch) {
517 // branch already exists
518 // set the object the branch should read/write from/to
519 branch->SetAddress(baggage_);
520 } else if (can_create) {
521 static const std::map<std::string, std::string> cpp_to_root_type_name =
522 {{"b", "O"}, {"s", "S"}, {"i", "I"},
523 {"l", "L"}, {"f", "F"}, {"d", "D"}};
524 // branch doesnt exist and we are allowed to make a new one
525 std::string cpp_type = typeid(*baggage_).name();
526 branch = tree->Branch(
527 branch_name.c_str(), baggage_,
528 (branch_name + "/" + cpp_to_root_type_name.at(cpp_type)).c_str());
529 }
530 return branch;
531 }
532
544 TBranch* attach(the_type<bool> t, TTree* tree,
545 const std::string& branch_name, bool can_create) {
546 return attachBasic(tree, branch_name, can_create);
547 }
548
560 TBranch* attach(the_type<short> t, TTree* tree,
561 const std::string& branch_name, bool can_create) {
562 return attachBasic(tree, branch_name, can_create);
563 }
564
576 TBranch* attach(the_type<int> t, TTree* tree,
577 const std::string& branch_name, bool can_create) {
578 return attachBasic(tree, branch_name, can_create);
579 }
580
592 TBranch* attach(the_type<long> t, TTree* tree,
593 const std::string& branch_name, bool can_create) {
594 return attachBasic(tree, branch_name, can_create);
595 }
596
608 TBranch* attach(the_type<float> t, TTree* tree,
609 const std::string& branch_name, bool can_create) {
610 return attachBasic(tree, branch_name, can_create);
611 }
612
624 TBranch* attach(the_type<double> t, TTree* tree,
625 const std::string& branch_name, bool can_create) {
626 return attachBasic(tree, branch_name, can_create);
627 }
628
629 private: // specializations of clear
634 void clear(the_type<bool> t) { *baggage_ = false; }
635
641 *baggage_ = std::numeric_limits<BaggageType>::min();
642 }
643
649 *baggage_ = std::numeric_limits<BaggageType>::min();
650 }
651
657 *baggage_ = std::numeric_limits<BaggageType>::min();
658 }
659
665 *baggage_ = std::numeric_limits<BaggageType>::min();
666 }
667
673 *baggage_ = std::numeric_limits<BaggageType>::min();
674 }
675
686 template <typename T>
688 baggage_->Clear();
689 }
690
695 template <typename Content>
696 void clear(the_type<std::vector<Content>> t) {
697 baggage_->clear();
698 }
699
704 template <typename Key, typename Val>
705 void clear(the_type<std::map<Key, Val>> t) {
706 baggage_->clear();
707 }
708
709 private: // specializations of post_update
714 template <typename T>
716
730 private: // specializations of stream
742 template <typename T>
743 void stream(the_type<T> t, std::ostream& s) const {
744 // s << *baggagage_;
745 }
746
756 template <typename Content>
757 void stream(the_type<std::vector<Content>> t, std::ostream& s) const {
758 s << baggage_->size();
759 /*
760 s << "[ ";
761 for (auto const& entry : *baggage_) s << entry << " ";
762 s << "]";
763 */
764 }
765
776 template <typename Key, typename Val>
777 void stream(the_type<std::map<Key, Val>> t, std::ostream& s) const {
778 s << baggage_->size();
779 /*
780 s << "{ ";
781 for (auto const& [k, v] : *baggage_) {
782 s << k << " -> " << v << " ";
783 }
784 s << "}";
785 */
786 }
787
788 private:
790 BaggageType* baggage_;
791 }; // Passenger
792
793 private:
809 template <typename BaggageType>
810 Passenger<BaggageType>& getRef(const std::string& name) {
811 return dynamic_cast<Passenger<BaggageType>&>(*passengers_[name]);
812 }
813
814 private:
821 std::unordered_map<std::string, std::unique_ptr<Seat>> passengers_;
822
823}; // Bus
824
825} // namespace framework
826
827#endif // FRAMEWORK_BUS_H
Empty class to access protected status bit.
Definition Bus.h:425
A bus passenger.
Definition Bus.h:287
void clear(the_type< std::map< Key, Val > > t)
Clear a map by calling the std::map::clear method.
Definition Bus.h:705
Passenger()
Constructor.
Definition Bus.h:299
virtual void stream(std::ostream &s) const
Stream the passenger's object to the input ostream.
Definition Bus.h:386
const BaggageType & get() const
Get the object this passenger is carrying.
Definition Bus.h:352
void clear(the_type< short > t)
Clear short by setting it to the minimum defined by the compiler.
Definition Bus.h:640
void clear(the_type< int > t)
Clear int by setting it to the minimum defined by the compiler.
Definition Bus.h:648
TBranch * attach(the_type< long > t, TTree *tree, const std::string &branch_name, bool can_create)
Specialization for longs.
Definition Bus.h:592
void stream(the_type< T > t, std::ostream &s) const
For std::vector, use the sort method after the contents are updated.
Definition Bus.h:743
void clear(the_type< double > t)
Clear double by setting it to the minimum defined by the compiler.
Definition Bus.h:672
virtual TBranch * attach(TTree *tree, const std::string &branch_name, bool can_create)
Attach this passenger to the input tree.
Definition Bus.h:343
void clear(the_type< float > t)
Clear float by setting it to the minimum defined by the compiler.
Definition Bus.h:664
void stream(the_type< std::map< Key, Val > > t, std::ostream &s) const
Stream a map of objects by looping through them.
Definition Bus.h:777
TBranch * attachBasic(TTree *tree, const std::string &branch_name, bool can_create)
Attach a basic type.
Definition Bus.h:513
TBranch * attach(the_type< short > t, TTree *tree, const std::string &branch_name, bool can_create)
Specialization for shorts.
Definition Bus.h:560
BaggageType * baggage_
A pointer to the baggage we own and created.
Definition Bus.h:790
friend std::ostream & operator<<(std::ostream &s, const framework::Bus::Passenger< BaggageType > &p)
Stream this object to the output stream.
Definition Bus.h:400
virtual void clear()
Reset the object we are carrying to an undefined state.
Definition Bus.h:377
TBranch * attach(the_type< T > t, TTree *tree, const std::string &branch_name, bool can_create)
Attach to a (potentially) new branch on the input tree.
Definition Bus.h:458
void clear(the_type< bool > t)
Clear bool by setting it to false.
Definition Bus.h:634
TBranch * attach(the_type< double > t, TTree *tree, const std::string &branch_name, bool can_create)
Specialization for doubles.
Definition Bus.h:624
void post_update(the_type< T > t)
In general, don't do anything after an object has been updated.
Definition Bus.h:715
void update(const BaggageType &updated_obj)
Update this passenger's baggage.
Definition Bus.h:365
virtual ~Passenger()
Destructor.
Definition Bus.h:318
TBranch * attach(the_type< bool > t, TTree *tree, const std::string &branch_name, bool can_create)
Specialization for bools.
Definition Bus.h:544
void clear(the_type< long > t)
Clear long by setting it to the minimum defined by the compiler.
Definition Bus.h:656
void stream(the_type< std::vector< Content > > t, std::ostream &s) const
Stream a vector of objects by looping through them.
Definition Bus.h:757
TBranch * attach(the_type< int > t, TTree *tree, const std::string &branch_name, bool can_create)
Specialization for ints.
Definition Bus.h:576
void clear(the_type< std::vector< Content > > t)
Clear a vector by calling the std::vector::clear method.
Definition Bus.h:696
TBranch * attach(the_type< float > t, TTree *tree, const std::string &branch_name, bool can_create)
Specialization for floats.
Definition Bus.h:608
void clear(the_type< T > t)
Clear a general class by calling its 'Clear' method.
Definition Bus.h:687
The handle of a bus passenger.
Definition Bus.h:180
virtual void stream(std::ostream &s) const =0
Define how we should stream the object to the input stream.
friend std::ostream & operator<<(std::ostream &s, const std::unique_ptr< framework::Bus::Seat > &seat)
Stream this object to the output stream.
Definition Bus.h:238
virtual void clear()=0
Clear this passenger.
virtual TBranch * attach(TTree *tree, const std::string &branch_name, bool can_create)=0
Attach this passenger to the input tree.
virtual ~Seat()
Destructor.
Definition Bus.h:188
A map of bus passengers.
Definition Bus.h:29
const BaggageType & get(const std::string &name)
Get the baggage carried by the passenger with the passed name.
Definition Bus.h:43
void update(const std::string &name, const BaggageType &obj)
Update the object a passenger is carrying.
Definition Bus.h:83
void clear()
Reset the objects carried by the passengers.
Definition Bus.h:126
friend std::ostream & operator<<(std::ostream &s, const framework::Bus &b)
Allow for the bus to be streamed to an ostream.
Definition Bus.h:164
void stream(std::ostream &s) const
Write the bus to the input ostream.
Definition Bus.h:150
bool isOnBoard(const std::string &name)
Check if a passenger is on the bus.
Definition Bus.h:117
TBranch * attach(TTree *tree, const std::string &name, bool can_create)
Attach the input tree to the object a passenger is carrying.
Definition Bus.h:107
void board(const std::string &name)
Board a new passenger onto the bus.
Definition Bus.h:65
void everybodyOff()
Kicks all of the passengers off the bus and therefore destroys any objects they are carrying.
Definition Bus.h:140
Passenger< BaggageType > & getRef(const std::string &name)
Get a reference to a passenger on the bus.
Definition Bus.h:810
std::unordered_map< std::string, std::unique_ptr< Seat > > passengers_
Map of passenger names to the seats filled by passengers.
Definition Bus.h:821
All classes in the ldmx-sw project use this namespace.
Definition PerfDict.cxx:45
A simple, empty struct to allow us to pass the type of baggage to functions as a parameter.
Definition Bus.h:412