File indexing completed on 2026-09-12 08:24:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
0030 #include <cmath>
0031 #include <sstream>
0032
0033 using namespace dd4hep;
0034
0035
0036 Author::Author(Detector& ) {
0037 m_element = new NamedObject("", "author");
0038 }
0039
0040
0041 std::string Author::authorName() const {
0042 return m_element->GetName();
0043 }
0044
0045
0046 void Author::setAuthorName(const std::string& nam) {
0047 m_element->SetName(nam.c_str());
0048 }
0049
0050
0051 std::string Author::authorEmail() const {
0052 return m_element->GetTitle();
0053 }
0054
0055
0056 void Author::setAuthorEmail(const std::string& addr) {
0057 m_element->SetTitle(addr.c_str());
0058 }
0059
0060
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
0067 const std::string Header::name() const {
0068 return m_element->GetName();
0069 }
0070
0071
0072 void Header::setName(const std::string& new_name) {
0073 m_element->SetName(new_name.c_str());
0074 }
0075
0076
0077 const std::string Header::title() const {
0078 return m_element->GetTitle();
0079 }
0080
0081
0082 void Header::setTitle(const std::string& new_title) {
0083 m_element->SetTitle(new_title.c_str());
0084 }
0085
0086
0087 const std::string& Header::url() const {
0088 return data<Object>()->url;
0089 }
0090
0091
0092 void Header::setUrl(const std::string& new_url) {
0093 data<Object>()->url = new_url;
0094 }
0095
0096
0097 const std::string& Header::author() const {
0098 return data<Object>()->author;
0099 }
0100
0101
0102 void Header::setAuthor(const std::string& new_author) {
0103 data<Object>()->author = new_author;
0104 }
0105
0106
0107 const std::string& Header::status() const {
0108 return data<Object>()->status;
0109 }
0110
0111
0112 void Header::setStatus(const std::string& new_status) {
0113 data<Object>()->status = new_status;
0114 }
0115
0116
0117 const std::string& Header::version() const {
0118 return data<Object>()->version;
0119 }
0120
0121
0122 void Header::setVersion(const std::string& new_version) {
0123 data<Object>()->version = new_version;
0124 }
0125
0126
0127 const std::string& Header::comment() const {
0128 return data<Object>()->comment;
0129 }
0130
0131
0132 void Header::setComment(const std::string& new_comment) {
0133 data<Object>()->comment = new_comment;
0134 }
0135
0136
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
0142 Constant::Constant(const std::string& nam) {
0143 m_element = new Object(nam.c_str(), "", "number");
0144 }
0145
0146
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
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
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
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
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
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
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
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
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
0258 std::size_t Material::numProperties() const {
0259 return access()->GetMaterial()->GetNproperties();
0260 }
0261
0262
0263 Material::Property Material::property(std::size_t index) const {
0264 return access()->GetMaterial()->GetProperty(index);
0265 }
0266
0267
0268 Material::Property Material::property(const char* nam) const {
0269 return access()->GetMaterial()->GetProperty(nam);
0270 }
0271
0272
0273 Material::Property Material::property(const std::string& nam) const {
0274 return access()->GetMaterial()->GetProperty(nam.c_str());
0275 }
0276
0277
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
0286 std::size_t Material::numConstProperties() const {
0287 return access()->GetMaterial()->GetNconstProperties();
0288 }
0289
0290
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
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
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
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
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
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
0354 bool VisAttr::showDaughters() const {
0355 return object<Object>().showDaughters;
0356 }
0357
0358
0359 void VisAttr::setShowDaughters(bool value) {
0360 object<Object>().showDaughters = value;
0361 }
0362
0363
0364 bool VisAttr::visible() const {
0365 return object<Object>().visible;
0366 }
0367
0368
0369 void VisAttr::setVisible(bool value) {
0370 object<Object>().visible = value;
0371 }
0372
0373
0374 int VisAttr::lineStyle() const {
0375 return object<Object>().lineStyle;
0376 }
0377
0378
0379 void VisAttr::setLineStyle(int value) {
0380 object<Object>().lineStyle = value;
0381 }
0382
0383
0384 int VisAttr::drawingStyle() const {
0385 return object<Object>().drawingStyle;
0386 }
0387
0388
0389 void VisAttr::setDrawingStyle(int value) {
0390 object<Object>().drawingStyle = value;
0391 }
0392
0393
0394 float VisAttr::alpha() const {
0395 return object<Object>().alpha;
0396 }
0397
0398
0399 int VisAttr::color() const {
0400 return object<Object>().color->GetNumber();
0401 }
0402
0403
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
0408
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
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
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
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
0460 bool Limit::operator==(const Limit& c) const {
0461 return value == c.value && name == c.name && particles == c.particles;
0462 }
0463
0464
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
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
0485 LimitSet::LimitSet(const std::string& nam) {
0486 assign(new Object(), nam, "limitset");
0487 }
0488
0489
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
0496 const std::set<Limit>& LimitSet::limits() const {
0497 const Object* o = data<Object>();
0498 return o->limits;
0499 }
0500
0501
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
0508 const std::set<Limit>& LimitSet::cuts() const {
0509 return data<Object>()->cuts;
0510 }
0511
0512
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
0542 std::vector<std::string>& Region::limits() const {
0543 return object<Object>().user_limits;
0544 }
0545
0546
0547 double Region::cut() const {
0548 return object<Object>().cut;
0549 }
0550
0551
0552 double Region::threshold() const {
0553 return object<Object>().threshold;
0554 }
0555
0556
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
0574
0575
0576
0577
0578 struct IDSpec : public Ref_t {
0579
0580 template <typename Q>
0581 IDSpec(const Handle<Q>& e) : Ref_t(e) {}
0582
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