Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 07:54:19

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 auhor'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 auhor'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 to tabular properties of the optical surface
0258 Material::Property Material::property(const char* nam)  const    {
0259   return access()->GetMaterial()->GetProperty(nam);
0260 }
0261 
0262 /// Access to tabular properties of the optical surface
0263 Material::Property Material::property(const std::string& nam)  const   {
0264   return access()->GetMaterial()->GetProperty(nam.c_str());
0265 }
0266 
0267 /// Access string property value from the material table
0268 std::string Material::propertyRef(const std::string& name, const std::string& default_value)    {
0269   auto* o = access()->GetMaterial();
0270   const char* p = o->GetPropertyRef(name.c_str());
0271   if ( p ) return p;
0272   return default_value;
0273 }
0274 
0275 /// Access to tabular properties of the optical surface
0276 double Material::constProperty(const std::string& nam)  const   {
0277   Bool_t err = kFALSE;
0278   auto* o = access()->GetMaterial();
0279   double value = o->GetConstProperty(nam.c_str(), &err);
0280   if ( err != kTRUE ) return value;
0281   throw std::runtime_error("Attempt to access non existing material const property: "+nam);
0282 }
0283 
0284 /// Access string property value from the material table
0285 std::string Material::constPropertyRef(const std::string& name, const std::string& default_value)    {
0286   auto* o = access()->GetMaterial();
0287   const char* p = o->GetConstPropertyRef(name.c_str());
0288   if ( p ) return p;
0289   return default_value;
0290 }
0291 
0292 /// String representation of this object
0293 std::string Material::toString() const {
0294   if ( isValid() ) {
0295     TGeoMedium*  val = ptr();
0296     std::stringstream out;
0297     out << val->GetName() << " " << val->GetTitle()
0298         << " id:" << std::hex << val->GetId()
0299         << " Pointer:" << val->GetPointerName();
0300     return out.str();
0301   }
0302   throw std::runtime_error("Attempt to convert invalid material handle to string!");
0303 }
0304 
0305 /// Constructor to be used when creating a new entity
0306 VisAttr::VisAttr(const std::string& nam) {
0307   Object* obj = new Object();
0308   assign(obj, nam, "vis");
0309   obj->color = gROOT->GetColor(kWhite);
0310   obj->alpha = 0.9f;
0311   setLineStyle (SOLID);
0312   setDrawingStyle(SOLID);
0313   setShowDaughters(true);
0314   setColor(1e0, 1e0, 1e0, 1e0);
0315 }
0316 
0317 /// Constructor to be used when creating a new entity
0318 VisAttr::VisAttr(const char* nam) {
0319   Object* obj = new Object();
0320   assign(obj, nam, "vis");
0321   obj->color = gROOT->GetColor(kWhite);
0322   obj->alpha = 0.9f;
0323   setLineStyle (SOLID);
0324   setDrawingStyle(SOLID);
0325   setShowDaughters(true);
0326   setColor(1e0, 1e0, 1e0, 1e0);
0327 }
0328 
0329 /// Get Flag to show/hide daughter elements
0330 bool VisAttr::showDaughters() const {
0331   return object<Object>().showDaughters;
0332 }
0333 
0334 /// Set Flag to show/hide daughter elements
0335 void VisAttr::setShowDaughters(bool value) {
0336   object<Object>().showDaughters = value;
0337 }
0338 
0339 /// Get visibility flag
0340 bool VisAttr::visible() const {
0341   return object<Object>().visible;
0342 }
0343 
0344 /// Set visibility flag
0345 void VisAttr::setVisible(bool value) {
0346   object<Object>().visible = value;
0347 }
0348 
0349 /// Get line style
0350 int VisAttr::lineStyle() const {
0351   return object<Object>().lineStyle;
0352 }
0353 
0354 /// Set line style
0355 void VisAttr::setLineStyle(int value) {
0356   object<Object>().lineStyle = value;
0357 }
0358 
0359 /// Get drawing style
0360 int VisAttr::drawingStyle() const {
0361   return object<Object>().drawingStyle;
0362 }
0363 
0364 /// Set drawing style
0365 void VisAttr::setDrawingStyle(int value) {
0366   object<Object>().drawingStyle = value;
0367 }
0368 
0369 /// Get alpha value
0370 float VisAttr::alpha() const {
0371   return object<Object>().alpha;
0372 }
0373 
0374 /// Get object color
0375 int VisAttr::color() const {
0376   return object<Object>().color->GetNumber();
0377 }
0378 
0379 /// Set object color
0380 void VisAttr::setColor(float alpha, float red, float green, float blue) {
0381   Object& o  = object<Object>();
0382   const auto num_before = gROOT->GetListOfColors()->GetLast();
0383   // Set tolerance high enough to always lookup from existing palette. This
0384   // helps to preserve colors when saving TGeo to .root files.
0385   TColor::SetColorThreshold(1.0f/31.0f);
0386   Int_t col  = TColor::GetColor(red, green, blue);
0387   const auto num_after = gROOT->GetListOfColors()->GetLast();
0388   if (num_before != num_after) {
0389     printout(INFO,"VisAttr","+++ %s Allocated a Color: r:%02X g:%02X b:%02X, this will not save to a ROOT file",
0390          this->name(), int(red*255.), int(green*255.), int(blue*255));
0391   }
0392   o.alpha    = alpha;
0393   o.color    = gROOT->GetColor(col);
0394   if ( !o.color )    {
0395     except("VisAttr","+++ %s Failed to allocate Color: r:%02X g:%02X b:%02X",
0396        this->name(), int(red*255.), int(green*255.), int(blue*255));
0397   }
0398   o.colortr = new TColor(gROOT->GetListOfColors()->GetLast()+1,
0399              o.color->GetRed(), o.color->GetGreen(), o.color->GetBlue());
0400   o.colortr->SetAlpha(alpha);
0401 }
0402 
0403 /// Get RGB values of the color (if valid)
0404 bool VisAttr::rgb(float& red, float& green, float& blue) const {
0405   Object& o = object<Object>();
0406   if ( o.color )  {
0407     o.color->GetRGB(red, green, blue);
0408     return true;
0409   }
0410   return false;
0411 }
0412 
0413 /// Get alpha and RGB values of the color (if valid)
0414 bool VisAttr::argb(float& alpha, float& red, float& green, float& blue) const {
0415   Object& o = object<Object>();
0416   if ( o.color )  {
0417     alpha = o.alpha;
0418     o.color->GetRGB(red, green, blue);
0419     return true;
0420   }
0421   return false;
0422 }
0423 
0424 /// String representation of this object
0425 std::string VisAttr::toString() const {
0426   const VisAttr::Object* obj = &object<Object>();
0427   TColor* c = obj->color;
0428   char text[256];
0429   std::snprintf(text, sizeof(text), "%-20s RGB:%-8s [%d] %7.2f  Style:%d %d ShowDaughters:%3s Visible:%3s", ptr()->GetName(),
0430                   c->AsHexString(), c->GetNumber(), c->GetAlpha(), int(obj->drawingStyle), int(obj->lineStyle),
0431                   yes_no(obj->showDaughters), yes_no(obj->visible));
0432   return text;
0433 }
0434 
0435 /// Equality operator
0436 bool Limit::operator==(const Limit& c) const {
0437   return value == c.value && name == c.name && particles == c.particles;
0438 }
0439 
0440 /// operator less
0441 bool Limit::operator<(const Limit& c) const {
0442   if (name < c.name)
0443     return true;
0444   if (value < c.value)
0445     return true;
0446   if (particles < c.particles)
0447     return true;
0448   return false;
0449 }
0450 
0451 /// Conversion to a string representation
0452 std::string Limit::toString() const {
0453   std::string res = name + " = " + content;
0454   if (!unit.empty())
0455     res += unit + " ";
0456   res += " (" + particles + ")";
0457   return res;
0458 }
0459 
0460 /// Constructor to be used when creating a new DOM tree
0461 LimitSet::LimitSet(const std::string& nam) {
0462   assign(new Object(), nam, "limitset");
0463 }
0464 
0465 /// Add new limit. Returns true if the new limit was added, false if it already existed.
0466 bool LimitSet::addLimit(const Limit& limit) {
0467   std::pair<Object::iterator, bool> ret = data<Object>()->limits.insert(limit);
0468   return ret.second;
0469 }
0470 
0471 /// Accessor to limits container
0472 const std::set<Limit>& LimitSet::limits() const {
0473   const Object* o = data<Object>();
0474   return o->limits;
0475 }
0476 
0477 /// Add new limit. Returns true if the new limit was added, false if it already existed.
0478 bool LimitSet::addCut(const Limit& cut_obj)   {
0479   std::pair<Object::iterator, bool> ret = data<Object>()->cuts.insert(cut_obj);
0480   return ret.second;
0481 }
0482 
0483 /// Accessor to limits container
0484 const std::set<Limit>& LimitSet::cuts() const    {
0485   return data<Object>()->cuts;
0486 }
0487 
0488 /// Constructor to be used when creating a new DOM tree
0489 Region::Region(const std::string& nam) {
0490   Object* p = new Object();
0491   assign(p, nam, "region");
0492   p->magic = magic_word();
0493   p->store_secondaries = false;
0494   p->threshold = 10.0;
0495   p->cut = 10.0;
0496   p->use_default_cut = true;
0497   p->was_threshold_set = false;
0498 }
0499 
0500 Region& Region::setStoreSecondaries(bool value) {
0501   object<Object>().store_secondaries = value;
0502   return *this;
0503 }
0504 
0505 Region& Region::setThreshold(double value) {
0506   object<Object>().threshold = value;
0507   object<Object>().was_threshold_set = true;
0508   return *this;
0509 }
0510 
0511 Region& Region::setCut(double value) {
0512   object<Object>().cut = value;
0513   object<Object>().use_default_cut = false;
0514   return *this;
0515 }
0516 
0517 /// Access references to user limits
0518 std::vector<std::string>& Region::limits() const {
0519   return object<Object>().user_limits;
0520 }
0521 
0522 /// Access cut value
0523 double Region::cut() const {
0524   return object<Object>().cut;
0525 }
0526 
0527 /// Access production threshold
0528 double Region::threshold() const {
0529   return object<Object>().threshold;
0530 }
0531 
0532 /// Access secondaries flag
0533 bool Region::storeSecondaries() const {
0534   return object<Object>().store_secondaries;
0535 }
0536 
0537 bool Region::useDefaultCut() const {
0538   return object<Object>().use_default_cut;
0539 }
0540 
0541 bool Region::wasThresholdSet() const {
0542   return object<Object>().was_threshold_set;
0543 }
0544 
0545 #undef setAttr
0546 
0547 #if 0
0548 
0549 /** @class IDSpec Objects.h
0550  *
0551  *  @author  M.Frank
0552  *  @version 1.0
0553  */
0554 struct IDSpec : public Ref_t {
0555   /// Constructor to be used when reading the already parsed DOM tree
0556   template <typename Q>
0557   IDSpec(const Handle<Q>& e) : Ref_t(e) {}
0558   /// Constructor to be used when creating a new DOM tree
0559   IDSpec(Detector& doc, const std::string& name, const IDDescriptor& dsc);
0560   void addField(const std::string& name, const std::pair<int,int>& field);
0561 };
0562 
0563 IDSpec::IDSpec(Detector& description, const std::string& name, const IDDescriptor& dsc)
0564   : RefElement(doc,Tag_idspec,name)
0565 {
0566   const IDDescriptor::FieldIDs& f = dsc.ids();
0567   const IDDescriptor::FieldMap& m = dsc.fields();
0568   object<Object>().Attr_length = dsc.maxBit();
0569   for(const auto& i : f )  {
0570     const std::string& nam = i.second;
0571     const pair<int,int>& fld = m.find(nam)->second;
0572     addField(nam,fld);
0573   }
0574 }
0575 
0576 void IDSpec::addField(const std::string& name, const pair<int,int>& field) {
0577   addField(Strng_t(name),field);
0578 }
0579 
0580 void IDSpec::addField(const std::string& name, const pair<int,int>& field) {
0581   Element e(document(),Tag_idfield);
0582   e.object<Object>().Attr_signed = field.second<0;
0583   e.object<Object>().Attr_label = name;
0584   e.object<Object>().Attr_start = field.first;
0585   e.object<Object>().Attr_length = abs(field.second);
0586   m_element.append(e);
0587 }
0588 #endif