15 #define DETECTORTOOLS_CPP
26 #include <TGeoMatrix.h>
36 namespace detail {
namespace tools {
59 if ( parent.
ptr() == child.
ptr() )
return true;
61 if ( par.ptr() == parent.
ptr() )
return true;
64 throw std::runtime_error(
"Search for parent detector element with invalid handles not allowed.");
71 if ( parent.
ptr() == child.
ptr() ) {
72 path.emplace_back(child);
75 TIter next(parent->GetVolume()->GetNodes());
77 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
78 if ( daughter == child.
ptr() ) {
79 path.emplace_back(daughter);
85 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
87 bool res =
findChild(daughter, child, sub_path);
89 path.insert(path.end(), sub_path.begin(), sub_path.end());
90 path.emplace_back(daughter);
102 if ( 0 == ::strcmp(parent.
ptr()->GetName(),child.
ptr()->GetName()) ) {
103 path.emplace_back(child);
106 TIter next(parent->GetVolume()->GetNodes());
108 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
109 if ( 0 == ::strcmp(daughter->GetName(),child.
ptr()->GetName()) ) {
110 path.emplace_back(daughter);
116 for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
118 bool res = findChildByName(daughter, child, sub_path);
120 path.insert(path.end(), sub_path.begin(), sub_path.end());
121 path.emplace_back(daughter);
139 if ( parent.
ptr() == child.
ptr() ) {
145 elements.emplace_back(par);
146 if ( par.ptr() == parent.
ptr() ) {
151 throw std::runtime_error(std::string(
"The detector element ")+parent.
name()+std::string(
" is no parent of ")+child.
name());
153 throw std::runtime_error(
"Search for parent detector element with invalid handles not allowed.");
161 det_nodes.emplace_back(pv);
163 if ( par.ptr() == parent.
ptr() )
return;
165 throw std::runtime_error(std::string(
"The detector element ")+parent.
name()+std::string(
" is no parent of ")+element.
name());
173 det_nodes.emplace_back(pv);
180 std::string path =
"";
182 for(
auto i=nodes.rbegin(); i != nodes.rend(); ++i)
183 path +=
"/" + std::string((*i).name());
186 for(
auto i=begin(nodes); i != end(nodes); ++i)
187 path +=
"/" + std::string((*i)->GetName());
194 std::string path =
"";
196 for(ElementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
197 path +=
"/" + std::string((*i)->GetName());
200 for(ElementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
201 path +=
"/" + std::string((*i)->GetName());
221 size_t idx = subpath.find(
'/',1);
222 if ( subpath[0] ==
'/' ) {
224 if ( idx == std::string::npos )
return top;
227 if ( idx == std::string::npos )
228 return parent.
child(subpath);
229 std::string name = subpath.substr(0,idx);
234 throw std::runtime_error(
"dd4hep: DetElement "+parent.
path()+
" has no child named:"+name+
" [No such child]");
236 throw std::runtime_error(
"dd4hep: Cannot determine child with path "+subpath+
" from invalid parent [invalid handle]");
246 throw std::runtime_error(
"dd4hep: DetElement cannot determine top parent (world) [invalid handle]");
250 for (
size_t i = 0, n = det_nodes.size(); n > 0 && i < n-1; ++i) {
251 if (!findChildByName(det_nodes[i + 1], det_nodes[i], all_nodes)) {
252 throw std::runtime_error(
"dd4hep: DetElement cannot determine placement path of "
253 + std::string(det_nodes[i].name()) +
" [internal error]");
256 if ( det_nodes.size() > 0 ) {
257 all_nodes.emplace_back(det_nodes.back());
265 makePlacementPath(std::move(det_nodes), all_nodes);
272 makePlacementPath(std::move(det_nodes), all_nodes);
284 std::string path =
"";
286 for(PlacementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
287 path +=
"/" + std::string((*i)->GetName());
290 for(PlacementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
291 path +=
"/" + std::string((*i)->GetName());
298 std::string path =
"";
300 for(std::vector<const TGeoNode*>::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
301 path +=
"/" + std::string((*i)->GetName());
304 for(
const auto* n : nodes )
305 path +=
"/" + std::string(n->GetName());
311 if ( !mat ) mat =
new TGeoHMatrix(*gGeoIdentity);
318 if (nodes.size() > 0) {
319 for (
size_t i = 0, n=nodes.size(); n>0 && i < n-1; ++i) {
321 mat.MultiplyLeft(p->GetMatrix());
323 if ( inverse ) mat = mat.Inverse();
329 TGeoNode* top = top_place.
ptr();
330 const char* path = place.c_str();
332 Int_t length = strlen(path);
333 if (!length)
return 0;
334 TString spath = path;
337 Int_t ind1 = spath.Index(
"/");
340 if ( strcmp(path,top->GetName()) )
return 0;
345 if (ind1>0) ind1 = -1;
346 else ind2 = spath.Index(
"/", ind1+1);
348 if (ind2<0) ind2 = length;
349 TString name(spath(ind1+1, ind2-ind1-1));
350 if ( name == top->GetName() ) {
351 if (ind2>=length-1)
return top;
357 TGeoNode *node = top;
360 ind2 = spath.Index(
"/", ind1+1);
365 vol = node->GetVolume();
366 name = spath(ind1+1, ind2-ind1-1);
367 node = vol->GetNode(name.Data());
370 else if (ind2>=length-1)
379 std::stringstream log;
380 for(
const auto&
v : ids )
381 log <<
v.first <<
"=" <<
v.second <<
"; ";
387 std::stringstream log;
388 for(
const auto&
id : ids ) {
391 log <<
id.first <<
"=" <<
id.second <<
"," << value <<
" [" << f->
offset() <<
"," << f->
width() <<
"] ";
398 std::vector<std::string> result;
399 if ( !path.empty() ) {
400 std::string tmp = path[0]==
'/' ? path.substr(1) : path;
401 for(
size_t idx=tmp.find(
'/'); idx != std::string::npos; idx=tmp.find(
'/')) {
402 std::string val = tmp.substr(0,idx);
403 result.emplace_back(val);
404 tmp = tmp.length()>idx ? tmp.substr(idx+1) : std::string();
406 if ( !tmp.empty() ) {
407 result.emplace_back(tmp);