I am looping over geometry using a TGeoIterator and I want to be able to select only TGeoNodes that have any of their parts within x<0. Ideally, this is simple: I could loop over all vertices of the TGeoNodes and check if any of them has x<0; alternatively, I could loop over the 8 vertices of their bounding boxes. However, I couldn’t find this functionality easily in the documentation… I was wondering if I could get some help with that? Thank you very much!
Hi @ddobrigk ,
I think we need @agheata 's help here, let’s ping him.
Cheers,
Enrico
EDIT: I think @agheata will be off for the next few days – if you don’t hear from us at some point next week please give us a ping!
#include <iostream>
#include <TError.h>
#include <TGeoBBox.h>
#include <TGeoManager.h>
#include <TGeoNode.h>
void node_location(const char *geomfile="alice_2015.root") {
using point_t = double[3];
// Load some root geometry
TGeoManager *geom = TGeoManager::Import(geomfile);
if (!geom) {
::Error("node_location", "ERROR: geometry %s not found\n", geomfile);
return;
}
TGeoVolume *top = gGeoManager->GetTopVolume();
TGeoIterator iter(top);
TGeoNode *current;
// Vist the geometry tree from top. Get the transformation applying to the current
// geometry physical node, use it to transform the vertices of its bounding box from
// local to global reference frame. If all vertices have x < 0, we skip checking the
// Daughter nodes because they will have the same property
TString path;
point_t vertices[8];
point_t global; // current vertex in global coordinates
bool selected = false;
while ((current = iter.Next())) {
auto trans = iter.GetCurrentMatrix();
auto box = (TGeoBBox*)current->GetVolume()->GetShape();
box->SetBoxPoints((double*)vertices);
// Loop bounding box vertices
for (auto ip = 0; ip < 8; ip++) {
trans->LocalToMaster(vertices[ip], global);
// Check the condition here
if (global[0] < 0) {
selected = true;
continue; // next vertex
}
selected = false;
break;
}
// If not all vertices were selected, the node is not selected, visit daughters
if (!selected)
continue;
// Otherwise we just skip checking daughters here, but know that they are ALL selected
// If the program needs to add them to some new geometry, one could for example
// create another TGeoIterator here: `newiter = TGeoIterator(current->GetVolume())` and visit all daughters
// without any check. Pay attention to the global transformation retuned by newiter, which would
// need to be multiplied with the one returned by the current iterator
iter.GetPath(path);
std::cout << "Selected physical node: <" << path << "> and all its children.\n";
iter.Skip(); // this will skip all sub-nodes of the current one and resume visiting from the next sibling
}
}
1 Like
Hi Andrei,
Many, many thanks! I have all I need
Have a nice afternoon,
David
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.