ROOT logo
// @(#)root/geom:$Id: TGeoNode.cxx 25858 2008-10-17 16:32:05Z brun $
// Author: Andrei Gheata   24/10/01

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

////////////////////////////////////////////////////////////////////////////////
// TGeoNode
//_________
//   A node represent a volume positioned inside another.They store links to both
// volumes and to the TGeoMatrix representing the relative positioning. Node are
// never instanciated directly by users, but created as a result of volume operations.
// Adding a volume named A with a given user ID inside a volume B will create a node 
// node named A_ID. This will be added to the list of nodes stored by B. Also,
// when applying a division operation in N slices to a volume A, a list of nodes
// B_1, B_2, ..., B_N is also created. A node B_i does not represent a unique
// object in the geometry because its container A might be at its turn positioned
// as node inside several other volumes. Only when a complete branch of nodes
// is fully defined up to the top node in the geometry, a given path like:
//       /TOP_1/.../A_3/B_7 will represent an unique object. Its global transformation
// matrix can be computed as the pile-up of all local transformations in its
// branch. We will therefore call "logical graph" the hierarchy defined by nodes
// and volumes. The expansion of the logical graph by all possible paths defines
// a tree sructure where all nodes are unique "touchable" objects. We will call
// this the "physical tree". Unlike the logical graph, the physical tree can
// become a huge structure with several milions of nodes in case of complex
// geometries, therefore it is not always a good idea to keep it transient
// in memory. Since a the logical and physical structures are correlated, the
// modeller rather keeps track only of the current branch, updating the current
// global matrix at each change of the level in geometry. The current physical node
// is not an object that can be asked for at a given moment, but rather represented
// by the combination: current node + current global matrix. However, physical nodes
// have unique ID's that can be retreived for a given modeler state. These can be
// fed back to the modeler in order to force a physical node to become current.
// The advantage of this comes from the fact that all navigation queries check
// first the current node, therefore knowing the location of a point in the 
// geometry can be saved as a starting state for later use.
//
//   Nodes can be declared as "overlapping" in case they do overlap with other
// nodes inside the same container or extrude this container. Non-overlapping
// nodes can be created with:
//
//      TGeoVolume::AddNode(TGeoVolume *daughter, Int_t copy_No, TGeoMatrix *matr);
//
// The creation of overapping nodes can be done with a similar prototype:
//
//      TGeoVolume::AddNodeOverlap(same arguments);
//
// When closing the geometry, overlapping nodes perform a check of possible
// overlaps with their neighbours. These are stored and checked all the time
// during navigation, therefore navigation is slower when embedding such nodes
// into geometry.
//
//   Node have visualization attributes as volume have. When undefined by users,
// painting a node on a pad will take the corresponding volume attributes.
// 
//Begin_Html
/*
<img src="gif/t_node.jpg">
*/
//End_Html

#include "Riostream.h"

#include "TBrowser.h"
#include "TObjArray.h"
#include "TStyle.h"

#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TGeoShape.h"
#include "TGeoVolume.h"
#include "TVirtualGeoPainter.h"
#include "TGeoVoxelFinder.h"
#include "TGeoNode.h"
#include "TMath.h"
#include "TStopwatch.h"

// statics and globals

ClassImp(TGeoNode)

//_____________________________________________________________________________
TGeoNode::TGeoNode()
{
// Default constructor
   fVolume       = 0;
   fMother       = 0;
   fNumber       = 0;
   fOverlaps     = 0;
   fNovlp        = 0;
}

//_____________________________________________________________________________
TGeoNode::TGeoNode(const TGeoVolume *vol)
{
// Constructor
   if (!vol) {
      Error("ctor", "volume not specified");
      return;
   }
   fVolume       = (TGeoVolume*)vol;
   if (fVolume->IsAdded()) fVolume->SetReplicated();
   fVolume->SetAdded();
   fMother       = 0;
   fNumber       = 0;
   fOverlaps     = 0;
   fNovlp        = 0;
}

//_____________________________________________________________________________
TGeoNode::TGeoNode(const TGeoNode& gn) :
  TNamed(gn),
  TGeoAtt(gn),
  fVolume(gn.fVolume),
  fMother(gn.fMother),
  fNumber(gn.fNumber),
  fNovlp(gn.fNovlp),
  fOverlaps(gn.fOverlaps)
{ 
   //copy constructor
}

//_____________________________________________________________________________
TGeoNode& TGeoNode::operator=(const TGeoNode& gn) 
{
   //assignment operator
   if(this!=&gn) {
      TNamed::operator=(gn);
      TGeoAtt::operator=(gn);
      fVolume=gn.fVolume;
      fMother=gn.fMother;
      fNumber=gn.fNumber;
      fNovlp=gn.fNovlp;
      fOverlaps=gn.fOverlaps;
   } 
   return *this;
}

//_____________________________________________________________________________
TGeoNode::~TGeoNode()
{
// Destructor
   if (fOverlaps) delete [] fOverlaps;
}

//_____________________________________________________________________________
void TGeoNode::Browse(TBrowser *b)
{
// How-to-browse for a node.
   if (!b) return;
   if (!GetNdaughters()) return;
   TGeoNode *daughter;
   TString title;
   for (Int_t i=0; i<GetNdaughters(); i++) {
      daughter = GetDaughter(i);
      b->Add(daughter, daughter->GetName(), daughter->IsVisible());
   }      
}

//_____________________________________________________________________________
Int_t TGeoNode::CountDaughters(Bool_t unique_volumes)
{
// Returns the number of daughters. Nodes pointing to same volume counted
// once if unique_volumes is set.
   static Int_t icall = 0;   
   Int_t counter = 0;
   // Count this node
   if (unique_volumes) {
      if (!fVolume->IsSelected()) {
         counter++;
         fVolume->SelectVolume(kFALSE);
      }
   } else counter++;
   icall++;
   Int_t nd = fVolume->GetNdaughters();
   // Count daughters recursively
   for (Int_t i=0; i<nd; i++) counter += GetDaughter(i)->CountDaughters(unique_volumes);
   icall--;
   // Un-mark volumes
   if (icall == 0) fVolume->SelectVolume(kTRUE);
   return counter;
}      

//_____________________________________________________________________________
void TGeoNode::CheckOverlaps(Double_t ovlp, Option_t *option)
{
// Check overlaps bigger than OVLP hierarchically, starting with this node.
   Int_t icheck = 0;
   Int_t ncheck = 0;
   TStopwatch *timer;
   Int_t i;
   Bool_t sampling = kFALSE;
   TString opt(option);
   opt.ToLower();
   if (opt.Contains("s")) sampling = kTRUE;

   TGeoManager *geom = fVolume->GetGeoManager();
   ncheck = CountDaughters(kFALSE);
   timer = new TStopwatch();
   geom->ClearOverlaps();
   geom->SetCheckingOverlaps(kTRUE);
   Info("CheckOverlaps", "Checking overlaps for %s and daughters within %g", fVolume->GetName(),ovlp);
   if (sampling) {
      Info("CheckOverlaps", "Checking overlaps by sampling <%s> for %s and daughters", option, fVolume->GetName());
      Info("CheckOverlaps", "=== NOTE: Extrusions NOT checked with sampling option ! ===");
   }   
   timer->Start();
   geom->GetGeomPainter()->OpProgress(fVolume->GetName(),icheck,ncheck,timer,kFALSE);
   fVolume->CheckOverlaps(ovlp,option);
   icheck++;
   TGeoIterator next(fVolume);
   TGeoNode *node;
   TString path;
   while ((node=next())) {
      next.GetPath(path);
      icheck++;
      if (!node->GetVolume()->IsSelected()) {
         geom->GetGeomPainter()->OpProgress(node->GetVolume()->GetName(),icheck,ncheck,timer,kFALSE);
         node->GetVolume()->SelectVolume(kFALSE);
         node->GetVolume()->CheckOverlaps(ovlp,option);
      }   
   }   
   fVolume->SelectVolume(kTRUE);
   geom->SetCheckingOverlaps(kFALSE);
   geom->SortOverlaps();
   TObjArray *overlaps = geom->GetListOfOverlaps();
   Int_t novlps = overlaps->GetEntriesFast();     
   TNamed *obj;
   for (i=0; i<novlps; i++) {
      obj = (TNamed*)overlaps->At(i);
      obj->SetName(Form("ov%05d",i));
   }
   geom->GetGeomPainter()->OpProgress("Check overlaps:",icheck,ncheck,timer,kTRUE);
   Info("CheckOverlaps", "Number of illegal overlaps/extrusions : %d\n", novlps);
   delete timer;
}      

//_____________________________________________________________________________
Int_t TGeoNode::DistancetoPrimitive(Int_t px, Int_t py)
{
// compute the closest distance of approach from point px,py to this node
   Int_t dist = 9999;
   if (!fVolume) return dist;
   if (gGeoManager != fVolume->GetGeoManager()) gGeoManager = fVolume->GetGeoManager();
   TVirtualGeoPainter *painter = gGeoManager->GetPainter();
   if (!painter) return dist;
   dist = painter->DistanceToPrimitiveVol(fVolume, px, py);
   return dist;
}
      
//_____________________________________________________________________________
void TGeoNode::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
// Execute mouse actions on this volume.
   if (!fVolume) return;
   TVirtualGeoPainter *painter = fVolume->GetGeoManager()->GetPainter();
   if (!painter) return;
   painter->ExecuteVolumeEvent(fVolume, event, px, py);
}

