File indexing completed on 2025-01-18 09:13:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/IDDescriptor.h>
0016 #include <DD4hep/detail/Handle.inl>
0017 #include <DD4hep/detail/ObjectsInterna.h>
0018 #include <DD4hep/InstanceCount.h>
0019 #include <DD4hep/Volumes.h>
0020 #include <DD4hep/Printout.h>
0021
0022
0023 #include <stdexcept>
0024 #include <cstdlib>
0025 #include <cmath>
0026
0027 using namespace dd4hep;
0028
0029 namespace {
0030 void _construct(IDDescriptor::Object* o, const std::string& dsc) {
0031 BitFieldCoder& bf = o->decoder;
0032 o->fieldIDs.clear();
0033 o->fieldMap.clear();
0034 o->description = dsc;
0035 for (size_t i = 0; i < bf.size(); ++i) {
0036 const BitFieldElement* f = &bf[i];
0037 o->fieldIDs.emplace_back(i, f->name());
0038 o->fieldMap.emplace_back(f->name(), f);
0039 }
0040 }
0041 }
0042
0043
0044 IDDescriptor::IDDescriptor(const std::string& nam, const std::string& description) {
0045 Object* obj = new Object(description);
0046 assign(obj, nam, "iddescriptor");
0047 _construct(obj, description);
0048 }
0049
0050
0051 void IDDescriptor::rebuild(const std::string& description) {
0052 Object* p = ptr();
0053 std::string dsc = description;
0054 p->decoder.~BitFieldCoder();
0055 new(&p->decoder) BitFieldCoder(dsc);
0056 _construct(p, dsc);
0057 }
0058
0059
0060 std::string IDDescriptor::toString() const {
0061 if ( isValid() ) {
0062 return m_element->GetName();
0063 }
0064 return "----";
0065 }
0066
0067 std::string IDDescriptor::fieldDescription() const {
0068 BitFieldCoder& bf = data<Object>()->decoder;
0069 return bf.fieldDescription();
0070 }
0071
0072
0073 unsigned IDDescriptor::maxBit() const {
0074 return data<Object>()->decoder.highestBit();
0075 }
0076
0077
0078 const IDDescriptor::FieldIDs& IDDescriptor::ids() const {
0079 if ( isValid() ) {
0080 return data<Object>()->fieldIDs;
0081 }
0082 except("IDDescriptor","dd4hep: Attempt to access an invalid IDDescriptor object.");
0083 throw std::runtime_error("dd4hep");
0084 }
0085
0086
0087 const IDDescriptor::FieldMap& IDDescriptor::fields() const {
0088 if ( isValid() ) {
0089 return data<Object>()->fieldMap;
0090 }
0091 except("IDDescriptor","dd4hep: Attempt to access an invalid IDDescriptor object.");
0092 throw std::runtime_error("dd4hep");
0093 }
0094
0095
0096 const BitFieldElement* IDDescriptor::field(const std::string& field_name) const {
0097 const FieldMap& fm = fields();
0098 for (const auto& i : fm )
0099 if (i.first == field_name)
0100 return i.second;
0101 except("IDDescriptor","dd4hep: %s: This ID descriptor has no field with the name: %s",
0102 name(),field_name.c_str());
0103 throw std::runtime_error("dd4hep");
0104 }
0105
0106
0107 const BitFieldElement* IDDescriptor::field(size_t identifier) const {
0108 const FieldMap& fm = fields();
0109 return fm[identifier].second;
0110 }
0111
0112
0113 std::size_t IDDescriptor::fieldID(const std::string& field_name) const {
0114 const FieldIDs& fm = ids();
0115 for (const auto& i : fm )
0116 if (i.second == field_name)
0117 return i.first;
0118 except("IDDescriptor","dd4hep: %s: This ID descriptor has no field with the name: %s",
0119 name(),field_name.c_str());
0120 throw std::runtime_error("dd4hep");
0121 }
0122
0123
0124 VolumeID IDDescriptor::get_mask(const std::vector<std::pair<std::string, int> >& id_vector) const {
0125 VolumeID mask = 0ULL;
0126 for (const auto& i : id_vector ) {
0127 const auto* fld = field(i.first);
0128 mask |= fld->mask();
0129 }
0130 return mask;
0131 }
0132
0133
0134 VolumeID IDDescriptor::encode(const std::vector<std::pair<std::string, int> >& id_vector) const {
0135 VolumeID id = 0;
0136
0137
0138 for (const auto& i : id_vector ) {
0139 const BitFieldElement* fld = field(i.first);
0140 int off = fld->offset();
0141 VolumeID val = i.second;
0142 id |= ((fld->value(val << off) << off)&fld->mask());
0143 }
0144 return id;
0145 }
0146
0147
0148 VolumeID IDDescriptor::encode(const Field* fld, VolumeID value) {
0149 if ( fld ) {
0150 int off = fld->offset();
0151 return ((fld->value(value << off) << off)&fld->mask());
0152 }
0153 except("IDDescriptor","dd4hep: %s: Cannot encode value with void Field reference.");
0154 return 0UL;
0155 }
0156
0157
0158 VolumeID IDDescriptor::encode_reverse(const std::vector<std::pair<std::string, int> >& id_vector) const
0159 {
0160 return detail::reverseBits<VolumeID>(encode(id_vector));
0161 }
0162
0163
0164 void IDDescriptor::decodeFields(VolumeID vid,
0165 std::vector<std::pair<const BitFieldElement*, VolumeID> >& flds) const
0166 {
0167 const std::vector<BitFieldElement>& v = access()->decoder.fields();
0168 flds.clear();
0169 for (auto& f : v )
0170 flds.emplace_back(&f, f.value(vid));
0171 }
0172
0173
0174 std::string IDDescriptor::str(VolumeID vid) const {
0175 const std::vector<BitFieldElement>& v = access()->decoder.fields();
0176 std::stringstream str;
0177 for (auto& f : v )
0178 str << f.name() << ":" << std::setw(4) << std::setfill('0')
0179 << std::hex << std::right << f.value(vid)
0180 << std::left << std::dec << " ";
0181 return str.str().substr(0, str.str().length()-1);
0182 }
0183
0184
0185 std::string IDDescriptor::str(VolumeID vid, VolumeID mask) const {
0186 const std::vector<BitFieldElement>& v = access()->decoder.fields();
0187 std::stringstream str;
0188 for (auto& f : v ) {
0189 if ( 0 == (mask&f.mask()) ) continue;
0190 str << f.name() << ":" << std::setw(4) << std::setfill('0')
0191 << std::hex << std::right << f.value(vid)
0192 << std::left << std::dec << " ";
0193 }
0194 return str.str().substr(0, str.str().length()-1);
0195 }
0196
0197
0198 BitFieldCoder* IDDescriptor::decoder() const {
0199 return &(data<Object>()->decoder);
0200 }