Check if TGeoNode has part within x<0

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 :grinning:

Have a nice afternoon,
David

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.