15 #define DETECTORTOOLS_CPP
27 #include <TGeoMatrix.h>
37 namespace detail {
namespace tools {
60 if ( parent.
ptr() == child.
ptr() )
return true;
62 if ( par.ptr() == parent.
ptr() )
return true;
65 throw std::runtime_error(
"Search for parent detector element with invalid handles not allowed.");
72 if ( parent.
ptr() == child.
ptr() ) {
73 path.emplace_back(child);
76 TIter next(parent->GetVolume()->GetNodes());
78 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
79 if ( daughter == child.
ptr() ) {
80 path.emplace_back(daughter);
86 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
88 bool res =
findChild(daughter, child, sub_path);
90 path.insert(path.end(), sub_path.begin(), sub_path.end());
91 path.emplace_back(daughter);
103 if ( 0 == ::strcmp(parent.
ptr()->GetName(),child.
ptr()->GetName()) ) {
104 path.emplace_back(child);
107 TIter next(parent->GetVolume()->GetNodes());
109 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
110 if ( 0 == ::strcmp(daughter->GetName(),child.
ptr()->GetName()) ) {
111 path.emplace_back(daughter);
117 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
119 bool res = findChildByName(daughter, child, sub_path);
121 path.insert(path.end(), sub_path.begin(), sub_path.end());
122 path.emplace_back(daughter);
140 if ( parent.
ptr() == child.
ptr() ) {
146 elements.emplace_back(par);
147 if ( par.ptr() == parent.
ptr() ) {
152 throw std::runtime_error(std::string(
"The detector element ")+parent.
name()+std::string(
" is no parent of ")+child.
name());
154 throw std::runtime_error(
"Search for parent detector element with invalid handles not allowed.");
161 parent = element.
world();
166 det_nodes.emplace_back(pv);
168 if ( par.ptr() == parent.
ptr() )
return;
170 throw std::runtime_error((
"The detector element "+std::string(parent.
name())+
" is no parent of ")+element.
name());
172 throw std::runtime_error(
"Cannot access element path [Invalid DetElement]");
180 det_nodes.emplace_back(pv);
187 std::string path =
"";
189 for(
auto i=nodes.rbegin(); i != nodes.rend(); ++i)
190 path +=
"/" + std::string((*i).name());
193 for(
auto i=begin(nodes); i != end(nodes); ++i)
194 path +=
"/" + std::string((*i)->GetName());
201 std::string path =
"";
203 for(ElementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
204 path +=
"/" + std::string((*i)->GetName());
207 for(ElementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
208 path +=
"/" + std::string((*i)->GetName());
228 size_t idx = subpath.find(
'/',1);
229 if ( subpath[0] ==
'/' ) {
231 if ( idx == std::string::npos )
return top;
234 if ( idx == std::string::npos )
235 return parent.
child(subpath);
236 std::string name = subpath.substr(0,idx);
241 throw std::runtime_error(
"dd4hep: DetElement "+parent.
path()+
" has no child named:"+name+
" [No such child]");
243 throw std::runtime_error(
"dd4hep: Cannot determine child with path "+subpath+
" from invalid parent [invalid handle]");
253 throw std::runtime_error(
"dd4hep: DetElement cannot determine top parent (world) [invalid handle]");
257 for (
size_t i = 0, n = det_nodes.size(); n > 0 && i < n-1; ++i) {
258 if (!findChildByName(det_nodes[i + 1], det_nodes[i], all_nodes)) {
259 throw std::runtime_error(
"dd4hep: DetElement cannot determine placement path of "
260 + std::string(det_nodes[i].name()) +
" [internal error]");
263 if ( det_nodes.size() > 0 ) {
264 all_nodes.emplace_back(det_nodes.back());
272 makePlacementPath(std::move(det_nodes), all_nodes);
279 makePlacementPath(std::move(det_nodes), all_nodes);
291 std::string path =
"";
293 for(PlacementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
294 path +=
"/" + std::string((*i)->GetName());
297 for(PlacementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
298 path +=
"/" + std::string((*i)->GetName());
305 std::string path =
"";
307 for(std::vector<const TGeoNode*>::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
308 path +=
"/" + std::string((*i)->GetName());
311 for(
const auto* n : nodes )
312 path +=
"/" + std::string(n->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)
386 std::stringstream log;
387 for(
const auto&
v : ids )
388 log <<
v.first <<
"=" <<
v.second <<
"; ";
394 std::stringstream log;
395 for(
const auto&
id : ids ) {
398 log <<
id.first <<
"=" <<
id.second <<
"," << value <<
" [" << f->
offset() <<
"," << f->
width() <<
"] ";
405 std::vector<std::string> result;
406 if ( !path.empty() ) {
407 std::string tmp = path[0]==
'/' ? path.substr(1) : path;
408 for(
size_t idx=tmp.find(
'/'); idx != std::string::npos; idx=tmp.find(
'/')) {
409 std::string val = tmp.substr(0,idx);
410 result.emplace_back(val);
411 tmp = tmp.length()>idx ? tmp.substr(idx+1) : std::string();
413 if ( !tmp.empty() ) {
414 result.emplace_back(tmp);