//_____________________________________________________________________________
char *TGeoNode::GetObjectInfo(Int_t px, Int_t py) const
{
// Get node info for the browser.
   if (!fVolume) return 0;
   TVirtualGeoPainter *painter = fVolume->GetGeoManager()->GetPainter();
   if (!painter) return 0;
   return painter->GetVolumeInfo(fVolume, px, py);
}

//_____________________________________________________________________________
Bool_t TGeoNode::IsOnScreen() const
{
// check if this node is drawn. Assumes that this node is current
   
   if (fVolume->TestAttBit(TGeoAtt::kVisOnScreen)) return kTRUE;
   return kFALSE;
}

//_____________________________________________________________________________
void TGeoNode::InspectNode() const
{
// Inspect this node.
   Info("InspectNode","Inspecting node %s", GetName());
   if (IsOverlapping()) Info("InspectNode","node is MANY");
   if (fOverlaps && fMother) {
      Info("InspectNode","possibly overlaping with :");
      for (Int_t i=0; i<fNovlp; i++)
         Info("InspectNode","   node %s", fMother->GetNode(fOverlaps[i])->GetName());
   }
   Info("InspectNode","Transformation matrix:\n");
   TGeoMatrix *matrix = GetMatrix();
   if (matrix) matrix->Print();
   if (fMother)
      Info("InspectNode","Mother volume %s\n", fMother->GetName());
   fVolume->InspectShape();
}

//_____________________________________________________________________________
void TGeoNode::CheckShapes()
{
// check for wrong parameters in shapes
   fVolume->CheckShapes();
   Int_t nd = GetNdaughters();
   if (!nd) return;
   for (Int_t i=0; i<nd; i++) fVolume->GetNode(i)->CheckShapes();
}

//_____________________________________________________________________________
void TGeoNode::DrawOnly(Option_t *option)
{
// draw only this node independently of its vis options
   fVolume->DrawOnly(option);
}

//_____________________________________________________________________________
void TGeoNode::Draw(Option_t *option)
{
// draw current node according to option
   gGeoManager->FindNode();
   gGeoManager->CdUp();
   Double_t point[3];
   gGeoManager->MasterToLocal(gGeoManager->GetCurrentPoint(), &point[0]);
   gGeoManager->SetCurrentPoint(&point[0]);
   gGeoManager->GetCurrentVolume()->Draw(option);
}

//_____________________________________________________________________________
void TGeoNode::DrawOverlaps()
{
// Method drawing the overlap candidates with this node.
   if (!fNovlp) {printf("node %s is ONLY\n", GetName()); return;}
   if (!fOverlaps) {printf("node %s no overlaps\n", GetName()); return;}
   TGeoNode *node;
   Int_t i;
   Int_t nd = fMother->GetNdaughters();
   for (i=0; i<nd; i++) {
      node = fMother->GetNode(i);
      node->GetVolume()->SetVisibility(kFALSE);
   }   
   fVolume->SetVisibility(kTRUE);
   for (i=0; i<fNovlp; i++) {
      node = fMother->GetNode(fOverlaps[i]);
      node->GetVolume()->SetVisibility(kTRUE);
   }
   gGeoManager->SetVisLevel(1);
   fMother->Draw();
}

//_____________________________________________________________________________
void TGeoNode::FillIdArray(Int_t &ifree, Int_t &nodeid, Int_t *array) const
{
// Fill array with node id. Recursive on node branch.
   Int_t nd = GetNdaughters();
   if (!nd) return;
   TGeoNode *daughter;
   Int_t istart = ifree; // start index for daughters
   ifree += nd;
   for (Int_t id=0; id<nd; id++) {
      daughter = GetDaughter(id);
      array[istart+id] = ifree;
      array[ifree++] = ++nodeid;
      daughter->FillIdArray(ifree, nodeid, array);
   }
}      
   

//_____________________________________________________________________________
Int_t TGeoNode::FindNode(const TGeoNode *node, Int_t level)
{
// Search for a node within the branch of this one.
   Int_t nd = GetNdaughters();
   if (!nd) return -1;
   TIter next(fVolume->GetNodes());
   TGeoNode *daughter;
   while ((daughter=(TGeoNode*)next())) {
      if (daughter==node) {
         gGeoManager->GetListOfNodes()->AddAt(daughter,level+1);
         return (level+1);
      }
   }
   next.Reset();
   Int_t new_level;
   while ((daughter=(TGeoNode*)next())) {
      new_level = daughter->FindNode(node, level+1);
      if (new_level>=0) {
         gGeoManager->GetListOfNodes()->AddAt(daughter, level+1);
         return new_level;
      }
   }
   return -1;
}

//_____________________________________________________________________________
void TGeoNode::SaveAttributes(ostream &out)
{
// save attributes for this node
   if (IsVisStreamed()) return;
   SetVisStreamed(kTRUE);
   char quote='"';
   Bool_t voldef = kFALSE;
   if ((fVolume->IsVisTouched()) && (!fVolume->IsVisStreamed())) {
      fVolume->SetVisStreamed(kTRUE);
      out << "   vol = gGeoManager->GetVolume("<<quote<<fVolume->GetName()<<quote<<");"<<endl;
      voldef = kTRUE;
      if (!fVolume->IsVisDaughters())
         out << "   vol->SetVisDaughters(kFALSE);"<<endl;
      if (fVolume->IsVisible()) {
/*
         if (fVolume->GetLineColor() != gStyle->GetLineColor())
            out<<"   vol->SetLineColor("<<fVolume->GetLineColor()<<");"<<endl;
         if (fVolume->GetLineStyle() != gStyle->GetLineStyle())
            out<<"   vol->SetLineStyle("<<fVolume->GetLineStyle()<<");"<<endl;
         if (fVolume->GetLineWidth() != gStyle->GetLineWidth())
            out<<"   vol->SetLineWidth("<<fVolume->GetLineWidth()<<");"<<endl;
*/
      } else {
         out <<"   vol->SetVisibility(kFALSE);"<<endl;
      }
   }
   if (!IsVisDaughters()) return;
   Int_t nd = GetNdaughters();
   if (!nd) return;
   TGeoNode *node;
   for (Int_t i=0; i<nd; i++) {
      node = GetDaughter(i);
      if (node->IsVisStreamed()) continue;
      if (node->IsVisTouched()) {
         if (!voldef)
            out << "   vol = gGeoManager->GetVolume("<<quote<<fVolume->GetName()<<quote<<");"<<endl;
         out<<"   node = vol->GetNode("<<i<<");"<<endl;
         if (!node->IsVisDaughters()) {
            out<<"   node->VisibleDaughters(kFALSE);"<<endl;
            node->SetVisStreamed(kTRUE);
            continue;
         }
         if (!node->IsVisible()) 
            out<<"   node->SetVisibility(kFALSE);"<<endl;
      }         
      node->SaveAttributes(out);
      node->SetVisStreamed(kTRUE);
   }
}

//_____________________________________________________________________________
Bool_t TGeoNode::MayOverlap(Int_t iother) const 
{
// Check the overlab between the bounding box of the node overlaps with the one
// the brother with index IOTHER.
   if (!fOverlaps) return kFALSE;
   for (Int_t i=0; i<fNovlp; i++) if (fOverlaps[i]==iother) return kTRUE;
   return kFALSE;
}   

//_____________________________________________________________________________
void TGeoNode::MasterToLocal(const Double_t *master, Double_t *local) const
{
// Convert the point coordinates from mother reference to local reference system
   GetMatrix()->MasterToLocal(master, local);
}

//_____________________________________________________________________________
void TGeoNode::MasterToLocalVect(const Double_t *master, Double_t *local) const
{
// Convert a vector from mother reference to local reference system
   GetMatrix()->MasterToLocalVect(master, local);
}

//_____________________________________________________________________________
void TGeoNode::LocalToMaster(const Double_t *local, Double_t *master) const
{
// Convert the point coordinates from local reference system to mother reference
   GetMatrix()->LocalToMaster(local, master);
}

//_____________________________________________________________________________
void TGeoNode::LocalToMasterVect(const Double_t *local, Double_t *master) const
{
// Convert a vector from local reference system to mother reference
   GetMatrix()->LocalToMasterVect(local, master);
}

//_____________________________________________________________________________
void TGeoNode::ls(Option_t * /*option*/) const
{
// Print the path (A/B/C/...) to this node on stdout
}

//_____________________________________________________________________________
void TGeoNode::Paint(Option_t *option)
{
// Paint this node and its content according to visualization settings.
   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
   if (!painter) return;
   painter->PaintNode(this, option);
}

