36 ClassImp(TGeoBranchArray);
41 TGeoBranchArray::TGeoBranchArray(Int_t maxlevel)
45 fArray(&fRealArray[0])
47 memset(fRealArray, 0, fMaxLevel*
sizeof(TGeoNode*));
55 TGeoBranchArray * TGeoBranchArray::MakeInstance(
size_t maxlevel)
57 TGeoBranchArray* ba = 0;
58 size_t needed = SizeOf(maxlevel);
59 char *ptr =
new char[ needed ];
61 new (ptr) TGeoBranchArray(maxlevel);
62 ba =
reinterpret_cast<TGeoBranchArray*
>(ptr);
63 ba->SetBit(kBASelfAlloc, kTRUE);
72 TGeoBranchArray * TGeoBranchArray::MakeInstanceAt(
size_t maxlevel,
void *addr)
74 TGeoBranchArray* ba = 0;
75 new (addr) TGeoBranchArray(maxlevel);
76 ba =
reinterpret_cast<TGeoBranchArray*
>(addr);
77 ba->SetBit(kBASelfAlloc, kFALSE);
85 TGeoBranchArray * TGeoBranchArray::MakeCopy(
const TGeoBranchArray &other)
87 TGeoBranchArray *copy = 0;
88 size_t needed = SizeOf(other.fMaxLevel);
89 char *ptr =
new char[ needed ];
91 new (ptr) TGeoBranchArray(other.fMaxLevel);
92 copy =
reinterpret_cast<TGeoBranchArray*
>(ptr);
93 copy->SetBit(kBASelfAlloc, kTRUE);
94 copy->fLevel = other.fLevel;
95 copy->fMatrix = other.fMatrix;
96 if (other.fLevel+1) memcpy(copy->fArray, other.fArray, (other.fLevel+1)*
sizeof(TGeoNode*));
103 TGeoBranchArray * TGeoBranchArray::MakeCopyAt(
const TGeoBranchArray &other,
void *addr)
105 TGeoBranchArray *copy = 0;
106 new (addr) TGeoBranchArray(other.fMaxLevel);
107 copy =
reinterpret_cast<TGeoBranchArray*
>(addr);
108 copy->SetBit(kBASelfAlloc, kFALSE);
109 copy->fLevel = other.fLevel;
110 copy->fMatrix = other.fMatrix;
111 if (other.fLevel+1) memcpy(copy->fArray, other.fArray, (other.fLevel+1)*
sizeof(TGeoNode*));
119 void TGeoBranchArray::CopyTo(TGeoBranchArray *dest)
121 memcpy(dest->DataStart(), DataStart(), DataSize());
122 dest->fArray = &(dest->fRealArray[0]);
128 void TGeoBranchArray::ReleaseInstance(TGeoBranchArray *obj)
130 obj->~TGeoBranchArray();
131 if (obj->TestBit(kBASelfAlloc))
delete [] (
char*)obj;
139 void TGeoBranchArray::UpdateArray(
size_t nobj)
141 size_t needed = SizeOf();
147 char *where =
reinterpret_cast<char*
>(
this);
148 for (
size_t i=0; i<nobj; ++i, where += needed) {
149 TGeoBranchArray *obj =
reinterpret_cast<TGeoBranchArray*
>(where);
150 obj->fArray = &(obj->fRealArray[0]);
157 TGeoBranchArray::TGeoBranchArray(
const TGeoBranchArray& other)
159 fLevel(other.fLevel),
160 fMaxLevel(other.fMaxLevel),
161 fMatrix(other.fMatrix),
165 fArray =
new TGeoNode*[fMaxLevel];
166 if (fLevel+1) memcpy(fArray, other.fArray, (fLevel+1)*
sizeof(TGeoNode*));
173 TGeoBranchArray& TGeoBranchArray::operator=(
const TGeoBranchArray& other)
175 if (&other ==
this)
return *
this;
176 fLevel = other.fLevel;
177 fMatrix.CopyFrom(&other.fMatrix);
178 if (fLevel+1) memcpy(fArray, other.fArray, (fLevel+1)*
sizeof(TGeoNode*));
185 void TGeoBranchArray::AddLevel(Int_t dindex)
188 Error(
"AddLevel",
"You must initialize from navigator or copy from another branch array first.");
191 if (fLevel>fMaxLevel) {
192 Fatal(
"AddLevel",
"Max level = %d reached\n", fMaxLevel);
204 fArray[fLevel] = fArray[fLevel-1]->GetVolume()->GetNode(dindex);
210 Bool_t TGeoBranchArray::operator ==(
const TGeoBranchArray& other)
const
212 Int_t value = Compare(&other);
213 if (value==0)
return kTRUE;
220 Bool_t TGeoBranchArray::operator !=(
const TGeoBranchArray& other)
const
222 Int_t value = Compare(&other);
223 if (value!=0)
return kTRUE;
230 Bool_t TGeoBranchArray::operator >(
const TGeoBranchArray& other)
const
232 Int_t value = Compare(&other);
233 if (value>0)
return kTRUE;
240 Bool_t TGeoBranchArray::operator <(
const TGeoBranchArray& other)
const
242 Int_t value = Compare(&other);
243 if (value<0)
return kTRUE;
250 Bool_t TGeoBranchArray::operator >=(
const TGeoBranchArray& other)
const
252 Int_t value = Compare(&other);
253 if (value>=0)
return kTRUE;
260 Bool_t TGeoBranchArray::operator <=(
const TGeoBranchArray& other)
const
262 Int_t value = Compare(&other);
263 if (value<=0)
return kTRUE;
271 Long64_t TGeoBranchArray::BinarySearch(Long64_t n,
const TGeoBranchArray **array, TGeoBranchArray *value)
273 Long64_t nabove, nbelow, middle;
274 const TGeoBranchArray *pind;
277 while(nabove-nbelow > 1) {
278 middle = (nabove+nbelow)/2;
279 pind = array[middle-1];
280 if (*value == *pind)
return middle-1;
281 if (*value < *pind) nabove = middle;
282 else nbelow = middle;
292 Int_t TGeoBranchArray::Compare(
const TObject *obj)
const
295 TGeoBranchArray *other = (TGeoBranchArray*)obj;
296 Int_t otherLevel = other->GetLevel();
297 Int_t maxLevel = TMath::Min(fLevel, otherLevel);
298 TGeoNode **otherArray = other->GetArray();
299 for (i=0; i<maxLevel+1; i++) {
300 if (fArray[i]==otherArray[i])
continue;
301 if ((Long64_t)fArray[i]<(Long64_t)otherArray[i])
return -1;
304 if (fLevel==otherLevel)
return 0;
305 if (fLevel<otherLevel)
return -1;
312 void TGeoBranchArray::CleanMatrix()
320 void TGeoBranchArray::Init(TGeoNode **branch, TGeoMatrix *global, Int_t level)
322 fMatrix.CopyFrom(global);
323 if (level>fMaxLevel) {
324 Fatal(
"Init",
"Requested level %d exceeds maximum level %d", level+1, fMaxLevel);
328 memcpy(fArray, branch, (fLevel+1)*
sizeof(TGeoNode*));
334 void TGeoBranchArray::InitFromNavigator(TGeoNavigator *nav)
336 TGeoNodeCache *cache = nav->GetCache();
337 const TGeoNode **branch = (
const TGeoNode**)cache->GetBranch();
338 Int_t level = cache->GetLevel();
339 fMatrix.CopyFrom(cache->GetCurrentMatrix());
340 if (level>fMaxLevel) {
341 Fatal(
"InitFromNavigator",
"Requested level %d exceeds maximum level %d", level+1, fMaxLevel);
345 memcpy(fArray, branch, (fLevel+1)*
sizeof(TGeoNode*));
346 if (nav->IsOutside()) fLevel = -1;
352 void TGeoBranchArray::GetPath(TString &path)
const
355 if (!fArray || !fArray[0])
return;
356 for (Int_t i=0; i<fLevel+1; i++) {
358 path += fArray[i]->GetName();
365 void TGeoBranchArray::Print(Option_t *)
const
369 printf(
"branch: %s\n", path.Data());
375 void TGeoBranchArray::Sort(Int_t n, TGeoBranchArray **array, Int_t *index, Bool_t down)
377 for (Int_t i=0; i<n; i++) index[i] = i;
379 std::sort(index, index + n, compareBAdesc(array));
381 std::sort(index, index + n, compareBAasc(array));
388 void TGeoBranchArray::UpdateNavigator(TGeoNavigator *nav)
const
390 if (fLevel<0) {nav->SetOutside(kTRUE);
return;}
392 Int_t navlev = nav->GetLevel();
394 Int_t maxlev = TMath::Min(fLevel, navlev);
395 for (i=1; i<maxlev+1; ++i) {
396 if (fArray[i] != nav->GetMother(navlev-i))
break;
400 for (i=0; i<navlev-matchlev; i++) nav->CdUp();
401 for (i=matchlev+1; i<fLevel+1; i++) nav->CdDown(fArray[i]);