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