//_____________________________________________________________________________
void TGeoNode::PrintCandidates() const
{
// print daughters candidates for containing current point
//   cd();
   Double_t point[3];
   gGeoManager->MasterToLocal(gGeoManager->GetCurrentPoint(), &point[0]);
   printf("   Local : %g, %g, %g\n", point[0], point[1], point[2]);
   if (!fVolume->Contains(&point[0])) {
      printf("current point not inside this\n");
      return;
   }
   TGeoPatternFinder *finder = fVolume->GetFinder();
   TGeoNode *node;
   if (finder) {
      printf("current node divided\n");
      node = finder->FindNode(&point[0]);
      if (!node) {
         printf("point not inside division element\n");
         return;
      }
      printf("inside division element %s\n", node->GetName());
      return;
   }
   TGeoVoxelFinder *voxels = fVolume->GetVoxels();
   if (!voxels) {
      printf("volume not voxelized\n");
      return;
   }
   Int_t ncheck = 0;
   Int_t *check_list = voxels->GetCheckList(&point[0], ncheck);
   voxels->PrintVoxelLimits(&point[0]);
   if (!check_list) {
      printf("no candidates for current point\n");
      return;
   }
   TString overlap = "ONLY";
   for (Int_t id=0; id<ncheck; id++) {
      node = fVolume->GetNode(check_list[id]);
      if (node->IsOverlapping()) overlap = "MANY";
      else overlap = "ONLY";
      printf("%i %s %s\n", check_list[id], node->GetName(), overlap.Data());
   }
   PrintOverlaps();
}

//_____________________________________________________________________________
void TGeoNode::PrintOverlaps() const
{
// print possible overlapping nodes
//   if (!IsOverlapping()) {printf("node %s is ONLY\n", GetName()); return;}
   if (!fOverlaps) {printf("node %s no overlaps\n", GetName()); return;}
   printf("Overlaps for node %s :\n", GetName());
   TGeoNode *node;
   for (Int_t i=0; i<fNovlp; i++) {
      node = fMother->GetNode(fOverlaps[i]);
      printf("   %s\n", node->GetName());
   }
}

//_____________________________________________________________________________
Double_t TGeoNode::Safety(Double_t *point, Bool_t in) const
{
// computes the closest distance from given point to this shape

   Double_t local[3];
   GetMatrix()->MasterToLocal(point,local);
   return fVolume->GetShape()->Safety(local,in);
}

//_____________________________________________________________________________
void TGeoNode::SetOverlaps(Int_t *ovlp, Int_t novlp)
{
// set the list of overlaps for this node (ovlp must be created with operator new)
   if (fOverlaps) delete [] fOverlaps;
   fOverlaps = ovlp;
   fNovlp = novlp;
}

//_____________________________________________________________________________
void TGeoNode::SetVisibility(Bool_t vis)
{
// Set visibility of the node (obsolete).
   if (gGeoManager->IsClosed()) SetVisTouched(kTRUE);
   TGeoAtt::SetVisibility(vis);
   if (vis && !fVolume->IsVisible()) fVolume->SetVisibility(vis);
   gGeoManager->ModifiedPad();
}

//_____________________________________________________________________________
void TGeoNode::VisibleDaughters(Bool_t vis)
{
// Set visibility of the daughters (obsolete).
   if (gGeoManager->IsClosed()) SetVisTouched(kTRUE);
   SetVisDaughters(vis);
   gGeoManager->ModifiedPad();
}

////////////////////////////////////////////////////////////////////////////////
// TGeoNodeMatrix - a node containing local transformation
//
//
//
//
//Begin_Html
/*
<img src=".gif">
*/
//End_Html

ClassImp(TGeoNodeMatrix)


//_____________________________________________________________________________
TGeoNodeMatrix::TGeoNodeMatrix()
{
// Default constructor
   fMatrix       = 0;
}

//_____________________________________________________________________________
TGeoNodeMatrix::TGeoNodeMatrix(const TGeoVolume *vol, const TGeoMatrix *matrix) :
             TGeoNode(vol)
{
// Constructor. 
   fMatrix = (TGeoMatrix*)matrix;
   if (!fMatrix) fMatrix = gGeoIdentity;
}

//_____________________________________________________________________________
TGeoNodeMatrix::TGeoNodeMatrix(const TGeoNodeMatrix& gnm)
               :TGeoNode(gnm), 
                fMatrix(gnm.fMatrix)
{
// Copy ctor.
}

//_____________________________________________________________________________
TGeoNodeMatrix& TGeoNodeMatrix::operator=(const TGeoNodeMatrix& gnm)
{
// Assignment.
   if (this!=&gnm) {
      TGeoNode::operator=(gnm); 
      fMatrix=gnm.fMatrix;
   }
   return *this;
}
      
//_____________________________________________________________________________
TGeoNodeMatrix::~TGeoNodeMatrix()
{
// Destructor
}

//_____________________________________________________________________________
Int_t TGeoNodeMatrix::GetByteCount() const
{
// return the total size in bytes of this node
   Int_t count = 40 + 4; // TGeoNode + fMatrix
//   if (fMatrix) count += fMatrix->GetByteCount();
   return count;
}

//_____________________________________________________________________________
Int_t TGeoNodeMatrix::GetOptimalVoxels() const
{
//--- Returns type of optimal voxelization for this node.
// type = 0 -> cartesian
// type = 1 -> cylindrical
   Bool_t type = fVolume->GetShape()->IsCylType();
   if (!type) return 0;
   if (!fMatrix->IsRotAboutZ()) return 0;
   const Double_t *transl = fMatrix->GetTranslation();
   if (TMath::Abs(transl[0])>1E-10) return 0;
   if (TMath::Abs(transl[1])>1E-10) return 0;
   return 1;
}   

//_____________________________________________________________________________
TGeoNode *TGeoNodeMatrix::MakeCopyNode() const
{
// Make a copy of this node.
   TGeoNodeMatrix *node = new TGeoNodeMatrix(fVolume, fMatrix);
   node->SetName(GetName());
   // set the mother
   node->SetMotherVolume(fMother);
   // set the copy number
   node->SetNumber(fNumber);
   // copy overlaps
   if (fNovlp>0) {
      if (fOverlaps) {
         Int_t *ovlps = new Int_t[fNovlp];
         memcpy(ovlps, fOverlaps, fNovlp*sizeof(Int_t));
         node->SetOverlaps(ovlps, fNovlp);
      } else {
         node->SetOverlaps(fOverlaps, fNovlp);
      }
   }
   // copy VC
   if (IsVirtual()) node->SetVirtual();
   return node;
}

//_____________________________________________________________________________
void TGeoNodeMatrix::SetMatrix(const TGeoMatrix *matrix)
{
// Matrix setter.
   fMatrix = (TGeoMatrix*)matrix;
   if (!fMatrix) fMatrix = gGeoIdentity;
}   

/*************************************************************************
 * TGeoNodeOffset - node containing an offset
 *
 *************************************************************************/
ClassImp(TGeoNodeOffset)


//_____________________________________________________________________________
TGeoNodeOffset::TGeoNodeOffset()
{
// Default constructor
   TObject::SetBit(kGeoNodeOffset);
   fOffset = 0;
   fIndex = 0;
   fFinder = 0;
}

//_____________________________________________________________________________
TGeoNodeOffset::TGeoNodeOffset(const TGeoVolume *vol, Int_t index, Double_t offset) :
           TGeoNode(vol)
{
// Constructor. Null pointer to matrix means identity transformation
   TObject::SetBit(kGeoNodeOffset);
   fOffset = offset;
   fIndex = index;
   fFinder = 0;
}

//_____________________________________________________________________________
TGeoNodeOffset::TGeoNodeOffset(const TGeoNodeOffset& gno) :
  TGeoNode(gno),
  fOffset(gno.fOffset),
  fIndex(gno.fIndex),
  fFinder(gno.fFinder)
{ 
   //copy constructor
}

//_____________________________________________________________________________
TGeoNodeOffset& TGeoNodeOffset::operator=(const TGeoNodeOffset& gno)
{
   //assignment operator
   if(this!=&gno) {
      TGeoNode::operator=(gno);
      fOffset=gno.fOffset;
      fIndex=gno.fIndex;
      fFinder=gno.fFinder;
   } 
   return *this;
}

//_____________________________________________________________________________
TGeoNodeOffset::~TGeoNodeOffset()
{
// Destructor
}

//_____________________________________________________________________________
Int_t TGeoNodeOffset::GetIndex() const
{
// Get the index of this offset.
   return (fIndex+fFinder->GetDivIndex());
}

//_____________________________________________________________________________
TGeoNode *TGeoNodeOffset::MakeCopyNode() const
{
// make a copy of this node
   TGeoNodeOffset *node = new TGeoNodeOffset(fVolume, GetIndex(), fOffset);
   node->SetName(GetName());
   // set the mother
   node->SetMotherVolume(fMother);
   // set the copy number
   node->SetNumber(fNumber);
   if (IsVirtual()) node->SetVirtual();
   // set the finder
   node->SetFinder(GetFinder());
   return node;
}

/*************************************************************************
 * TGeoIterator - a geometry iterator
 *
 *************************************************************************/

