CellUniqueId.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file CellUniqueId.cxx
3 /// \brief Give every cell in the geometry a unique ID number based on
4 /// the TGeo path to the node
5 ///
6 /// \version $Id: CellUniqueId.cxx,v 1.2 2012-09-20 21:42:43 greenc Exp $
7 /// \author messier@indiana.edu
8 ////////////////////////////////////////////////////////////////////////
10 
11 #include <iostream>
12 #include "TGeoNode.h"
13 #include <cstdlib>
14 #include <climits>
15 #include <unordered_map>
16 
17 namespace geo {
18 
19  //....................................................................
20 
21  CellUniqueId NodesToUniqueId(const std::vector<const TGeoNode*>& n,
22  unsigned int depth)
23  {
24  // Only the last seven levels are required for uniqueness. Avoid overflowing
25  // the CellUniqueId.
26  const unsigned int nlvl = 6;
27  if(depth < nlvl) return 0;
28 
29  // There are only a handful of unique node pointers, store them here
30  static std::unordered_map<const TGeoNode*, int> nodemap;
31 
32  CellUniqueId id = 0;
33  for(unsigned int i = depth-nlvl; i <= depth; ++i){
34  auto it = nodemap.find(n[i]);
35  if(it == nodemap.end()){
36  //will be adding new index to the map
37  int mapsize = nodemap.size()+1;
38  nodemap[n[i]] = mapsize;
39  id += mapsize;
40  // In testing (2018/01/26) it was 141.
41  // In testing (2018/01/30) it was 255
42  if(nodemap.size() == 512){
43  std::cout << "NodesToUniqueId: Number of unique TGeoNodes exceeds 511."
44  << " Need to fix the logic here. Abort." << std::endl;
45  abort();
46  }
47  }
48  else{
49  id += it->second;
50  }
51 
52  if(id > ULLONG_MAX/512){
53  std::cout << "NodesToUniqueId: overflow" << std::endl;
54  abort();
55  }
56  id *= 512;
57  } // end for i
58  return id+1; // ensure result is always nonzero
59 
60  // This is the old code, but as of the root6 upgrade, the paths are all
61  // like vPlaneV_0/vModuleV_0/vExtruV_0/vCellV_0 rather than
62  // vPlaneV_3/vModuleV_1/vExtruV_4/vCellV_1, so we use the list of parent
63  // pointers to determine the unique ID instead.
64  /*
65  static std::vector<int> ids;
66  ids.clear();
67  for (unsigned int i=0; i<=depth; ++i) {
68  GetNodeNumbers(n[i]->GetName(), ids);
69  }
70  return IdsToUniqueId(ids);
71  */
72  }
73 
74  //....................................................................
75 
76  // Comment out all of these functions. Now that paths can't be relied upon
77  // (after the root6 upgrade) these are all just foot-guns
78 
79  /*
80  CellUniqueId PathToUniqueId(const char* path)
81  {
82  static std::vector<int> ids;
83  ids.clear();
84  GetNodeNumbers(path, ids);
85  return IdsToUniqueId(ids);
86  }
87 
88  //....................................................................
89 
90  CellUniqueId IdsToUniqueId(const std::vector<int>& ids)
91  {
92  CellUniqueId id = 0ULL;
93 
94  // Experience has shown that only depths below this "depth0"
95  // contribute to a cell's 'uniqueness'. need 6 levels to
96  // fill up the CellUniqueId
97  static const unsigned int nlvl = 6;
98  if(ids.size() < nlvl){
99  return id;
100  }
101  unsigned int depth0 = ids.size() - nlvl;
102 
103  // Now construct the id
104  for (unsigned int i=depth0; i<ids.size(); ++i) {
105  // The following check is useful, although not really
106  // required. The code in Geometry.cxx checks that the ID's are
107  // unique which is all that really matters. Even if we happen to
108  // overflow the storage limits of the CellUniqueId, the result
109  // will always be the same for the same cell. So, as long as the
110  // overflow is unique, all is OK. BTW, I've checked that as of
111  // at least v1.6 2008/08/17 the CellUniqueID's do not overflow
112  //
113  // if (id>0 && ULLONG_MAX/id < 1000) abort();
114  id = 1000*id + ids[i];
115  }
116 
117  return id;
118  }
119 
120  //....................................................................
121  // the path is of the form /vDetEnclosure_1/vSuperBlockND_479/vBlockND_476/vPlaneH_422/vModuleH_420/vExtruH_381/vCellH_371 so search from the end to the beginning for the node numbers
122  //
123  void GetNodeNumbers(const char* nm, std::vector<int>& id)
124  {
125  char buff[8];
126  const char* c;
127  const char* start = nm;
128  const char* end;
129  int indx;
130 
131  while (1) {
132  start = strchr(start, '_');
133  if (start == NULL) break;
134  ++start;
135  end = strchr(start, '/');
136  if (end==NULL) end = strchr(start, '\0');
137  if (end==NULL) abort();
138 
139  for (indx=0, c=start; c<end; ++indx, ++c) buff[indx] = *c;
140  buff[indx] = '\0';
141 
142  id.push_back(atoi(buff));
143  }
144  }
145  */
146 }
147 ////////////////////////////////////////////////////////////////////////
set< int >::iterator it
CellUniqueId NodesToUniqueId(const std::vector< const TGeoNode * > &n, unsigned int depth)
Give every cell in the geometry a unique ID number based on the TGeo path to the node.
OStream cout
Definition: OStream.cxx:6
unsigned long long int CellUniqueId
Definition: CellUniqueId.h:15
Helper for AttenCurve.
Definition: Path.h:10