StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiDetectorTreeBuilder.cxx
1 //StiDetectorTreeBuilder.cxx
2 //M.L. Miller (Yale Software)
3 //07/01
4 
5 #include <cassert>
6 #include "Stiostream.h"
7 #include <stdio.h>
8 #include <dirent.h>
9 #include <sys/stat.h>
10 #include <stdexcept>
11 
12 #include "St_base/StMessMgr.h"
13 #include "StiDetector.h"
14 #include "StiPlacement.h"
15 #include "StiCompositeTreeNode.h"
16 #include "StiDetectorBuilder.h"
17 #include "StiDetectorTreeBuilder.h"
18 #include "StlUtilities.h"
19 #include "StiToolkit.h"
20 
21 ostream& operator<<(ostream&, const StiDetector&);
22 
24  : mroot(0),
25  mnodefactory(StiToolkit::instance()->getDetectorNodeFactory()),
26  mregion(0)
27 {
28  LOG_INFO <<"StiDetectorTreeBuilder::StiDetectorTreeBuilder() : Started/Done"<<endm;
29 }
30 
32 {}
33 
35 {
36  LOG_INFO <<"StiDetectorTreeBuilder::build() : Started"<<endm;
37  if (mroot)
38  {
39  LOG_INFO << "StiDetectorTreeBuilder::build()\tError!\troot tree already built"<<endm;
40  assert(mroot);
41  }
42  assert(builder);
43  assert(mnodefactory);
44  mDetectorBuilder = builder;
45  LOG_INFO <<"StiDetectorTreeBuilder::build() : Build root"<<endm;
46 
47  buildRoot();
49  LOG_INFO <<"StiDetectorTreeBuilder::build() : Sort Tree"<<endm;
50  //Now sort the tree:
52  //mysorter(mregion); (old)
53  mysorter(mroot); //new (MLM)
54  //Now index the tree to give efficient sibling traversal
55  LOG_INFO <<"StiDetectorTreeBuilder::build() : Index Tree"<<endm;
57  myindexer(mroot);
58  //myindexer(mregion);
59  LOG_INFO <<"StiDetectorTreeBuilder::build() : Done"<<endm;
60  return mroot;
61 }
62 
64 {
65  mroot = mnodefactory->getInstance();
66  mroot->setName("star");
67  //make 3 daughters
68  StiDetectorNode* mid = mnodefactory->getInstance();
69  StiDetectorNode* fwd = mnodefactory->getInstance();
70  StiDetectorNode* bwd = mnodefactory->getInstance();
71 
72  mid->setName("midrapidity");
73  fwd->setName("forwardrapidity");
74  bwd->setName("backwardrapidity");
75 
76  StiOrderKey midKey;
77  midKey.key = static_cast<double>(StiPlacement::kMidRapidity);
78  StiOrderKey fwdKey;
79  fwdKey.key = static_cast<double>(StiPlacement::kForwardRapidity);
80  StiOrderKey bwdKey;
81  bwdKey.key = static_cast<double>(StiPlacement::kBackwardRapidity);
82 
83  mid->setOrderKey(midKey);
84  fwd->setOrderKey(fwdKey);
85  bwd->setOrderKey(bwdKey);
86 
87  mroot->add(mid);
88  mroot->add(fwd);
89  mroot->add(bwd);
90 
91  mregion = mid;
92 }
93 
94 
96 {
97  //LOG_INFO << "StiDetectorTreeBuilder::addToTree(StiDetector*) : Started"<<endm;
98  //Which region do we hang it on?
99  StiPlacement* placement = layer->getPlacement();
100  SameOrderKey<StiDetector> mySameOrderKey;
101  StiOrderKey tempOrderKey;
102  tempOrderKey.key = static_cast<double>( placement->getRegion() );
103  mySameOrderKey.morderKey = tempOrderKey; //order is of type const StiOrderKey&
104  StiDetectorNodeVector::iterator where = find_if(mroot->begin(), mroot->end(), mySameOrderKey);
105 
106  if (where==mroot->end()) {
107  //must abort!!! If this happens do not go on!!!
108  LOG_ERROR <<"StiDetectorContainer::build() : mid-rapidity region not found - where==0"<<endm;
109  abort();
110  }
111 
112  //ok, now we have the region
113  mregion = (*where);
114 
115  //Where do we hang in radius (or z-position for fwd/bwd)?
116  StiPlacement::StiRegion theRegion = layer->getPlacement()->getRegion();
117 
118  StiOrderKey radius;
119  string radstring;
120  StiPlacement *place=layer->getPlacement();
121 
122  if ( theRegion == StiPlacement::kMidRapidity ) {
123  radius.key = place->getLayerRadius();
124  radstring = "_radius";
125  }
126  else {
127  LOG_ERROR <<"StiDetectorBuiler::addToTree() : unkown region:\t"<<theRegion
128  <<"\tfrom detector:\t"<<layer->getName()<<"\tabort"<<endm;
129  abort();
130  }
131 
132  StiDetectorNode* radialnode = hangWhere(mregion, radius, radstring);
133  //Where do we hang in phi?
134  StiOrderKey refAngle;
135  refAngle.key = layer->getPlacement()->getLayerAngle();
136  string phistring = "_refAngle";
137  StiDetectorNode* phinode = hangWhere(radialnode, refAngle, phistring);
138 
139  assert(phinode);
140  //Maintain the relationship between these two.
141  //It's not so elegant to have the Detector know about the node that it's stored on, but
142  //it's fast way to get from the detector to the node, and it allows the project to be
143  //generally independent of the tree-node, ie, the tracker only has to know about
144  //StiDetector objects.
145  //So, we put the extra layer of coupling in StiDetector, not Tracke, SeedFinder, etc...
146  if (phinode->getData()) phinode = hangWhere(radialnode, refAngle, phistring,1);
147  assert(!phinode->getData());
148  phinode->setData(layer);
149  layer->setTreeNode(phinode);
150 
151 }
152 
153 // Starting with the given parent, use the ordering key of the given type
154 // to determine where the new detector should be hung.
156  string& keystring, int newOne)
157 {
158  SameOrderKey<StiDetector> mySameOrderKey;
159  mySameOrderKey.morderKey = order; //order is of type const StiOrderKey&
160 
161  StiDetectorNodeVector::iterator where = find_if(parent->begin(), parent->end(), mySameOrderKey);
162 
163  if (newOne || where == parent->end()) {
164  //LOG_INFO <<"hangWhere(). Start new node"<<endm;
165  StiDetectorNode* temp = mnodefactory->getInstance();
166  char tempname[100];
167  sprintf(tempname,"_%f", order.key);
168  keystring.append(tempname);
169  string newname = parent->getName();
170  newname.append(keystring);
171 
172  temp->setName(newname);
173  temp->setOrderKey(order);
174  parent->add(temp);
175  return temp;
176  }
177  else {
178  return (*where);
179  }
180 }
181 
183 {
184  //LOG_INFO << "StiDetectorTreeBuilder::loopOnDetectors() : Started"<<endm;
185  while(mDetectorBuilder->hasMore())
186  {
187  //StiDetector* layer = mdetfactory->getInstance();
188  //mDetectorBuilder->fillNext(layer);
189  StiDetector* detector = mDetectorBuilder->next();
190  assert(detector);
191  detector->build();
192  addToTree(detector);
193  // add to by-name map
194  }
195  // LOG_INFO << "StiDetectorTreeBuilder::loopOnDetectors() : Done"<<endm;
196  return;
197 }
const string & getName() const
Return the name of the node.
StiDetectorNode * hangWhere(StiDetectorNode *parent, const StiOrderKey &order, string &keystring, int newOne=0)
Decide where to hang the detector object on the tree.
void addToTree(StiDetector *)
Actually hang an individual detector object on the tree.
StiDetectorNode * mroot
Store a pointer to the root of the tree.
T * getData() const
Return a (non-const!) pointer to the data hung on this node.
StiDetectorNode * build(StiDetectorBuilder *builder)
Build the Detector model.
void loopOnDetectors()
Iterate over the detector objects served by StiDetectorBuilder.
StiDetectorTreeBuilder()
Default Contstructor.
Factory< StiDetectorNode > * mnodefactory
This object is assumed not to be owned by this class.
void buildRoot()
Assemble detector objects into tree.
StiDetectorBuilder * mDetectorBuilder
Store a pointer to the StiDetectorBuilder instance.
virtual void add(StiCompositeTreeNode *)
Add a child to this node.
Abstract interface for a STI toolkit.
void setName(const string &)
Set the name of the node.
vec_type::iterator begin()
Provide random access iterator to the beginning of the vector of children.
Definition of toolkit.
Definition: StiToolkit.h:55
virtual ~StiDetectorTreeBuilder()
Default Destructor.
vec_type::iterator end()
Provide random access iterator to the end of the vector of children.
StiDetectorNode * mregion
Pointer to the current region in the tree (e.g., mid rapidity)
void setData(T *)
Set the data to be hung on the node.
void setOrderKey(const StiOrderKey &)
Set the order-key for the node.
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22