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