StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiIstDetectorBuilder.cxx
1 // 12/12/2012 : modification of the builder to take into account the new geometry path names
2 // backward compatibility with upgr15 geometry is lost
3 
4 // $Id: StiIstDetectorBuilder.cxx,v 1.24 2014/08/22 17:49:18 perev Exp $
5 //
6 // $Log: StiIstDetectorBuilder.cxx,v $
7 // Revision 1.24 2014/08/22 17:49:18 perev
8 // StiEloss calculator creates in material now
9 //
10 // Revision 1.23 2012/12/18 20:52:32 bouchet
11 // update for DEV13 geometry
12 //
13 // Revision 1.22 2010/10/20 20:05:06 fisyak
14 // Move SROD and SBSP from StiSvtDetectorBuilder to StiStarDetectorBuilder to account configurations without SVT detector installed (bug #2025)
15 //
16 // Revision 1.21 2010/08/25 21:57:41 fisyak
17 // Get rid off access to specfic detector tracking parameters which usage has been disable since 2008/06/11
18 //
19 // Revision 1.20 2009/03/16 13:51:00 fisyak
20 // Move out all Sti Chairs into StDetectorDb
21 //
22 // Revision 1.19 2009/02/06 21:26:30 wleight
23 // UPGR15 Update
24 //
25 // Revision 1.18 2008/04/03 20:04:21 fisyak
26 // Straighten out DB access via chairs
27 //
28 // Revision 1.17 2007/04/27 18:44:03 wleight
29 // Corrected a problem with incorrect assignment of hit errors
30 //
31 // Revision 1.16 2007/04/23 14:42:10 wleight
32 // Added new hit error calculator for outer half of 17cm layer
33 //
34 // Revision 1.14 2007/04/06 15:58:21 wleight
35 // Changed some cout statements to LOG_INFO
36 //
37 // Revision 1.13 2006/12/14 22:01:47 wleight
38 // Changed hit errors so that they are obtained from the database and are different for each layer
39 //
40 // Revision 1.12 2006/11/28 22:18:01 wleight
41 // Changed hit errors to 60 microns for x and 1.9 mm for y
42 //
43 // Revision 1.11 2006/10/20 18:43:12 wleight
44 // Changes to make perfect hits in the IST work with UPGR05
49 #include <stdio.h>
50 #include <map>
51 #include <exception>
52 using namespace std;
53 #include <stdexcept>
54 #include "StMessMgr.h"
55 #include "StThreeVectorD.hh"
56 
57 //#include "Sti/Base/Messenger.h"
58 #include "Sti/Base/Factory.h"
59 #include "Sti/StiPlanarShape.h"
60 #include "Sti/StiCylindricalShape.h"
61 #include "Sti/StiMaterial.h"
62 #include "Sti/StiPlacement.h"
63 #include "Sti/StiDetector.h"
64 #include "Sti/StiToolkit.h"
65 #include "Sti/StiIsActiveFunctor.h"
67 #include "StiRnD/Ist/StiIstIsActiveFunctor.h"
68 #include "StiRnD/Ist/StiIstDetectorBuilder.h"
69 //#include "Sti/StiElossCalculator.h"
70 #include "StiRnD/Ist/StiIstDetectorBuilder.h"
71 #include "StDetectorDbMaker/StiIst1HitErrorCalculator.h"
72 //#include "StSsdUtil/StSsdConfig.hh"
73 //#include "StSsdUtil/StSsdGeometry.hh"
74 //#include "StSsdUtil/StSsdWaferGeometry.hh"
75 //#include "StSsdDbMaker/StSsdDbMaker.h"
76 //#include "StSsdDbMaker/St_SsdDb_Reader.hh"
77 
79  : StiDetectorBuilder("Ist",active), _siMat(0), _hybridMat(0)
80 {
81  // Hit error parameters : it is set to 20 microns, in both x and y coordinates
82  //_hitCalculator1.setName("ist1HitError");
83  //_hitCalculator2.setName("ist2HitError");
84  //_hitCalculator3.setName("ist3HitError");
85 }
86 
87 StiIstDetectorBuilder::~StiIstDetectorBuilder()
88 {}
89 
90 void StiIstDetectorBuilder::loadDS(TDataSet& ds){
91  cout<<"StiIstDetectorBuilder::loadDS(TDataSet& ds) -I- started: "<<endl;
92  //_hitCalculator1.loadDS(ds);
93  //_hitCalculator2.loadDS(ds);
94  //_hitCalculator3.loadDS(ds);
95 }
96 
97 
99 {
100  int nRows = 1 ;
101  gMessMgr->Info() << "StiIstDetectorBuilder::buildDetectors() - I - Started "<<endm;
102 
103  setNRows(nRows);
104  if (StiVMCToolKit::GetVMC()) {useVMCGeometry();}
105 }
106 
107 //________________________________________________________________________________
109  cout << "StiIstDetectorBuilder::buildDetectors() -I- Use VMC geometry" << endl;
110  SetCurrentDetectorBuilder(this);
111 
112  // Build the material map
113  struct Material_t {
114  const Char_t *name;
115  StiMaterial **p;
116  };
117  Material_t map[] = {
118  {"AIR", &_gasMat},
119  {"SILICON", &_siMat},
120  {"SILICON", &_hybridMat}
121  };
122  Int_t M = sizeof(map)/sizeof(Material_t);
123  for (Int_t i = 0; i < M; i++) {
124  const TGeoMaterial *mat = gGeoManager->GetMaterial(map[i].name);
125  if (! mat) continue;
126  Double_t PotI = StiVMCToolKit::GetPotI(mat);
127  *map[i].p = add(new StiMaterial(mat->GetName(),
128  mat->GetZ(),
129  mat->GetA(),
130  mat->GetDensity(),
131  mat->GetDensity()*mat->GetRadLen(),
132  PotI));
133  }
134 
135  // Build the volume map and loop over all found volumes
136  const VolumeMap_t IstVolumes[] =
137  {
138  {"IBSS", "active silicon", "HALL_1/CAVE_1/IDSM_1/IBMO_1","",""},
139  {"IBSP", "inactive silicon","HALL_1/CAVE_1/IDSM_1/IBMO_1","",""}
140  };
141  Int_t NoIstVols = sizeof(IstVolumes)/sizeof(VolumeMap_t);
142  gGeoManager->RestoreMasterVolume();
143  gGeoManager->CdTop();
144  for (Int_t i = 0; i < NoIstVols; i++) {
145  gGeoManager->cd(IstVolumes[i].path);
146  TGeoNode *nodeT = gGeoManager->GetCurrentNode();
147  if (! nodeT) continue;;
148  StiVMCToolKit::LoopOverNodes(nodeT, IstVolumes[i].path, IstVolumes[i].name, MakeAverageVolume);
149  }
150 }
151 
152 void StiIstDetectorBuilder::AverageVolume(TGeoPhysicalNode *nodeP) {
153 
154  LOG_DEBUG << "StiDetectorBuilder::AverageVolume -I TGeoPhysicalNode\t" << nodeP->GetName() << endm;
155  //cout << "StiDetectorBuilder::AverageVolume -I TGeoPhysicalNode\t" << nodeP->GetName() << endl;
156 
157  // Ugh, have to hardwire
158  const Int_t NWAFERS = 12;
159 
160  TString nameP(nodeP->GetName());
161 
162  // decode detector ------------------------------
163  nameP.ReplaceAll("HALL_1/CAVE_1/","");
164  TString temp=nameP;
165  temp.ReplaceAll("IDSM_1/IBMO_1","");
166  int q=temp.Index("_");
167  temp.Replace(0,q+1,"");
168  TString num0=temp(0,2);
169  if(!num0.IsDigit()) num0=temp(0,1);
170  int layer=num0.Atoi();
171  q=temp.Index("_");
172  temp.Replace(0,q+1,"");
173  TString num1=temp(0,2);
174  if(!num1.IsDigit()) num1=temp(0,1);
175  int ladder=num1.Atoi();
176  q=temp.Index("_");
177  temp.Replace(0,q+1,"");
178  TString num2=temp(0,2);
179  if(!num2.IsDigit()) num2=temp(0,1);
180 // int wafer=num2.Atoi();
181  q=temp.Index("_");
182  temp.Replace(0,q+1,"");
183  TString num3=temp(0,1);
184  // int side=num3.Atoi();
185  if(ladder!=1) return;
186 
187  // Check whether this is an active volume
188  Bool_t ActiveVolume = kFALSE;
189  if (nodeP->GetVolume()->GetMedium()->GetParam(0) == 1) {
190  ActiveVolume = kTRUE;
191  }
192 
193  // Material definitions
194  TGeoMaterial *matP = nodeP->GetVolume()->GetMaterial();
195  Double_t PotI = StiVMCToolKit::GetPotI(matP);
196  static StiMaterial *matS = 0;
197  if (! matS) matS = add(new StiMaterial(matP->GetName(),
198  matP->GetZ(),
199  matP->GetA(),
200  matP->GetDensity(),
201  matP->GetDensity()*matP->GetRadLen(),
202  PotI));
203 // Double_t ionization = matS->getIonization();
204 // StiElossCalculator *ElossCalculator = new StiElossCalculator(matS->getZOverA(),
205 // ionization*ionization,
206 // matS->getA(),
207 // matS->getZ(),
208 // matS->getDensity());
209  // Extract volume geometry for this node
210  TGeoBBox *box = (TGeoBBox *) nodeP->GetShape();
211  StiShape *sh = new StiPlanarShape(nodeP->GetVolume()->GetName(), // Name
212  NWAFERS*box->GetDZ(), // halfDepth
213  box->GetDY(), // thickness
214  box->GetDX()); // halfWidth
215  add(sh);
216 
217  // Position information
218  TGeoHMatrix *hmat = nodeP->GetMatrix();
219  Double_t *xyz = hmat->GetTranslation();
220  Double_t *rot = hmat->GetRotationMatrix();
221  StThreeVectorD centerVector(xyz[0],xyz[1],xyz[2]);
222  StThreeVectorD normalVector(rot[1],rot[4],rot[7]);
223  //cout<<"centerVector: "<<centerVector<<endl;
224  //cout<<"normalVector: "<<normalVector<<endl;
225 
226  // Normalize normal vector, just in case....
227  normalVector /= normalVector.magnitude();
228 
229  // Volume positioning
230  StiPlacement *pPlacement = new StiPlacement;
231  Double_t phi = centerVector.phi();
232  Double_t phiD = normalVector.phi();
233  Double_t r = centerVector.perp();
234  pPlacement->setZcenter(0);
235  pPlacement->setLayerRadius(r);
236  /*
237  double layerAngleOffset=(wafer-NWAFERS/2.)/25.;
238  cout<<"offset: "<<layerAngleOffset<<endl;
239  double layerAngle=phi+layerAngleOffset;
240  cout<<"layerAngle: "<<layerAngle<<endl;
241  pPlacement->setLayerAngle(layerAngle);
242  */
243  if(nameP.Contains("IBSS")) pPlacement->setLayerAngle(phi);
244  if(nameP.Contains("IBSP")) pPlacement->setLayerAngle(phi-.05);
245  pPlacement->setRegion(StiPlacement::kMidRapidity);
246  pPlacement->setNormalRep(phiD, r*TMath::Cos(phi-phiD), r*TMath::Sin(phi-phiD));
247  assert(pPlacement);
248  //cout<<"normal radius: "<<pPlacement->getNormalRadius()<<endl;
249  //cout<<"normal ref angle: "<<pPlacement->getNormalRefAngle()<<endl;
250 
251  StiDetector *pDetector = getDetectorFactory()->getInstance();
252  pDetector->setName(nameP.Data());
253  pDetector->setIsOn(false);
254  //addLayer is used to "create" another layer
255  //if hits are from the inactive silicon (addLayer==2), they will not be used
256  Int_t addLayer =0;
257  if (ActiveVolume) {
258  pDetector->setIsActive(new StiIstIsActiveFunctor);
259  cout<<"active volume: "<<nameP<<endl;
260  addLayer = 1;
261  }
262  else {
263  pDetector->setIsActive(new StiNeverActiveFunctor);
264  cout<<"inactive volume: "<<nameP<<endl;
265  addLayer =2;
266  }
267  pDetector->setIsContinuousMedium(false);
268  pDetector->setIsDiscreteScatterer(true);
269  pDetector->setShape(sh);
270  pDetector->setPlacement(pPlacement);
271  pDetector->setGas(GetCurrentDetectorBuilder()->getGasMat());
272  pDetector->setMaterial(matS);
273 // pDetector->setElossCalculator(ElossCalculator);
274  pDetector->setHitErrorCalculator(StiIst1HitErrorCalculator::instance());
275 
276  // Adding detector, note that no keys are set in IST!
277  //add(ladder,wafer,pDetector);
278  add(addLayer,layer,pDetector);
279 
280  LOG_INFO << "StiIstDetectorBuilder: Added detector -I- " << pDetector->getName() << endm;
281 
282  // Whole bunch of debugging information
283  /*
284  Float_t rad2deg = 180.0/3.1415927;
285  cout << "===>NEW:IST:pDetector:Name = " << pDetector->getName() << endl;
286  cout << "===>NEW:IST:pPlacement:NormalRefAngle = " << pPlacement->getNormalRefAngle()*rad2deg << endl;
287  cout << "===>NEW:IST:pPlacement:NormalRadius = " << pPlacement->getNormalRadius() << endl;
288  cout << "===>NEW:IST:pPlacement:NormalYoffset = " << pPlacement->getNormalYoffset() << endl;
289  cout << "===>NEW:IST:pPlacement:CenterRefAngle = " << pPlacement->getCenterRefAngle()*rad2deg << endl;
290  cout << "===>NEW:IST:pPlacement:CenterRadius = " << pPlacement->getCenterRadius() << endl;
291  cout << "===>NEW:IST:pPlacement:CenterOrientation = " << pPlacement->getCenterOrientation()*rad2deg << endl;
292  cout << "===>NEW:IST:pPlacement:LayerRadius = " << pPlacement->getLayerRadius() << endl;
293  cout << "===>NEW:IST:pPlacement:LayerAngle = " << pPlacement->getLayerAngle()*rad2deg << endl;
294  cout << "===>NEW:IST:pPlacement:Zcenter = " << pPlacement->getZcenter() << endl;
295  cout << "===>NEW:IST:pDetector:Layer = " << layer << endl;
296  cout << "===>NEW:IST:pDetector:Ladder = " << ladder << endl;
297  cout << "===>NEW:IST:pDetector:Wafer = " << wafer << endl;
298  cout << "===>NEW:IST:pDetector:Side(defunct) = " << side << endl;
299  cout << "===>NEW:IST:pDetector:Active? = " << pDetector->isActive() << endl;
300  */
301 
302 }
303 
virtual void buildDetectors(StMaker &source)
function object for determine a Ist padrow&#39;s active regions
StiIstDetectorBuilder(bool active, bool buildIdealGeom=true)
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
virtual void setNRows(UInt_t nRows)
Abstract interface for a STI toolkit.
void setName(const string &newName)
Set the name of the object.
Definition: Named.cxx:15
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22
Class implements an object which is never active.