File indexing completed on 2025-01-18 09:13:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/detail/DetectorInterna.h>
0016 #include <DD4hep/detail/ConditionsInterna.h>
0017 #include <DD4hep/detail/AlignmentsInterna.h>
0018 #include <DD4hep/AlignmentTools.h>
0019 #include <DD4hep/DetectorTools.h>
0020 #include <DD4hep/Printout.h>
0021 #include <DD4hep/Detector.h>
0022 #include <DD4hep/World.h>
0023
0024 using namespace dd4hep;
0025
0026 namespace {
0027 static std::string s_empty_string;
0028 }
0029
0030
0031 DetElement::Processor::Processor() {
0032 }
0033
0034
0035 DetElement::Processor::~Processor() {
0036 }
0037
0038
0039 DetElement::DetElement(Object* det_data, const std::string& det_name, const std::string& det_type)
0040 : Handle<DetElementObject>(det_data)
0041 {
0042 this->assign(det_data, det_name, det_type);
0043 }
0044
0045
0046 DetElement::DetElement(const std::string& det_name, const std::string& det_type, int det_id) {
0047 assign(new Object(det_name,det_id), det_name, det_type);
0048 ptr()->id = det_id;
0049 }
0050
0051
0052 DetElement::DetElement(const std::string& det_name, int det_id) {
0053 assign(new Object(det_name,det_id), det_name, "");
0054 ptr()->id = det_id;
0055 }
0056
0057
0058 DetElement::DetElement(DetElement det_parent, const std::string& det_name, int det_id) {
0059 assign(new Object(det_name,det_id), det_name, det_parent.type());
0060 ptr()->id = det_id;
0061 det_parent.add(*this);
0062 }
0063
0064
0065 void* DetElement::addExtension(ExtensionEntry* e) const {
0066 return access()->addExtension(e->hash64(), e);
0067 }
0068
0069
0070 void* DetElement::extension(unsigned long long int k, bool alert) const {
0071 return access()->extension(k, alert);
0072 }
0073
0074
0075 void DetElement::i_addUpdateCall(unsigned int callback_type, const Callback& callback) const {
0076 access()->updateCalls.emplace_back(callback,callback_type);
0077 }
0078
0079
0080 void DetElement::removeAtUpdate(unsigned int typ, void* pointer) const {
0081 access()->removeAtUpdate(typ,pointer);
0082 }
0083
0084
0085 const std::string& DetElement::placementPath() const {
0086 Object* o = ptr();
0087 if ( o ) {
0088 if (o->placementPath.empty()) {
0089 o->placementPath = detail::tools::placementPath(*this);
0090 }
0091 return o->placementPath;
0092 }
0093 return s_empty_string;
0094 }
0095
0096
0097 std::string DetElement::type() const {
0098 return m_element ? m_element->GetTitle() : "";
0099 }
0100
0101
0102 DetElement& DetElement::setType(const std::string& typ) {
0103 access()->SetTitle(typ.c_str());
0104 return *this;
0105 }
0106
0107
0108 unsigned int DetElement::typeFlag() const {
0109 return m_element ? m_element->typeFlag : 0 ;
0110 }
0111
0112
0113 DetElement& DetElement::setTypeFlag(unsigned int types) {
0114 access()->typeFlag = types ;
0115 return *this;
0116 }
0117
0118 namespace {
0119 static void make_path(DetElement::Object* o) {
0120 DetElement par = o->parent;
0121 if ( par.isValid() ) {
0122 o->path = par.path() + "/" + o->name;
0123 if ( o->level < 0 ) o->level = par.level() + 1;
0124 }
0125 else {
0126 o->path = "/" + o->name;
0127 o->level = 0;
0128 }
0129 o->key = dd4hep::detail::hash32(o->path);
0130 }
0131 }
0132
0133
0134 unsigned int DetElement::key() const {
0135 Object* o = ptr();
0136 if ( o ) {
0137 if ( o->key != 0 )
0138 return o->key;
0139 make_path(o);
0140 return o->key;
0141 }
0142 return 0;
0143 }
0144
0145
0146 int DetElement::level() const {
0147 Object* o = ptr();
0148 if ( o ) {
0149 if ( o->level >= 0 )
0150 return o->level;
0151 make_path(o);
0152 return o->level;
0153 }
0154 return -1;
0155 }
0156
0157
0158 const std::string& DetElement::path() const {
0159 Object* o = ptr();
0160 if ( o ) {
0161 if ( !o->path.empty() )
0162 return o->path;
0163 make_path(o);
0164 return o->path;
0165 }
0166 return s_empty_string;
0167 }
0168
0169 int DetElement::id() const {
0170 return access()->id;
0171 }
0172
0173 bool DetElement::combineHits() const {
0174 return access()->combineHits != 0;
0175 }
0176
0177 DetElement& DetElement::setCombineHits(bool value, SensitiveDetector& sens) {
0178 access()->combineHits = value;
0179 if (sens.isValid())
0180 sens.setCombineHits(value);
0181 return *this;
0182 }
0183
0184
0185 Alignment DetElement::nominal() const {
0186 Object* o = access();
0187 if ( !o->nominal.isValid() ) {
0188 o->nominal = AlignmentCondition("nominal");
0189 o->nominal->values().detector = *this;
0190
0191
0192 dd4hep::detail::tools::computeIdeal(o->nominal);
0193 }
0194 return o->nominal;
0195 }
0196
0197
0198 Alignment DetElement::survey() const {
0199 Object* o = access();
0200 if ( !o->survey.isValid() ) {
0201 o->survey = AlignmentCondition("survey");
0202 dd4hep::detail::tools::copy(nominal(), o->survey);
0203 }
0204 return o->survey;
0205 }
0206
0207 const DetElement::Children& DetElement::children() const {
0208 return access()->children;
0209 }
0210
0211
0212 DetElement DetElement::child(const std::string& child_name) const {
0213 if (isValid()) {
0214 const Children& c = ptr()->children;
0215 Children::const_iterator i = c.find(child_name);
0216 if ( i != c.end() ) return (*i).second;
0217 throw std::runtime_error("dd4hep: DetElement::child Unknown child with name: "+child_name);
0218 }
0219 throw std::runtime_error("dd4hep: DetElement::child: Self is not defined [Invalid Handle]");
0220 }
0221
0222
0223 DetElement DetElement::child(const std::string& child_name, bool throw_if_not_found) const {
0224 if (isValid()) {
0225 const Children& c = ptr()->children;
0226 Children::const_iterator i = c.find(child_name);
0227 if ( i != c.end() ) return (*i).second;
0228 if ( throw_if_not_found ) {
0229 throw std::runtime_error("dd4hep: DetElement::child Unknown child with name: "+child_name);
0230 }
0231 }
0232 if ( throw_if_not_found ) {
0233 throw std::runtime_error("dd4hep: DetElement::child: Self is not defined [Invalid Handle]");
0234 }
0235 return DetElement();
0236 }
0237
0238
0239 DetElement DetElement::parent() const {
0240 Object* o = ptr();
0241 return (o) ? o->parent : DetElement();
0242 }
0243
0244
0245 DetElement DetElement::world() const {
0246 Object* o = ptr();
0247 return (o) ? o->world() : World();
0248 }
0249
0250
0251 void DetElement::check(bool cond, const std::string& msg) const {
0252 if (cond) {
0253 throw std::runtime_error("dd4hep: " + msg);
0254 }
0255 }
0256
0257
0258 DetElement& DetElement::add(DetElement sdet) {
0259 if (isValid()) {
0260 auto r = object<Object>().children.emplace(sdet.name(), sdet);
0261 if (r.second) {
0262 sdet.access()->parent = *this;
0263 return *this;
0264 }
0265 except("dd4hep",
0266 "DetElement::add: Element %s is already present in path %s [Double-Insert]",
0267 sdet.name(), this->path().c_str());
0268 }
0269 except("dd4hep", "DetElement::add: Self is not defined [Invalid Handle]");
0270 throw std::runtime_error("dd4hep: DetElement::add");
0271 }
0272
0273
0274 DetElement DetElement::clone(int flg) const {
0275 Object* o = access();
0276 Object* n = o->clone(o->id, flg);
0277 n->SetName(o->GetName());
0278 n->SetTitle(o->GetTitle());
0279 return n;
0280 }
0281
0282 DetElement DetElement::clone(const std::string& new_name) const {
0283 return clone(new_name, access()->id);
0284 }
0285
0286 DetElement DetElement::clone(const std::string& new_name, int new_id) const {
0287 Object* o = access();
0288 Object* n = o->clone(new_id, COPY_PLACEMENT);
0289 n->SetName(new_name.c_str());
0290 n->SetTitle(o->GetTitle());
0291 return n;
0292 }
0293
0294 std::pair<DetElement,Volume> DetElement::reflect(const std::string& new_name) const {
0295 return reflect(new_name, access()->id);
0296 }
0297
0298 std::pair<DetElement,Volume> DetElement::reflect(const std::string& new_name, int new_id) const {
0299 return reflect(new_name, new_id, SensitiveDetector(0));
0300 }
0301
0302 std::pair<DetElement,Volume> DetElement::reflect(const std::string& new_name, int new_id, SensitiveDetector sd) const {
0303 if ( placement().isValid() ) {
0304 return m_element->reflect(new_name, new_id, sd);
0305 }
0306 except("DetElement","reflect: Only placed DetElement objects can be reflected: %s",
0307 path().c_str());
0308 return std::make_pair(DetElement(),Volume());
0309 }
0310
0311
0312 PlacedVolume DetElement::idealPlacement() const {
0313 if (isValid()) {
0314 Object& o = object<Object>();
0315 return o.idealPlace;
0316 }
0317 return PlacedVolume();
0318 }
0319
0320
0321 PlacedVolume DetElement::placement() const {
0322 if (isValid()) {
0323 Object& o = object<Object>();
0324 return o.placement;
0325 }
0326 return PlacedVolume();
0327 }
0328
0329
0330 DetElement& DetElement::setPlacement(const PlacedVolume& pv) {
0331 if (pv.isValid()) {
0332 Object* o = access();
0333 o->placement = pv;
0334 if ( !o->idealPlace.isValid() ) {
0335 o->idealPlace = pv;
0336 }
0337 return *this;
0338 }
0339 except("dd4hep", "DetElement::setPlacement: Placement is not defined [Invalid Handle]");
0340 throw std::runtime_error("dd4hep: DetElement::add");
0341 }
0342
0343
0344 dd4hep::VolumeID DetElement::volumeID() const {
0345 if (isValid()) {
0346 return object<Object>().volumeID;
0347 }
0348 return 0;
0349 }
0350
0351
0352 Volume DetElement::volume() const {
0353 return access()->placement.volume();
0354 }
0355
0356
0357 Solid DetElement::solid() const {
0358 return volume()->GetShape();
0359 }
0360
0361 DetElement& DetElement::setVisAttributes(const Detector& description, const std::string& nam, const Volume& vol) {
0362 vol.setVisAttributes(description, nam);
0363 return *this;
0364 }
0365
0366 DetElement& DetElement::setRegion(const Detector& description, const std::string& nam, const Volume& vol) {
0367 if (!nam.empty()) {
0368 vol.setRegion(description.region(nam));
0369 }
0370 return *this;
0371 }
0372
0373 DetElement& DetElement::setLimitSet(const Detector& description, const std::string& nam, const Volume& vol) {
0374 if (!nam.empty()) {
0375 vol.setLimitSet(description.limitSet(nam));
0376 }
0377 return *this;
0378 }
0379
0380 DetElement& DetElement::setAttributes(const Detector& description,
0381 const Volume& vol,
0382 const std::string& region,
0383 const std::string& limits,
0384 const std::string& vis)
0385 {
0386 return setRegion(description, region, vol).setLimitSet(description, limits, vol).setVisAttributes(description, vis, vol);
0387 }
0388
0389
0390 SensitiveDetector::SensitiveDetector(const std::string& nam, const std::string& typ) {
0391
0392
0393
0394
0395
0396
0397 assign(new Object(nam), nam, typ);
0398 object<Object>().ecut = 0e0;
0399 object<Object>().verbose = 0;
0400 }
0401
0402
0403 SensitiveDetector& SensitiveDetector::setType(const std::string& typ) {
0404 access()->SetTitle(typ.c_str());
0405 return *this;
0406 }
0407
0408
0409 std::string SensitiveDetector::type() const {
0410 return m_element ? m_element->GetTitle() : s_empty_string;
0411 }
0412
0413
0414 SensitiveDetector& SensitiveDetector::setReadout(Readout ro) {
0415 access()->readout = ro;
0416 return *this;
0417 }
0418
0419
0420 Readout SensitiveDetector::readout() const {
0421 return access()->readout;
0422 }
0423
0424
0425 IDDescriptor SensitiveDetector::idSpec() const {
0426 return readout().idSpec();
0427 }
0428
0429
0430 SensitiveDetector& SensitiveDetector::setEnergyCutoff(double value) {
0431 access()->ecut = value;
0432 return *this;
0433 }
0434
0435
0436 double SensitiveDetector::energyCutoff() const {
0437 return access()->ecut;
0438 }
0439
0440
0441 SensitiveDetector& SensitiveDetector::setHitsCollection(const std::string& collection) {
0442 access()->hitsCollection = collection;
0443 return *this;
0444 }
0445
0446
0447 const std::string& SensitiveDetector::hitsCollection() const {
0448 return access()->hitsCollection;
0449 }
0450
0451
0452 SensitiveDetector& SensitiveDetector::setVerbose(bool value) {
0453 int v = value ? 1 : 0;
0454 access()->verbose = v;
0455 return *this;
0456 }
0457
0458
0459 bool SensitiveDetector::verbose() const {
0460 return access()->verbose == 1;
0461 }
0462
0463
0464 SensitiveDetector& SensitiveDetector::setCombineHits(bool value) {
0465 int v = value ? 1 : 0;
0466 access()->combineHits = v;
0467 return *this;
0468 }
0469
0470
0471 bool SensitiveDetector::combineHits() const {
0472 return access()->combineHits == 1;
0473 }
0474
0475
0476 SensitiveDetector& SensitiveDetector::setRegion(Region reg) {
0477 access()->region = reg;
0478 return *this;
0479 }
0480
0481
0482 Region SensitiveDetector::region() const {
0483 return access()->region;
0484 }
0485
0486
0487 SensitiveDetector& SensitiveDetector::setLimitSet(LimitSet ls) {
0488 access()->limits = ls;
0489 return *this;
0490 }
0491
0492
0493 LimitSet SensitiveDetector::limits() const {
0494 return access()->limits;
0495 }
0496
0497
0498 void* SensitiveDetector::addExtension(unsigned long long int k,ExtensionEntry* e) const
0499 {
0500 return access()->addExtension(k,e);
0501 }
0502
0503
0504 void* SensitiveDetector::extension(unsigned long long int k) const {
0505 return access()->extension(k);
0506 }
0507
0508
0509 void* SensitiveDetector::extension(unsigned long long int k, bool alert) const {
0510 return access()->extension(k, alert);
0511 }