StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiDetectorBuilder.cxx
1 #include "Stiostream.h"
2 #include "Sti/Base/Factory.h"
3 #include "Sti/StiDetector.h"
4 #include "Sti/StiPlanarShape.h"
5 #include "Sti/StiCylindricalShape.h"
6 #include "Sti/StiPlacement.h"
7 #include "Sti/StiMaterial.h"
8 #include "Sti/StiDetectorBuilder.h"
9 #include "Sti/StiToolkit.h"
11 #include "StiUtilities/StiDebug.h"
12 #include "Sti/StiElossCalculator.h"
13 #include "StDetectorDbMaker/StiDefaultTrackingParameters.h"
14 #include "StThreeVector.hh"
15 #include "StMaker.h"
16 #include "StThreeVectorD.hh"
17 #include "TMath.h"
18 #include "TVector3.h"
19 
20 StiDetectorBuilder* StiDetectorBuilder::fCurrentDetectorBuilder = 0;
21 int StiDetectorBuilder::_debug = 0;
22 //________________________________________________________________________________
23 StiDetectorBuilder::StiDetectorBuilder(const string & name,bool active)
24  : Named(name+"Builder"),
25  mThkSplit(0.2),
26  mMaxSplit( 20),
27  _groupId(-1),
28  _active(active),
29  _detectorFactory( StiToolkit::instance()->getDetectorFactory() ),
30  _trackingParameters(0),
31  _gasMat(0)
32 {
33  cout << "StiDetectorBuilder::StiDetectorBuilder() - INFO - Instantiating builder named:"<<name<<endl;
34  fCurrentDetectorBuilder = this;
35 }
36 
37 //________________________________________________________________________________
38 StiDetectorBuilder::~StiDetectorBuilder()
39 {}
40 
41 //________________________________________________________________________________
42 bool StiDetectorBuilder::hasMore() const
43 {
44  //cout<<"StiDetectorBuilder::hasMore() - INFO - Started"<<endl;
45  return mDetectorIterator != mDetectorMap.end();
46 } // hasMore()
47 
48 //________________________________________________________________________________
49 StiDetector * StiDetectorBuilder::next()
50 {
51  //cout<<"StiDetectorBuilder::hasMore() - INFO - Started"<<endl;
52  if (mDetectorIterator != mDetectorMap.end())
53  return (mDetectorIterator++)->second;
54  else
55  return 0;
56 } // next()
57 
58 //________________________________________________________________________________
59 StiMaterial* StiDetectorBuilder::findMaterial(const string& szName) const
60 {
61  materialMap::const_iterator where = mMaterialMap.find(NameMapKey(szName));
62  return (where!= mMaterialMap.end()) ? (*where).second : 0;
63 } // findMaterial()
64 
65 //________________________________________________________________________________
66 StiShape* StiDetectorBuilder::findShape(const string& szName) const
67 {
68  shapeMap::const_iterator where = mShapeMap.find(NameMapKey(szName));
69  return (where!=mShapeMap.end()) ? (*where).second: 0;
70 } // findShape()
71 
72 //________________________________________________________________________________
73 StiDetector* StiDetectorBuilder::findDetector(const string& szName) const
74 {
75  detectorMap::const_iterator where = mDetectorMap.find(NameMapKey(szName));
76  return (where!=mDetectorMap.end()) ? (*where).second: 0;
77 } // findDetector()
78 
79 //________________________________________________________________________________
80 StiMaterial * StiDetectorBuilder::add(StiMaterial *material)
81 {
82  NameMapKey key(material->getName());
83  mMaterialMap.insert( materialMapValType(key,material) );
84  return material;
85 }
86 
87 //________________________________________________________________________________
88 StiShape * StiDetectorBuilder::add(StiShape *shape)
89 {
90  NameMapKey key(shape->getName());
91  mShapeMap.insert( shapeMapValType(key, shape) );
92  return shape;
93 }
94 
95 //________________________________________________________________________________
96 StiDetector * StiDetectorBuilder::add(UInt_t row, UInt_t sector, StiDetector *detector)
97 {
98  setNSectors(row,sector+1);
99  if (_detectors[row][sector]) {
100  printf("***ERROR*** StiDetectorBuilder::add(%d,%d,\"%s\") "
101  ,row,sector,detector->getName().c_str());
102  printf(" is replacing %s\n",_detectors[row][sector]->getName().c_str());
103  assert( !_detectors[row][sector]);
104  }
105  _detectors[row][sector] = detector;
106  if (_debug || sector == 0) {
107  cout << "StiDetectorBuilder::add(" << row << "," << sector << ") detector ";
108  if (detector) cout << detector->getName();
109  else cout << " NULL ??";
110  cout <<endl;
111  }
112  return add(detector);
113 }
114 
118 //________________________________________________________________________________
119 StiDetector * StiDetectorBuilder::add(StiDetector *detector)
120 {
121  NameMapKey key(detector->getName());
122  StiDetector *old = findDetector(detector->getName());
123  if (old ) {
124  cout << "StiDetectorBuilder::add(" << detector << old << "existing with the same name " << detector->getName() <<endl;
125  assert(0);
126  }
127  mDetectorMap.insert( detectorMapValType(key, detector) );
128  //complete the building of this detector element
129  // in the base class nothing is actually done
130  // but ROOT stuff is built in the drawable version of this class.
131  detector->setGroupId(_groupId);
132  if (! detector->getTrackingParameters())
133  detector->setTrackingParameters(StiDefaultTrackingParameters::instance());
134  return detector;
135 }
136 //________________________________________________________________________________
137 void StiDetectorBuilder::del(UInt_t row, UInt_t sector)
138 {
139 // * Completely removes previously added Sti detector/volume at a given row and
140 // * sector. Returnstrue if removal was successful orfalse otherwise.
141 //
142 
143  assert(row < _detectors.size());
144  assert(sector < _detectors[row].size());
145 
146  StiDetector* stiDetector = getDetector(row, sector);
147 
148  assert(stiDetector);
149  cout << "StiDetectorBuilder::del(" << row << "," << sector << ") detector " << stiDetector->getName() <<endl;
150 
151  mDetectorMap.erase(stiDetector->getName());
152 
153 //delete stiDetector;
154  getDetectorFactory()->free(stiDetector);
155 
156  _detectors[row][sector] = 0;
157 }
158 
159 
160 //________________________________________________________________________________
161 void StiDetectorBuilder::build(StMaker& source)
162 {
163  buildDetectors(source);
164 
165  mDetectorIterator = mDetectorMap.begin();
166 }
167 
168 //________________________________________________________________________________
169 void StiDetectorBuilder::buildDetectors(StMaker& source)
170 {}
171 //________________________________________________________________________________
172 void StiDetectorBuilder::AverageVolume(TGeoPhysicalNode *nodeP)
173 {
174  if (debug()) {cout << "StiDetectorBuilder::AverageVolume -I TGeoPhysicalNode\t" << nodeP->GetName() << endl;}
175  TGeoVolume *volP = nodeP->GetVolume();
176  TGeoMaterial *matP = volP->GetMaterial(); if (debug()) matP->Print("");
177  TGeoShape *shapeP = nodeP->GetShape(); if (debug()) {cout << "New Shape\t"; StiVMCToolKit::PrintShape(shapeP);}
178  TGeoHMatrix *hmat = nodeP->GetMatrix(); if (debug()) hmat->Print("");
179  Double_t PotI = StiVMCToolKit::GetPotI(matP);
180  StiMaterial *matS = add(new StiMaterial(matP->GetName(),
181  matP->GetZ(),
182  matP->GetA(),
183  matP->GetDensity(),
184  matP->GetDensity()*matP->GetRadLen(),
185  PotI));
186 // Double_t ionization = matS->getIonization();
187 // StiElossCalculator *ElossCalculator =
188 // new StiElossCalculator(matS->getZOverA(), ionization, matS->getA(), matS->getZ(),matS->getDensity());
189  StiShape *sh = findShape(volP->GetName());
190  Double_t *xyz = hmat->GetTranslation();
191 // Double_t *rot = hmat->GetRotationMatrix();
192  Double_t Phi = 0;
193  // Double_t xc,yc,zc,rc,rn, nx,ny,nz,yOff;
194  StiPlacement *pPlacement = 0;
195  do {//only once
196  if (!shapeP->TestShapeBit(TGeoShape::kGeoTube)) break;
197  TGeoTube *shapeC = (TGeoTube *)shapeP;
198  Double_t Rmax = shapeC->GetRmax();
199  Double_t Rmin = shapeC->GetRmin();
200  Double_t delta=fabs(xyz[0])+fabs(xyz[1]);
201  if (delta>0.1*Rmin) break;
202  Double_t dZ = shapeC->GetDz();
203  Double_t dPhi = 2*TMath::Pi();
204  Double_t dR = Rmax - Rmin;
205 
206  if (shapeP->TestShapeBit(TGeoShape::kGeoTubeSeg)) {
207  TGeoTubeSeg *shapeS = (TGeoTubeSeg *) shapeP;
208  Double_t gloV[3];
209  Double_t Phi1 = TMath::DegToRad()*shapeS->GetPhi1();
210  Double_t Phi2 = TMath::DegToRad()*shapeS->GetPhi2();
211  if (Phi2<Phi1) Phi2+=M_PI*2;
212  Double_t PhiM = (Phi2+Phi1)/2;
213  dPhi = (Phi2-Phi1);
214  Double_t locV[3]={cos(PhiM),sin(PhiM),0};
215  hmat->LocalToMaster(locV,gloV);
216  Phi = atan2(gloV[1],gloV[0]);
217  }
218 
219  TString Name(nodeP->GetName());
220  sh = new StiCylindricalShape(Name.Data(), // Name
221  dZ, // halfDepth
222  dR, // thickness
223  Rmax, // outerRadius
224  dPhi); // openingAngle
225  add(sh);
226  pPlacement = new StiPlacement;
227  pPlacement->setZcenter(xyz[2]);
228  pPlacement->setLayerRadius((Rmin+Rmax)*0.5);
229  pPlacement->setLayerAngle(Phi);
230  pPlacement->setRegion(StiPlacement::kMidRapidity);
231  pPlacement->setNormalRep(Phi,0.5*(Rmin+Rmax), 0);
232  } while(0);
233 
234  if (!pPlacement) {// BBox
235 
236  shapeP->ComputeBBox();
237 
238  TGeoBBox *box = (TGeoBBox*) shapeP;
239  TGeoRotation geoRotation(*hmat);
240 
241  // Sti geometry deals only with simple object rotated about the z axis
242  double euler_phi = geoRotation.GetPhiRotation()/180*M_PI;
243 
244  // Define "center" and normal vectors for the considered volume
245  TVector3 centerVec(xyz);
246 
247  double halfThickness = box->GetDX();
248  double halfWidth = box->GetDY();
249  double dz = box->GetDZ();
250  double r = centerVec.Perp();
251  double phi = centerVec.Phi();
252 
253  // Consider two normal vectors, i.e. along the x and y axes in the local coordinate system
254  TVector3 normVec(cos(euler_phi), sin(euler_phi), 0);
255  TVector3 normVecPerp(-sin(euler_phi), cos(euler_phi), 0);
256 
257  double centerOrient = centerVec.DeltaPhi(normVec);
258 // double centerOrient2 = normVec.DeltaPhi(centerVec);
259 // double centerOrientPerp = centerVec.DeltaPhi(normVecPerp);
260 
261  // First, select the normal vector closest to the central vector
262  if ( fabs(centerVec.Dot(normVecPerp)) > fabs(centerVec.Dot(normVec)) )
263  {
264  halfThickness = box->GetDY();
265  halfWidth = box->GetDX();
266  normVec = normVecPerp;
267  }
268 
269  // Then make sure the normal is pointing outwards
270  if (normVec.Dot(centerVec) < 0) {
271  normVec *= -1;
272  normVecPerp *= -1;
273  }
274 
275  if (!sh) {
276  // name, halfDepth, thickness, halfWidth
277  sh = new StiPlanarShape(volP->GetName(), dz, 2*halfThickness, halfWidth);
278  add(sh);
279  }
280 
281  centerOrient = centerVec.DeltaPhi(normVec);
282 
283  double normVecMag = fabs(r*cos(centerOrient));
284  double normVecOffset = r*sin(centerOrient);
285 
286  pPlacement = new StiPlacement;
287  pPlacement->setZcenter(xyz[2]);
288  pPlacement->setLayerRadius(r); //this is only used for ordering in detector container...
289  pPlacement->setLayerAngle(phi); //this is only used for ordering in detector container...
290  pPlacement->setRegion(StiPlacement::kMidRapidity);
291  pPlacement->setNormalRep(normVec.Phi(), normVecMag, normVecOffset);
292  }
293  assert(pPlacement);
294  StiDetector *pDetector = getDetectorFactory()->getInstance();
295  TString nameP(nodeP->GetName());
296  nameP.ReplaceAll("HALL_1/CAVE_1/","");
297  nameP.Strip(); // GVB: Do not truncate the name: it needs to be unique
298  pDetector->setName(nameP.Data());
299  pDetector->setIsActive(new StiNeverActiveFunctor);
300  pDetector->setShape(sh);
301  pDetector->setPlacement(pPlacement);
302  pDetector->setGas(GetCurrentDetectorBuilder()->getGasMat());
303  pDetector->setMaterial(matS);
304 
305  if (mThkSplit>0 && mMaxSplit>1) {// try to split
306  StiDetVect dv;
307  pDetector->splitIt(dv,mThkSplit,mMaxSplit);
308  for (int i=0;i<(int)dv.size();i++) {
309  int layer = getNRows();
310  add(layer,0,dv[i]);
311  cout << "StiDetectorBuilder::AverageVolume build detector " << dv[i]->getName() << " at layer " << layer << endl;
312  } }
313  else {
314  int layer = getNRows();
315  add(layer,0,pDetector);
316  cout << "StiDetectorBuilder::AverageVolume build detector " << pDetector->getName() << " at layer " << layer << endl;
317  }
318 
319 }
320 
324 //________________________________________________________________________________
325 UInt_t StiDetectorBuilder::getNSectors(UInt_t row) const
326 {
327  assert(row<_detectors.size());
328  return _detectors[row].size();
329 }
330 
331 
332 //________________________________________________________________________________
333 StiDetector * StiDetectorBuilder::getDetector(UInt_t row, UInt_t sector) const
334 {
335  assert(row<_detectors.size());
336  assert(sector<_detectors[row].size());
337  return _detectors[row][sector];
338 }
339 
340 //________________________________________________________________________________
341 void StiDetectorBuilder::setDetector(UInt_t row, UInt_t sector, StiDetector *detector)
342 {
343  setNSectors(row+1,sector+1);
344 assert(!_detectors[row][sector]);
345  _detectors[row][sector] = detector;
346 }
347 
348 
349 void StiDetectorBuilder::Print() const
350 {
351  std::cout << "StiDetectorBuilder::Print(): " << getName() << std::endl;
352  std::copy(mDetectorMap.begin(), mDetectorMap.end(), std::ostream_iterator<DetectorMapPair>(std::cout, "\n"));
353 }
354 
355 
356 ostream& operator<<(ostream& os, const DetectorMapPair& detMapEntry)
357 {
358  return os << *detMapEntry.second;
359 }
friend ostream & operator<<(ostream &os, const StiHit &h)
Definition: StiHit.cxx:89
virtual void free(Abstract *obj)=0
Free an object for reuse.
Definition: Named.h:16
const StiDetector * detector() const
Definition: StiHit.h:96
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
Abstract interface for a STI toolkit.
Definition of toolkit.
Definition: StiToolkit.h:55
void setName(const string &newName)
Set the name of the object.
Definition: Named.cxx:15
virtual UInt_t getNSectors(UInt_t row=0) const
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22
Class implements an object which is never active.