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.");
162 det_nodes.emplace_back(pv);
164 if ( par.ptr() == parent.
ptr() )
return;
166 throw std::runtime_error(std::string(
"The detector element ")+parent.
name()+std::string(
" is no parent of ")+element.
name());
174 det_nodes.emplace_back(pv);
181 std::string path =
"";
183 for(
auto i=nodes.rbegin(); i != nodes.rend(); ++i)
184 path +=
"/" + std::string((*i).name());
187 for(
auto i=begin(nodes); i != end(nodes); ++i)
188 path +=
"/" + std::string((*i)->GetName());
195 std::string path =
"";
197 for(ElementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
198 path +=
"/" + std::string((*i)->GetName());
201 for(ElementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
202 path +=
"/" + std::string((*i)->GetName());
222 size_t idx = subpath.find(
'/',1);
223 if ( subpath[0] ==
'/' ) {
225 if ( idx == std::string::npos )
return top;
228 if ( idx == std::string::npos )
229 return parent.
child(subpath);
230 std::string name = subpath.substr(0,idx);
235 throw std::runtime_error(
"dd4hep: DetElement "+parent.
path()+
" has no child named:"+name+
" [No such child]");
237 throw std::runtime_error(
"dd4hep: Cannot determine child with path "+subpath+
" from invalid parent [invalid handle]");
247 throw std::runtime_error(
"dd4hep: DetElement cannot determine top parent (world) [invalid handle]");
251 for (
size_t i = 0, n = det_nodes.size(); n > 0 && i < n-1; ++i) {
252 if (!findChildByName(det_nodes[i + 1], det_nodes[i], all_nodes)) {
253 throw std::runtime_error(
"dd4hep: DetElement cannot determine placement path of "
254 + std::string(det_nodes[i].name()) +
" [internal error]");
257 if ( det_nodes.size() > 0 ) {
258 all_nodes.emplace_back(det_nodes.back());
266 makePlacementPath(std::move(det_nodes), all_nodes);
273 makePlacementPath(std::move(det_nodes), all_nodes);
285 std::string path =
"";
287 for(PlacementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
288 path +=
"/" + std::string((*i)->GetName());
291 for(PlacementPath::const_iterator i=nodes.begin();i!=nodes.end();++i)
292 path +=
"/" + std::string((*i)->GetName());
299 std::string path =
"";
301 for(std::vector<const TGeoNode*>::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
302 path +=
"/" + std::string((*i)->GetName());
305 for(
const auto* n : nodes )
306 path +=
"/" + std::string(n->GetName());
312 if ( !mat ) mat =
new TGeoHMatrix(*gGeoIdentity);
319 if (nodes.size() > 0) {
320 for (
size_t i = 0, n=nodes.size(); n>0 && i < n-1; ++i) {
322 mat.MultiplyLeft(p->GetMatrix());
324 if ( inverse ) mat = mat.Inverse();
330 TGeoNode* top = top_place.
ptr();
331 const char* path = place.c_str();
333 Int_t length = strlen(path);
334 if (!length)
return 0;
335 TString spath = path;
338 Int_t ind1 = spath.Index(
"/");
341 if ( strcmp(path,top->GetName()) )
return 0;
346 if (ind1>0) ind1 = -1;
347 else ind2 = spath.Index(
"/", ind1+1);
349 if (ind2<0) ind2 = length;
350 TString name(spath(ind1+1, ind2-ind1-1));
351 if ( name == top->GetName() ) {
352 if (ind2>=length-1)
return top;
358 TGeoNode *node = top;
361 ind2 = spath.Index(
"/", ind1+1);
366 vol = node->GetVolume();
367 name = spath(ind1+1, ind2-ind1-1);
368 node = vol->GetNode(name.Data());
371 else if (ind2>=length-1)
380 std::stringstream log;
381 for(
const auto&
v : ids )
382 log <<
v.first <<
"=" <<
v.second <<
"; ";
388 std::stringstream log;
389 for(
const auto&
id : ids ) {
392 log <<
id.first <<
"=" <<
id.second <<
"," << value <<
" [" << f->
offset() <<
"," << f->
width() <<
"] ";
399 std::vector<std::string> result;
400 if ( !path.empty() ) {
401 std::string tmp = path[0]==
'/' ? path.substr(1) : path;
402 for(
size_t idx=tmp.find(
'/'); idx != std::string::npos; idx=tmp.find(
'/')) {
403 std::string val = tmp.substr(0,idx);
404 result.emplace_back(val);
405 tmp = tmp.length()>idx ? tmp.substr(idx+1) : std::string();
407 if ( !tmp.empty() ) {
408 result.emplace_back(tmp);