////////////////////////////////////////////////////////////////////////////////
// TGeoIterator
//==============
// A geometry iterator that sequentially follows all nodes of the geometrical
// hierarchy of a volume. The iterator has to be initiated with a top volume 
// pointer:
//
//    TGeoIterator next(myVolume);
//
// One can use the iterator as any other in ROOT:
//
//    TGeoNode *node;
//    while ((node=next())) {
//       ...
//    }
// 
// The iterator can perform 2 types of iterations that can be selected via:
//
//    next.SetType(Int_t type);
//
// Here TYPE can be:
//    0 (default) - 'first daughter next' behavior
//    1           - iteration at the current level only
//
// Supposing the tree structure looks like:
//
// TOP ___ A_1 ___ A1_1 ___ A11_1
//    |       |        |___ A12_1
//    |      |_____A2_1 ___ A21_1
//    |                |___ A21_2
//    |___ B_1 ...
//
// The order of iteration for TYPE=0 is: A_1, A1_1, A11_1, A12_1, A2_1, A21_1,
// A21_2, B_1, ...
// The order of iteration for TYPE=1 is: A_1, B_1, ...
// At any moment during iteration, TYPE can be changed. If the last iterated node
// is for instance A1_1 and the iteration type was 0, one can do:
//
//    next.SetType(1);
// The next iterated nodes will be the rest of A daughters: A2,A3,... The iterator
// will return 0 after finishing all daughters of A.
//
// During iteration, the following can be retreived:
// - Top volume where iteration started:    TGeoIterator::GetTopVolume()
// - Node at level I in the current branch: TGeoIterator::GetNode(Int_t i)
// - Iteration type:                        TGeoIterator::GetType()
// - Global matrix of the current node with respect to the top volume:
//                                          TGeoIterator::GetCurrentMatrix()
//
// The iterator can be reset by changing (or not) the top volume:
//
//    TGeoIterator::Reset(TGeoVolume *top);
//
// Example:
//==========
// We want to find out a volume named "MyVol" in the hierarchy of TOP volume.
// 
//    TIter next(TOP);
//    TGeoNode *node;
//    TString name("MyVol");
//    while ((node=next())) 
//       if (name == node->GetVolume()->GetName()) return node->GetVolume();
//
////////////////////////////////////////////////////////////////////////////////

ClassImp(TGeoIterator)

//_____________________________________________________________________________
TGeoIterator::TGeoIterator(TGeoVolume *top)
{
// Geometry iterator for a branch starting with a TOP node.
   fTop = top;
   fLevel = 0;
   fMustResume = kFALSE;
   fMustStop = kFALSE;
   fType = 0;
   fArray = new Int_t[30];
   fMatrix = new TGeoHMatrix();
   fTopName = fTop->GetName();
}   

//_____________________________________________________________________________
TGeoIterator::TGeoIterator(const TGeoIterator &iter)
{
// Copy ctor.
   fTop = iter.GetTopVolume();
   fLevel = iter.GetLevel();
   fMustResume = kFALSE;
   fMustStop = kFALSE;
   fType = iter.GetType();
   fArray = new Int_t[30+ 30*Int_t(fLevel/30)];
   for (Int_t i=0; i<fLevel+1; i++) fArray[i] = iter.GetIndex(i);
   fMatrix = new TGeoHMatrix(*iter.GetCurrentMatrix());
   fTopName = fTop->GetName();
}

//_____________________________________________________________________________
TGeoIterator::~TGeoIterator()
{
// Destructor.
   if (fArray) delete [] fArray;
   delete fMatrix;
}   

//_____________________________________________________________________________
TGeoIterator &TGeoIterator::operator=(const TGeoIterator &iter)
{
// Assignment.
   fTop = iter.GetTopVolume();
   fLevel = iter.GetLevel();
   fMustResume = kFALSE;
   fMustStop = kFALSE;
   fType = iter.GetType();
   if (fArray) delete [] fArray;
   fArray = new Int_t[30+ 30*Int_t(fLevel/30)];
   for (Int_t i=0; i<fLevel+1; i++) fArray[i] = iter.GetIndex(i);
   if (!fMatrix) fMatrix = new TGeoHMatrix();
   *fMatrix = *iter.GetCurrentMatrix();
   fTopName = fTop->GetName();
   return *this;   
}   

//_____________________________________________________________________________
TGeoNode *TGeoIterator::Next()
{
// Returns next node.
   if (fMustStop) return 0;
   TGeoNode *mother = 0;
   TGeoNode *next = 0;
   Int_t i;
   Int_t nd = fTop->GetNdaughters();
   if (!nd) {
      fMustStop = kTRUE;
      return 0;
   }   
   if (!fLevel) {
      fArray[++fLevel] = 0;
      next = fTop->GetNode(0);
      return next;
   }   
   next = fTop->GetNode(fArray[1]);
   // Move to current node
   for (i=2; i<fLevel+1; i++) {
      mother = next;
      next = mother->GetDaughter(fArray[i]);
   }   
   if (fMustResume) {
      fMustResume = kFALSE;
      return next;
   }   
   
   switch (fType) {
      case 0:  // default next daughter behavior
         nd = next->GetNdaughters();
         if (nd) {
            // First daughter next
            fLevel++;
            if ((fLevel%30)==0) IncreaseArray();
            fArray[fLevel] = 0;
            return next->GetDaughter(0);
         }
         // cd up and pick next
         while (next) {
            next = GetNode(fLevel-1);
            if (!next) {
               nd = fTop->GetNdaughters();
               if (fArray[fLevel]<nd-1) return fTop->GetNode(++fArray[fLevel]);
               fMustStop = kTRUE;
               return 0;
            } else {
               nd = next->GetNdaughters();
               if (fArray[fLevel]<nd-1) return next->GetDaughter(++fArray[fLevel]);
            }   
            fLevel--;
         }   
         break;
      case 1:  // one level search
         if (mother) nd = mother->GetNdaughters();
         if (fArray[fLevel]<nd-1) {
            if (!mother) return fTop->GetNode(++fArray[fLevel]);
            else return mother->GetDaughter(++fArray[fLevel]);
         }
   }
   fMustStop = kTRUE;
   return 0;
}
   
//_____________________________________________________________________________
TGeoNode *TGeoIterator::operator()()
{
// Returns next node.
   return Next();
}   

//_____________________________________________________________________________
const TGeoMatrix *TGeoIterator::GetCurrentMatrix() const
{
// Returns global matrix for current node.
   fMatrix->Clear();
   if (!fLevel) return fMatrix;
   TGeoNode *node = fTop->GetNode(fArray[1]);
   fMatrix->Multiply(node->GetMatrix());
   for (Int_t i=2; i<fLevel+1; i++) {
      node = node->GetDaughter(fArray[i]);
      fMatrix->Multiply(node->GetMatrix());
   }
   return fMatrix;   
}   

//_____________________________________________________________________________
TGeoNode *TGeoIterator::GetNode(Int_t level) const
{
// Returns current node at a given level.
   if (!level || level>fLevel) return 0;
   TGeoNode *node = fTop->GetNode(fArray[1]);
   for (Int_t i=2; i<level+1; i++) node = node->GetDaughter(fArray[i]);
   return node;
}

//_____________________________________________________________________________
void TGeoIterator::GetPath(TString &path) const
{
// Returns the path for the current node.
   path = fTopName;
   if (!fLevel) return;
   TGeoNode *node = fTop->GetNode(fArray[1]);
   path += "/";
   path += node->GetName();
   for (Int_t i=2; i<fLevel+1; i++) {
      node = node->GetDaughter(fArray[i]);
      path += "/";
      path += node->GetName();
   }   
}      

//_____________________________________________________________________________
void TGeoIterator::IncreaseArray() 
{
// Increase by 30 the size of the array.
   Int_t *array = new Int_t[fLevel+30];
   memcpy(array, fArray, fLevel*sizeof(Int_t));
   delete [] fArray;
   fArray = array;
}   
 
//_____________________________________________________________________________
void TGeoIterator::Reset(TGeoVolume *top)
{
// Resets the iterator for volume TOP.
   if (top) fTop = top;
   fLevel = 0;
   fMustResume = kFALSE;
   fMustStop = kFALSE;
}      

//_____________________________________________________________________________
void TGeoIterator::SetTopName(const char *name)
{
// Set the top name for path
   fTopName = name;
}   

