TGeoCache.cxx

Go to the documentation of this file.
00001 // @(#)root/geom:$Id: TGeoCache.cxx 36535 2010-11-08 14:41:54Z agheata $
00002 // Author: Andrei Gheata   18/03/02
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 ////////////////////////////////////////////////////////////////////////////////
00013 // Physical tree description.
00014 //
00015 //
00016 //
00017 //
00018 //Begin_Html
00019 /*
00020 <img src=".gif">
00021 */
00022 //End_Html
00023 
00024 #include "TGeoManager.h"
00025 #include "TGeoMatrix.h"
00026 #include "TGeoVolume.h"
00027 #include "TGeoCache.h"
00028 
00029 const Int_t kN3 = 3*sizeof(Double_t);
00030 
00031 
00032 ClassImp(TGeoNodeCache)
00033 
00034 /*************************************************************************
00035  * TGeoNodeCache - special pool of reusable nodes
00036  *
00037  *
00038  *************************************************************************/
00039 
00040 //_____________________________________________________________________________
00041 TGeoNodeCache::TGeoNodeCache()
00042 {
00043 // Dummy constructor
00044    fGeoCacheMaxLevels    = 100;
00045    fGeoCacheStackSize    = 1000;
00046    fLevel       = 0;
00047    fStackLevel  = 0;
00048    fCurrentID   = 0;
00049    fIndex       = 0;
00050    fPath        = "";
00051    fTop         = 0;
00052    fNode        = 0;
00053    fMatrix      = 0;
00054    fStack       = 0;
00055    fMatrixBranch = 0;
00056    fMPB         = 0;
00057    fNodeBranch  = 0;
00058    fNodeIdArray = 0;
00059    for (Int_t i=0; i<100; i++) fIdBranch[i] = 0;
00060 }
00061 
00062 //_____________________________________________________________________________
00063 TGeoNodeCache::TGeoNodeCache(TGeoNode *top, Bool_t nodeid, Int_t capacity)
00064 {
00065 // Default constructor
00066    fGeoCacheMaxLevels    = capacity;
00067    fGeoCacheStackSize    = 1000;
00068    fLevel       = 0;
00069    fStackLevel  = 0;
00070    fCurrentID   = 0;
00071    fIndex       = 0;
00072    fPath        = "";
00073    fTop         = top;
00074    fNode        = top;
00075    fStack = new TObjArray(fGeoCacheStackSize);
00076    for (Int_t ist=0; ist<fGeoCacheStackSize; ist++)
00077       fStack->Add(new TGeoCacheState(fGeoCacheMaxLevels)); // !obsolete 100
00078    fMatrixBranch = new TGeoHMatrix *[fGeoCacheMaxLevels];
00079    fMPB = new TGeoHMatrix *[fGeoCacheMaxLevels];
00080    for (Int_t i=0; i<fGeoCacheMaxLevels; i++) {
00081       fMPB[i] = new TGeoHMatrix(TString::Format("global_%d",i));
00082       fMatrixBranch[i] = 0;
00083    }
00084    fMatrix = fMatrixBranch[0] = fMPB[0];
00085    fNodeBranch  = new TGeoNode *[fGeoCacheMaxLevels];
00086    fNodeBranch[0] = top;
00087    fNodeIdArray = 0;
00088    for (Int_t i=0; i<100; i++) fIdBranch[i] = 0;
00089    if (nodeid) BuildIdArray();
00090    CdTop();
00091 }
00092 
00093 //_____________________________________________________________________________
00094 TGeoNodeCache::TGeoNodeCache(const TGeoNodeCache& gnc)
00095               :TObject(gnc),
00096                fGeoCacheMaxLevels(gnc.fGeoCacheMaxLevels),
00097                fGeoCacheStackSize(gnc.fGeoCacheStackSize),
00098                fLevel(gnc.fLevel),
00099                fStackLevel(gnc.fStackLevel),
00100                fCurrentID(gnc.fCurrentID),
00101                fIndex(gnc.fIndex),
00102                fPath(gnc.fPath),
00103                fTop(gnc.fTop),
00104                fNode(gnc.fNode),
00105                fMatrix(gnc.fMatrix),
00106                fStack(gnc.fStack),
00107                fMatrixBranch(gnc.fMatrixBranch),
00108                fMPB(gnc.fMPB),
00109                fNodeBranch(gnc.fNodeBranch),
00110                fNodeIdArray(gnc.fNodeIdArray)
00111 {
00112    // Copy constructor
00113    Error("CC","Not implemented!");
00114 }
00115 
00116 //_____________________________________________________________________________
00117 TGeoNodeCache& TGeoNodeCache::operator=(const TGeoNodeCache&)
00118 {
00119    // Assignment operator
00120    Error("operator=","Assignment not allowed");
00121    return *this;
00122 }
00123 
00124 //_____________________________________________________________________________
00125 TGeoNodeCache::~TGeoNodeCache()
00126 {
00127 // Destructor
00128    if (fStack) {
00129       fStack->Delete();
00130       delete fStack;
00131    }
00132    if (fMatrixBranch) delete [] fMatrixBranch;
00133    if (fMPB) {
00134       for (Int_t i=0; i<fGeoCacheMaxLevels; i++) delete fMPB[i];
00135       delete [] fMPB;
00136    }
00137    if (fNodeBranch)   delete [] fNodeBranch;
00138    if (fNodeIdArray)  delete [] fNodeIdArray;
00139 }
00140 
00141 //_____________________________________________________________________________
00142 void TGeoNodeCache::BuildIdArray()
00143 {
00144 // Builds node id array.
00145    Int_t nnodes = gGeoManager->GetNNodes();
00146    //if (nnodes>3E7) return;
00147    if (fNodeIdArray) delete [] fNodeIdArray;
00148    Info("BuildIDArray","--- node ID tracking enabled, size=%lu Bytes\n", ULong_t((2*nnodes+1)*sizeof(Int_t)));
00149    fNodeIdArray = new Int_t[2*nnodes+1];
00150    fNodeIdArray[0] = 0;
00151    Int_t ifree  = 1;
00152    Int_t nodeid = 0;
00153    gGeoManager->GetTopNode()->FillIdArray(ifree, nodeid, fNodeIdArray);
00154    fIdBranch[0] = 0;
00155 }
00156 
00157 //_____________________________________________________________________________
00158 void TGeoNodeCache::CdNode(Int_t nodeid) {
00159 // Change current path to point to the node having this id.
00160 // Node id has to be in range : 0 to fNNodes-1 (no check for performance reasons)
00161    if (!fNodeIdArray) {
00162       printf("WARNING:CdNode() disabled - too many nodes\n");
00163       return;
00164    }
00165    Int_t *arr = fNodeIdArray;
00166    if (nodeid == arr[fIndex]) return;
00167    while (fLevel>0) {
00168       gGeoManager->CdUp();
00169       if (nodeid == arr[fIndex]) return;
00170    }
00171    gGeoManager->CdTop();
00172    Int_t currentID = 0;
00173    Int_t nd = GetNode()->GetNdaughters();
00174    Int_t nabove, nbelow, middle;
00175    while (nodeid!=currentID && nd) {
00176       nabove = nd+1;
00177       nbelow = 0;
00178       while (nabove-nbelow > 1) {
00179          middle = (nabove+nbelow)>>1;
00180          currentID = arr[arr[fIndex+middle]];
00181          if (nodeid == currentID) {
00182             gGeoManager->CdDown(middle-1);
00183             return;
00184          }
00185          if (nodeid < currentID) nabove = middle;
00186          else                    nbelow = middle;
00187       }
00188       gGeoManager->CdDown(nbelow-1);
00189       currentID = arr[fIndex];
00190       nd = GetNode()->GetNdaughters();
00191    }
00192 }
00193 
00194 //_____________________________________________________________________________
00195 Bool_t TGeoNodeCache::CdDown(Int_t index)
00196 {
00197 // Make daughter INDEX of current node the active state. Compute global matrix.
00198    TGeoNode *newnode = fNode->GetDaughter(index);
00199    if (!newnode) return kFALSE;
00200    fLevel++;
00201    if (fNodeIdArray) {
00202       fIndex = fNodeIdArray[fIndex+index+1];
00203       fIdBranch[fLevel] = fIndex;
00204    }
00205    fNode = newnode;
00206    fNodeBranch[fLevel] = fNode;
00207    TGeoMatrix  *local = newnode->GetMatrix();
00208    TGeoHMatrix *newmat = fMPB[fLevel];
00209    if (!local->IsIdentity()) {
00210       newmat->CopyFrom(fMatrix);
00211       newmat->Multiply(local);
00212       fMatrix = newmat;
00213    }
00214    fMatrixBranch[fLevel] = fMatrix;
00215    return kTRUE;
00216 }
00217 
00218 //_____________________________________________________________________________
00219 void TGeoNodeCache::CdUp()
00220 {
00221 // Make mother of current node the active state.
00222    if (!fLevel) return;
00223    fLevel--;
00224    if (fNodeIdArray) fIndex = fIdBranch[fLevel];
00225    fNode = fNodeBranch[fLevel];
00226    fMatrix = fMatrixBranch[fLevel];
00227 }
00228 
00229 //_____________________________________________________________________________
00230 Int_t TGeoNodeCache::GetCurrentNodeId() const
00231 {
00232 // Returns a fixed ID for current physical node
00233    if (fNodeIdArray) return fNodeIdArray[fIndex];
00234    return GetNodeId();
00235 }
00236 
00237 //_____________________________________________________________________________
00238 Int_t TGeoNodeCache::GetNodeId() const
00239 {
00240 // Get unique node id.
00241    Long_t id=0;
00242    for (Int_t level=0;level<fLevel+1; level++)
00243       id += (Long_t)fNodeBranch[level];
00244    return (Int_t)id;
00245 }
00246 
00247 //_____________________________________________________________________________
00248 void TGeoNodeCache::GetBranchNames(Int_t *names) const
00249 {
00250 // Fill names with current branch volume names (4 char - used by GEANT3 interface).
00251    const char *name;
00252    for (Int_t i=0; i<fLevel+1; i++) {
00253       name = fNodeBranch[i]->GetVolume()->GetName();
00254       memcpy(&names[i], name, sizeof(Int_t));
00255    }
00256 }
00257 
00258 //_____________________________________________________________________________
00259 void TGeoNodeCache::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
00260 {
00261 // Fill copy numbers of current branch nodes.
00262    for (Int_t i=0; i<fLevel+1; i++) {
00263       copyNumbers[i]   = fNodeBranch[i]->GetNumber();
00264       volumeNumbers[i] = fNodeBranch[i]->GetVolume()->GetNumber();
00265    }
00266 }
00267 
00268 //_____________________________________________________________________________
00269 void TGeoNodeCache::GetBranchOnlys(Int_t *isonly) const
00270 {
00271 // Fill copy numbers of current branch nodes.
00272    Bool_t ismany = kFALSE;
00273    for (Int_t i=0; i<fLevel+1; i++) {
00274       if (!fNodeBranch[i]->IsOffset()) ismany=fNodeBranch[i]->IsOverlapping();
00275       isonly[i] = (ismany)?0:1;
00276    }
00277 }
00278 
00279 //_____________________________________________________________________________
00280 const char *TGeoNodeCache::GetPath()
00281 {
00282 // Returns the current geometry path.
00283    fPath = "";
00284    for (Int_t level=0;level<fLevel+1; level++) {
00285       fPath += "/";
00286       fPath += fNodeBranch[level]->GetName();
00287    }
00288    return fPath.Data();
00289 }
00290 
00291 //_____________________________________________________________________________
00292 Int_t TGeoNodeCache::PushState(Bool_t ovlp, Int_t startlevel, Int_t nmany, Double_t *point)
00293 {
00294 // Push current state into heap.
00295    if (fStackLevel>=fGeoCacheStackSize) {
00296       printf("ERROR TGeoNodeCach::PushSate() : stack of states full\n");
00297       return 0;
00298    }
00299    ((TGeoCacheState*)fStack->At(fStackLevel))->SetState(fLevel,startlevel,nmany,ovlp,point);
00300    return ++fStackLevel;
00301 }
00302 
00303 //_____________________________________________________________________________
00304 Bool_t TGeoNodeCache::PopState(Int_t &nmany, Double_t *point)
00305 {
00306 // Pop next state/point from heap.
00307    if (!fStackLevel) return 0;
00308    Bool_t ovlp = ((TGeoCacheState*)fStack->At(--fStackLevel))->GetState(fLevel,nmany,point);
00309    Refresh();
00310 //   return (fStackLevel+1);
00311    return ovlp;
00312 }
00313 
00314 //_____________________________________________________________________________
00315 Bool_t TGeoNodeCache::PopState(Int_t &nmany, Int_t level, Double_t *point)
00316 {
00317 // Pop next state/point from heap and restore matrices starting from LEVEL.
00318    if (level<=0) return 0;
00319    Bool_t ovlp = ((TGeoCacheState*)fStack->At(level-1))->GetState(fLevel,nmany,point);
00320    Refresh();
00321    return ovlp;
00322 }
00323 
00324 //_____________________________________________________________________________
00325 Bool_t TGeoNodeCache::RestoreState(Int_t &nmany, TGeoCacheState *state, Double_t *point)
00326 {
00327 // Pop next state/point from a backed-up state.
00328    Bool_t ovlp = state->GetState(fLevel,nmany,point);
00329    Refresh();
00330    return ovlp;
00331 }
00332 
00333 //_____________________________________________________________________________
00334 void TGeoNodeCache::LocalToMaster(const Double_t *local, Double_t *master) const
00335 {
00336 // Local point converted to master frame defined by current matrix.
00337    fMatrix->LocalToMaster(local, master);
00338 }
00339 
00340 //_____________________________________________________________________________
00341 void TGeoNodeCache::MasterToLocal(const Double_t *master, Double_t *local) const
00342 {
00343 // Point in master frame defined by current matrix converted to local one.
00344    fMatrix->MasterToLocal(master, local);
00345 }
00346 
00347 //_____________________________________________________________________________
00348 void TGeoNodeCache::LocalToMasterVect(const Double_t *local, Double_t *master) const
00349 {
00350 // Local vector converted to master frame defined by current matrix.
00351    fMatrix->LocalToMasterVect(local, master);
00352 }
00353 
00354 //_____________________________________________________________________________
00355 void TGeoNodeCache::MasterToLocalVect(const Double_t *master, Double_t *local) const
00356 {
00357 // Vector in master frame defined by current matrix converted to local one.
00358    fMatrix->MasterToLocalVect(master,local);
00359 }
00360 
00361 //_____________________________________________________________________________
00362 void TGeoNodeCache::LocalToMasterBomb(const Double_t *local, Double_t *master) const
00363 {
00364 // Local point converted to master frame defined by current matrix and rescaled with bomb factor.
00365    fMatrix->LocalToMasterBomb(local, master);
00366 }
00367 
00368 //_____________________________________________________________________________
00369 void TGeoNodeCache::MasterToLocalBomb(const Double_t *master, Double_t *local) const
00370 {
00371 // Point in master frame defined by current matrix converted to local one and rescaled with bomb factor.
00372    fMatrix->MasterToLocalBomb(master, local);
00373 }
00374 
00375 ClassImp(TGeoCacheState)
00376 
00377 /*************************************************************************
00378 * TGeoCacheState - class storing the state of the cache at a given moment
00379 *
00380 *
00381 *************************************************************************/
00382 
00383 //_____________________________________________________________________________
00384 TGeoCacheState::TGeoCacheState()
00385 {
00386 // Default ctor.
00387    fCapacity = 0;
00388    fLevel = 0;
00389    fNmany = 0;
00390    fStart = 0;
00391    memset(fIdBranch, 0, 30*sizeof(Int_t));
00392    memset(fPoint, 0, 3*sizeof(Int_t));
00393    fOverlapping = kFALSE;
00394    fNodeBranch = 0;
00395    fMatrixBranch = 0;
00396    fMatPtr = 0;
00397 }
00398 
00399 //_____________________________________________________________________________
00400 TGeoCacheState::TGeoCacheState(Int_t capacity)
00401 {
00402 // Ctor.
00403    fCapacity = capacity;
00404    fLevel = 0;
00405    fNmany = 0;
00406    fStart = 0;
00407    memset(fIdBranch, 0, 30*sizeof(Int_t));
00408    memset(fPoint, 0, 3*sizeof(Int_t));
00409    fOverlapping = kFALSE;
00410    fNodeBranch = new TGeoNode *[capacity];
00411    fMatrixBranch = new TGeoHMatrix *[capacity];
00412    fMatPtr = new TGeoHMatrix *[capacity];
00413    for (Int_t i=0; i<capacity; i++)
00414       fMatrixBranch[i] = new TGeoHMatrix("global");
00415 }
00416 
00417 //_____________________________________________________________________________
00418 TGeoCacheState::TGeoCacheState(const TGeoCacheState& gcs) :
00419   TObject(gcs),
00420   fCapacity(gcs.fCapacity),
00421   fLevel(gcs.fLevel),
00422   fNmany(gcs.fNmany),
00423   fStart(gcs.fStart),
00424   fOverlapping(gcs.fOverlapping)
00425 {
00426    //copy constructor
00427    Int_t i;
00428    for (i=0; i<3; i++) fPoint[i]=gcs.fPoint[i];
00429    for(i=0; i<30; i++) fIdBranch[i]=gcs.fIdBranch[i];
00430    fNodeBranch = new TGeoNode *[fCapacity];
00431    fMatrixBranch = new TGeoHMatrix *[fCapacity];
00432    fMatPtr = new TGeoHMatrix *[fCapacity];
00433    for (i=0; i<fCapacity; i++) {
00434       fNodeBranch[i] = gcs.fNodeBranch[i];
00435       fMatrixBranch[i] = new TGeoHMatrix(*gcs.fMatrixBranch[i]);
00436       fMatPtr[i] = gcs.fMatPtr[i];
00437    }
00438 }
00439 
00440 //_____________________________________________________________________________
00441 TGeoCacheState& TGeoCacheState::operator=(const TGeoCacheState& gcs)
00442 {
00443    //assignment operator
00444    Int_t i;
00445    if(this!=&gcs) {
00446       TObject::operator=(gcs);
00447       fCapacity=gcs.fCapacity;
00448       fLevel=gcs.fLevel;
00449       fNmany=gcs.fNmany;
00450       fStart=gcs.fStart;
00451       for(i=0; i<30; i++) fIdBranch[i]=gcs.fIdBranch[i];
00452       for(i=0; i<3; i++) fPoint[i]=gcs.fPoint[i];
00453       fOverlapping=gcs.fOverlapping;
00454       fNodeBranch = new TGeoNode *[fCapacity];
00455       fMatrixBranch = new TGeoHMatrix *[fCapacity];
00456       fMatPtr = new TGeoHMatrix *[fCapacity];
00457       for (i=0; i<fCapacity; i++) {
00458          fNodeBranch[i] = gcs.fNodeBranch[i];
00459          fMatrixBranch[i] = new TGeoHMatrix(*gcs.fMatrixBranch[i]);
00460          fMatPtr[i] = gcs.fMatPtr[i];
00461       }
00462    }
00463    return *this;
00464 }
00465 
00466 //_____________________________________________________________________________
00467 TGeoCacheState::~TGeoCacheState()
00468 {
00469 // Dtor.
00470    if (fNodeBranch) {
00471       delete [] fNodeBranch;
00472       for (Int_t i=0; i<fCapacity; i++)
00473          delete fMatrixBranch[i];
00474       delete [] fMatrixBranch;
00475       delete [] fMatPtr;
00476    }
00477 }
00478 
00479 //_____________________________________________________________________________
00480 void TGeoCacheState::SetState(Int_t level, Int_t startlevel, Int_t nmany, Bool_t ovlp, Double_t *point)
00481 {
00482 // Fill current modeller state.
00483    fLevel = level;
00484    fStart = startlevel;
00485    fNmany = nmany;
00486    TGeoNodeCache *cache = gGeoManager->GetCache();
00487    if (cache->HasIdArray()) memcpy(fIdBranch, cache->GetIdBranch()+fStart, (level+1-fStart)*sizeof(Int_t));
00488    TGeoNode **node_branch = (TGeoNode **) cache->GetBranch();
00489    TGeoHMatrix **mat_branch  = (TGeoHMatrix **) cache->GetMatrices();
00490 
00491    memcpy(fNodeBranch, node_branch+fStart, (level+1-fStart)*sizeof(TGeoNode *));
00492    memcpy(fMatPtr, mat_branch+fStart, (level+1-fStart)*sizeof(TGeoHMatrix *));
00493    TGeoHMatrix *last = 0;
00494    TGeoHMatrix *current;
00495    for (Int_t i=0; i<level+1-fStart; i++) {
00496       current = mat_branch[i+fStart];
00497       if (current == last) continue;
00498       *fMatrixBranch[i] = current;
00499       last = current;
00500    }
00501    fOverlapping = ovlp;
00502    if (point) memcpy(fPoint, point, 3*sizeof(Double_t));
00503 }
00504 
00505 //_____________________________________________________________________________
00506 Bool_t TGeoCacheState::GetState(Int_t &level, Int_t &nmany, Double_t *point) const
00507 {
00508 // Restore a modeler state.
00509    level = fLevel;
00510    nmany = fNmany;
00511    TGeoNodeCache *cache = gGeoManager->GetCache();
00512    if (cache->HasIdArray()) cache->FillIdBranch(fIdBranch, fStart);
00513    TGeoNode **node_branch = (TGeoNode **) cache->GetBranch();
00514    TGeoHMatrix **mat_branch  = (TGeoHMatrix **) cache->GetMatrices();
00515 
00516    memcpy(node_branch+fStart, fNodeBranch, (level+1-fStart)*sizeof(TGeoNode *));
00517    memcpy(mat_branch+fStart, fMatPtr, (level+1-fStart)*sizeof(TGeoHMatrix *));
00518    TGeoHMatrix *last = 0;
00519    TGeoHMatrix *current;
00520    for (Int_t i=0; i<level+1-fStart; i++) {
00521       current = mat_branch[i+fStart];
00522       if (current == last) continue;
00523       *current = fMatrixBranch[i];
00524       last = current;
00525    }
00526    if (point) memcpy(point, fPoint, 3*sizeof(Double_t));
00527    return fOverlapping;
00528 }

Generated on Tue Jul 5 14:12:55 2011 for ROOT_528-00b_version by  doxygen 1.5.1