15 #define DETECTORTOOLS_CPP
26 #include "TGeoMatrix.h"
39 namespace DetectorTools {
59 using namespace DD4hep;
60 using namespace DD4hep::Geometry;
65 if ( parent.
ptr() == child.
ptr() )
return true;
67 if ( par.ptr() == parent.
ptr() )
return true;
70 throw runtime_error(
"Search for parent detector element with invalid handles not allowed.");
77 if ( parent.
ptr() == child.
ptr() ) {
78 path.push_back(child);
81 TIter next(parent->GetVolume()->GetNodes());
83 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
84 if ( daughter == child.
ptr() ) {
85 path.push_back(daughter);
91 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
93 bool res =
findChild(daughter, child, sub_path);
95 path.insert(path.end(), sub_path.begin(), sub_path.end());
96 path.push_back(daughter);
108 if ( 0 == ::strcmp(parent.
ptr()->GetName(),child.
ptr()->GetName()) ) {
109 path.push_back(child);
112 TIter next(parent->GetVolume()->GetNodes());
114 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
115 if ( 0 == ::strcmp(daughter->GetName(),child.
ptr()->GetName()) ) {
116 path.push_back(daughter);
122 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
126 path.insert(path.end(), sub_path.begin(), sub_path.end());
127 path.push_back(daughter);
138 detectors.push_back(par);
145 if ( parent.
ptr() == child.
ptr() ) {
146 detectors.push_back(child);
151 elements.push_back(par);
152 if ( par.ptr() == parent.
ptr() ) {
153 detectors = elements;
157 throw runtime_error(
string(
"The detector element ")+parent.
name()+string(
" is no parent of ")+child.
name());
159 throw runtime_error(
"Search for parent detector element with invalid handles not allowed.");
167 det_nodes.push_back(pv);
169 if ( par.ptr() == parent.
ptr() )
return;
171 throw runtime_error(
string(
"The detector element ")+parent.
name()+string(
" is no parent of ")+element.
name());
179 det_nodes.push_back(pv);
188 for(PlacementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
189 s +=
"/" +
string((*i).name());
192 for(PlacementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
193 s +=
"/" +
string((*i)->GetName());
202 for(ElementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
203 s +=
"/" +
string((*i)->GetName());
206 for(ElementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
207 s +=
"/" +
string((*i)->GetName());
227 size_t idx = subpath.find(
'/',1);
228 if ( subpath[0] ==
'/' ) {
230 if ( idx == string::npos )
return top;
233 if ( idx == string::npos )
234 return parent.
child(subpath);
235 string name = subpath.substr(0,idx);
240 throw runtime_error(
"DD4hep: DetElement "+parent.
path()+
" has no child named:"+name+
" [No such child]");
242 throw runtime_error(
"DD4hep: Cannot determine child with path "+subpath+
" from invalid parent [invalid handle]");
252 throw runtime_error(
"DD4hep: DetElement cannot determine top parent (world) [invalid handle]");
256 for (
size_t i = 0, n = det_nodes.size(); i < n-1; ++i) {
258 throw runtime_error(
"DD4hep: DetElement cannot determine placement path of "
259 +
string(det_nodes[i].name()) +
" [internal error]");
262 if ( det_nodes.size() > 0 ) {
263 all_nodes.push_back(det_nodes.back());
292 for(PlacementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
293 s +=
"/" +
string((*i)->GetName());
296 for(PlacementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
297 s +=
"/" +
string((*i)->GetName());
306 for(std::vector<const TGeoNode*>::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
307 s +=
"/" +
string((*i)->GetName());
310 for(std::vector<const TGeoNode*>::const_iterator i=nodes.begin();i!=nodes.end();++i)
311 s +=
"/" +
string((*i)->GetName());
318 if ( !mat ) mat =
new TGeoHMatrix(*gGeoIdentity);
325 if (nodes.size() > 0) {
326 for (
size_t i = 0, n=nodes.size(); n>0 && i < n-1; ++i) {
328 mat.MultiplyLeft(p->GetMatrix());
330 if ( inverse ) mat = mat.Inverse();
336 TGeoNode* top = top_place.
ptr();
337 const char* path = place.c_str();
339 Int_t length = strlen(path);
340 if (!length)
return 0;
341 TString spath = path;
344 Int_t ind1 = spath.Index(
"/");
347 if ( strcmp(path,top->GetName()) )
return 0;
352 if (ind1>0) ind1 = -1;
353 else ind2 = spath.Index(
"/", ind1+1);
355 if (ind2<0) ind2 = length;
356 TString name(spath(ind1+1, ind2-ind1-1));
357 if ( name == top->GetName() ) {
358 if (ind2>=length-1)
return top;
364 TGeoNode *node = top;
367 ind2 = spath.Index(
"/", ind1+1);
372 vol = node->GetVolume();
373 name = spath(ind1+1, ind2-ind1-1);
374 node = vol->GetNode(name.Data());
377 else if (ind2>=length-1)
387 for (PlacedVolume::VolIDs::const_iterator vit = ids.begin(); vit != ids.end(); ++vit)
388 log << (*vit).first <<
"=" << (*vit).second <<
"; ";
395 for (PlacedVolume::VolIDs::const_iterator idIt = ids.begin(); idIt != ids.end(); ++idIt) {
399 log <<
id.first <<
"=" <<
id.second <<
"," << value <<
" [" << f->offset() <<
"," << f->width() <<
"] ";
Handle class holding a placed volume (also called physical volume)
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
const char * name() const
Access the object name (or "" if not supported by the object)
bool isValid() const
Check the validity of the object held by the handle.
T * ptr() const
Access to the held object.
DetElement child(const std::string &name) const
Access to individual children by name.
Field field(const std::string &field_name) const
Get the field descriptor of one field by name.
const std::string & path() const
Path of the detector element (not necessarily identical to placement path!)
DetElement parent() const
Access to the detector elements's parent.
Handle class describing a detector element.
The main interface to the DD4hep detector description package.
Class implementing the ID encoding of detector response.