File indexing completed on 2025-03-13 08:19:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/detail/Handle.inl>
0016 #include <DD4hep/detail/DetectorInterna.h>
0017 #include <DD4hep/detail/ConditionsInterna.h>
0018 #include <DD4hep/detail/AlignmentsInterna.h>
0019 #include <DD4hep/InstanceCount.h>
0020 #include <DD4hep/DetectorTools.h>
0021 #include <DD4hep/Printout.h>
0022
0023 #include <TGeoVolume.h>
0024 #include <TGeoMatrix.h>
0025 #include <TGeoManager.h>
0026
0027 using namespace dd4hep;
0028
0029 using PlacementPath = detail::tools::PlacementPath;
0030 using ElementPath = detail::tools::ElementPath;
0031
0032 DD4HEP_INSTANTIATE_HANDLE_NAMED(DetElementObject);
0033 DD4HEP_INSTANTIATE_HANDLE_NAMED(SensitiveDetectorObject);
0034 DD4HEP_INSTANTIATE_HANDLE_NAMED(WorldObject,DetElementObject);
0035
0036
0037 SensitiveDetectorObject::SensitiveDetectorObject()
0038 : NamedObject(), ObjectExtensions(typeid(SensitiveDetectorObject)), magic(magic_word()),
0039 verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection() {
0040 printout(VERBOSE,"SensitiveDetectorObject","+++ Created new anonymous SensitiveDetectorObject()");
0041 InstanceCount::increment(this);
0042 }
0043
0044
0045 SensitiveDetectorObject::SensitiveDetectorObject(const std::string& nam)
0046 : NamedObject(), ObjectExtensions(typeid(SensitiveDetectorObject)), magic(magic_word()),
0047 verbose(0), combineHits(0), ecut(0.0), readout(), region(), limits(), hitsCollection() {
0048 SetName(nam.c_str());
0049 printout(VERBOSE,"SensitiveDetectorObject","+++ Created new SensitiveDetectorObject('%s')",nam.c_str());
0050 InstanceCount::increment(this);
0051 }
0052
0053
0054 SensitiveDetectorObject::~SensitiveDetectorObject() {
0055 readout.clear();
0056 region.clear();
0057 limits.clear();
0058 ObjectExtensions::clear();
0059 InstanceCount::decrement(this);
0060 }
0061
0062
0063 DetElementObject::DetElementObject()
0064 : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()),
0065 flag(0), id(0), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(),
0066 idealPlace(), placement(), volumeID(0), parent(), children(),
0067 nominal(), survey()
0068 {
0069 printout(VERBOSE,"DetElementObject","+++ Created new anonymous DetElementObject()");
0070 InstanceCount::increment(this);
0071 }
0072
0073
0074 DetElementObject::DetElementObject(const std::string& nam, int ident)
0075 : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()),
0076 flag(0), id(ident), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(),
0077 idealPlace(), placement(), volumeID(0), parent(), children(),
0078 nominal(), survey()
0079 {
0080 SetName(nam.c_str());
0081 printout(VERBOSE,"DetElementObject","+++ Created new DetElementObject('%s', %d)",nam.c_str(),id);
0082 InstanceCount::increment(this);
0083 }
0084
0085
0086 DetElementObject::~DetElementObject() {
0087 detail::destroyHandles(children);
0088 detail::destroyHandle (nominal);
0089 detail::destroyHandle (survey);
0090 placement.clear();
0091 idealPlace.clear();
0092 parent.clear();
0093 ObjectExtensions::clear();
0094 InstanceCount::decrement(this);
0095 }
0096
0097
0098 DetElementObject* DetElementObject::clone(int new_id, int flg) const {
0099 DetElementObject* obj = new DetElementObject();
0100 obj->id = new_id;
0101 obj->typeFlag = typeFlag;
0102 obj->flag = 0;
0103 obj->key = 0;
0104 obj->level = -1;
0105 obj->combineHits = combineHits;
0106 obj->nominal = AlignmentCondition();
0107 obj->survey = AlignmentCondition();
0108 obj->parent = DetElement();
0109 if ( (flg & DetElement::COPY_PLACEMENT) == DetElement::COPY_PLACEMENT ) {
0110 obj->placement = placement;
0111 obj->idealPlace = idealPlace;
0112 obj->placementPath = "";
0113 }
0114
0115 obj->ObjectExtensions::clear();
0116 obj->ObjectExtensions::copyFrom(extensions, obj);
0117
0118 obj->children.clear();
0119 for (const auto& i : children ) {
0120 const DetElementObject& d = i.second._data();
0121 int child_id = flg&DetElement::PROPAGATE_PARENT_ID ? obj->id : d.id;
0122 DetElement c = d.clone(child_id, DetElement::COPY_PLACEMENT);
0123 c->SetName(d.GetName());
0124 c->SetTitle(d.GetTitle());
0125 bool r = obj->children.emplace(c.name(), c).second;
0126 if ( r ) {
0127 c._data().parent = obj;
0128 }
0129 else {
0130 except("DetElement","+++ DetElement::copy: Element %s is already "
0131 "present [Double-Insert]", c.name());
0132 }
0133 }
0134 return obj;
0135 }
0136
0137
0138 std::pair<DetElement,Volume> DetElementObject::reflect(const std::string& new_name, int new_id, SensitiveDetector sd) {
0139 struct ChildMapper {
0140 std::map<TGeoNode*,TGeoNode*> nodes;
0141 void match(DetElement de_det, DetElement de_ref) const {
0142 auto k = nodes.find(de_det.placement().ptr());
0143 printout(DEBUG,"DetElement","reflect: Match %s %p ",de_det.name(), de_det.placement().ptr());
0144 if ( k == nodes.end() ) {
0145 except("DetElement","reflect: Something went wrong when reflecting the source volume!");
0146 }
0147 de_ref.setPlacement((*k).second);
0148 const auto& childrens_det = de_det.children();
0149 const auto& childrens_ref = de_ref.children();
0150 for(auto i=childrens_det.begin(), j=childrens_ref.begin(); i!=childrens_det.end(); ++i, ++j)
0151 match((*i).second, (*j).second);
0152 }
0153 void map(TGeoNode* n1, TGeoNode* n2) {
0154 if ( nodes.find(n1) == nodes.end() ) {
0155 TGeoVolume* v1 = n1->GetVolume();
0156 TGeoVolume* v2 = n2->GetVolume();
0157 nodes.insert(std::make_pair(n1,n2));
0158 printout(DEBUG,"DetElement","reflect: Map %p --- %p ",n1,n2);
0159 for(Int_t i=0; i<v1->GetNdaughters(); ++i)
0160 map(v1->GetNode(i), v2->GetNode(i));
0161 }
0162 }
0163 } mapper;
0164 DetElement det(this);
0165 DetElement det_ref = det.clone(new_name, new_id);
0166 Volume vol = det.volume();
0167 TGeoVolume* vol_det = vol.ptr();
0168 TGeoVolume* vol_ref = vol.reflect(sd);
0169 const auto& childrens_det = det.children();
0170 const auto& childrens_ref = det_ref.children();
0171
0172 for(Int_t i=0; i<vol_det->GetNdaughters(); ++i)
0173 mapper.map(vol_det->GetNode(i), vol_ref->GetNode(i));
0174 for(auto i=childrens_det.begin(), j=childrens_ref.begin(); i!=childrens_det.end(); ++i, ++j)
0175 mapper.match((*i).second, (*j).second);
0176 return std::make_pair(det_ref,vol_ref);
0177 }
0178
0179
0180 World DetElementObject::i_access_world() {
0181 if ( !privateWorld.isValid() ) {
0182 DetElementObject* p = parent.ptr();
0183 if ( 0 == p ) {
0184 privateWorld = (WorldObject*)this;
0185 return privateWorld;
0186 }
0187 return p->world();
0188 }
0189 return privateWorld;
0190 }
0191
0192
0193 void DetElementObject::revalidate() {
0194 PlacementPath par_path;
0195 DetElement det(this);
0196 DetElement par(det.parent());
0197 DetElement wrld = world();
0198 std::string place = det.placementPath();
0199
0200 detail::tools::placementPath(par, this, par_path);
0201 PlacedVolume node = detail::tools::findNode(wrld.placement(),place);
0202 if ( !node.isValid() ) {
0203 except("DetElement","The placement %s is not part of the hierarchy.",place.c_str());
0204 }
0205 printout((idealPlace.ptr() != node.ptr()) ? INFO : DEBUG,
0206 "DetElement","+++ Invalidate chache of %s -> %s Placement:%p --> %p %s",
0207 det.path().c_str(), detail::tools::placementPath(par_path).c_str(),
0208 placement.ptr(), node.ptr(), (placement.ptr() == node.ptr()) ? "" : "[UPDATE]");
0209 if ( idealPlace.ptr() != node.ptr() && 0 == node->GetUserExtension() ) {
0210 auto ext = idealPlace->GetUserExtension();
0211 node->SetUserExtension(ext);
0212 }
0213 Volume node_vol = node.volume();
0214 Volume plac_vol = idealPlace.volume();
0215 if ( node_vol.ptr() != plac_vol.ptr() && 0 == node_vol->GetUserExtension() ) {
0216 auto ext = plac_vol->GetUserExtension();
0217 node_vol->SetUserExtension(ext);
0218 }
0219
0220 placement = node;
0221
0222 for(const auto& i : children )
0223 i.second->revalidate();
0224 }
0225
0226
0227 void DetElementObject::removeAtUpdate(unsigned int typ, void* pointer) {
0228 for (auto i=updateCalls.begin(); i != updateCalls.end(); ++i) {
0229 if ( (typ&((*i).second)) == typ && (*i).first.par == pointer ) {
0230 updateCalls.erase(i);
0231 return;
0232 }
0233 }
0234 }
0235
0236
0237 void DetElementObject::update(unsigned int tags, void* param) {
0238 DetElement det(this);
0239 const void* args[3] = { (void*)((unsigned long)tags), this, param };
0240 if ( (tags&DetElement::PLACEMENT_CHANGED)==DetElement::PLACEMENT_CHANGED &&
0241 (tags&DetElement::PLACEMENT_HIGHEST)==DetElement::PLACEMENT_HIGHEST ) {
0242 printout(INFO,"DetElement",
0243 "++ Need to update local and child caches of %s",
0244 det.path().c_str());
0245 revalidate();
0246 }
0247 for ( const auto& i : updateCalls ) {
0248 if ( (tags&i.second) )
0249 i.first.execute(args);
0250 }
0251 }
0252
0253
0254 WorldObject::WorldObject(Detector& _description, const std::string& nam)
0255 : DetElementObject(nam,0), description(&_description)
0256 {
0257 }
0258
0259
0260 WorldObject::~WorldObject() {
0261 }