Re: Level of a TGeoNode/TGeoVolume

From: Andrei Gheata <Andrei.Gheata_at_cern.ch>
Date: Thu, 16 Feb 2006 09:14:07 +0100


Hi Christian,

This is an old thread, but you might be interested in the new TGeoIterator class. This allows 2 iteration modes of a branch starting with a volume and it works evem in case geometry is not closed. The good thing about it is speed since the iteration is not recursive (full ALICE geom - 2.5 mil nodes in 0.25 s). I attached the class to TGeoNode.h/.cxx and you can find a description of usage in the source file.

Hope this helps,
Andrei

Christian Holm Christensen wrote:

>Hi Andrei,
>
>On Wed, 2005-11-30 at 15:22 +0100, Andrei Gheata wrote:
>
>
>>Hi Christian,
>>
>>I do not really see the point for such a complex query in your case.
>>Indeed, a "geometry iterator" may do the job, but such a search by name
>>may be always error prone.
>>
>>
>
>Of course.
>
>
>
>>Generally one knows a priory the depth of any
>>node in his geometry since he has to build it.
>>
>>
>
>Not if you have alternative geometries and you're reading the geometry
>from file or the like. Take ALICE as an example. Suppose you have
>alternative geometry definitions for some sub-detector - say the FMD.
>You then run some job to produce the full geometry of ALICE, an write it
>to a file. Later you read in that geometry from the file, to do
>further simulation, digitisation, reconstruction, or the like. You
>apply some alignment corrections to that geometry. The FMD simulation,
>digitisation, reconstruction, etc. code would then have to employ some
>way of finding out where exactly (how deep) the senstive volumes are to
>do the job. Now, it would be good if the FMD code could query the
>geometry manager just how deep a given node (volume) is.
>
>Another good thing to have, would be to be able to figure out the full
>path of a node, so that one can declare that path to be a physical
>volume. I've attached a modified script that does this too.
>
>
>
>> I agree that there might
>>be cases when the depth may not be constant (e.g. positioning the same
>>volume in containers at different depths), but if this is the case the
>>iterator will not necessary give you the right answer...
>>
>>
>
>Why not? Can you really have nodes that does not have unique names?
>And if so, one could check for that by looping over the full geometry,
>and flag it as an error. Note, that the function `CheckNodes' can in
>principle start the search anywhere.
>
>
>
>>The argument
>>with complicated volume made by composition does not stand since there
>>you do not use volumes, but shapes so you can provide a different
>>identifier (name).
>>
>>
>
>This was just an example, not meant as an argument. Suppose you have
>the two geometry tree's
>
> 0 ALIC ALIC
> | |
> +----+--- .... +----+--- ....
> | |
> 1 FMD FMD
> | |
> +-------+ +-------+
> | | | |
> 2 RNG RNG RNG RNG
> | ... | ...
> | |
> +----------+ |
> | | |
> 3 HRNG HRNG SECT
> | ... |
> | |
> 4 MODU STRI
> |
> 5 SECT
> |
> 6 STRI
>
>In the left case, I need to get the 4th-level parent of STRI to know
>which RNG I'm in, while in the right case, I need to know the 2nd-level
>parent to know which RNG I'm in.
>
>
>
>>Anyway, if the relative depth that you need is really a variable that
>>you can identify only run time, any sort of iterators like this will
>>give you a severe penalty in simulation time, so you better think of
>>something else.
>>
>>
>
>Of course you shouldn't search the hierarchy each and every time - that
>would be plain stupid. As the geometry will not change after it's
>closed, one can easily cache the values of the various levels in the
>user code, and use that cached value in the stepping.
>
>Yours,
>
>
>
>------------------------------------------------------------------------
>
>#include <TGeoManager.h>
>#include <TGeoVolume.h>
>#include <TObjArray.h>
>#include <iostream>
>
>//____________________________________________________________________
>Int_t CheckNodes(TGeoNode* node, const char* name, Int_t& lvl)
>{
> // If there's no node here.
> if (!node) return -1;
> // Check if it this one
> TString sname(name);
> if (sname == node->GetName()) return lvl;
>
> // Check if the node is an immediate daugther
> TObjArray* nodes = node->GetNodes();
> if (!nodes) return -1;
> // Increase the level, and search immediate sub nodes.
> lvl++;
> TGeoNode* found = static_cast<TGeoNode*>(nodes->FindObject(name));
> if (found) return lvl;
>
> // Check the sub node, if any of their sub-nodes match.
> for (Int_t i = 0; i < nodes->GetEntries(); i++) {
> TGeoNode* sub = static_cast<TGeoNode*>(nodes->At(i));
> if (!sub) continue;
> // Recurive check
> if (CheckNodes(sub, name, lvl) >= 0) return lvl;
> }
> // If not found, decrease the level
> lvl--;
> return -1;
>}
>//____________________________________________________________________
>Int_t
>FindNodeDepth(const char* name)
>{
> TGeoNode* node = gGeoManager->GetTopNode();
> Int_t lvl = 0;
> return CheckNodes(node, name, lvl);
>}
>//____________________________________________________________________
>Int_t CheckVolumes(TGeoVolume* vol, const char* name, Int_t& lvl)
>{
> // If there's no node here.
> if (!vol) return -1;
> // Check if it this one
> TString sname(name);
> if (sname == vol->GetName()) return lvl;
>
> // Check if the node is an immediate daugther
> TObjArray* nodes = vol->GetNodes();
> if (!nodes) return -1;
>
> // Increase level
> lvl++;
> // Check the sub node, if any of their sub-nodes match.
> for (Int_t i = 0; i < nodes->GetEntries(); i++) {
> TGeoNode* node = static_cast<TGeoNode*>(nodes->At(i));
> if (!node) continue;
> TGeoVolume* sub = node->GetVolume();
> if (!sub) continue;
> if (sname == sub->GetName()) return lvl;
> // Recurive check
> if (CheckVolumes(sub, name, lvl) >= 0) return lvl;
> }
> // If not found, decrease the level
> lvl--;
> return -1;
>}
>//____________________________________________________________________
>Int_t
>FindDepth(const char* name)
>{
> TGeoVolume* top = gGeoManager->GetTopVolume();
> Int_t lvl = 0;
> return CheckVolumes(top, name, lvl);
>}
>
>//____________________________________________________________________
>Int_t CheckNodePaths(TGeoNode* node, const char* name, Int_t& lvl,
> TString& path)
>{
> // If there's no node here.
> if (!node) return -1;
> // Check if it this one
> TString sname(name);
> if (sname == node->GetName()) return lvl;
> // Check if the node is an immediate daugther
> TObjArray* nodes = node->GetNodes();
> if (!nodes) return -1;
> // Increase the level, and search immediate sub nodes.
> lvl++;
> TGeoNode* found = static_cast<TGeoNode*>(nodes->FindObject(name));
> if (found) {
> path = Form("%s/%s", node->GetName(), name);
> return lvl;
> }
>
> // Check the sub node, if any of their sub-nodes match.
> for (Int_t i = 0; i < nodes->GetEntries(); i++) {
> TGeoNode* sub = static_cast<TGeoNode*>(nodes->At(i));
> if (!sub) continue;
> // Recurive check
> if (CheckNodePaths(sub, name, lvl, path) >= 0) {
> path.Prepend(Form("%s/", node->GetName()));
> return lvl;
> }
> }
> // If not found, decrease the level
> lvl--;
> return -1;
>}
>//____________________________________________________________________
>TString
>FindPath(const char* name)
>{
> TString path;
> TGeoNode* node = gGeoManager->GetTopNode();
> Int_t lvl = 0;
> CheckNodePaths(node, name, lvl, path);
> return path;
>}
>//____________________________________________________________________
>//
>// EOF
>//
>
>
>
>
Received on Thu Feb 16 2006 - 09:11:43 MET

This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:31:57 MET