//_____________________________________________________________________________
void TGeoIterator::Skip()
{
// Stop iterating the current branch. The iteration of the next node will
// behave as if the branch starting from the current node (included) is not existing.
   fMustResume = kTRUE;
   TGeoNode *next = GetNode(fLevel);
   if (!next) return;
   Int_t nd;
   switch (fType) {
      case 0:  // default next daughter behavior
         // cd up and pick next
         while (next) {
            next = GetNode(fLevel-1);
            nd = (next==0)?fTop->GetNdaughters():next->GetNdaughters();
            if (fArray[fLevel]<nd-1) {
               ++fArray[fLevel];
               return;
            }
            fLevel--;
            if (!fLevel) {
               fMustStop = kTRUE;
               return;
            }   
         }     
         break;
      case 1:  // one level search
         next = GetNode(fLevel-1);
         nd = (next==0)?fTop->GetNdaughters():next->GetNdaughters();
         if (fArray[fLevel]<nd-1) {
            ++fArray[fLevel];
            return;
         }
         fMustStop = kTRUE;   
         break;
   }
}         
 TGeoNode.cxx:1
 TGeoNode.cxx:2
 TGeoNode.cxx:3
 TGeoNode.cxx:4
 TGeoNode.cxx:5
 TGeoNode.cxx:6
 TGeoNode.cxx:7
 TGeoNode.cxx:8
 TGeoNode.cxx:9
 TGeoNode.cxx:10
 TGeoNode.cxx:11
 TGeoNode.cxx:12
 TGeoNode.cxx:13
 TGeoNode.cxx:14
 TGeoNode.cxx:15
 TGeoNode.cxx:16
 TGeoNode.cxx:17
 TGeoNode.cxx:18
 TGeoNode.cxx:19
 TGeoNode.cxx:20
 TGeoNode.cxx:21
 TGeoNode.cxx:22
 TGeoNode.cxx:23
 TGeoNode.cxx:24
 TGeoNode.cxx:25
 TGeoNode.cxx:26
 TGeoNode.cxx:27
 TGeoNode.cxx:28
 TGeoNode.cxx:29
 TGeoNode.cxx:30
 TGeoNode.cxx:31
 TGeoNode.cxx:32
 TGeoNode.cxx:33
 TGeoNode.cxx:34
 TGeoNode.cxx:35
 TGeoNode.cxx:36
 TGeoNode.cxx:37
 TGeoNode.cxx:38
 TGeoNode.cxx:39
 TGeoNode.cxx:40
 TGeoNode.cxx:41
 TGeoNode.cxx:42
 TGeoNode.cxx:43
 TGeoNode.cxx:44
 TGeoNode.cxx:45
 TGeoNode.cxx:46
 TGeoNode.cxx:47
 TGeoNode.cxx:48
 TGeoNode.cxx:49
 TGeoNode.cxx:50
 TGeoNode.cxx:51
 TGeoNode.cxx:52
 TGeoNode.cxx:53
 TGeoNode.cxx:54
 TGeoNode.cxx:55
 TGeoNode.cxx:56
 TGeoNode.cxx:57
 TGeoNode.cxx:58
 TGeoNode.cxx:59
 TGeoNode.cxx:60
 TGeoNode.cxx:61
 TGeoNode.cxx:62
 TGeoNode.cxx:63
 TGeoNode.cxx:64
 TGeoNode.cxx:65
 TGeoNode.cxx:66
 TGeoNode.cxx:67
 TGeoNode.cxx:68
 TGeoNode.cxx:69
 TGeoNode.cxx:70
 TGeoNode.cxx:71
 TGeoNode.cxx:72
 TGeoNode.cxx:73
 TGeoNode.cxx:74
 TGeoNode.cxx:75
 TGeoNode.cxx:76
 TGeoNode.cxx:77
 TGeoNode.cxx:78
 TGeoNode.cxx:79
 TGeoNode.cxx:80
 TGeoNode.cxx:81
 TGeoNode.cxx:82
 TGeoNode.cxx:83
 TGeoNode.cxx:84
 TGeoNode.cxx:85
 TGeoNode.cxx:86
 TGeoNode.cxx:87
 TGeoNode.cxx:88
 TGeoNode.cxx:89
 TGeoNode.cxx:90
 TGeoNode.cxx:91
 TGeoNode.cxx:92
 TGeoNode.cxx:93
 TGeoNode.cxx:94
 TGeoNode.cxx:95
 TGeoNode.cxx:96
 TGeoNode.cxx:97
 TGeoNode.cxx:98
 TGeoNode.cxx:99
 TGeoNode.cxx:100
 TGeoNode.cxx:101
 TGeoNode.cxx:102
 TGeoNode.cxx:103
 TGeoNode.cxx:104
 TGeoNode.cxx:105
 TGeoNode.cxx:106
 TGeoNode.cxx:107
 TGeoNode.cxx:108
 TGeoNode.cxx:109
 TGeoNode.cxx:110
 TGeoNode.cxx:111
 TGeoNode.cxx:112
 TGeoNode.cxx:113
 TGeoNode.cxx:114
 TGeoNode.cxx:115
 TGeoNode.cxx:116
 TGeoNode.cxx:117
 TGeoNode.cxx:118
 TGeoNode.cxx:119
 TGeoNode.cxx:120
 TGeoNode.cxx:121
 TGeoNode.cxx:122
 TGeoNode.cxx:123
 TGeoNode.cxx:124
 TGeoNode.cxx:125
 TGeoNode.cxx:126
 TGeoNode.cxx:127
 TGeoNode.cxx:128
 TGeoNode.cxx:129
 TGeoNode.cxx:130
 TGeoNode.cxx:131
 TGeoNode.cxx:132
 TGeoNode.cxx:133
 TGeoNode.cxx:134
 TGeoNode.cxx:135
 TGeoNode.cxx:136
 TGeoNode.cxx:137
 TGeoNode.cxx:138
 TGeoNode.cxx:139
 TGeoNode.cxx:140
 TGeoNode.cxx:141
 TGeoNode.cxx:142
 TGeoNode.cxx:143
 TGeoNode.cxx:144
 TGeoNode.cxx:145
 TGeoNode.cxx:146
 TGeoNode.cxx:147
 TGeoNode.cxx:148
 TGeoNode.cxx:149
 TGeoNode.cxx:150
 TGeoNode.cxx:151
 TGeoNode.cxx:152
 TGeoNode.cxx:153
 TGeoNode.cxx:154
 TGeoNode.cxx:155
 TGeoNode.cxx:156
 TGeoNode.cxx:157
 TGeoNode.cxx:158
 TGeoNode.cxx:159
 TGeoNode.cxx:160
 TGeoNode.cxx:161
 TGeoNode.cxx:162
 TGeoNode.cxx:163
 TGeoNode.cxx:164
 TGeoNode.cxx:165
 TGeoNode.cxx:166
 TGeoNode.cxx:167
 TGeoNode.cxx:168
 TGeoNode.cxx:169
 TGeoNode.cxx:170
 TGeoNode.cxx:171
 TGeoNode.cxx:172
 TGeoNode.cxx:173
 TGeoNode.cxx:174
 TGeoNode.cxx:175
 TGeoNode.cxx:176
 TGeoNode.cxx:177
 TGeoNode.cxx:178
 TGeoNode.cxx:179
 TGeoNode.cxx:180
 TGeoNode.cxx:181
 TGeoNode.cxx:182
 TGeoNode.cxx:183
 TGeoNode.cxx:184
 TGeoNode.cxx:185
 TGeoNode.cxx:186
 TGeoNode.cxx:187
 TGeoNode.cxx:188
 TGeoNode.cxx:189
 TGeoNode.cxx:190
 TGeoNode.cxx:191
 TGeoNode.cxx:192
 TGeoNode.cxx:193
 TGeoNode.cxx:194
 TGeoNode.cxx:195
 TGeoNode.cxx:196
 TGeoNode.cxx:197
 TGeoNode.cxx:198
 TGeoNode.cxx:199
 TGeoNode.cxx:200
 TGeoNode.cxx:201
 TGeoNode.cxx:202
 TGeoNode.cxx:203
 TGeoNode.cxx:204
 TGeoNode.cxx:205
 TGeoNode.cxx:206
 TGeoNode.cxx:207
 TGeoNode.cxx:208
 TGeoNode.cxx:209
 TGeoNode.cxx:210
 TGeoNode.cxx:211
 TGeoNode.cxx:212
 TGeoNode.cxx:213
 TGeoNode.cxx:214
 TGeoNode.cxx:215
 TGeoNode.cxx:216
 TGeoNode.cxx:217
 TGeoNode.cxx:218
 TGeoNode.cxx:219
 TGeoNode.cxx:220
 TGeoNode.cxx:221
 TGeoNode.cxx:222
 TGeoNode.cxx:223
 TGeoNode.cxx:224
 TGeoNode.cxx:225
 TGeoNode.cxx:226
 TGeoNode.cxx:227
 TGeoNode.cxx:228
 TGeoNode.cxx:229
 TGeoNode.cxx:230
 TGeoNode.cxx:231
 TGeoNode.cxx:232
 TGeoNode.cxx:233
 TGeoNode.cxx:234
 TGeoNode.cxx:235
 TGeoNode.cxx:236
 TGeoNode.cxx:237
 TGeoNode.cxx:238
 TGeoNode.cxx:239
 TGeoNode.cxx:240
 TGeoNode.cxx:241
 TGeoNode.cxx:242
 TGeoNode.cxx:243
 TGeoNode.cxx:244
 TGeoNode.cxx:245
 TGeoNode.cxx:246
 TGeoNode.cxx:247
 TGeoNode.cxx:248
 TGeoNode.cxx:249
 TGeoNode.cxx:250
 TGeoNode.cxx:251
 TGeoNode.cxx:252
 TGeoNode.cxx:253
 TGeoNode.cxx:254
 TGeoNode.cxx:255
 TGeoNode.cxx:256
 TGeoNode.cxx:257
 TGeoNode.cxx:258
 TGeoNode.cxx:259
 TGeoNode.cxx:260
 TGeoNode.cxx:261
 TGeoNode.cxx:262
 TGeoNode.cxx:263
 TGeoNode.cxx:264
 TGeoNode.cxx:265
 TGeoNode.cxx:266
 TGeoNode.cxx:267
 TGeoNode.cxx:268
 TGeoNode.cxx:269
 TGeoNode.cxx:270
 TGeoNode.cxx:271
 TGeoNode.cxx:272
 TGeoNode.cxx:273
 TGeoNode.cxx:274
 TGeoNode.cxx:275
 TGeoNode.cxx:276
 TGeoNode.cxx:277
 TGeoNode.cxx:278
 TGeoNode.cxx:279
 TGeoNode.cxx:280
 TGeoNode.cxx:281
 TGeoNode.cxx:282
 TGeoNode.cxx:283
 TGeoNode.cxx:284
 TGeoNode.cxx:285
 TGeoNode.cxx:286
 TGeoNode.cxx:287
 TGeoNode.cxx:288
 TGeoNode.cxx:289
 TGeoNode.cxx:290
 TGeoNode.cxx:291
 TGeoNode.cxx:292
 TGeoNode.cxx:293
 TGeoNode.cxx:294
 TGeoNode.cxx:295
 TGeoNode.cxx:296
 TGeoNode.cxx:297
 TGeoNode.cxx:298
 TGeoNode.cxx:299
 TGeoNode.cxx:300
 TGeoNode.cxx:301
 TGeoNode.cxx:302
 TGeoNode.cxx:303
 TGeoNode.cxx:304
 TGeoNode.cxx:305
 TGeoNode.cxx:306
 TGeoNode.cxx:307
 TGeoNode.cxx:308
 TGeoNode.cxx:309
 TGeoNode.cxx:310
 TGeoNode.cxx:311
 TGeoNode.cxx:312
 TGeoNode.cxx:313
 TGeoNode.cxx:314
 TGeoNode.cxx:315
 TGeoNode.cxx:316
 TGeoNode.cxx:317
 TGeoNode.cxx:318
 TGeoNode.cxx:319
 TGeoNode.cxx:320
 TGeoNode.cxx:321
 TGeoNode.cxx:322
 TGeoNode.cxx:323
 TGeoNode.cxx:324
 TGeoNode.cxx:325
 TGeoNode.cxx:326
 TGeoNode.cxx:327
 TGeoNode.cxx:328
 TGeoNode.cxx:329
 TGeoNode.cxx:330
 TGeoNode.cxx:331
 TGeoNode.cxx:332
 TGeoNode.cxx:333
 TGeoNode.cxx:334
 TGeoNode.cxx:335
 TGeoNode.cxx:336
 TGeoNode.cxx:337
 TGeoNode.cxx:338
 TGeoNode.cxx:339
 TGeoNode.cxx:340
 TGeoNode.cxx:341
 TGeoNode.cxx:342
 TGeoNode.cxx:343
 TGeoNode.cxx:344
 TGeoNode.cxx:345
 TGeoNode.cxx:346
 TGeoNode.cxx:347
 TGeoNode.cxx:348
 TGeoNode.cxx:349
 TGeoNode.cxx:350
 TGeoNode.cxx:351
 TGeoNode.cxx:352
 TGeoNode.cxx:353
 TGeoNode.cxx:354
 TGeoNode.cxx:355
 TGeoNode.cxx:356
 TGeoNode.cxx:357
 TGeoNode.cxx:358
 TGeoNode.cxx:359
 TGeoNode.cxx:360
 TGeoNode.cxx:361
 TGeoNode.cxx:362
 TGeoNode.cxx:363
 TGeoNode.cxx:364
 TGeoNode.cxx:365
 TGeoNode.cxx:366
 TGeoNode.cxx:367
 TGeoNode.cxx:368
 TGeoNode.cxx:369
 TGeoNode.cxx:370
 TGeoNode.cxx:371
 TGeoNode.cxx:372
 TGeoNode.cxx:373
 TGeoNode.cxx:374
 TGeoNode.cxx:375
 TGeoNode.cxx:376
 TGeoNode.cxx:377
 TGeoNode.cxx:378
 TGeoNode.cxx:379
 TGeoNode.cxx:380
 TGeoNode.cxx:381
 TGeoNode.cxx:382
 TGeoNode.cxx:383
 TGeoNode.cxx:384
 TGeoNode.cxx:385
 TGeoNode.cxx:386
 TGeoNode.cxx:387
 TGeoNode.cxx:388
 TGeoNode.cxx:389
 TGeoNode.cxx:390
 TGeoNode.cxx:391
 TGeoNode.cxx:392
 TGeoNode.cxx:393
 TGeoNode.cxx:394
 TGeoNode.cxx:395
 TGeoNode.cxx:396
 TGeoNode.cxx:397
 TGeoNode.cxx:398
 TGeoNode.cxx:399
 TGeoNode.cxx:400
 TGeoNode.cxx:401
 TGeoNode.cxx:402
 TGeoNode.cxx:403
 TGeoNode.cxx:404
 TGeoNode.cxx:405
 TGeoNode.cxx:406
 TGeoNode.cxx:407
 TGeoNode.cxx:408
 TGeoNode.cxx:409
 TGeoNode.cxx:410
 TGeoNode.cxx:411
 TGeoNode.cxx:412
 TGeoNode.cxx:413
 TGeoNode.cxx:414
 TGeoNode.cxx:415
 TGeoNode.cxx:416
 TGeoNode.cxx:417
 TGeoNode.cxx:418
 TGeoNode.cxx:419
 TGeoNode.cxx:420
 TGeoNode.cxx:421
 TGeoNode.cxx:422
 TGeoNode.cxx:423
 TGeoNode.cxx:424
 TGeoNode.cxx:425
 TGeoNode.cxx:426
 TGeoNode.cxx:427
 TGeoNode.cxx:428
 TGeoNode.cxx:429
 TGeoNode.cxx:430
 TGeoNode.cxx:431
 TGeoNode.cxx:432
 TGeoNode.cxx:433
 TGeoNode.cxx:434
 TGeoNode.cxx:435
 TGeoNode.cxx:436
 TGeoNode.cxx:437
 TGeoNode.cxx:438
 TGeoNode.cxx:439
 TGeoNode.cxx:440
 TGeoNode.cxx:441
 TGeoNode.cxx:442
 TGeoNode.cxx:443
 TGeoNode.cxx:444
 TGeoNode.cxx:445
 TGeoNode.cxx:446
 TGeoNode.cxx:447
 TGeoNode.cxx:448
 TGeoNode.cxx:449
 TGeoNode.cxx:450
 TGeoNode.cxx:451
 TGeoNode.cxx:452
 TGeoNode.cxx:453
 TGeoNode.cxx:454
 TGeoNode.cxx:455
 TGeoNode.cxx:456
 TGeoNode.cxx:457
 TGeoNode.cxx:458
 TGeoNode.cxx:459
 TGeoNode.cxx:460
 TGeoNode.cxx:461
 TGeoNode.cxx:462
 TGeoNode.cxx:463
 TGeoNode.cxx:464
 TGeoNode.cxx:465
 TGeoNode.cxx:466
 TGeoNode.cxx:467
 TGeoNode.cxx:468
 TGeoNode.cxx:469
 TGeoNode.cxx:470
 TGeoNode.cxx:471
 TGeoNode.cxx:472
 TGeoNode.cxx:473
 TGeoNode.cxx:474
 TGeoNode.cxx:475
 TGeoNode.cxx:476
 TGeoNode.cxx:477
 TGeoNode.cxx:478
 TGeoNode.cxx:479
 TGeoNode.cxx:480
 TGeoNode.cxx:481
 TGeoNode.cxx:482
 TGeoNode.cxx:483
 TGeoNode.cxx:484
 TGeoNode.cxx:485
 TGeoNode.cxx:486
 TGeoNode.cxx:487
 TGeoNode.cxx:488
 TGeoNode.cxx:489
 TGeoNode.cxx:490
 TGeoNode.cxx:491
 TGeoNode.cxx:492
 TGeoNode.cxx:493
 TGeoNode.cxx:494
 TGeoNode.cxx:495
 TGeoNode.cxx:496
 TGeoNode.cxx:497
 TGeoNode.cxx:498
 TGeoNode.cxx:499
 TGeoNode.cxx:500
 TGeoNode.cxx:501
 TGeoNode.cxx:502
 TGeoNode.cxx:503
 TGeoNode.cxx:504
 TGeoNode.cxx:505
 TGeoNode.cxx:506
 TGeoNode.cxx:507
 TGeoNode.cxx:508
 TGeoNode.cxx:509
 TGeoNode.cxx:510
 TGeoNode.cxx:511
 TGeoNode.cxx:512
 TGeoNode.cxx:513
 TGeoNode.cxx:514
 TGeoNode.cxx:515
 TGeoNode.cxx:516
 TGeoNode.cxx:517
 TGeoNode.cxx:518
 TGeoNode.cxx:519
 TGeoNode.cxx:520
 TGeoNode.cxx:521
 TGeoNode.cxx:522
 TGeoNode.cxx:523
 TGeoNode.cxx:524
 TGeoNode.cxx:525
 TGeoNode.cxx:526
 TGeoNode.cxx:527
 TGeoNode.cxx:528
 TGeoNode.cxx:529
 TGeoNode.cxx:530
 TGeoNode.cxx:531
 TGeoNode.cxx:532
 TGeoNode.cxx:533
 TGeoNode.cxx:534
 TGeoNode.cxx:535
 TGeoNode.cxx:536
 TGeoNode.cxx:537
 TGeoNode.cxx:538
 TGeoNode.cxx:539
 TGeoNode.cxx:540
 TGeoNode.cxx:541
 TGeoNode.cxx:542
 TGeoNode.cxx:543
 TGeoNode.cxx:544
 TGeoNode.cxx:545
 TGeoNode.cxx:546
 TGeoNode.cxx:547
 TGeoNode.cxx:548
 TGeoNode.cxx:549
 TGeoNode.cxx:550
 TGeoNode.cxx:551
 TGeoNode.cxx:552
 TGeoNode.cxx:553
 TGeoNode.cxx:554
 TGeoNode.cxx:555
 TGeoNode.cxx:556
 TGeoNode.cxx:557
 TGeoNode.cxx:558
 TGeoNode.cxx:559
 TGeoNode.cxx:560
 TGeoNode.cxx:561
 TGeoNode.cxx:562
 TGeoNode.cxx:563
 TGeoNode.cxx:564
 TGeoNode.cxx:565
 TGeoNode.cxx:566
 TGeoNode.cxx:567
 TGeoNode.cxx:568
 TGeoNode.cxx:569
 TGeoNode.cxx:570
 TGeoNode.cxx:571
 TGeoNode.cxx:572
 TGeoNode.cxx:573
 TGeoNode.cxx:574
 TGeoNode.cxx:575
 TGeoNode.cxx:576
 TGeoNode.cxx:577
 TGeoNode.cxx:578
 TGeoNode.cxx:579
 TGeoNode.cxx:580
 TGeoNode.cxx:581
 TGeoNode.cxx:582
 TGeoNode.cxx:583
 TGeoNode.cxx:584
 TGeoNode.cxx:585
 TGeoNode.cxx:586
 TGeoNode.cxx:587
 TGeoNode.cxx:588
 TGeoNode.cxx:589
 TGeoNode.cxx:590
 TGeoNode.cxx:591
 TGeoNode.cxx:592
 TGeoNode.cxx:593
 TGeoNode.cxx:594
 TGeoNode.cxx:595
 TGeoNode.cxx:596
 TGeoNode.cxx:597
 TGeoNode.cxx:598
 TGeoNode.cxx:599
 TGeoNode.cxx:600
 TGeoNode.cxx:601
 TGeoNode.cxx:602
 TGeoNode.cxx:603
 TGeoNode.cxx:604
 TGeoNode.cxx:605
 TGeoNode.cxx:606
 TGeoNode.cxx:607
 TGeoNode.cxx:608
 TGeoNode.cxx:609
 TGeoNode.cxx:610
 TGeoNode.cxx:611
 TGeoNode.cxx:612
 TGeoNode.cxx:613
 TGeoNode.cxx:614
 TGeoNode.cxx:615
 TGeoNode.cxx:616
 TGeoNode.cxx:617
 TGeoNode.cxx:618
 TGeoNode.cxx:619
 TGeoNode.cxx:620
 TGeoNode.cxx:621
 TGeoNode.cxx:622
 TGeoNode.cxx:623
 TGeoNode.cxx:624
 TGeoNode.cxx:625
 TGeoNode.cxx:626
 TGeoNode.cxx:627
 TGeoNode.cxx:628
 TGeoNode.cxx:629
 TGeoNode.cxx:630
 TGeoNode.cxx:631
 TGeoNode.cxx:632
 TGeoNode.cxx:633
 TGeoNode.cxx:634
 TGeoNode.cxx:635
 TGeoNode.cxx:636
 TGeoNode.cxx:637
 TGeoNode.cxx:638
 TGeoNode.cxx:639
 TGeoNode.cxx:640
 TGeoNode.cxx:641
 TGeoNode.cxx:642
 TGeoNode.cxx:643
 TGeoNode.cxx:644
 TGeoNode.cxx:645
 TGeoNode.cxx:646
 TGeoNode.cxx:647
 TGeoNode.cxx:648
 TGeoNode.cxx:649
 TGeoNode.cxx:650
 TGeoNode.cxx:651
 TGeoNode.cxx:652
 TGeoNode.cxx:653
 TGeoNode.cxx:654
 TGeoNode.cxx:655
 TGeoNode.cxx:656
 TGeoNode.cxx:657
 TGeoNode.cxx:658
 TGeoNode.cxx:659
 TGeoNode.cxx:660
 TGeoNode.cxx:661
 TGeoNode.cxx:662
 TGeoNode.cxx:663
 TGeoNode.cxx:664
 TGeoNode.cxx:665
 TGeoNode.cxx:666
 TGeoNode.cxx:667
 TGeoNode.cxx:668
 TGeoNode.cxx:669
 TGeoNode.cxx:670
 TGeoNode.cxx:671
 TGeoNode.cxx:672
 TGeoNode.cxx:673
 TGeoNode.cxx:674
 TGeoNode.cxx:675
 TGeoNode.cxx:676
 TGeoNode.cxx:677
 TGeoNode.cxx:678
 TGeoNode.cxx:679
 TGeoNode.cxx:680
 TGeoNode.cxx:681
 TGeoNode.cxx:682
 TGeoNode.cxx:683
 TGeoNode.cxx:684
 TGeoNode.cxx:685
 TGeoNode.cxx:686
 TGeoNode.cxx:687
 TGeoNode.cxx:688
 TGeoNode.cxx:689
 TGeoNode.cxx:690
 TGeoNode.cxx:691
 TGeoNode.cxx:692
 TGeoNode.cxx:693
 TGeoNode.cxx:694
 TGeoNode.cxx:695
 TGeoNode.cxx:696
 TGeoNode.cxx:697
 TGeoNode.cxx:698
 TGeoNode.cxx:699
 TGeoNode.cxx:700
 TGeoNode.cxx:701
 TGeoNode.cxx:702
 TGeoNode.cxx:703
 TGeoNode.cxx:704
 TGeoNode.cxx:705
 TGeoNode.cxx:706
 TGeoNode.cxx:707
 TGeoNode.cxx:708
 TGeoNode.cxx:709
 TGeoNode.cxx:710
 TGeoNode.cxx:711
 TGeoNode.cxx:712
 TGeoNode.cxx:713
 TGeoNode.cxx:714
 TGeoNode.cxx:715
 TGeoNode.cxx:716
 TGeoNode.cxx:717
 TGeoNode.cxx:718
 TGeoNode.cxx:719
 TGeoNode.cxx:720
 TGeoNode.cxx:721
 TGeoNode.cxx:722
 TGeoNode.cxx:723
 TGeoNode.cxx:724
 TGeoNode.cxx:725
 TGeoNode.cxx:726
 TGeoNode.cxx:727
 TGeoNode.cxx:728
 TGeoNode.cxx:729
 TGeoNode.cxx:730
 TGeoNode.cxx:731
 TGeoNode.cxx:732
 TGeoNode.cxx:733
 TGeoNode.cxx:734
 TGeoNode.cxx:735
 TGeoNode.cxx:736
 TGeoNode.cxx:737
 TGeoNode.cxx:738
 TGeoNode.cxx:739
 TGeoNode.cxx:740
 TGeoNode.cxx:741
 TGeoNode.cxx:742
 TGeoNode.cxx:743
 TGeoNode.cxx:744
 TGeoNode.cxx:745
 TGeoNode.cxx:746
 TGeoNode.cxx:747
 TGeoNode.cxx:748
 TGeoNode.cxx:749
 TGeoNode.cxx:750
 TGeoNode.cxx:751
 TGeoNode.cxx:752
 TGeoNode.cxx:753
 TGeoNode.cxx:754
 TGeoNode.cxx:755
 TGeoNode.cxx:756
 TGeoNode.cxx:757
 TGeoNode.cxx:758
 TGeoNode.cxx:759
 TGeoNode.cxx:760
 TGeoNode.cxx:761
 TGeoNode.cxx:762
 TGeoNode.cxx:763
 TGeoNode.cxx:764
 TGeoNode.cxx:765
 TGeoNode.cxx:766
 TGeoNode.cxx:767
 TGeoNode.cxx:768
 TGeoNode.cxx:769
 TGeoNode.cxx:770
 TGeoNode.cxx:771
 TGeoNode.cxx:772
 TGeoNode.cxx:773
 TGeoNode.cxx:774
 TGeoNode.cxx:775
 TGeoNode.cxx:776
 TGeoNode.cxx:777
 TGeoNode.cxx:778
 TGeoNode.cxx:779
 TGeoNode.cxx:780
 TGeoNode.cxx:781
 TGeoNode.cxx:782
 TGeoNode.cxx:783
 TGeoNode.cxx:784
 TGeoNode.cxx:785
 TGeoNode.cxx:786
 TGeoNode.cxx:787
 TGeoNode.cxx:788
 TGeoNode.cxx:789
 TGeoNode.cxx:790
 TGeoNode.cxx:791
 TGeoNode.cxx:792
 TGeoNode.cxx:793
 TGeoNode.cxx:794
 TGeoNode.cxx:795
 TGeoNode.cxx:796
 TGeoNode.cxx:797
 TGeoNode.cxx:798
 TGeoNode.cxx:799
 TGeoNode.cxx:800
 TGeoNode.cxx:801
 TGeoNode.cxx:802
 TGeoNode.cxx:803
 TGeoNode.cxx:804
 TGeoNode.cxx:805
 TGeoNode.cxx:806
 TGeoNode.cxx:807
 TGeoNode.cxx:808
 TGeoNode.cxx:809
 TGeoNode.cxx:810
 TGeoNode.cxx:811
 TGeoNode.cxx:812
 TGeoNode.cxx:813
 TGeoNode.cxx:814
 TGeoNode.cxx:815
 TGeoNode.cxx:816
 TGeoNode.cxx:817
 TGeoNode.cxx:818
 TGeoNode.cxx:819
 TGeoNode.cxx:820
 TGeoNode.cxx:821
 TGeoNode.cxx:822
 TGeoNode.cxx:823
 TGeoNode.cxx:824
 TGeoNode.cxx:825
 TGeoNode.cxx:826
 TGeoNode.cxx:827
 TGeoNode.cxx:828
 TGeoNode.cxx:829
 TGeoNode.cxx:830
 TGeoNode.cxx:831
 TGeoNode.cxx:832
 TGeoNode.cxx:833
 TGeoNode.cxx:834
 TGeoNode.cxx:835
 TGeoNode.cxx:836
 TGeoNode.cxx:837
 TGeoNode.cxx:838
 TGeoNode.cxx:839
 TGeoNode.cxx:840
 TGeoNode.cxx:841
 TGeoNode.cxx:842
 TGeoNode.cxx:843
 TGeoNode.cxx:844
 TGeoNode.cxx:845
 TGeoNode.cxx:846
 TGeoNode.cxx:847
 TGeoNode.cxx:848
 TGeoNode.cxx:849
 TGeoNode.cxx:850
 TGeoNode.cxx:851
 TGeoNode.cxx:852
 TGeoNode.cxx:853
 TGeoNode.cxx:854
 TGeoNode.cxx:855
 TGeoNode.cxx:856
 TGeoNode.cxx:857
 TGeoNode.cxx:858
 TGeoNode.cxx:859
 TGeoNode.cxx:860
 TGeoNode.cxx:861
 TGeoNode.cxx:862
 TGeoNode.cxx:863
 TGeoNode.cxx:864
 TGeoNode.cxx:865
 TGeoNode.cxx:866
 TGeoNode.cxx:867
 TGeoNode.cxx:868
 TGeoNode.cxx:869
 TGeoNode.cxx:870
 TGeoNode.cxx:871
 TGeoNode.cxx:872
 TGeoNode.cxx:873
 TGeoNode.cxx:874
 TGeoNode.cxx:875
 TGeoNode.cxx:876
 TGeoNode.cxx:877
 TGeoNode.cxx:878
 TGeoNode.cxx:879
 TGeoNode.cxx:880
 TGeoNode.cxx:881
 TGeoNode.cxx:882
 TGeoNode.cxx:883
 TGeoNode.cxx:884
 TGeoNode.cxx:885
 TGeoNode.cxx:886
 TGeoNode.cxx:887
 TGeoNode.cxx:888
 TGeoNode.cxx:889
 TGeoNode.cxx:890
 TGeoNode.cxx:891
 TGeoNode.cxx:892
 TGeoNode.cxx:893
 TGeoNode.cxx:894
 TGeoNode.cxx:895
 TGeoNode.cxx:896
 TGeoNode.cxx:897
 TGeoNode.cxx:898
 TGeoNode.cxx:899
 TGeoNode.cxx:900
 TGeoNode.cxx:901
 TGeoNode.cxx:902
 TGeoNode.cxx:903
 TGeoNode.cxx:904
 TGeoNode.cxx:905
 TGeoNode.cxx:906
 TGeoNode.cxx:907
 TGeoNode.cxx:908
 TGeoNode.cxx:909
 TGeoNode.cxx:910
 TGeoNode.cxx:911
 TGeoNode.cxx:912
 TGeoNode.cxx:913
 TGeoNode.cxx:914
 TGeoNode.cxx:915
 TGeoNode.cxx:916
 TGeoNode.cxx:917
 TGeoNode.cxx:918
 TGeoNode.cxx:919
 TGeoNode.cxx:920
 TGeoNode.cxx:921
 TGeoNode.cxx:922
 TGeoNode.cxx:923
 TGeoNode.cxx:924
 TGeoNode.cxx:925
 TGeoNode.cxx:926
 TGeoNode.cxx:927
 TGeoNode.cxx:928
 TGeoNode.cxx:929
 TGeoNode.cxx:930
 TGeoNode.cxx:931
 TGeoNode.cxx:932
 TGeoNode.cxx:933
 TGeoNode.cxx:934
 TGeoNode.cxx:935
 TGeoNode.cxx:936
 TGeoNode.cxx:937
 TGeoNode.cxx:938
 TGeoNode.cxx:939
 TGeoNode.cxx:940
 TGeoNode.cxx:941
 TGeoNode.cxx:942
 TGeoNode.cxx:943
 TGeoNode.cxx:944
 TGeoNode.cxx:945
 TGeoNode.cxx:946
 TGeoNode.cxx:947
 TGeoNode.cxx:948
 TGeoNode.cxx:949
 TGeoNode.cxx:950
 TGeoNode.cxx:951
 TGeoNode.cxx:952
 TGeoNode.cxx:953
 TGeoNode.cxx:954
 TGeoNode.cxx:955
 TGeoNode.cxx:956
 TGeoNode.cxx:957
 TGeoNode.cxx:958
 TGeoNode.cxx:959
 TGeoNode.cxx:960
 TGeoNode.cxx:961
 TGeoNode.cxx:962
 TGeoNode.cxx:963
 TGeoNode.cxx:964
 TGeoNode.cxx:965
 TGeoNode.cxx:966
 TGeoNode.cxx:967
 TGeoNode.cxx:968
 TGeoNode.cxx:969
 TGeoNode.cxx:970
 TGeoNode.cxx:971
 TGeoNode.cxx:972
 TGeoNode.cxx:973
 TGeoNode.cxx:974
 TGeoNode.cxx:975
 TGeoNode.cxx:976
 TGeoNode.cxx:977
 TGeoNode.cxx:978
 TGeoNode.cxx:979
 TGeoNode.cxx:980
 TGeoNode.cxx:981
 TGeoNode.cxx:982
 TGeoNode.cxx:983
 TGeoNode.cxx:984
 TGeoNode.cxx:985
 TGeoNode.cxx:986
 TGeoNode.cxx:987
 TGeoNode.cxx:988
 TGeoNode.cxx:989
 TGeoNode.cxx:990
 TGeoNode.cxx:991
 TGeoNode.cxx:992
 TGeoNode.cxx:993
 TGeoNode.cxx:994
 TGeoNode.cxx:995
 TGeoNode.cxx:996
 TGeoNode.cxx:997
 TGeoNode.cxx:998
 TGeoNode.cxx:999
 TGeoNode.cxx:1000
 TGeoNode.cxx:1001
 TGeoNode.cxx:1002
 TGeoNode.cxx:1003
 TGeoNode.cxx:1004
 TGeoNode.cxx:1005
 TGeoNode.cxx:1006
 TGeoNode.cxx:1007
 TGeoNode.cxx:1008
 TGeoNode.cxx:1009
 TGeoNode.cxx:1010
 TGeoNode.cxx:1011
 TGeoNode.cxx:1012
 TGeoNode.cxx:1013
 TGeoNode.cxx:1014
 TGeoNode.cxx:1015
 TGeoNode.cxx:1016
 TGeoNode.cxx:1017
 TGeoNode.cxx:1018
 TGeoNode.cxx:1019
 TGeoNode.cxx:1020
 TGeoNode.cxx:1021
 TGeoNode.cxx:1022
 TGeoNode.cxx:1023
 TGeoNode.cxx:1024
 TGeoNode.cxx:1025
 TGeoNode.cxx:1026
 TGeoNode.cxx:1027
 TGeoNode.cxx:1028
 TGeoNode.cxx:1029
 TGeoNode.cxx:1030
 TGeoNode.cxx:1031
 TGeoNode.cxx:1032
 TGeoNode.cxx:1033
 TGeoNode.cxx:1034
 TGeoNode.cxx:1035
 TGeoNode.cxx:1036
 TGeoNode.cxx:1037
 TGeoNode.cxx:1038
 TGeoNode.cxx:1039
 TGeoNode.cxx:1040
 TGeoNode.cxx:1041
 TGeoNode.cxx:1042
 TGeoNode.cxx:1043
 TGeoNode.cxx:1044
 TGeoNode.cxx:1045
 TGeoNode.cxx:1046
 TGeoNode.cxx:1047
 TGeoNode.cxx:1048
 TGeoNode.cxx:1049
 TGeoNode.cxx:1050
 TGeoNode.cxx:1051
 TGeoNode.cxx:1052
 TGeoNode.cxx:1053
 TGeoNode.cxx:1054
 TGeoNode.cxx:1055
 TGeoNode.cxx:1056
 TGeoNode.cxx:1057
 TGeoNode.cxx:1058
 TGeoNode.cxx:1059
 TGeoNode.cxx:1060
 TGeoNode.cxx:1061
 TGeoNode.cxx:1062
 TGeoNode.cxx:1063
 TGeoNode.cxx:1064
 TGeoNode.cxx:1065
 TGeoNode.cxx:1066
 TGeoNode.cxx:1067
 TGeoNode.cxx:1068
 TGeoNode.cxx:1069
 TGeoNode.cxx:1070
 TGeoNode.cxx:1071
 TGeoNode.cxx:1072
 TGeoNode.cxx:1073
 TGeoNode.cxx:1074
 TGeoNode.cxx:1075
 TGeoNode.cxx:1076
 TGeoNode.cxx:1077
 TGeoNode.cxx:1078
 TGeoNode.cxx:1079
 TGeoNode.cxx:1080
 TGeoNode.cxx:1081
 TGeoNode.cxx:1082
 TGeoNode.cxx:1083
 TGeoNode.cxx:1084
 TGeoNode.cxx:1085
 TGeoNode.cxx:1086
 TGeoNode.cxx:1087
 TGeoNode.cxx:1088
 TGeoNode.cxx:1089
 TGeoNode.cxx:1090
 TGeoNode.cxx:1091
 TGeoNode.cxx:1092
 TGeoNode.cxx:1093
 TGeoNode.cxx:1094
 TGeoNode.cxx:1095
 TGeoNode.cxx:1096
 TGeoNode.cxx:1097
 TGeoNode.cxx:1098