Logo ROOT   6.08/07
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 /** \class TGeoBranchArray
13 \ingroup Geometry_classes
14 
15 An array of daughter indices making a geometry path. Can be used to
16 backup/restore a state. Allocated contiguously in memory.
17 
18 To setup an object of this type, one should use:
19 
20 ~~~ {.cpp}
21  TGeoBranchArray *array = new TGeoBranchArray(level);
22  array->InitFromNavigator(nav); // To initialize from current navigator state
23 ~~~
24 
25 The navigator can be updated to reflect this path array: `array->UpdateNavigator();`
26 */
27 
28 #include "TGeoBranchArray.h"
29 
30 #include "TMath.h"
31 #include "TThread.h"
32 #include "TString.h"
33 #include "TGeoNavigator.h"
34 #include "TGeoCache.h"
35 #include "TGeoManager.h"
36 
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 /// Constructor. Allocates the array with a size given by level.
41 
43  :fLevel(-1),
44  fMaxLevel(maxlevel),
45  fMatrix(),
46  fArray(&fRealArray[0])
47 {
48  memset(fRealArray, 0, fMaxLevel*sizeof(TGeoNode*));
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Make an instance of the class which allocates the node array. To be
53 /// released using ReleaseInstance. If addr is non-zero, the user promised that
54 /// addr contains at least that many bytes: size_t needed = SizeOf(maxlevel);
55 
57 {
58  TGeoBranchArray* ba = 0;
59  size_t needed = SizeOf(maxlevel);
60  char *ptr = new char[ needed ];
61  if (!ptr) return 0;
62  new (ptr) TGeoBranchArray(maxlevel);
63  ba = reinterpret_cast<TGeoBranchArray*>(ptr);
65  return ba;
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Make an instance of the class which allocates the node array. To be
70 /// released using ReleaseInstance. If addr is non-zero, the user promised that
71 /// addr contains at least that many bytes: size_t needed = SizeOf(maxlevel);
72 
73 TGeoBranchArray * TGeoBranchArray::MakeInstanceAt(size_t maxlevel, void *addr)
74 {
75  TGeoBranchArray* ba = 0;
76  new (addr) TGeoBranchArray(maxlevel);
77  ba = reinterpret_cast<TGeoBranchArray*>(addr);
79  return ba;
80 }
81 
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Make a copy of a branch array at the location (if indicated)
85 
87 {
88  TGeoBranchArray *copy = 0;
89  size_t needed = SizeOf(other.fMaxLevel);
90  char *ptr = new char[ needed ];
91  if (!ptr) return 0;
92  new (ptr) TGeoBranchArray(other.fMaxLevel);
93  copy = reinterpret_cast<TGeoBranchArray*>(ptr);
94  copy->SetBit(kBASelfAlloc, kTRUE);
95  copy->fLevel = other.fLevel;
96  copy->fMatrix = other.fMatrix;
97  if (other.fLevel+1) memcpy(copy->fArray, other.fArray, (other.fLevel+1)*sizeof(TGeoNode*));
98  return copy;
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Make a copy of a branch array at the location (if indicated)
103 
105 {
106  TGeoBranchArray *copy = 0;
107  new (addr) TGeoBranchArray(other.fMaxLevel);
108  copy = reinterpret_cast<TGeoBranchArray*>(addr);
109  copy->SetBit(kBASelfAlloc, kFALSE);
110  copy->fLevel = other.fLevel;
111  copy->fMatrix = other.fMatrix;
112  if (other.fLevel+1) memcpy(copy->fArray, other.fArray, (other.fLevel+1)*sizeof(TGeoNode*));
113  return copy;
114 }
115 
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Raw memcpy of the branch array content to an existing destination.
119 
121 {
122  memcpy(dest->DataStart(), DataStart(), DataSize());
123  dest->fArray = &(dest->fRealArray[0]);
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Releases the space allocated for the object
128 
130 {
131  obj->~TGeoBranchArray();
132  if (obj->TestBit(kBASelfAlloc)) delete [] (char*)obj;
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// Updates the internal addresses for n contiguous objects which have the same
137 /// fMaxLevel
138 /// Updates the internal addresses for n contiguous objects which have the same fMaxLevel
139 
141 {
142  size_t needed = SizeOf();
143 // char *where = &fArray;
144 // for (size_t i=0; i<nobj; ++i, where += needed) {
145 // TGeoNode ***array = reinterpret_cast<TGeoNode***>(where);
146 // *array = ((void**)where)+1;
147 // }
148  char *where = reinterpret_cast<char*>(this);
149  for (size_t i=0; i<nobj; ++i, where += needed) {
150  TGeoBranchArray *obj = reinterpret_cast<TGeoBranchArray*>(where);
151  obj->fArray = &(obj->fRealArray[0]);
152  }
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 /// Copy constructor. Not callable anymore. Use TGeoBranchArray::MakeCopy instead
157 
159  :TObject(other),
160  fLevel(other.fLevel),
161  fMaxLevel(other.fMaxLevel),
162  fMatrix(other.fMatrix),
163  fArray(NULL)
164 {
165  if (fMaxLevel) {
166  fArray = new TGeoNode*[fMaxLevel];
167  if (fLevel+1) memcpy(fArray, other.fArray, (fLevel+1)*sizeof(TGeoNode*));
168  }
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Assignment. Not valid anymore. Use TGeoBranchArray::MakeCopy instead
173 
175 {
176  if (&other == this) return *this;
177 // TThread::Lock();
178 // TObject::operator=(other);
179  fLevel = other.fLevel;
180  fMatrix.CopyFrom(&other.fMatrix);
181  if (fLevel+1) memcpy(fArray, other.fArray, (fLevel+1)*sizeof(TGeoNode*));
182 // SetBit(other.TestBit(kBASelfAlloc));
183 // TThread::UnLock();
184  return *this;
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 /// Add and extra daughter to the current path array. No validity check performed !
189 
191 {
192  if (fLevel<0) {
193  Error("AddLevel", "You must initialize from navigator or copy from another branch array first.");
194  return;
195  }
196  if (fLevel>fMaxLevel) {
197  Fatal("AddLevel", "Max level = %d reached\n", fMaxLevel);
198  return;
199  }
200  fLevel++;
201 /*
202  if (fLevel+1>fMaxLevel) {
203  TGeoNode **array = new TGeoNode*[fLevel+1];
204  memcpy(array, fArray, fLevel*sizeof(TGeoNode*));
205  delete [] fArray;
206  fArray = array;
207  }
208 */
209  fArray[fLevel] = fArray[fLevel-1]->GetVolume()->GetNode(dindex);
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Is equal operator.
214 
216 {
217  Int_t value = Compare(&other);
218  if (value==0) return kTRUE;
219  return kFALSE;
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Not equal operator.
224 
226 {
227  Int_t value = Compare(&other);
228  if (value!=0) return kTRUE;
229  return kFALSE;
230 }
231 
232 ////////////////////////////////////////////////////////////////////////////////
233 /// Is equal operator.
234 
236 {
237  Int_t value = Compare(&other);
238  if (value>0) return kTRUE;
239  return kFALSE;
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Is equal operator.
244 
246 {
247  Int_t value = Compare(&other);
248  if (value<0) return kTRUE;
249  return kFALSE;
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// Is equal operator.
254 
256 {
257  Int_t value = Compare(&other);
258  if (value>=0) return kTRUE;
259  return kFALSE;
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Is equal operator.
264 
266 {
267  Int_t value = Compare(&other);
268  if (value<=0) return kTRUE;
269  return kFALSE;
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Binary search in an array of n pointers to branch arrays, to locate value.
274 /// Returns element index or index of nearest element smaller than value
275 
277 {
278  Long64_t nabove, nbelow, middle;
279  const TGeoBranchArray *pind;
280  nabove = n+1;
281  nbelow = 0;
282  while(nabove-nbelow > 1) {
283  middle = (nabove+nbelow)/2;
284  pind = array[middle-1];
285  if (*value == *pind) return middle-1;
286  if (*value < *pind) nabove = middle;
287  else nbelow = middle;
288  }
289  return nbelow-1;
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Compare with other object of same type. Returns -1 if this is smaller (first
294 /// smaller array value prevails), 0 if equal (size and values) and 1 if this is
295 /// larger.
296 
298 {
299  Int_t i;
300  TGeoBranchArray *other = (TGeoBranchArray*)obj;
301  Int_t otherLevel = other->GetLevel();
302  Int_t maxLevel = TMath::Min(fLevel, otherLevel);
303  TGeoNode **otherArray = other->GetArray();
304  for (i=0; i<maxLevel+1; i++) {
305  if (fArray[i]==otherArray[i]) continue;
306  if ((Long64_t)fArray[i]<(Long64_t)otherArray[i]) return -1;
307  return 1;
308  }
309  if (fLevel==otherLevel) return 0;
310  if (fLevel<otherLevel) return -1;
311  return 1;
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Garbage collect the stored matrix.
316 
318 {
319 }
320 
321 ////////////////////////////////////////////////////////////////////////////////
322 /// Init the branch array from an array of nodes, the global matrix for the path and
323 /// the level.
324 
325 void TGeoBranchArray::Init(TGeoNode **branch, TGeoMatrix *global, Int_t level)
326 {
327  fMatrix.CopyFrom(global);
328  if (level>fMaxLevel) {
329  Fatal("Init", "Requested level %d exceeds maximum level %d", level+1, fMaxLevel);
330  return;
331  }
332  fLevel = level;
333  memcpy(fArray, branch, (fLevel+1)*sizeof(TGeoNode*));
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Init the branch array from current navigator state.
338 
340 {
341  TGeoNodeCache *cache = nav->GetCache();
342  const TGeoNode **branch = (const TGeoNode**)cache->GetBranch();
343  Int_t level = cache->GetLevel();
345  if (level>fMaxLevel) {
346  Fatal("InitFromNavigator", "Requested level %d exceeds maximum level %d", level+1, fMaxLevel);
347  return;
348  }
349  fLevel = level;
350  memcpy(fArray, branch, (fLevel+1)*sizeof(TGeoNode*));
351  if (nav->IsOutside()) fLevel = -1;
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Fill path pointed by the array.
356 
358 {
359  path = "";
360  if (!fArray || !fArray[0]) return;
361  for (Int_t i=0; i<fLevel+1; i++) {
362  path += "/";
363  path += fArray[i]->GetName();
364  }
365 }
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Print branch information
369 
371 {
372  TString path;
373  GetPath(path);
374  printf("branch: %s\n", path.Data());
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// Sorting of an array of branch array pointers.
379 
381 {
382  for (Int_t i=0; i<n; i++) index[i] = i;
383  if (down)
384  std::sort(index, index + n, compareBAdesc(array));
385  else
386  std::sort(index, index + n, compareBAasc(array));
387 }
388 
389 ////////////////////////////////////////////////////////////////////////////////
390 /// Update the navigator to reflect the branch.
391 /// nav->CdTop();
392 
394 {
395  if (fLevel<0) {nav->SetOutside(kTRUE); return;}
396  Int_t matchlev = 0;
397  Int_t navlev = nav->GetLevel();
398  Int_t i;
399  Int_t maxlev = TMath::Min(fLevel, navlev);
400  for (i=1; i<maxlev+1; ++i) {
401  if (fArray[i] != nav->GetMother(navlev-i)) break;
402  matchlev++;
403  }
404  // Go to matching level
405  for (i=0; i<navlev-matchlev; i++) nav->CdUp();
406  for (i=matchlev+1; i<fLevel+1; i++) nav->CdDown(fArray[i]);
407 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
long long Long64_t
Definition: RtypesCore.h:69
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
Geometrical transformation package.
Definition: TGeoMatrix.h:40
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
Bool_t operator!=(const TGeoBranchArray &other) const
Not equal operator.
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
size_t GetLevel() const
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
Bool_t operator>(const TGeoBranchArray &other) const
Is equal operator.
TGeoNodeCache * GetCache() const
const Bool_t kFALSE
Definition: Rtypes.h:92
size_t DataSize() const
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:739
Bool_t operator<(const TGeoBranchArray &other) const
Is equal operator.
static TGeoBranchArray * MakeCopy(const TGeoBranchArray &other)
Make a copy of a branch array at the location (if indicated)
Special pool of reusable nodes.
Definition: TGeoCache.h:57
virtual void Print(Option_t *option="") const
Print branch information.
void CopyFrom(const TGeoMatrix *other)
Fast copy method.
Bool_t operator<=(const TGeoBranchArray &other) const
Is equal operator.
void UpdateArray(size_t nobj)
Updates the internal addresses for n contiguous objects which have the same fMaxLevel Updates the int...
virtual ~TGeoBranchArray()
void GetPath(TString &path) const
Fill path pointed by the array.
Bool_t operator>=(const TGeoBranchArray &other) const
Is equal operator.
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)
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
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.
Bool_t IsOutside() const
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...
#define ClassImp(name)
Definition: Rtypes.h:279
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 ** GetArray() const
void AddLevel(Int_t dindex)
Add and extra daughter to the current path array. No validity check performed !
TGeoNode * GetMother(Int_t up=1) const
TGeoBranchArray & operator=(const TGeoBranchArray &)
Assignment. Not valid anymore. Use TGeoBranchArray::MakeCopy instead.
Int_t GetLevel() const
Mother of all ROOT objects.
Definition: TObject.h:37
Class providing navigation API for TGeo geometries.
Definition: TGeoNavigator.h:37
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:51
#define dest(otri, vertexptr)
Definition: triangle.c:1040
An array of daughter indices making a geometry path.
void * GetBranch() const
Definition: TGeoCache.h:98
#define NULL
Definition: Rtypes.h:82
void * DataStart() const
static TGeoBranchArray * MakeInstanceAt(size_t maxlevel, void *addr)
Make an instance of the class which allocates the node array.
void CopyTo(TGeoBranchArray *dest)
Raw memcpy of the branch array content to an existing destination.
TGeoBranchArray(Int_t level)
Constructor. Allocates the array with a size given by level.
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:953
void UpdateNavigator(TGeoNavigator *nav) const
Update the navigator to reflect the branch.
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
virtual Int_t Compare(const TObject *obj) const
Compare with other object of same type.
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:106
const Int_t n
Definition: legend1.C:16
TGeoNode * fRealArray[1]
[fMaxLevel+1] Array of nodes
TGeoHMatrix * GetCurrentMatrix() const
Definition: TGeoCache.h:103
size_t SizeOf() const
Int_t GetLevel() const
Definition: TGeoCache.h:112
TGeoNode ** fArray
const char * Data() const
Definition: TString.h:349