StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiSsdDetectorBuilder.cxx
1 // $Id: StiSsdDetectorBuilder.cxx,v 1.40 2015/02/03 10:21:17 smirnovd Exp $
2 //
3 // $Log: StiSsdDetectorBuilder.cxx,v $
4 // Revision 1.40 2015/02/03 10:21:17 smirnovd
5 // Check for valid gGeoManager in buildDetectors instead of constructor
6 //
7 // This is a fixup of the change committed on 2015-01-30 16:33:59 (8b14dfaf)
8 // The detector builder requires a valid TGeoManager object to build detector
9 // geometries. However in the current StiMaker gGeoManager is not available when
10 // detector builder is created. It becomes available just before the
11 // ::buildDetectors() is called in StiMasterDetectorBuilder::build()
12 //
13 // Revision 1.39 2015/01/30 21:34:00 smirnovd
14 // StiXxxDetectorBuilder: Added a check for valid global object of TGeoManager. The detector builder is required one and cannot proceed if one does not exist
15 //
16 // Revision 1.38 2014/12/02 23:25:54 smirnovd
17 // StiXxxDetectorBuilder: Removed deprecated calls to dummy methods
18 //
19 // Revision 1.37 2014/08/22 17:52:18 perev
20 // StiEloss calculator creates in material now
21 //
22 // Revision 1.36 2013/03/22 23:58:51 fisyak
23 // Remove name[50]
24 //
25 // Revision 1.35 2011/04/22 22:00:39 fisyak
26 // warn off
27 //
28 // Revision 1.34 2010/08/25 21:57:42 fisyak
29 // Get rid off access to specfic detector tracking parameters which usage has been disable since 2008/06/11
30 //
31 // Revision 1.33 2009/03/16 13:50:15 fisyak
32 // Move out all Sti Chairs into StDetectorDb
33 //
34 // Revision 1.32 2008/08/12 20:54:40 fisyak
35 // If StSsdBarrel does not exist then take SSD as dead material from whatever exist in GEANT
36 //
37 // Revision 1.31 2008/06/12 16:36:55 fisyak
38 // Remove all SSD endcap volumes
39 //
40 // Revision 1.30 2008/06/11 22:04:39 fisyak
41 // Add dead material
42 //
43 // Revision 1.29 2008/04/03 20:04:22 fisyak
44 // Straighten out DB access via chairs
45 //
46 // Revision 1.28 2007/07/12 20:39:13 fisyak
47 // Remove default errors for SSD
48 //
49 // Revision 1.27 2007/03/21 17:53:38 fisyak
50 // make use for new StSsdBarrel
51 //
52 // Revision 1.26 2006/10/17 20:18:05 fisyak
53 // Add handle when SVTT mother volume is missing
54 //
55 // Revision 1.25 2006/10/16 20:31:17 fisyak
56 // Clean dependencies from Sti useless classes
57 //
58 // Revision 1.24 2006/10/09 15:47:59 fisyak
59 // use Normal represantation, remove StiDedxCalculator
60 //
61 // Revision 1.23 2006/06/28 18:51:46 fisyak
62 // Add loading of tracking and hit error parameters from DB
63 //
64 // Revision 1.22 2006/05/31 04:00:02 fisyak
65 // remove SSD ladder mother volume
66 //
67 // Revision 1.21 2005/06/21 16:35:01 lmartin
68 // DetectorBuilder updated with the correct methods from StSsdUtil
69 //
70 // Revision 1.20 2005/06/21 15:31:47 lmartin
71 // CVS tags added
72 //
79 #include <stdio.h>
80 #include <assert.h>
81 #include <map>
82 using namespace std;
83 #include <stdexcept>
84 #include "StMessMgr.h"
85 #include "StThreeVectorD.hh"
86 #include "tables/St_ssdDimensions_Table.h"
87 #include "tables/St_ssdConfiguration_Table.h"
88 #include "tables/St_ssdWafersPosition_Table.h"
89 
90 #include "Sti/Base/Factory.h"
91 #include "Sti/StiPlanarShape.h"
92 #include "Sti/StiCylindricalShape.h"
93 #include "Sti/StiMaterial.h"
94 #include "Sti/StiPlacement.h"
95 #include "Sti/StiDetector.h"
96 #include "Sti/StiToolkit.h"
97 #include "StDetectorDbMaker/StiHitErrorCalculator.h"
98 #include "Sti/StiIsActiveFunctor.h"
100 #include "StiSsd/StiSsdIsActiveFunctor.h"
101 #include "StiSsd/StiSsdDetectorBuilder.h"
102 #include "StSsdUtil/StSsdBarrel.hh"
103 #include "StDetectorDbMaker/StiSsdHitErrorCalculator.h"
104 StiSsdDetectorBuilder::StiSsdDetectorBuilder(bool active)
105  : StiDetectorBuilder("Ssd",active), _siMat(0), _hybridMat(0)
106 {
107  // Hit error parameters : it is set to 20 microns, in both x and y coordinates
108 }
109 
110 StiSsdDetectorBuilder::~StiSsdDetectorBuilder()
111 {}
112 
113 
115 {
116  if (!gGeoManager)
117  throw runtime_error("StiSsdDetectorBuilder::StiSsdDetectorBuilder() "
118  "- Cannot build Sti geometry due to missing global object of TGeoManager class. "
119  "Make sure STAR geometry is properly loaded with BFC AgML option");
120 
121  gMessMgr->Info() << "StiSsdDetectorBuilder::buildDetectors() - I - Started "<<endm;
122  StSsdBarrel *mySsd = StSsdBarrel::Instance();
123  if (! mySsd) {// no active SSD
124  gMessMgr->Info() << "StiSsdDetectorBuilder::buildDetectors() - I - there is no SSD barrel - take whatever exist in GEANT" << endm;
125  StiVMCToolKit::GetVMC();
126  return;
127  }
128  int nRows = 1 ;
129  setNRows(nRows);
130  if (! _gasMat)
131  _gasMat = add(new StiMaterial("SsdAir",7.3, 14.61, 0.001205, 30420.*0.001205, 7.3*12.e-9));
132  if (! _siMat)
133  _siMat = add(new StiMaterial("SsdSi",14., 28.0855, 2.33, 21.82, 14.*12.*1e-9));
134  if (! _hybridMat)
135  _hybridMat = add(new StiMaterial("SsdHyb",14., 28.0855, 2.33, 21.82, 14.*12.*1e-9));
136 
137  //gMessMgr->Info() << "StiSsdDetectorBuilder::buildMaterials() - I - Done "<<endm;
138  cout << "StiSsdDetectorBuilder::buildMaterials() - I - Done "<<endl;
139  ssdDimensions_st *dimensions = mySsd->getDimensions();
140  Int_t NL = mySsd->getNumberOfLadders();
141  Int_t NW = mySsd->getNWaferPerLadder();
142  StSsdLadder *Ladder = mySsd->getLadder(0);
143  assert(Ladder);
144  StSsdWafer *Wafer1 = Ladder->getWafer(0);
145  StSsdWafer *Wafer2 = Ladder->getWafer(NW-1);
146  assert(Wafer1 && Wafer2);
147  Double_t width = TMath::Abs(Wafer1->x(2) - Wafer2->x(2))/2. + 2;
148  StiPlanarShape *ladderShape = new StiPlanarShape("SsdLadder",
149  width,
150  0.34, // increas by a factor ~10 2*dimensions->waferHalfThickness,
151  dimensions->waferHalfLength );
152  add(ladderShape);
153  Int_t layer = 0;
154  setNSectors(layer,NL);
161  for (Int_t ladder = 0; ladder < NL; ladder++) {
162  Ladder = mySsd->getLadder(ladder);
163  if (! Ladder) continue;
164  Wafer1 = Ladder->getWafer(0);
165  Wafer2 = Ladder->getWafer(NW-1);
166  if (! Wafer1 || ! Wafer2) continue;
167  StThreeVectorD centerVector1(Wafer1->x(0),Wafer1->x(1),Wafer1->x(2));
168  StThreeVectorD normalVector1(Wafer1->n(0),Wafer1->n(1),Wafer1->n(2));
169  StThreeVectorD centerVector2(Wafer2->x(0),Wafer2->x(1),Wafer2->x(2));
170  StThreeVectorD normalVector2(Wafer2->n(0),Wafer2->n(1),Wafer2->n(2));
171  StThreeVectorD centerVector = centerVector1 + centerVector2; centerVector *= 0.5;
172  StThreeVectorD normalVector = normalVector1 + normalVector2; normalVector *= 0.5;
173  Double_t prod = centerVector*normalVector;
174  if (prod < 0) normalVector *= -1;
175  double phi = centerVector.phi();
176  double phiD = normalVector.phi();
177  double r = centerVector.perp();
178  cout <<"Det Id = "<<Wafer1->getId()<<"\tcv\t:"<<centerVector<<"\tphi:\t"<<phi<<"\tr:\t"<<r<<"\tz:\t" << centerVector.z()<< endl;
179  StiPlacement *pPlacement = new StiPlacement;
180  pPlacement->setZcenter(centerVector.z());
181  pPlacement->setLayerRadius(r); //this is only used for ordering in detector container...
182  pPlacement->setLayerAngle(phi); //this is only used for ordering in detector container...
183  pPlacement->setRegion(StiPlacement::kMidRapidity);
184  // pPlacement->setNormalRep(phi, r, 0.); //but we have to use this to fix ladders 20 and 12
185  pPlacement->setNormalRep(phiD, r*TMath::Cos(phi-phiD), r*TMath::Sin(phi-phiD));
186  StiDetector *pLadder = _detectorFactory->getInstance();
187  pLadder->setName(Form("Ssd/Layer_%d/Ladder_%d/Wafers", layer, ladder));
188  pLadder->setIsActive(new StiIsActiveFunctor(_active));
189  pLadder->setGas(_gasMat);
190  pLadder->setMaterial(_siMat);
191  pLadder->setShape(ladderShape);
192  pLadder->setPlacement(pPlacement);
193  pLadder->setHitErrorCalculator(StiSsdHitErrorCalculator::instance());
194  pLadder->setKey(1,0);
195  pLadder->setKey(2,ladder-1);
196  add(layer,ladder,pLadder);
197  }
198  useVMCGeometry();
199 }
200 //________________________________________________________________________________
201 void StiSsdDetectorBuilder::useVMCGeometry() {
202  cout << "StiSsdDetectorBuilder::buildDetectors() -I- Use VMC geometry" << endl;
203  SetCurrentDetectorBuilder(this);
204  struct Material_t {
205  const Char_t *name;
206  StiMaterial **p;
207  };
208  Material_t map[] = {
209  {"AIR", &_gasMat},
210  {"SILICON", &_siMat},
211  {"SILICON", &_hybridMat}
212  };
213  Int_t M = sizeof(map)/sizeof(Material_t);
214  for (Int_t i = 0; i < M; i++) {
215  const TGeoMaterial *mat = gGeoManager->GetMaterial(map[i].name);
216  if (! mat) continue;
217  Double_t PotI = StiVMCToolKit::GetPotI(mat);
218  *map[i].p = add(new StiMaterial(mat->GetName(),
219  mat->GetZ(),
220  mat->GetA(),
221  mat->GetDensity(),
222  mat->GetDensity()*mat->GetRadLen(),
223  PotI));
224  }
225  const VolumeMap_t SsdVolumes[] = {
226  // SSD
227  // {"SFMO", "the mother of all Silicon Strip Detector volumes","HALL_1/CAVE_1/SVTT_1/SFMO_1","",""}, // 17.466824 [kg]
228  // {"SCMP","SSD mounting plate inserted in the cone","HALL_1/CAVE_1/SVTT_1/SFMO_1/SCMP_1-8","",""}, // 0.024494 [kg]
229  // {"SCVM","SSD V-shape mouting piece","HALL_1/CAVE_1/SVTT_1/SFMO_1/SCVM_1-8/*","",""}, // 0.057931 [kg]
230  // {"SSLT","the linking (sector to the cone) tube","HALL_1/CAVE_1/SVTT_1/SFMO_1/SSLT_1-8","",""}, // 0.027415 [kg]
231  // {"SSLB","the linking (sector to the cone)","HALL_1/CAVE_1/SVTT_1/SFMO_1/SSLB_1-8","",""}, // 0.073710 [kg]
232  // {"SSRS","the side of the small rib","HALL_1/CAVE_1/SVTT_1/SFMO_1/SSRS_1-4","",""}, // 0.462138 [kg]
233  // {"SSRT","the top of the side rib","HALL_1/CAVE_1/SVTT_1/SFMO_1/SSRT_1-4","",""}, // 0.172237 [kg]
234  // {"SSSS","Side parts of the small sectors","HALL_1/CAVE_1/SVTT_1/SFMO_1/SSSS_1-4","",""}, // 0.462138 [kg]
235  // {"SSST","Top parts of the small sectors","HALL_1/CAVE_1/SVTT_1/SFMO_1/SSST_1-4","",""}, // 0.172237 [kg]
236  {"SFLM","the mother of the ladder","HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/*","",""} // 0.546171 [kg]
237  // {"SFSM","the structure mother volume","HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/SFSM_1/*","",""} // 0.451003 [kg]
238  // {"SFDM","the detectors and adcs mother volume","HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/SFDM_1/*","",""} // 0.095168 [kg]
239  // {"SFSD","the strip detector", "HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/SFDM_1/SFSW_1-16/SFSD_1","ssd",""}// 0.002041 [kg]
240  };
241  Int_t NoSsdVols = sizeof(SsdVolumes)/sizeof(VolumeMap_t);
242  TString pathT("HALL_1/CAVE_1");
243  gGeoManager->RestoreMasterVolume();
244  gGeoManager->CdTop();
245  // Check that SVTT_1/SFMO_1 exist
246  TString path("");
247  for (Int_t i = 0; i < NoSsdVols; i++) {
248  gGeoManager->RestoreMasterVolume();
249  gGeoManager->CdTop();
250  if (gGeoManager->cd(pathT)) {
251  path = pathT;
252  TGeoNode *nodeT = gGeoManager->GetCurrentNode();
253  if (! nodeT) continue;;
254  StiVMCToolKit::LoopOverNodes(nodeT, path, SsdVolumes[i].name, MakeAverageVolume);
255  } else gMessMgr->Info() << "StiSsdDetectorBuilder::useVMCGeometry skip node " << pathT.Data() << endm;
256  }
257 }
258 //________________________________________________________________________________
259 ssdWafersPosition_st *StiSsdDetectorBuilder::ssdWafersPosition(Int_t Id, St_ssdWafersPosition *wafers) {
260  Int_t N = wafers->GetNRows();
261  ssdWafersPosition_st *wafer = wafers->GetTable();
262  for (Int_t i = 0; i < N; i++, wafer++) if (Id == wafer->id) return wafer;
263  return 0;
264 }
virtual void buildDetectors(StMaker &source)
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
virtual void setNRows(UInt_t nRows)
function object for determine a detector&#39;s active regions
Abstract interface for a STI toolkit.
void setName(const string &newName)
Set the name of the object.
Definition: Named.cxx:15