00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00036
00037
00038
00039
00040
00041 TGeoNodeCache::TGeoNodeCache()
00042 {
00043
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
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));
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
00113 Error("CC","Not implemented!");
00114 }
00115
00116
00117 TGeoNodeCache& TGeoNodeCache::operator=(const TGeoNodeCache&)
00118 {
00119
00120 Error("operator=","Assignment not allowed");
00121 return *this;
00122 }
00123
00124
00125 TGeoNodeCache::~TGeoNodeCache()
00126 {
00127
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
00145 Int_t nnodes = gGeoManager->GetNNodes();
00146
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
00160
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
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
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
00233 if (fNodeIdArray) return fNodeIdArray[fIndex];
00234 return GetNodeId();
00235 }
00236
00237
00238 Int_t TGeoNodeCache::GetNodeId() const
00239 {
00240
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
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
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
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
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
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
00307 if (!fStackLevel) return 0;
00308 Bool_t ovlp = ((TGeoCacheState*)fStack->At(--fStackLevel))->GetState(fLevel,nmany,point);
00309 Refresh();
00310
00311 return ovlp;
00312 }
00313
00314
00315 Bool_t TGeoNodeCache::PopState(Int_t &nmany, Int_t level, Double_t *point)
00316 {
00317
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
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
00337 fMatrix->LocalToMaster(local, master);
00338 }
00339
00340
00341 void TGeoNodeCache::MasterToLocal(const Double_t *master, Double_t *local) const
00342 {
00343
00344 fMatrix->MasterToLocal(master, local);
00345 }
00346
00347
00348 void TGeoNodeCache::LocalToMasterVect(const Double_t *local, Double_t *master) const
00349 {
00350
00351 fMatrix->LocalToMasterVect(local, master);
00352 }
00353
00354
00355 void TGeoNodeCache::MasterToLocalVect(const Double_t *master, Double_t *local) const
00356 {
00357
00358 fMatrix->MasterToLocalVect(master,local);
00359 }
00360
00361
00362 void TGeoNodeCache::LocalToMasterBomb(const Double_t *local, Double_t *master) const
00363 {
00364
00365 fMatrix->LocalToMasterBomb(local, master);
00366 }
00367
00368
00369 void TGeoNodeCache::MasterToLocalBomb(const Double_t *master, Double_t *local) const
00370 {
00371
00372 fMatrix->MasterToLocalBomb(master, local);
00373 }
00374
00375 ClassImp(TGeoCacheState)
00376
00377
00378
00379
00380
00381
00382
00383
00384 TGeoCacheState::TGeoCacheState()
00385 {
00386
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
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
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
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
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
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
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 }