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