Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:54

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/DetectorInterna.h>
0016 #include <DD4hep/detail/ConditionsInterna.h>
0017 #include <DD4hep/detail/AlignmentsInterna.h>
0018 #include <DD4hep/AlignmentTools.h>
0019 #include <DD4hep/DetectorTools.h>
0020 #include <DD4hep/Printout.h>
0021 #include <DD4hep/Detector.h>
0022 #include <DD4hep/World.h>
0023 
0024 using namespace dd4hep;
0025     
0026 namespace {
0027   static std::string s_empty_string;
0028 }
0029 
0030 /// Default constructor
0031 DetElement::Processor::Processor()   {
0032 }
0033 
0034 /// Default destructor
0035 DetElement::Processor::~Processor()   {
0036 }
0037 
0038 /// Clone constructor
0039 DetElement::DetElement(Object* det_data, const std::string& det_name, const std::string& det_type)
0040   : Handle<DetElementObject>(det_data)
0041 {
0042   this->assign(det_data, det_name, det_type);
0043 }
0044 
0045 /// Constructor for a new subdetector element
0046 DetElement::DetElement(const std::string& det_name, const std::string& det_type, int det_id) {
0047   assign(new Object(det_name,det_id), det_name, det_type);
0048   ptr()->id = det_id;
0049 }
0050 
0051 /// Constructor for a new subdetector element
0052 DetElement::DetElement(const std::string& det_name, int det_id) {
0053   assign(new Object(det_name,det_id), det_name, "");
0054   ptr()->id = det_id;
0055 }
0056 
0057 /// Constructor for a new subdetector element
0058 DetElement::DetElement(DetElement det_parent, const std::string& det_name, int det_id) {
0059   assign(new Object(det_name,det_id), det_name, det_parent.type());
0060   ptr()->id = det_id;
0061   det_parent.add(*this);
0062 }
0063 
0064 /// Add an extension object to the detector element
0065 void* DetElement::addExtension(ExtensionEntry* e) const  {
0066   return access()->addExtension(e->hash64(), e);
0067 }
0068 
0069 /// Access an existing extension object from the detector element
0070 void* DetElement::extension(unsigned long long int k, bool alert) const {
0071   return access()->extension(k, alert);
0072 }
0073 
0074 /// Internal call to extend the detector element with an arbitrary structure accessible by the type
0075 void DetElement::i_addUpdateCall(unsigned int callback_type, const Callback& callback)  const  {
0076   access()->updateCalls.emplace_back(callback,callback_type);
0077 }
0078 
0079 /// Remove callback from object
0080 void DetElement::removeAtUpdate(unsigned int typ, void* pointer)  const {
0081   access()->removeAtUpdate(typ,pointer);
0082 }
0083 
0084 /// Access to the full path to the placed object
0085 const std::string& DetElement::placementPath() const {
0086   Object* o = ptr();
0087   if ( o ) {
0088     if (o->placementPath.empty()) {
0089       o->placementPath = detail::tools::placementPath(*this);
0090     }
0091     return o->placementPath;
0092   }
0093   return s_empty_string;
0094 }
0095 
0096 /// Access detector type (structure, tracker, calorimeter, etc.).
0097 std::string DetElement::type() const {
0098   return m_element ? m_element->GetTitle() : "";
0099 }
0100 
0101 /// Set the type of the sensitive detector
0102 DetElement& DetElement::setType(const std::string& typ) {
0103   access()->SetTitle(typ.c_str());
0104   return *this;
0105 }
0106 
0107 /// Access the type of the sensitive detector
0108 unsigned int DetElement::typeFlag() const {
0109   return m_element ? m_element->typeFlag :  0 ;
0110 }
0111 
0112 /// Set the type of the sensitive detector
0113 DetElement& DetElement::setTypeFlag(unsigned int types) {
0114   access()->typeFlag = types ;
0115   return *this;
0116 }
0117 
0118 namespace {
0119   static void make_path(DetElement::Object* o)   {
0120     DetElement par = o->parent;
0121     if ( par.isValid() )  {
0122       o->path = par.path() + "/" + o->name;
0123       if ( o->level < 0 ) o->level = par.level() + 1;
0124     }
0125     else {
0126       o->path = "/" + o->name;
0127       o->level = 0;
0128     }
0129     o->key = dd4hep::detail::hash32(o->path);
0130   }
0131 }
0132 
0133 /// Access hash key of this detector element (Only valid once geometry is closed!)
0134 unsigned int DetElement::key()  const   {
0135   Object* o = ptr();
0136   if ( o )  {
0137     if ( o->key != 0 )
0138       return o->key;
0139     make_path(o);
0140     return o->key;
0141   }
0142   return 0;
0143 }
0144 
0145 /// Access the hierarchical level of the detector element
0146 int DetElement::level()  const   {
0147   Object* o = ptr();
0148   if ( o )  {
0149     if ( o->level >= 0 )
0150       return o->level;
0151     make_path(o);
0152     return o->level;
0153   }
0154   return -1;
0155 }
0156 
0157 /// Access the full path of the detector element
0158 const std::string& DetElement::path() const {
0159   Object* o = ptr();
0160   if ( o ) {
0161     if ( !o->path.empty() )
0162       return o->path;
0163     make_path(o);
0164     return o->path;
0165   }
0166   return s_empty_string;
0167 }
0168 
0169 int DetElement::id() const {
0170   return access()->id;
0171 }
0172 
0173 bool DetElement::combineHits() const {
0174   return access()->combineHits != 0;
0175 }
0176 
0177 DetElement& DetElement::setCombineHits(bool value, SensitiveDetector& sens) {
0178   access()->combineHits = value;
0179   if (sens.isValid())
0180     sens.setCombineHits(value);
0181   return *this;
0182 }
0183 
0184 /// Access to the alignment information
0185 Alignment DetElement::nominal() const   {
0186   Object* o = access();
0187   if ( !o->nominal.isValid() )   {
0188     o->nominal = AlignmentCondition("nominal");
0189     o->nominal->values().detector = *this;
0190     //o->flag |= Object::HAVE_WORLD_TRAFO;
0191     //o->flag |= Object::HAVE_PARENT_TRAFO;
0192     dd4hep::detail::tools::computeIdeal(o->nominal);
0193   }
0194   return o->nominal;
0195 }
0196 
0197 /// Access to the survey alignment information
0198 Alignment DetElement::survey() const  {
0199   Object* o = access();
0200   if ( !o->survey.isValid() )   {
0201     o->survey = AlignmentCondition("survey");
0202     dd4hep::detail::tools::copy(nominal(), o->survey);
0203   }
0204   return o->survey;
0205 }
0206 
0207 const DetElement::Children& DetElement::children() const {
0208   return access()->children;
0209 }
0210 
0211 /// Access to individual children by name
0212 DetElement DetElement::child(const std::string& child_name) const {
0213   if (isValid()) {
0214     const Children& c = ptr()->children;
0215     Children::const_iterator i = c.find(child_name);
0216     if ( i != c.end() ) return (*i).second;
0217     throw std::runtime_error("dd4hep: DetElement::child Unknown child with name: "+child_name);
0218   }
0219   throw std::runtime_error("dd4hep: DetElement::child: Self is not defined [Invalid Handle]");
0220 }
0221 
0222 /// Access to individual children by name. Have option to not throw an exception
0223 DetElement DetElement::child(const std::string& child_name, bool throw_if_not_found) const {
0224   if (isValid()) {
0225     const Children& c = ptr()->children;
0226     Children::const_iterator i = c.find(child_name);
0227     if ( i != c.end() ) return (*i).second;
0228     if ( throw_if_not_found )   {
0229       throw std::runtime_error("dd4hep: DetElement::child Unknown child with name: "+child_name);
0230     }
0231   }
0232   if ( throw_if_not_found )   {
0233     throw std::runtime_error("dd4hep: DetElement::child: Self is not defined [Invalid Handle]");
0234   }
0235   return DetElement();
0236 }
0237 
0238 /// Access to the detector elements's parent
0239 DetElement DetElement::parent() const {
0240   Object* o = ptr();
0241   return (o) ? o->parent : DetElement();
0242 }
0243 
0244 /// Access to the world object. Only possible once the geometry is closed.
0245 DetElement DetElement::world()  const   {
0246   Object* o = ptr();
0247   return (o) ? o->world() : World();
0248 }
0249 
0250 /// Simple checking routine
0251 void DetElement::check(bool cond, const std::string& msg) const {
0252   if (cond) {
0253     throw std::runtime_error("dd4hep: " + msg);
0254   }
0255 }
0256 
0257 /// Add a new child subdetector element
0258 DetElement& DetElement::add(DetElement sdet) {
0259   if (isValid()) {
0260     auto r = object<Object>().children.emplace(sdet.name(), sdet);
0261     if (r.second) {
0262       sdet.access()->parent = *this;
0263       return *this;
0264     }
0265     except("dd4hep",
0266            "DetElement::add: Element %s is already present in path %s [Double-Insert]",
0267            sdet.name(), this->path().c_str());
0268   }
0269   except("dd4hep", "DetElement::add: Self is not defined [Invalid Handle]");
0270   throw std::runtime_error("dd4hep: DetElement::add");
0271 }
0272 
0273 /// Clone (Deep copy) the DetElement structure
0274 DetElement DetElement::clone(int flg) const   {
0275   Object* o = access();
0276   Object* n = o->clone(o->id, flg);
0277   n->SetName(o->GetName());
0278   n->SetTitle(o->GetTitle());
0279   return n;
0280 }
0281 
0282 DetElement DetElement::clone(const std::string& new_name) const {
0283   return clone(new_name, access()->id);
0284 }
0285 
0286 DetElement DetElement::clone(const std::string& new_name, int new_id) const {
0287   Object* o = access();
0288   Object* n = o->clone(new_id, COPY_PLACEMENT);
0289   n->SetName(new_name.c_str());
0290   n->SetTitle(o->GetTitle());
0291   return n;
0292 }
0293 
0294 std::pair<DetElement,Volume> DetElement::reflect(const std::string& new_name) const {
0295   return reflect(new_name, access()->id);
0296 }
0297 
0298 std::pair<DetElement,Volume> DetElement::reflect(const std::string& new_name, int new_id) const {
0299   return reflect(new_name, new_id, SensitiveDetector(0));
0300 }
0301 
0302 std::pair<DetElement,Volume> DetElement::reflect(const std::string& new_name, int new_id, SensitiveDetector sd) const {
0303   if ( placement().isValid() )   {
0304     return m_element->reflect(new_name, new_id, sd);
0305   }
0306   except("DetElement","reflect: Only placed DetElement objects can be reflected: %s",
0307          path().c_str());
0308   return std::make_pair(DetElement(),Volume());
0309 }
0310 
0311 /// Access to the ideal physical volume of this detector element
0312 PlacedVolume DetElement::idealPlacement() const    {
0313   if (isValid()) {
0314     Object& o = object<Object>();
0315     return o.idealPlace;
0316   }
0317   return PlacedVolume();
0318 }
0319 
0320 /// Access to the physical volume of this detector element
0321 PlacedVolume DetElement::placement() const {
0322   if (isValid()) {
0323     Object& o = object<Object>();
0324     return o.placement;
0325   }
0326   return PlacedVolume();
0327 }
0328 
0329 /// Set the physical volumes of the detector element
0330 DetElement& DetElement::setPlacement(const PlacedVolume& pv) {
0331   if (pv.isValid()) {
0332     Object* o = access();
0333     o->placement = pv;
0334     if ( !o->idealPlace.isValid() )  {
0335       o->idealPlace = pv;
0336     }
0337     return *this;
0338   }
0339   except("dd4hep", "DetElement::setPlacement: Placement is not defined [Invalid Handle]");
0340   throw std::runtime_error("dd4hep: DetElement::add");
0341 }
0342 
0343 /// The cached VolumeID of this subdetector element
0344 dd4hep::VolumeID DetElement::volumeID() const   {
0345   if (isValid()) {
0346     return object<Object>().volumeID;
0347   }
0348   return 0;
0349 }
0350 
0351 /// Access to the logical volume of the placements (all daughters have the same!)
0352 Volume DetElement::volume() const {
0353   return access()->placement.volume();
0354 }
0355 
0356 /// Access to the shape of the detector element's placement
0357 Solid DetElement::solid() const    {
0358   return volume()->GetShape();
0359 }
0360 
0361 DetElement& DetElement::setVisAttributes(const Detector& description, const std::string& nam, const Volume& vol) {
0362   vol.setVisAttributes(description, nam);
0363   return *this;
0364 }
0365 
0366 DetElement& DetElement::setRegion(const Detector& description, const std::string& nam, const Volume& vol) {
0367   if (!nam.empty()) {
0368     vol.setRegion(description.region(nam));
0369   }
0370   return *this;
0371 }
0372 
0373 DetElement& DetElement::setLimitSet(const Detector& description, const std::string& nam, const Volume& vol) {
0374   if (!nam.empty()) {
0375     vol.setLimitSet(description.limitSet(nam));
0376   }
0377   return *this;
0378 }
0379 
0380 DetElement& DetElement::setAttributes(const Detector& description,
0381                                       const Volume& vol,
0382                                       const std::string& region,
0383                                       const std::string& limits,
0384                                       const std::string& vis)
0385 {
0386   return setRegion(description, region, vol).setLimitSet(description, limits, vol).setVisAttributes(description, vis, vol);
0387 }
0388 
0389 /// Constructor
0390 SensitiveDetector::SensitiveDetector(const std::string& nam, const std::string& typ) {
0391   /*
0392     <calorimeter ecut="0" eunit="MeV" hits_collection="EcalEndcapHits" name="EcalEndcap" verbose="0">
0393     <global_grid_xy grid_size_x="3.5" grid_size_y="3.5"/>
0394     <idspecref ref="EcalEndcapHits"/>
0395     </calorimeter>
0396   */
0397   assign(new Object(nam), nam, typ);
0398   object<Object>().ecut = 0e0;
0399   object<Object>().verbose = 0;
0400 }
0401 
0402 /// Set the type of the sensitive detector
0403 SensitiveDetector& SensitiveDetector::setType(const std::string& typ) {
0404   access()->SetTitle(typ.c_str());
0405   return *this;
0406 }
0407 
0408 /// Access the type of the sensitive detector
0409 std::string SensitiveDetector::type() const {
0410   return m_element ? m_element->GetTitle() : s_empty_string;
0411 }
0412 
0413 /// Assign the IDDescriptor reference
0414 SensitiveDetector& SensitiveDetector::setReadout(Readout ro) {
0415   access()->readout = ro;
0416   return *this;
0417 }
0418 
0419 /// Assign the IDDescriptor reference
0420 Readout SensitiveDetector::readout() const {
0421   return access()->readout;
0422 }
0423 
0424 /// Assign the IDDescriptor reference
0425 IDDescriptor SensitiveDetector::idSpec() const {
0426   return readout().idSpec();
0427 }
0428 
0429 /// Set energy cut off
0430 SensitiveDetector& SensitiveDetector::setEnergyCutoff(double value) {
0431   access()->ecut = value;
0432   return *this;
0433 }
0434 
0435 /// Access energy cut off
0436 double SensitiveDetector::energyCutoff() const {
0437   return access()->ecut;
0438 }
0439 
0440 /// Assign the name of the hits collection
0441 SensitiveDetector& SensitiveDetector::setHitsCollection(const std::string& collection) {
0442   access()->hitsCollection = collection;
0443   return *this;
0444 }
0445 
0446 /// Access the hits collection name
0447 const std::string& SensitiveDetector::hitsCollection() const {
0448   return access()->hitsCollection;
0449 }
0450 
0451 /// Assign the name of the hits collection
0452 SensitiveDetector& SensitiveDetector::setVerbose(bool value) {
0453   int v = value ? 1 : 0;
0454   access()->verbose = v;
0455   return *this;
0456 }
0457 
0458 /// Access flag to combine hist
0459 bool SensitiveDetector::verbose() const {
0460   return access()->verbose == 1;
0461 }
0462 
0463 /// Assign the name of the hits collection
0464 SensitiveDetector& SensitiveDetector::setCombineHits(bool value) {
0465   int v = value ? 1 : 0;
0466   access()->combineHits = v;
0467   return *this;
0468 }
0469 
0470 /// Access flag to combine hist
0471 bool SensitiveDetector::combineHits() const {
0472   return access()->combineHits == 1;
0473 }
0474 
0475 /// Set the regional attributes to the sensitive detector
0476 SensitiveDetector& SensitiveDetector::setRegion(Region reg) {
0477   access()->region = reg;
0478   return *this;
0479 }
0480 
0481 /// Access to the region setting of the sensitive detector (not mandatory)
0482 Region SensitiveDetector::region() const {
0483   return access()->region;
0484 }
0485 
0486 /// Set the limits to the sensitive detector
0487 SensitiveDetector& SensitiveDetector::setLimitSet(LimitSet ls) {
0488   access()->limits = ls;
0489   return *this;
0490 }
0491 
0492 /// Access to the limit set of the sensitive detector (not mandatory).
0493 LimitSet SensitiveDetector::limits() const {
0494   return access()->limits;
0495 }
0496 
0497 /// Add an extension object to the detector element
0498 void* SensitiveDetector::addExtension(unsigned long long int k,ExtensionEntry* e)  const
0499 {
0500   return access()->addExtension(k,e);
0501 }
0502 
0503 /// Access an existing extension object from the detector element
0504 void* SensitiveDetector::extension(unsigned long long int k) const {
0505   return access()->extension(k);
0506 }
0507 
0508 /// Access an existing extension object from the detector element
0509 void* SensitiveDetector::extension(unsigned long long int k, bool alert) const {
0510   return access()->extension(k, alert);
0511 }