LDMX Software
DetectorIDInterpreter.cxx
1#include "DetDescr/DetectorIDInterpreter.h"
2
3#include "DetDescr/EcalID.h"
5#include "DetDescr/HcalID.h"
6#include "DetDescr/SimSpecialID.h"
8#include "DetDescr/TrigScintID.h"
9
10namespace ldmx {
11
12std::map<DetectorIDInterpreter::IDSignature,
13 const DetectorIDInterpreter::SubdetectorIDFields*>
14 DetectorIDInterpreter::g_rosettaStone;
15
16DetectorIDInterpreter::~DetectorIDInterpreter() {}
17DetectorIDInterpreter::DetectorIDInterpreter() : id_(), p_fieldInfo_(0) {
18 init();
19}
20
21DetectorIDInterpreter::DetectorIDInterpreter(DetectorID did)
22 : id_(did), p_fieldInfo_(0) {
23 init();
24 unpack();
25}
26
27void DetectorIDInterpreter::setRawValue(DetectorID rawValue) {
28 id_ = rawValue;
29 init();
30 unpack();
31}
32
33void DetectorIDInterpreter::unpack() {
34 std::fill(fieldValues_.begin(), fieldValues_.end(), 0);
35 if (!p_fieldInfo_) return;
36 for (auto field : p_fieldInfo_->fieldList_) {
37 unsigned result = (field->getBitMask() & id_.raw()) >> field->getStartBit();
38 this->fieldValues_[field->getIndex()] = result;
39 }
40}
41
42void DetectorIDInterpreter::pack() {
43 DetectorID::RawValue rawValue = 0;
44 for (auto field : p_fieldInfo_->fieldList_) {
45 unsigned fieldValue = fieldValues_[field->getIndex()];
46 rawValue =
47 rawValue | ((fieldValue << field->getStartBit()) & field->getBitMask());
48 }
49 id_.setRawValue(rawValue);
50}
51
52DetectorIDInterpreter::FieldValue DetectorIDInterpreter::getFieldValue(
53 int i) const {
54 IDField* field = p_fieldInfo_->fieldList_.at(i);
55 unsigned result = (field->getBitMask() & id_.raw()) >> field->getStartBit();
56 return result;
57}
58
59void DetectorIDInterpreter::setFieldValue(int i, FieldValue val) {
60 fieldValues_[i] = val;
61 pack(); // keep packed
62}
63
64void DetectorIDInterpreter::setFieldValue(const std::string& fieldName,
65 FieldValue fieldValue) {
66 auto byname = p_fieldInfo_->fieldMap_.find(fieldName);
67 if (byname != p_fieldInfo_->fieldMap_.end())
68 fieldValues_[byname->second->getIndex()] = fieldValue;
69 pack(); // keep packed
70}
71
72const IDField* DetectorIDInterpreter::getField(
73 const std::string& fieldName) const {
74 auto byname = p_fieldInfo_->fieldMap_.find(fieldName);
75 if (byname != p_fieldInfo_->fieldMap_.end()) return (byname->second);
76 return 0;
77}
78
79DetectorIDInterpreter::FieldValue DetectorIDInterpreter::getFieldValue(
80 const std::string& fieldName) const {
81 auto byname = p_fieldInfo_->fieldMap_.find(fieldName);
82 return getFieldValue(byname->second->getIndex());
83}
84
85void DetectorIDInterpreter::init() {
86 if (g_rosettaStone.empty()) loadStandardInterpreters();
87
88 p_fieldInfo_ = 0;
89
90 if (id_.null()) return;
91
92 for (auto ptr : g_rosettaStone) {
93 if ((id_.raw() & ptr.first.mask_) == ptr.first.comparison_) {
94 p_fieldInfo_ = (ptr.second);
95 this->fieldValues_.resize(p_fieldInfo_->fieldList_.size());
96 return;
97 }
98 }
99
100 // fell through, no match
101 IDSignature sig;
102 sig.comparison_ = 0;
103 sig.mask_ = DetectorID::SUBDETECTORID_MASK << DetectorID::SUBDETECTORID_SHIFT;
104
105 auto ptr = g_rosettaStone.find(sig);
106 p_fieldInfo_ = (ptr->second);
107 this->fieldValues_.resize(p_fieldInfo_->fieldList_.size());
108}
109
110void DetectorIDInterpreter::registerInterpreter(
111 SubdetectorIDType idtype, const IDField::IDFieldList& fieldList) {
112 IDSignature sig;
113 sig.comparison_ = idtype << DetectorID::SUBDETECTORID_SHIFT;
114 sig.mask_ = DetectorID::SUBDETECTORID_MASK << DetectorID::SUBDETECTORID_SHIFT;
115 if (g_rosettaStone.find(sig) != g_rosettaStone.end()) {
116 EXCEPTION_RAISE("DetectorIDException",
117 "Attempted to replace interpreter for subdetector " +
118 std::to_string(idtype));
119 }
121 fields->fieldList_ = fieldList;
122 for (auto it : fieldList) fields->fieldMap_[it->getFieldName()] = it;
123 g_rosettaStone[sig] = fields;
124}
125
126void DetectorIDInterpreter::registerInterpreter(
127 SubdetectorIDType idtype, unsigned int mask, unsigned int equality,
128 const IDField::IDFieldList& fieldList) {
129 IDSignature sig;
130 sig.comparison_ = (idtype << DetectorID::SUBDETECTORID_SHIFT) | equality;
131 sig.mask_ =
132 (DetectorID::SUBDETECTORID_MASK << DetectorID::SUBDETECTORID_SHIFT) |
133 mask;
134 if (g_rosettaStone.find(sig) != g_rosettaStone.end()) {
135 EXCEPTION_RAISE("DetectorIDException",
136 "Attempted to replace interpreter for subdetector " +
137 std::to_string(idtype) + " mask " +
138 std::to_string(mask) + " equality " +
139 std::to_string(equality));
140 }
142 fields->fieldList_ = fieldList;
143 for (auto it : fieldList) fields->fieldMap_[it->getFieldName()] = it;
144 g_rosettaStone[sig] = fields;
145}
146
147void DetectorIDInterpreter::loadStandardInterpreters() {
148 if (!g_rosettaStone.empty()) return;
150 fields.push_back(
151 new IDField("subdetector", 0, DetectorID::SUBDETECTORID_SHIFT, 31));
152 fields.push_back(
153 new IDField("payload", 2, 0, DetectorID::SUBDETECTORID_SHIFT - 1));
154
155 registerInterpreter(SD_NULL, fields);
156
157 EcalID::createInterpreters();
158 EcalTriggerID::createInterpreters();
159 HcalID::createInterpreters();
160 TrackerID::createInterpreters();
161 TrigScintID::createInterpreters();
162 SimSpecialID::createInterpreters();
163}
164} // namespace ldmx
Class that defines an ECal detector ID with a cell number.
Class that defines an ECal trigger cell detector ID.
Class that defines an HCal sensitive detector.
Class that defines a Tracker detector ID with a module number.
unsigned FieldValue
Definition of the field value type.
Defines a 32-bit packed ID for uniquely identifying hits and detector components.
Definition DetectorID.h:35
Provides information about a field within a DetectorID.
Definition IDField.h:15
unsigned getStartBit()
Get the start bit of the field.
Definition IDField.cxx:19
std::vector< IDField * > IDFieldList
List of fields.
Definition IDField.h:25
unsigned getBitMask()
Get a bit mask for this field.
Definition IDField.cxx:23