ROOT  6.06/09
Reference Guide
TGeoBranchArray.cxx
Go to the documentation of this file.
1 // @(#):$Id$
2 // Author: Andrei Gheata 01/03/11
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 ////////////////////////////////////////////////////////////////////////////
13 //
14 // TGeoBranchArray - An array of daughter indices making a geometry path.
15 // Can be used to backup/restore a state. To setup an object of this type,
16 // one should use:
17 // TGeoBranchArray *array = new TGeoBranchArray(level);
18 // array->InitFromNavigator(nav); (To initialize from current navigator state)
19 // The navigator can be updated to reflect this path array:
20 // array->UpdateNavigator();
21 //
22 /////////////////////////////////////////////////////////////////////////////
23 
24 #include "TGeoBranchArray.h"
25 
26 #include "TMath.h"
27 #include "TThread.h"
28 #include "TString.h"
29 #include "TGeoNavigator.h"
30 #include "TGeoCache.h"
31 #include "TGeoManager.h"
32 
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /// Constructor. Alocates the array with a size given by level.
37 
39  :fLevel(-1),
40  fMaxLevel(maxlevel),
41  fMatrix(),
42  fArray(&fRealArray[0])
43 {
44  memset(fRealArray, 0, fMaxLevel*sizeof(TGeoNode*));
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Make an instance of the class which allocates the node array. To be
49 /// released using ReleaseInstance. If addr is non-zero, the user promised that
50 /// addr contains at least that many bytes: size_t needed = SizeOf(maxlevel);
51 
53 {
54  TGeoBranchArray* ba = 0;
55  size_t needed = SizeOf(maxlevel);
56  char *ptr = new char[ needed ];
57  if (!ptr) return 0;
58  new (ptr) TGeoBranchArray(maxlevel);
59  ba = reinterpret_cast<TGeoBranchArray*>(ptr);
61  return ba;
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Make an instance of the class which allocates the node array. To be
66 /// released using ReleaseInstance. If addr is non-zero, the user promised that
67 /// addr contains at least that many bytes: size_t needed = SizeOf(maxlevel);
68 
69 TGeoBranchArray * TGeoBranchArray::MakeInstanceAt(size_t maxlevel, void *addr)
70 {
71  TGeoBranchArray* ba = 0;
72  new (addr) TGeoBranchArray(maxlevel);
73  ba = reinterpret_cast<TGeoBranchArray*>(addr);
75  return ba;
76 }
77 
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Make a copy of a branch array at the location (if indicated)
81 
83 {
84  TGeoBranchArray *copy = 0;
85  size_t needed = SizeOf(other.fMaxLevel);
86  char *ptr = new char[ needed ];
87  if (!ptr) return 0;
88  new (ptr) TGeoBranchArray(other.fMaxLevel);
89  copy = reinterpret_cast<TGeoBranchArray*>(ptr);
90  copy->SetBit(kBASelfAlloc, kTRUE);
91  copy->fLevel = other.fLevel;
92  copy->fMatrix = other.fMatrix;
93  if (other.fLevel+1) memcpy(copy->fArray, other.fArray, (other.fLevel+1)*sizeof(TGeoNode*));
94  return copy;
95 }
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 /// Make a copy of a branch array at the location (if indicated)
99 
101 {
102  TGeoBranchArray *copy = 0;
103  new (addr) TGeoBranchArray(other.fMaxLevel);
104  copy = reinterpret_cast<TGeoBranchArray*>(addr);
105  copy->SetBit(kBASelfAlloc, kFALSE);
106  copy->fLevel = other.fLevel;
107  copy->fMatrix = other.fMatrix;
108  if (other.fLevel+1) memcpy(copy->fArray, other.fArray, (other.fLevel+1)*sizeof(TGeoNode*));
109  return copy;
110 }
111 
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Raw memcpy of the branch array content to an existing destination.
115 
117 {
118  memcpy(dest->DataStart(), DataStart(), DataSize());
119  dest->fArray = &(dest->fRealArray[0]);
120 }
121 
122 ////////////////////////////////////////////////////////////////////////////////
123 /// Releases the space allocated for the object
124 
126 {
127  obj->~TGeoBranchArray();
128  if (obj->TestBit(kBASelfAlloc)) delete [] (char*)obj;
129 }
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 /// Updates the internal addresses for n contiguous objects which have the same
133 /// fMaxLevel
134 /// Updates the internal addresses for n contiguous objects which have the same fMaxLevel
135 
137 {
138  size_t needed = SizeOf();
139 // char *where = &fArray;
140 // for (size_t i=0; i<nobj; ++i, where += needed) {
141 // TGeoNode ***array = reinterpret_cast<TGeoNode***>(where);
142 // *array = ((void**)where)+1;
143 // }
144  char *where = reinterpret_cast<char*>(this);
145  for (size_t i=0; i<nobj; ++i, where += needed) {
146  TGeoBranchArray *obj = reinterpret_cast<TGeoBranchArray*>(where);
147  obj->fArray = &(obj->fRealArray[0]);
148  }
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Copy constructor. Not callable anymore. Use TGeoBranchArray::MakeCopy instead
153 
155  :TObject(other),
156  fLevel(other.fLevel),
157  fMaxLevel(other.fMaxLevel),
158  fMatrix(other.fMatrix),
159  fArray(NULL)
160 {
161  if (fMaxLevel) {
162  fArray = new TGeoNode*[fMaxLevel];
163  if (fLevel+1) memcpy(fArray, other.fArray, (fLevel+1)*sizeof(TGeoNode*));
164  }
165 }
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 /// Assignment. Not valid anymore. Use TGeoBranchArray::MakeCopy instead
169 
171 {
172  if (&other == this) return *this;
173 // TThread::Lock();
174 // TObject::operator=(other);
175  fLevel = other.fLevel;
176  fMatrix.CopyFrom(&other.fMatrix);
177  if (fLevel+1) memcpy(fArray, other.fArray, (fLevel+1)*sizeof(TGeoNode*));
178 // SetBit(other.TestBit(kBASelfAlloc));
179 // TThread::UnLock();
180  return *this;
181 }
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Add and extra daughter to the current path array. No validity check performed !
185 
187 {
188  if (fLevel<0) {
189  Error("AddLevel", "You must initialize from navigator or copy from another branch array first.");
190  return;
191  }
192  if (fLevel>fMaxLevel) {
193  Fatal("AddLevel", "Max level = %d reached\n", fMaxLevel);
194  return;
195  }
196  fLevel++;
197 /*
198  if (fLevel+1>fMaxLevel) {
199  TGeoNode **array = new TGeoNode*[fLevel+1];
200  memcpy(array, fArray, fLevel*sizeof(TGeoNode*));
201  delete [] fArray;
202  fArray = array;
203  }
204 */
205  fArray[fLevel] = fArray[fLevel-1]->GetVolume()->GetNode(dindex);
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// Is equal operator.
210 
212 {
213  Int_t value = Compare(&other);
214  if (value==0) return kTRUE;
215  return kFALSE;
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Not equal operator.
220 
222 {
223  Int_t value = Compare(&other);
224  if (value!=0) return kTRUE;
225  return kFALSE;
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// Is equal operator.
230 
232 {
233  Int_t value = Compare(&other);
234  if (value>0) return kTRUE;
235  return kFALSE;
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Is equal operator.
240 
242 {
243  Int_t value = Compare(&other);
244  if (value<0) return kTRUE;
245  return kFALSE;
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Is equal operator.
250 
252 {
253  Int_t value = Compare(&other);
254  if (value>=0) return kTRUE;
255  return kFALSE;
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Is equal operator.
260 
262 {
263  Int_t value = Compare(&other);
264  if (value<=0) return kTRUE;
265  return kFALSE;
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Binary search in an array of n pointers to branch arrays, to locate value.
270 /// Returns element index or index of nearest element smaller than value
271 
273 {
274  Long64_t nabove, nbelow, middle;
275  const TGeoBranchArray *pind;
276  nabove = n+1;
277  nbelow = 0;
278  while(nabove-nbelow > 1) {
279  middle = (nabove+nbelow)/2;
280  pind = array[middle-1];
281  if (*value == *pind) return middle-1;
282  if (*value < *pind) nabove = middle;
283  else nbelow = middle;
284  }
285  return nbelow-1;
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////////
289 /// Compare with other object of same type. Returns -1 if this is smaller (first
290 /// smaller array value prevails), 0 if equal (size and values) and 1 if this is
291 /// larger.
292 
294 {
295  Int_t i;
296  TGeoBranchArray *other = (TGeoBranchArray*)obj;
297  Int_t otherLevel = other->GetLevel();
298  Int_t maxLevel = TMath::Min(fLevel, otherLevel);
299  TGeoNode **otherArray = other->GetArray();
300  for (i=0; i<maxLevel+1; i++) {
301  if (fArray[i]==otherArray[i]) continue;
302  if ((Long64_t)fArray[i]<(Long64_t)otherArray[i]) return -1;
303  return 1;
304  }
305  if (fLevel==otherLevel) return 0;
306  if (fLevel<otherLevel) return -1;
307  return 1;
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 /// Garbage collect the stored matrix.
312 
314 {
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Init the branch array from an array of nodes, the global matrix for the path and
319 /// the level.
320 
321 void TGeoBranchArray::Init(TGeoNode **branch, TGeoMatrix *global, Int_t level)
322 {
323  fMatrix.CopyFrom(global);
324  if (level>fMaxLevel) {
325  Fatal("Init", "Requested level %d exceeds maximum level %d", level+1, fMaxLevel);
326  return;
327  }
328  fLevel = level;
329  memcpy(fArray, branch, (fLevel+1)*sizeof(TGeoNode*));
330 }
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Init the branch array from current navigator state.
334 
336 {
337  TGeoNodeCache *cache = nav->GetCache();
338  const TGeoNode **branch = (const TGeoNode**)cache->GetBranch();
339  Int_t level = cache->GetLevel();
341  if (level>fMaxLevel) {
342  Fatal("InitFromNavigator", "Requested level %d exceeds maximum level %d", level+1, fMaxLevel);
343  return;
344  }
345  fLevel = level;
346  memcpy(fArray, branch, (fLevel+1)*sizeof(TGeoNode*));
347  if (nav->IsOutside()) fLevel = -1;
348 }
349 
350 ////////////////////////////////////////////////////////////////////////////////
351 /// Fill path pointed by the array.
352 
354 {
355  path = "";
356  if (!fArray || !fArray[0]) return;
357  for (Int_t i=0; i<fLevel+1; i++) {
358  path += "/";
359  path += fArray[i]->GetName();
360  }
361 }
362 
363 ////////////////////////////////////////////////////////////////////////////////
364 /// Print branch information
365 
367 {
368  TString path;
369  GetPath(path);
370  printf("branch: %s\n", path.Data());
371 }
372 
373 ////////////////////////////////////////////////////////////////////////////////
374 /// Sorting of an array of branch array pointers.
375 
377 {
378  for (Int_t i=0; i<n; i++) index[i] = i;
379  if (down)
380  std::sort(index, index + n, compareBAdesc(array));
381  else
382  std::sort(index, index + n, compareBAasc(array));
383 }
384 
385 ////////////////////////////////////////////////////////////////////////////////
386 /// Update the navigator to reflect the branch.
387 /// nav->CdTop();
388 
390 {
391  if (fLevel<0) {nav->SetOutside(kTRUE); return;}
392  Int_t matchlev = 0;
393  Int_t navlev = nav->GetLevel();
394  Int_t i;
395  Int_t maxlev = TMath::Min(fLevel, navlev);
396  for (i=1; i<maxlev+1; ++i) {
397  if (fArray[i] != nav->GetMother(navlev-i)) break;
398  matchlev++;
399  }
400  // Go to matching level
401  for (i=0; i<navlev-matchlev; i++) nav->CdUp();
402  for (i=matchlev+1; i<fLevel+1; i++) nav->CdDown(fArray[i]);
403 }
Bool_t operator<=(const TGeoBranchArray &other) const
Is equal operator.
Bool_t operator==(const TGeoBranchArray &other) const
Is equal operator.
size_t DataSize() const
virtual Int_t Compare(const TObject *obj) const
Compare with other object of same type.
long long Long64_t
Definition: RtypesCore.h:69
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:106
TGeoHMatrix * GetCurrentMatrix() const
Definition: TGeoCache.h:115
void SetOutside(Bool_t flag=kTRUE)
static void ReleaseInstance(TGeoBranchArray *obj)
Releases the space allocated for the object.
const char Option_t
Definition: RtypesCore.h:62
Basic string class.
Definition: TString.h:137
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
TGeoHMatrix fMatrix
Bool_t operator<(const TGeoBranchArray &other) const
Is equal operator.
void InitFromNavigator(TGeoNavigator *nav)
Init the branch array from current navigator state.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
size_t SizeOf() const
const char * Data() const
Definition: TString.h:349
size_t GetLevel() const
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
static TGeoBranchArray * MakeCopy(const TGeoBranchArray &other)
Make a copy of a branch array at the location (if indicated)
Bool_t IsOutside() const
void * GetBranch() const
Definition: TGeoCache.h:110
void CopyFrom(const TGeoMatrix *other)
Fast copy method.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Bool_t operator>(const TGeoBranchArray &other) const
Is equal operator.
Bool_t operator!=(const TGeoBranchArray &other) const
Not equal operator.
void UpdateArray(size_t nobj)
Updates the internal addresses for n contiguous objects which have the same fMaxLevel Updates the int...
void * DataStart() const
Int_t GetLevel() const
Int_t GetLevel() const
Definition: TGeoCache.h:124
virtual ~TGeoBranchArray()
void CleanMatrix()
Garbage collect the stored matrix.
static TGeoBranchArray * MakeCopyAt(const TGeoBranchArray &other, void *addr)
Make a copy of a branch array at the location (if indicated)
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
void CdDown(Int_t index)
Make a daughter of current node current.
static Long64_t BinarySearch(Long64_t n, const TGeoBranchArray **array, TGeoBranchArray *value)
Binary search in an array of n pointers to branch arrays, to locate value.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TGeoNodeCache * GetCache() const
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
Bool_t operator>=(const TGeoBranchArray &other) const
Is equal operator.
void Init(TGeoNode **branch, TGeoMatrix *global, Int_t level)
Init the branch array from an array of nodes, the global matrix for the path and the level...
void CdUp()
Go one level up in geometry.
static TGeoBranchArray * MakeInstance(size_t maxlevel)
Make an instance of the class which allocates the node array.
TGeoNode * GetMother(Int_t up=1) const
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void UpdateNavigator(TGeoNavigator *nav) const
Update the navigator to reflect the branch.
void AddLevel(Int_t dindex)
Add and extra daughter to the current path array. No validity check performed !
TGeoBranchArray & operator=(const TGeoBranchArray &)
Assignment. Not valid anymore. Use TGeoBranchArray::MakeCopy instead.
TGeoNode ** GetArray() const
Mother of all ROOT objects.
Definition: TObject.h:58
virtual void Print(Option_t *option="") const
Print branch information.
#define dest(otri, vertexptr)
Definition: triangle.c:1040
#define NULL
Definition: Rtypes.h:82
static TGeoBranchArray * MakeInstanceAt(size_t maxlevel, void *addr)
Make an instance of the class which allocates the node array.
TGMatrixLayout * fMatrix
void CopyTo(TGeoBranchArray *dest)
Raw memcpy of the branch array content to an existing destination.
TGeoBranchArray(Int_t level)
static void Sort(Int_t n, TGeoBranchArray **array, Int_t *index, Bool_t down=kTRUE)
Sorting of an array of branch array pointers.
const Bool_t kTRUE
Definition: Rtypes.h:91
TObject * obj
float value
Definition: math.cpp:443
const Int_t n
Definition: legend1.C:16
void GetPath(TString &path) const
Fill path pointed by the array.
ClassImp(TGeoBranchArray) TGeoBranchArray
Constructor. Alocates the array with a size given by level.
TGeoNode * fRealArray[1]
[fMaxLevel+1] Array of nodes
TGeoNode ** fArray