Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-12 08:24:07

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/Detector.h>
0016 #include <DD4hep/Printout.h>
0017 #include <DD4hep/IDDescriptor.h>
0018 #include <DD4hep/InstanceCount.h>
0019 #include <DD4hep/detail/ObjectsInterna.h>
0020 
0021 #include <TMap.h>
0022 #include <TROOT.h>
0023 #include <TColor.h>
0024 #include <TGeoMatrix.h>
0025 #include <TGeoManager.h>
0026 #include <TGeoElement.h>
0027 #include <TGeoMaterial.h>
0028 
0029 // C/C++ include files
0030 #include <cmath>
0031 #include <sstream>
0032 
0033 using namespace dd4hep;
0034 
0035 /// Constructor to be used when creating a new DOM tree
0036 Author::Author(Detector& /* description */) {
0037   m_element = new NamedObject("", "author");
0038 }
0039 
0040 /// Access the author's name
0041 std::string Author::authorName() const {
0042   return m_element->GetName();
0043 }
0044 
0045 /// Set the author's name
0046 void Author::setAuthorName(const std::string& nam) {
0047   m_element->SetName(nam.c_str());
0048 }
0049 
0050 /// Access the author's email address
0051 std::string Author::authorEmail() const {
0052   return m_element->GetTitle();
0053 }
0054 
0055 /// Set the author's email address
0056 void Author::setAuthorEmail(const std::string& addr) {
0057   m_element->SetTitle(addr.c_str());
0058 }
0059 
0060 /// Constructor to be used when creating a new DOM tree
0061 Header::Header(const std::string& author_name, const std::string& descr_url) {
0062   Object* obj_ptr = new Object();
0063   assign(obj_ptr, author_name, descr_url);
0064 }
0065 
0066 /// Accessor to object name
0067 const std::string Header::name() const {
0068   return m_element->GetName();
0069 }
0070 
0071 /// Accessor: set object name
0072 void Header::setName(const std::string& new_name) {
0073   m_element->SetName(new_name.c_str());
0074 }
0075 
0076 /// Accessor to object title
0077 const std::string Header::title() const {
0078   return m_element->GetTitle();
0079 }
0080 
0081 /// Accessor: set object title
0082 void Header::setTitle(const std::string& new_title) {
0083   m_element->SetTitle(new_title.c_str());
0084 }
0085 
0086 /// Accessor to object url
0087 const std::string& Header::url() const {
0088   return data<Object>()->url;
0089 }
0090 
0091 /// Accessor: set object url
0092 void Header::setUrl(const std::string& new_url) {
0093   data<Object>()->url = new_url;
0094 }
0095 
0096 /// Accessor to object author
0097 const std::string& Header::author() const {
0098   return data<Object>()->author;
0099 }
0100 
0101 /// Accessor: set object author
0102 void Header::setAuthor(const std::string& new_author) {
0103   data<Object>()->author = new_author;
0104 }
0105 
0106 /// Accessor to object status
0107 const std::string& Header::status() const {
0108   return data<Object>()->status;
0109 }
0110 
0111 /// Accessor: set object status
0112 void Header::setStatus(const std::string& new_status) {
0113   data<Object>()->status = new_status;
0114 }
0115 
0116 /// Accessor to object version
0117 const std::string& Header::version() const {
0118   return data<Object>()->version;
0119 }
0120 
0121 /// Accessor: set object version
0122 void Header::setVersion(const std::string& new_version) {
0123   data<Object>()->version = new_version;
0124 }
0125 
0126 /// Accessor to object comment
0127 const std::string& Header::comment() const {
0128   return data<Object>()->comment;
0129 }
0130 
0131 /// Accessor: set object comment
0132 void Header::setComment(const std::string& new_comment) {
0133   data<Object>()->comment = new_comment;
0134 }
0135 
0136 /// Constructor to be used when creating a new DOM tree
0137 Constant::Constant(const std::string& nam, const std::string& val, const std::string& typ) {
0138   m_element = new Object(nam, val, typ);
0139 }
0140 
0141 /// Constructor to be used when creating a new DOM tree
0142 Constant::Constant(const std::string& nam) {
0143   m_element = new Object(nam.c_str(), "", "number");
0144 }
0145 
0146 /// Access the constant
0147 std::string Constant::dataType() const   {
0148   if ( isValid() )  {
0149     return m_element->dataType;
0150   }
0151   throw std::runtime_error("dd4hep: Attempt to access internals from invalid Constant handle!");
0152 }
0153 
0154 /// String representation of this object
0155 std::string Constant::toString() const {
0156   std::stringstream os;
0157   os << m_element->GetName() << "  \"" << m_element->GetTitle() << "\"  ";
0158   if ( m_element->dataType == "string" ) os << "Value:" << m_element->GetTitle();
0159   else os << "Value:" << _toDouble(m_element->GetTitle());
0160   return os.str();
0161 }
0162 
0163 /// Constructor to be used when creating a new DOM tree
0164 Atom::Atom(const std::string& nam, const std::string& formula, int Z, int N, double density) {
0165   TGeoElementTable* t = TGeoElement::GetElementTable();
0166   TGeoElement*      e = t->FindElement(nam.c_str());
0167   if (!e) {
0168     t->AddElement(nam.c_str(), formula.c_str(), Z, N, density);
0169     e = t->FindElement(nam.c_str());
0170   }
0171   m_element = e;
0172 }
0173 
0174 /// proton number of the underlying material
0175 double  Material::Z() const {
0176   Handle < TGeoMedium > val(*this);
0177   if (val.isValid()) {
0178     TGeoMaterial* mat = val->GetMaterial();
0179     if ( mat )
0180       return mat->GetZ();
0181     throw std::runtime_error("dd4hep: The medium " + std::string(val->GetName()) + " has an invalid material reference!");
0182   }
0183   throw std::runtime_error("dd4hep: Attempt to access proton number from invalid material handle!");
0184 }
0185 
0186 /// atomic number of the underlying material
0187 double  Material::A() const {
0188   if ( isValid() ) {
0189     TGeoMaterial* mat = ptr()->GetMaterial();
0190     if ( mat )
0191       return mat->GetA();
0192     throw std::runtime_error("dd4hep: The medium " + std::string(ptr()->GetName()) + " has an invalid material reference!");
0193   }
0194   throw std::runtime_error("dd4hep: Attempt to access atomic number from invalid material handle!");
0195 }
0196 
0197 /// density of the underlying material
0198 double  Material::density() const {
0199   if ( isValid() )  {
0200     TGeoMaterial* mat = ptr()->GetMaterial();
0201     if ( mat )
0202       return mat->GetDensity();
0203     throw std::runtime_error("dd4hep: The medium " + std::string(ptr()->GetName()) + " has an invalid material reference!");
0204   }
0205   throw std::runtime_error("dd4hep: Attempt to access density from invalid material handle!");
0206 }
0207 
0208 /// Access the radiation length of the underlying material
0209 double Material::radLength() const {
0210   if ( isValid() ) {
0211     TGeoMaterial* mat = ptr()->GetMaterial();
0212     if ( mat )
0213       return mat->GetRadLen();
0214     throw std::runtime_error("dd4hep: The medium " + std::string(ptr()->GetName()) + " has an invalid material reference!");
0215   }
0216   throw std::runtime_error("dd4hep: Attempt to access radiation length from invalid material handle!");
0217 }
0218 
0219 /// Access the radiation length of the underlying material
0220 double Material::intLength() const {
0221   if ( isValid() ) {
0222     TGeoMaterial* mat = ptr()->GetMaterial();
0223     if ( mat )
0224       return mat->GetIntLen();
0225     throw std::runtime_error("The medium " + std::string(ptr()->GetName()) + " has an invalid material reference!");
0226   }
0227   throw std::runtime_error("Attempt to access interaction length from invalid material handle!");
0228 }
0229 
0230 /// Access the fraction of an element within the material
0231 double Material::fraction(Atom atom) const    {
0232   double frac = 0e0, tot = 0e0;
0233   TGeoElement*  elt = atom.access();
0234   TGeoMaterial* mat = access()->GetMaterial();
0235   for ( int i=0, n=mat->GetNelements(); i<n; ++i )  {
0236     TGeoElement* e = mat->GetElement(i);
0237     if ( mat->IsMixture() )  {
0238       TGeoMixture* mix = (TGeoMixture*)mat;
0239       tot  += mix->GetWmixt()[i];
0240     }
0241     else {
0242       tot = 1e0;
0243     }
0244     if ( e == elt )   {
0245       if ( mat->IsMixture() )  {
0246         TGeoMixture* mix = (TGeoMixture*)mat;
0247         frac += mix->GetWmixt()[i];
0248       }
0249       else  {
0250         frac = 1e0;
0251       }
0252     }
0253   }
0254   return tot>1e-20 ? frac/tot : 0.0;
0255 }
0256 
0257 /// Access the number of properties attached to the material (if any)
0258 std::size_t Material::numProperties()  const  {
0259   return access()->GetMaterial()->GetNproperties();
0260 }
0261 
0262 /// Access to tabular properties of the material by index
0263 Material::Property Material::property(std::size_t index)  const  {
0264   return access()->GetMaterial()->GetProperty(index);
0265 }
0266 
0267 /// Access to tabular properties of the optical surface
0268 Material::Property Material::property(const char* nam)  const  {
0269   return access()->GetMaterial()->GetProperty(nam);
0270 }
0271 
0272 /// Access to tabular properties of the optical surface
0273 Material::Property Material::property(const std::string& nam)  const   {
0274   return access()->GetMaterial()->GetProperty(nam.c_str());
0275 }
0276 
0277 /// Access string property value from the material table
0278 std::string Material::propertyRef(const std::string& name, const std::string& default_value)    {
0279   auto* o = access()->GetMaterial();
0280   const char* p = o->GetPropertyRef(name.c_str());
0281   if ( p ) return p;
0282   return default_value;
0283 }
0284 
0285 /// Access the number of properties attached to the material (if any)
0286 std::size_t Material::numConstProperties()  const  {
0287   return access()->GetMaterial()->GetNconstProperties();
0288 }
0289 
0290 /// Access to const properties of the material by index
0291 double Material::constProperty(std::size_t index)  const  {
0292   Bool_t err = kFALSE;
0293   const auto* mat  = access()->GetMaterial();
0294   double value = mat->GetConstProperty(index, &err);
0295   if ( err != kTRUE ) return value;
0296   throw std::runtime_error("Attempt to access non existing material const property with index: "+std::to_string(index));
0297 }
0298 
0299 /// Access to tabular properties of the optical surface
0300 double Material::constProperty(const std::string& nam)  const   {
0301   Bool_t err = kFALSE;
0302   auto*  mat = access()->GetMaterial();
0303   double value = mat->GetConstProperty(nam.c_str(), &err);
0304   if ( err != kTRUE ) return value;
0305   throw std::runtime_error("Attempt to access non existing material const property: "+nam);
0306 }
0307 
0308 /// Access string property value from the material table
0309 std::string Material::constPropertyRef(const std::string& name, const std::string& default_value)    {
0310   auto* o = access()->GetMaterial();
0311   const char* p = o->GetConstPropertyRef(name.c_str());
0312   if ( p ) return p;
0313   return default_value;
0314 }
0315 
0316 /// String representation of this object
0317 std::string Material::toString() const {
0318   if ( isValid() ) {
0319     TGeoMedium*  val = ptr();
0320     std::stringstream out;
0321     out << val->GetName() << " " << val->GetTitle()
0322         << " id:" << std::hex << val->GetId()
0323         << " Pointer:" << val->GetPointerName();
0324     return out.str();
0325   }
0326   throw std::runtime_error("Attempt to convert invalid material handle to string!");
0327 }
0328 
0329 /// Constructor to be used when creating a new entity
0330 VisAttr::VisAttr(const std::string& nam) {
0331   Object* obj = new Object();
0332   assign(obj, nam, "vis");
0333   obj->color = gROOT->GetColor(kWhite);
0334   obj->alpha = 0.9f;
0335   setLineStyle (SOLID);
0336   setDrawingStyle(SOLID);
0337   setShowDaughters(true);
0338   setColor(1e0, 1e0, 1e0, 1e0);
0339 }
0340 
0341 /// Constructor to be used when creating a new entity
0342 VisAttr::VisAttr(const char* nam) {
0343   Object* obj = new Object();
0344   assign(obj, nam, "vis");
0345   obj->color = gROOT->GetColor(kWhite);
0346   obj->alpha = 0.9f;
0347   setLineStyle (SOLID);
0348   setDrawingStyle(SOLID);
0349   setShowDaughters(true);
0350   setColor(1e0, 1e0, 1e0, 1e0);
0351 }
0352 
0353 /// Get Flag to show/hide daughter elements
0354 bool VisAttr::showDaughters() const {
0355   return object<Object>().showDaughters;
0356 }
0357 
0358 /// Set Flag to show/hide daughter elements
0359 void VisAttr::setShowDaughters(bool value) {
0360   object<Object>().showDaughters = value;
0361 }
0362 
0363 /// Get visibility flag
0364 bool VisAttr::visible() const {
0365   return object<Object>().visible;
0366 }
0367 
0368 /// Set visibility flag
0369 void VisAttr::setVisible(bool value) {
0370   object<Object>().visible = value;
0371 }
0372 
0373 /// Get line style
0374 int VisAttr::lineStyle() const {
0375   return object<Object>().lineStyle;
0376 }
0377 
0378 /// Set line style
0379 void VisAttr::setLineStyle(int value) {
0380   object<Object>().lineStyle = value;
0381 }
0382 
0383 /// Get drawing style
0384 int VisAttr::drawingStyle() const {
0385   return object<Object>().drawingStyle;
0386 }
0387 
0388 /// Set drawing style
0389 void VisAttr::setDrawingStyle(int value) {
0390   object<Object>().drawingStyle = value;
0391 }
0392 
0393 /// Get alpha value
0394 float VisAttr::alpha() const {
0395   return object<Object>().alpha;
0396 }
0397 
0398 /// Get object color
0399 int VisAttr::color() const {
0400   return object<Object>().color->GetNumber();
0401 }
0402 
0403 /// Set object color
0404 void VisAttr::setColor(float alpha, float red, float green, float blue) {
0405   Object& o  = object<Object>();
0406   const auto num_before = gROOT->GetListOfColors()->GetLast();
0407   // Set tolerance high enough to always lookup from existing palette. This
0408   // helps to preserve colors when saving TGeo to .root files.
0409   TColor::SetColorThreshold(1.0f/31.0f);
0410   Int_t col  = TColor::GetColor(red, green, blue);
0411   const auto num_after = gROOT->GetListOfColors()->GetLast();
0412   if (num_before != num_after) {
0413     printout(INFO,"VisAttr","+++ %s Allocated a Color: r:%02X g:%02X b:%02X, this will not save to a ROOT file",
0414              this->name(), int(red*255.), int(green*255.), int(blue*255));
0415   }
0416   o.alpha    = alpha;
0417   o.color    = gROOT->GetColor(col);
0418   if ( !o.color )    {
0419     except("VisAttr","+++ %s Failed to allocate Color: r:%02X g:%02X b:%02X",
0420            this->name(), int(red*255.), int(green*255.), int(blue*255));
0421   }
0422   o.colortr = new TColor(gROOT->GetListOfColors()->GetLast()+1,
0423                          o.color->GetRed(), o.color->GetGreen(), o.color->GetBlue());
0424   o.colortr->SetAlpha(alpha);
0425 }
0426 
0427 /// Get RGB values of the color (if valid)
0428 bool VisAttr::rgb(float& red, float& green, float& blue) const {
0429   Object& o = object<Object>();
0430   if ( o.color )  {
0431     o.color->GetRGB(red, green, blue);
0432     return true;
0433   }
0434   return false;
0435 }
0436 
0437 /// Get alpha and RGB values of the color (if valid)
0438 bool VisAttr::argb(float& alpha, float& red, float& green, float& blue) const {
0439   Object& o = object<Object>();
0440   if ( o.color )  {
0441     alpha = o.alpha;
0442     o.color->GetRGB(red, green, blue);
0443     return true;
0444   }
0445   return false;
0446 }
0447 
0448 /// String representation of this object
0449 std::string VisAttr::toString() const {
0450   const VisAttr::Object* obj = &object<Object>();
0451   TColor* c = obj->color;
0452   char text[256];
0453   std::snprintf(text, sizeof(text), "%-20s RGB:%-8s [%d] %7.2f  Style:%d %d ShowDaughters:%3s Visible:%3s", ptr()->GetName(),
0454                   c->AsHexString(), c->GetNumber(), c->GetAlpha(), int(obj->drawingStyle), int(obj->lineStyle),
0455                   yes_no(obj->showDaughters), yes_no(obj->visible));
0456   return text;
0457 }
0458 
0459 /// Equality operator
0460 bool Limit::operator==(const Limit& c) const {
0461   return value == c.value && name == c.name && particles == c.particles;
0462 }
0463 
0464 /// operator less
0465 bool Limit::operator<(const Limit& c) const {
0466   if (name < c.name)
0467     return true;
0468   if (value < c.value)
0469     return true;
0470   if (particles < c.particles)
0471     return true;
0472   return false;
0473 }
0474 
0475 /// Conversion to a string representation
0476 std::string Limit::toString() const {
0477   std::string res = name + " = " + content;
0478   if (!unit.empty())
0479     res += unit + " ";
0480   res += " (" + particles + ")";
0481   return res;
0482 }
0483 
0484 /// Constructor to be used when creating a new DOM tree
0485 LimitSet::LimitSet(const std::string& nam) {
0486   assign(new Object(), nam, "limitset");
0487 }
0488 
0489 /// Add new limit. Returns true if the new limit was added, false if it already existed.
0490 bool LimitSet::addLimit(const Limit& limit) {
0491   std::pair<Object::iterator, bool> ret = data<Object>()->limits.insert(limit);
0492   return ret.second;
0493 }
0494 
0495 /// Accessor to limits container
0496 const std::set<Limit>& LimitSet::limits() const {
0497   const Object* o = data<Object>();
0498   return o->limits;
0499 }
0500 
0501 /// Add new limit. Returns true if the new limit was added, false if it already existed.
0502 bool LimitSet::addCut(const Limit& cut_obj)   {
0503   std::pair<Object::iterator, bool> ret = data<Object>()->cuts.insert(cut_obj);
0504   return ret.second;
0505 }
0506 
0507 /// Accessor to limits container
0508 const std::set<Limit>& LimitSet::cuts() const    {
0509   return data<Object>()->cuts;
0510 }
0511 
0512 /// Constructor to be used when creating a new DOM tree
0513 Region::Region(const std::string& nam) {
0514   Object* p = new Object();
0515   assign(p, nam, "region");
0516   p->magic = magic_word();
0517   p->store_secondaries = false;
0518   p->threshold = 10.0;
0519   p->cut = 10.0;
0520   p->use_default_cut = true;
0521   p->was_threshold_set = false;
0522 }
0523 
0524 Region& Region::setStoreSecondaries(bool value) {
0525   object<Object>().store_secondaries = value;
0526   return *this;
0527 }
0528 
0529 Region& Region::setThreshold(double value) {
0530   object<Object>().threshold = value;
0531   object<Object>().was_threshold_set = true;
0532   return *this;
0533 }
0534 
0535 Region& Region::setCut(double value) {
0536   object<Object>().cut = value;
0537   object<Object>().use_default_cut = false;
0538   return *this;
0539 }
0540 
0541 /// Access references to user limits
0542 std::vector<std::string>& Region::limits() const {
0543   return object<Object>().user_limits;
0544 }
0545 
0546 /// Access cut value
0547 double Region::cut() const {
0548   return object<Object>().cut;
0549 }
0550 
0551 /// Access production threshold
0552 double Region::threshold() const {
0553   return object<Object>().threshold;
0554 }
0555 
0556 /// Access secondaries flag
0557 bool Region::storeSecondaries() const {
0558   return object<Object>().store_secondaries;
0559 }
0560 
0561 bool Region::useDefaultCut() const {
0562   return object<Object>().use_default_cut;
0563 }
0564 
0565 bool Region::wasThresholdSet() const {
0566   return object<Object>().was_threshold_set;
0567 }
0568 
0569 #undef setAttr
0570 
0571 #if 0
0572 
0573 /** @class IDSpec Objects.h
0574  *
0575  *  @author  M.Frank
0576  *  @version 1.0
0577  */
0578 struct IDSpec : public Ref_t {
0579   /// Constructor to be used when reading the already parsed DOM tree
0580   template <typename Q>
0581   IDSpec(const Handle<Q>& e) : Ref_t(e) {}
0582   /// Constructor to be used when creating a new DOM tree
0583   IDSpec(Detector& doc, const std::string& name, const IDDescriptor& dsc);
0584   void addField(const std::string& name, const std::pair<int,int>& field);
0585 };
0586 
0587 IDSpec::IDSpec(Detector& description, const std::string& name, const IDDescriptor& dsc)
0588   : RefElement(doc,Tag_idspec,name)
0589 {
0590   const IDDescriptor::FieldIDs& f = dsc.ids();
0591   const IDDescriptor::FieldMap& m = dsc.fields();
0592   object<Object>().Attr_length = dsc.maxBit();
0593   for(const auto& i : f )  {
0594     const std::string& nam = i.second;
0595     const pair<int,int>& fld = m.find(nam)->second;
0596     addField(nam,fld);
0597   }
0598 }
0599 
0600 void IDSpec::addField(const std::string& name, const pair<int,int>& field) {
0601   addField(Strng_t(name),field);
0602 }
0603 
0604 void IDSpec::addField(const std::string& name, const pair<int,int>& field) {
0605   Element e(document(),Tag_idfield);
0606   e.object<Object>().Attr_signed = field.second<0;
0607   e.object<Object>().Attr_label = name;
0608   e.object<Object>().Attr_start = field.first;
0609   e.object<Object>().Attr_length = abs(field.second);
0610   m_element.append(e);
0611 }
0612 #endif