22 ClassImp(TGeoNodeCache);
34 TGeoNodeCache::TGeoNodeCache()
36 fGeoCacheMaxLevels = 100;
37 fGeoCacheStackSize = 10;
38 fGeoInfoStackSize = 100;
55 for (Int_t i=0; i<100; i++) fIdBranch[i] = 0;
61 TGeoNodeCache::TGeoNodeCache(TGeoNode *top, Bool_t nodeid, Int_t capacity)
63 fGeoCacheMaxLevels = capacity;
64 fGeoCacheStackSize = 10;
65 fGeoInfoStackSize = 100;
74 fStack =
new TObjArray(fGeoCacheStackSize);
75 for (Int_t ist=0; ist<fGeoCacheStackSize; ist++)
76 fStack->Add(
new TGeoCacheState(fGeoCacheMaxLevels));
77 fMatrixBranch =
new TGeoHMatrix *[fGeoCacheMaxLevels];
78 fMPB =
new TGeoHMatrix *[fGeoCacheMaxLevels];
79 fNodeBranch =
new TGeoNode*[fGeoCacheMaxLevels];
80 fInfoBranch =
new TGeoStateInfo*[fGeoInfoStackSize];
81 for (Int_t i=0; i<fGeoCacheMaxLevels; i++) {
82 fMPB[i] =
new TGeoHMatrix(TString::Format(
"global_%d",i));
86 for (Int_t i=0; i<fGeoInfoStackSize; i++) {
90 fMatrix = fMatrixBranch[0] = fMPB[0];
93 for (Int_t i=0; i<100; i++) fIdBranch[i] = 0;
94 if (nodeid) BuildIdArray();
101 TGeoNodeCache::~TGeoNodeCache()
107 if (fMatrixBranch)
delete [] fMatrixBranch;
109 for (Int_t i=0; i<fGeoCacheMaxLevels; i++)
delete fMPB[i];
112 delete [] fNodeBranch;
114 for (Int_t i=0; i<fGeoInfoStackSize; i++)
delete fInfoBranch[i];
116 delete [] fInfoBranch;
117 if (fNodeIdArray)
delete [] fNodeIdArray;
124 void TGeoNodeCache::BuildIdArray()
126 Int_t nnodes = gGeoManager->GetNNodes();
128 if (fNodeIdArray)
delete [] fNodeIdArray;
129 Info(
"BuildIDArray",
"--- node ID tracking enabled, size=%lu Bytes\n", ULong_t((2*nnodes+1)*
sizeof(Int_t)));
130 fNodeIdArray =
new Int_t[2*nnodes+1];
134 gGeoManager->GetTopNode()->FillIdArray(ifree, nodeid, fNodeIdArray);
135 gGeoManager->CdTop();
142 void TGeoNodeCache::BuildInfoBranch()
144 if (!fInfoBranch) fInfoBranch =
new TGeoStateInfo*[fGeoInfoStackSize];
145 else if (fInfoBranch[0])
return;
146 for (Int_t i=0; i<fGeoInfoStackSize; i++) {
147 fInfoBranch[i] =
new TGeoStateInfo();
154 TGeoStateInfo *TGeoNodeCache::GetMakePWInfo(Int_t nd)
156 if (fPWInfo)
return fPWInfo;
157 fPWInfo =
new TGeoStateInfo(nd);
165 void TGeoNodeCache::CdNode(Int_t nodeid) {
167 Error(
"CdNode",
"Navigation based on physical node unique id disabled.\n To enable, use: gGeoManager->GetCache()->BuildIdArray()");
170 Int_t *arr = fNodeIdArray;
171 if (nodeid == arr[fIndex])
return;
174 if (nodeid == arr[fIndex])
return;
176 gGeoManager->CdTop();
178 Int_t nd = GetNode()->GetNdaughters();
179 Int_t nabove, nbelow, middle;
180 while (nodeid!=currentID && nd) {
183 while (nabove-nbelow > 1) {
184 middle = (nabove+nbelow)>>1;
185 currentID = arr[arr[fIndex+middle]];
186 if (nodeid == currentID) {
187 gGeoManager->CdDown(middle-1);
190 if (nodeid < currentID) nabove = middle;
191 else nbelow = middle;
193 gGeoManager->CdDown(nbelow-1);
194 currentID = arr[fIndex];
195 nd = GetNode()->GetNdaughters();
202 Bool_t TGeoNodeCache::CdDown(Int_t index)
204 TGeoNode *newnode = fNode->GetDaughter(index);
205 if (!newnode)
return kFALSE;
208 fIndex = fNodeIdArray[fIndex+index+1];
209 fIdBranch[fLevel] = fIndex;
212 fNodeBranch[fLevel] = fNode;
213 TGeoMatrix *local = newnode->GetMatrix();
214 TGeoHMatrix *newmat = fMPB[fLevel];
215 if (!local->IsIdentity()) {
216 newmat->CopyFrom(fMatrix);
217 newmat->Multiply(local);
220 fMatrixBranch[fLevel] = fMatrix;
227 Bool_t TGeoNodeCache::CdDown(TGeoNode *newnode)
229 if (!newnode)
return kFALSE;
232 Int_t index = fNode->GetVolume()->GetIndex(newnode);
233 fIndex = fNodeIdArray[fIndex+index+1];
234 fIdBranch[fLevel] = fIndex;
237 fNodeBranch[fLevel] = fNode;
238 TGeoMatrix *local = newnode->GetMatrix();
239 TGeoHMatrix *newmat = fMPB[fLevel];
240 if (!local->IsIdentity()) {
241 newmat->CopyFrom(fMatrix);
242 newmat->Multiply(local);
245 fMatrixBranch[fLevel] = fMatrix;
252 void TGeoNodeCache::CdUp()
256 if (fNodeIdArray) fIndex = fIdBranch[fLevel];
257 fNode = fNodeBranch[fLevel];
258 fMatrix = fMatrixBranch[fLevel];
264 Int_t TGeoNodeCache::GetCurrentNodeId()
const
266 if (fNodeIdArray)
return fNodeIdArray[fIndex];
273 Int_t TGeoNodeCache::GetNodeId()
const
276 for (Int_t level=0;level<fLevel+1; level++)
277 id += (Long_t)fNodeBranch[level];
284 void TGeoNodeCache::GetBranchNames(Int_t *names)
const
287 for (Int_t i=0; i<fLevel+1; i++) {
288 name = fNodeBranch[i]->GetVolume()->GetName();
289 memcpy(&names[i], name,
sizeof(Int_t));
296 void TGeoNodeCache::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers)
const
298 for (Int_t i=0; i<fLevel+1; i++) {
299 copyNumbers[i] = fNodeBranch[i]->GetNumber();
300 volumeNumbers[i] = fNodeBranch[i]->GetVolume()->GetNumber();
307 void TGeoNodeCache::GetBranchOnlys(Int_t *isonly)
const
309 Bool_t ismany = kFALSE;
310 for (Int_t i=0; i<fLevel+1; i++) {
311 if (!fNodeBranch[i]->IsOffset()) ismany=fNodeBranch[i]->IsOverlapping();
312 isonly[i] = (ismany)?0:1;
319 TGeoStateInfo *TGeoNodeCache::GetInfo()
321 if (fInfoLevel==fGeoInfoStackSize-1) {
322 TGeoStateInfo **infoBranch =
new TGeoStateInfo*[2*fGeoInfoStackSize];
323 memcpy(infoBranch, fInfoBranch, fGeoInfoStackSize*
sizeof(TGeoStateInfo*));
324 for (Int_t i=fGeoInfoStackSize; i<2*fGeoInfoStackSize; i++)
325 infoBranch[i] =
new TGeoStateInfo();
326 delete [] fInfoBranch;
327 fInfoBranch = infoBranch;
328 fGeoInfoStackSize *= 2;
330 return fInfoBranch[fInfoLevel++];
336 void TGeoNodeCache::ReleaseInfo()
344 const char *TGeoNodeCache::GetPath()
347 for (Int_t level=0;level<fLevel+1; level++) {
349 fPath += fNodeBranch[level]->GetName();
357 Int_t TGeoNodeCache::PushState(Bool_t ovlp, Int_t startlevel, Int_t nmany, Double_t *point)
359 if (fStackLevel>=fGeoCacheStackSize) {
360 for (Int_t ist=0; ist<fGeoCacheStackSize; ist++)
361 fStack->Add(
new TGeoCacheState(fGeoCacheMaxLevels));
363 ((TGeoCacheState*)fStack->At(fStackLevel))->SetState(fLevel,startlevel,nmany,ovlp,point);
364 return ++fStackLevel;
370 Bool_t TGeoNodeCache::PopState(Int_t &nmany, Double_t *point)
372 if (!fStackLevel)
return 0;
373 Bool_t ovlp = ((TGeoCacheState*)fStack->At(--fStackLevel))->GetState(fLevel,nmany,point);
382 Bool_t TGeoNodeCache::PopState(Int_t &nmany, Int_t level, Double_t *point)
384 if (level<=0)
return 0;
385 Bool_t ovlp = ((TGeoCacheState*)fStack->At(level-1))->GetState(fLevel,nmany,point);
393 Bool_t TGeoNodeCache::RestoreState(Int_t &nmany, TGeoCacheState *state, Double_t *point)
395 Bool_t ovlp = state->GetState(fLevel,nmany,point);
403 void TGeoNodeCache::LocalToMaster(
const Double_t *local, Double_t *master)
const
405 fMatrix->LocalToMaster(local, master);
411 void TGeoNodeCache::MasterToLocal(
const Double_t *master, Double_t *local)
const
413 fMatrix->MasterToLocal(master, local);
419 void TGeoNodeCache::LocalToMasterVect(
const Double_t *local, Double_t *master)
const
421 fMatrix->LocalToMasterVect(local, master);
427 void TGeoNodeCache::MasterToLocalVect(
const Double_t *master, Double_t *local)
const
429 fMatrix->MasterToLocalVect(master,local);
435 void TGeoNodeCache::LocalToMasterBomb(
const Double_t *local, Double_t *master)
const
437 fMatrix->LocalToMasterBomb(local, master);
443 void TGeoNodeCache::MasterToLocalBomb(
const Double_t *master, Double_t *local)
const
445 fMatrix->MasterToLocalBomb(master, local);
448 ClassImp(TGeoCacheState);
460 TGeoCacheState::TGeoCacheState()
466 memset(fIdBranch, 0, 30*
sizeof(Int_t));
467 memset(fPoint, 0, 3*
sizeof(Int_t));
468 fOverlapping = kFALSE;
477 TGeoCacheState::TGeoCacheState(Int_t capacity)
479 fCapacity = capacity;
483 memset(fIdBranch, 0, 30*
sizeof(Int_t));
484 memset(fPoint, 0, 3*
sizeof(Int_t));
485 fOverlapping = kFALSE;
486 fNodeBranch =
new TGeoNode *[capacity];
487 fMatrixBranch =
new TGeoHMatrix *[capacity];
488 fMatPtr =
new TGeoHMatrix *[capacity];
489 for (Int_t i=0; i<capacity; i++) {
490 fMatrixBranch[i] =
new TGeoHMatrix(
"global");
498 TGeoCacheState::TGeoCacheState(
const TGeoCacheState& gcs) :
500 fCapacity(gcs.fCapacity),
504 fOverlapping(gcs.fOverlapping)
507 for (i=0; i<3; i++) fPoint[i]=gcs.fPoint[i];
508 for(i=0; i<30; i++) fIdBranch[i]=gcs.fIdBranch[i];
509 fNodeBranch =
new TGeoNode *[fCapacity];
510 fMatrixBranch =
new TGeoHMatrix *[fCapacity];
511 fMatPtr =
new TGeoHMatrix *[fCapacity];
512 for (i=0; i<fCapacity; i++) {
513 fNodeBranch[i] = gcs.fNodeBranch[i];
514 fMatrixBranch[i] =
new TGeoHMatrix(*gcs.fMatrixBranch[i]);
515 fMatPtr[i] = gcs.fMatPtr[i];
522 TGeoCacheState& TGeoCacheState::operator=(
const TGeoCacheState& gcs)
526 TObject::operator=(gcs);
527 fCapacity=gcs.fCapacity;
531 for(i=0; i<30; i++) fIdBranch[i]=gcs.fIdBranch[i];
532 for(i=0; i<3; i++) fPoint[i]=gcs.fPoint[i];
533 fOverlapping=gcs.fOverlapping;
534 fNodeBranch =
new TGeoNode *[fCapacity];
535 fMatrixBranch =
new TGeoHMatrix *[fCapacity];
536 fMatPtr =
new TGeoHMatrix *[fCapacity];
537 for (i=0; i<fCapacity; i++) {
538 fNodeBranch[i] = gcs.fNodeBranch[i];
539 fMatrixBranch[i] =
new TGeoHMatrix(*gcs.fMatrixBranch[i]);
540 fMatPtr[i] = gcs.fMatPtr[i];
549 TGeoCacheState::~TGeoCacheState()
552 for (Int_t i=0; i<fCapacity; i++) {
553 delete fMatrixBranch[i];
555 delete [] fNodeBranch;
556 delete [] fMatrixBranch;
564 void TGeoCacheState::SetState(Int_t level, Int_t startlevel, Int_t nmany, Bool_t ovlp, Double_t *point)
569 TGeoNodeCache *cache = gGeoManager->GetCache();
570 if (cache->HasIdArray()) memcpy(fIdBranch, cache->GetIdBranch()+fStart, (level+1-fStart)*
sizeof(Int_t));
571 TGeoNode **node_branch = (TGeoNode **) cache->GetBranch();
572 TGeoHMatrix **mat_branch = (TGeoHMatrix **) cache->GetMatrices();
573 Int_t nelem = level+1-fStart;
574 memcpy(fNodeBranch, node_branch+fStart, nelem*
sizeof(TGeoNode *));
575 memcpy(fMatPtr, mat_branch+fStart, nelem*
sizeof(TGeoHMatrix *));
576 TGeoHMatrix *last = 0;
577 TGeoHMatrix *current;
578 for (Int_t i=0; i<nelem; i++) {
579 current = mat_branch[i+fStart];
580 if (current == last)
continue;
581 *fMatrixBranch[i] = current;
585 if (point) memcpy(fPoint, point, 3*
sizeof(Double_t));
591 Bool_t TGeoCacheState::GetState(Int_t &level, Int_t &nmany, Double_t *point)
const
595 TGeoNodeCache *cache = gGeoManager->GetCache();
596 if (cache->HasIdArray()) cache->FillIdBranch(fIdBranch, fStart);
597 TGeoNode **node_branch = (TGeoNode **) cache->GetBranch();
598 TGeoHMatrix **mat_branch = (TGeoHMatrix **) cache->GetMatrices();
599 Int_t nelem = level+1-fStart;
600 memcpy(node_branch+fStart, fNodeBranch, nelem*
sizeof(TGeoNode *));
601 memcpy(mat_branch+fStart, fMatPtr, (level+1-fStart)*
sizeof(TGeoHMatrix *));
602 TGeoHMatrix *last = 0;
603 TGeoHMatrix *current;
604 for (Int_t i=0; i<nelem; i++) {
605 current = mat_branch[i+fStart];
606 if (current == last)
continue;
607 *current = fMatrixBranch[i];
610 if (point) memcpy(point, fPoint, 3*
sizeof(Double_t));