File indexing completed on 2025-06-30 07:54:19
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 Material::Property Material::property(const char* nam) const {
0259 return access()->GetMaterial()->GetProperty(nam);
0260 }
0261
0262
0263 Material::Property Material::property(const std::string& nam) const {
0264 return access()->GetMaterial()->GetProperty(nam.c_str());
0265 }
0266
0267
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
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
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
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
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
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
0330 bool VisAttr::showDaughters() const {
0331 return object<Object>().showDaughters;
0332 }
0333
0334
0335 void VisAttr::setShowDaughters(bool value) {
0336 object<Object>().showDaughters = value;
0337 }
0338
0339
0340 bool VisAttr::visible() const {
0341 return object<Object>().visible;
0342 }
0343
0344
0345 void VisAttr::setVisible(bool value) {
0346 object<Object>().visible = value;
0347 }
0348
0349
0350 int VisAttr::lineStyle() const {
0351 return object<Object>().lineStyle;
0352 }
0353
0354
0355 void VisAttr::setLineStyle(int value) {
0356 object<Object>().lineStyle = value;
0357 }
0358
0359
0360 int VisAttr::drawingStyle() const {
0361 return object<Object>().drawingStyle;
0362 }
0363
0364
0365 void VisAttr::setDrawingStyle(int value) {
0366 object<Object>().drawingStyle = value;
0367 }
0368
0369
0370 float VisAttr::alpha() const {
0371 return object<Object>().alpha;
0372 }
0373
0374
0375 int VisAttr::color() const {
0376 return object<Object>().color->GetNumber();
0377 }
0378
0379
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
0384
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
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
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
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
0436 bool Limit::operator==(const Limit& c) const {
0437 return value == c.value && name == c.name && particles == c.particles;
0438 }
0439
0440
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
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
0461 LimitSet::LimitSet(const std::string& nam) {
0462 assign(new Object(), nam, "limitset");
0463 }
0464
0465
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
0472 const std::set<Limit>& LimitSet::limits() const {
0473 const Object* o = data<Object>();
0474 return o->limits;
0475 }
0476
0477
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
0484 const std::set<Limit>& LimitSet::cuts() const {
0485 return data<Object>()->cuts;
0486 }
0487
0488
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
0518 std::vector<std::string>& Region::limits() const {
0519 return object<Object>().user_limits;
0520 }
0521
0522
0523 double Region::cut() const {
0524 return object<Object>().cut;
0525 }
0526
0527
0528 double Region::threshold() const {
0529 return object<Object>().threshold;
0530 }
0531
0532
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
0550
0551
0552
0553
0554 struct IDSpec : public Ref_t {
0555
0556 template <typename Q>
0557 IDSpec(const Handle<Q>& e) : Ref_t(e) {}
0558
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