Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 08:19:38

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
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 /// Default constructor
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 /// Initializing constructor
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 /// Internal object destructor: release extension object(s)
0054 SensitiveDetectorObject::~SensitiveDetectorObject() {
0055   readout.clear();
0056   region.clear();
0057   limits.clear();
0058   ObjectExtensions::clear();
0059   InstanceCount::decrement(this);
0060 }
0061 
0062 /// Default constructor
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 /// Initializing constructor
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 /// Internal object destructor: release extension object(s)
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 /// Deep object copy to replicate DetElement trees e.g. for reflection
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   // This implicitly assumes that the children do not access the parent's extensions!
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 /// Reflect all volumes in a DetElement sub-tree and re-attach the placements
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 /// Access to the world object. Only possible once the geometry is closed.
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 /// Revalidate the caches
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   // Now we can assign the new placement to the object
0220   placement = node;
0221   /// Now iterate down the children....
0222   for(const auto& i : children )
0223     i.second->revalidate();
0224 }
0225 
0226 /// Remove callback from object
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 /// Trigger update callbacks
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 /// Initializing constructor
0254 WorldObject::WorldObject(Detector& _description, const std::string& nam) 
0255   : DetElementObject(nam,0), description(&_description)
0256 {
0257 }
0258 
0259 /// Internal object destructor: release extension object(s)
0260 WorldObject::~WorldObject()  {
0261 }