StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiSstDetectorBuilder.cxx
1 #include <assert.h>
2 #include <sstream>
3 #include <string>
4 
5 #include "TGeoVolume.h"
6 #include "TGeoMatrix.h"
7 #include "TVector3.h"
8 
9 #include "StMessMgr.h"
10 #include "tables/St_ssdDimensions_Table.h"
11 #include "tables/St_ssdConfiguration_Table.h"
12 #include "tables/St_ssdWafersPosition_Table.h"
13 
14 #include "StEvent/StEnumerations.h"
15 #include "Sti/Base/Factory.h"
16 #include "Sti/StiPlanarShape.h"
17 #include "Sti/StiCylindricalShape.h"
18 #include "Sti/StiMaterial.h"
19 #include "Sti/StiPlacement.h"
20 #include "Sti/StiDetector.h"
21 #include "Sti/StiToolkit.h"
22 #include "StiSsd/StiSstDetectorBuilder.h"
24 #include "StiSsd/StiSsdIsActiveFunctor.h"
25 #include "StSsdUtil/StSstConsts.h"
26 #include "StDetectorDbMaker/StiSstHitErrorCalculator.h"
27 
28 
38 StiSstDetectorBuilder::StiSstDetectorBuilder(bool active, bool buildIdealGeom)
39  : StiDetectorBuilder("Sst", active), mBuildIdealGeom(buildIdealGeom), mSstDb(0)
40 {
41  setGroupId(kSstId);
42 }
43 
44 
49 {
50  //StSsdBarrel *mySsd = StSsdBarrel::Instance();
51 
52  if (!gGeoManager)
53  throw runtime_error("StiSstDetectorBuilder::buildDetectors() "
54  "- Cannot build Sti geometry due to missing global object of TGeoManager class. "
55  "Make sure STAR geometry is properly loaded with BFC AgML option");
56 
57  if (!mBuildIdealGeom) {
58 
59  if (!gStSstDbMaker) {
60  LOG_ERROR << "StiSstDetectorBuilder::buildDetectors() - SST geometry was requested from "
61  "DB but no StSstDb object found. Check for sstDb option in BFC chain" << endm;
62  exit(EXIT_FAILURE);
63  }
64 
65  mSstDb = (StSstDbMaker*) gStSstDbMaker;
66  assert(mSstDb);
67 
68  LOG_INFO << "StiSstDetectorBuilder::buildDetectors() - Will build SST geometry from DB tables" << endm;
69  }
70 
71  SetCurrentDetectorBuilder(this);
72 
73  // Gas material must be defined. Here we use air properties
74  const TGeoMaterial* geoMat = gGeoManager->GetMaterial("AIR");
75 
76  _gasMat = geoMat ? add(new StiMaterial(geoMat->GetName(), geoMat->GetZ(), geoMat->GetA(), geoMat->GetDensity(), geoMat->GetRadLen()))
77  : add(new StiMaterial("AIR", 7.3, 14.61, 0.001205, 30420.));
78 
79  if (StiVMCToolKit::GetVMC()) {
82  }
83 }
84 
85 
93 {
94  // Define silicon material used in manual construction of sensitive layers in this builder
95  const TGeoMaterial* geoMat = gGeoManager->GetMaterial("SILICON");
96 
97  StiMaterial* silicon = geoMat ? add(new StiMaterial(geoMat->GetName(), geoMat->GetZ(), geoMat->GetA(), geoMat->GetDensity(), geoMat->GetRadLen()))
98  : add(new StiMaterial("SILICON", 14, 28.0855, 2.33, 9.36) );
99 
100  // Build active sti volumes for SST sensors
101  int stiRow = getNRows(); // Put all sensitive volumes in the same (and next available) Sti row
102  // Use the "middle" sensor on the ladder to extract alignment corrections from DB
103  int iSensor = floor(kSstNumSensorsPerLadder/2);
104 
105  for (int iLadder = 1; iLadder <= kSstNumLadders; ++iLadder)
106  {
107  std::string geoPath( formTGeoPath(iLadder, iSensor) );
108 
109  if ( geoPath.empty() ) {
110  LOG_WARN << "StiSstDetectorBuilder::useVMCGeometry() - Cannot find path to SFSD (SST sensitive) node. Skipping to next ladder..." << endm;
111  continue;
112  }
113 
114  TGeoVolume* sensorVol = gGeoManager->GetCurrentNode()->GetVolume();
115  TGeoHMatrix sensorMatrix( *gGeoManager->MakePhysicalNode(geoPath.c_str())->GetMatrix() );
116 
117  // Temporarily save the translation for this sensor in Z so, we can center
118  // the newly built sensors at Z=0 (in ideal geometry) later
119  double idealOffsetZ = sensorMatrix.GetTranslation()[2];
120 
121  if (!mBuildIdealGeom) {
122  const TGeoHMatrix* sensorMatrixDb = mSstDb->getHMatrixSensorOnGlobal(iLadder, iSensor);
123 
124  if (!sensorMatrixDb) {
125  LOG_WARN << "StiSstDetectorBuilder::useVMCGeometry() - Cannot get SST sensor position matrix. Skipping to next ladder..." << endm;
126  continue;
127  }
128 
129  sensorMatrix = *sensorMatrixDb;
130  }
131 
132  // Update the global translation in Z so that the new volumes are centered at Z=0
133  sensorMatrix.SetDz(sensorMatrix.GetTranslation()[2] - idealOffsetZ);
134 
135  TGeoBBox *sensorBBox = (TGeoBBox*) sensorVol->GetShape();
136 
137  // XXX:ds: Need to verify the constant for sensor spacing
138  double sensorLength = kSstNumSensorsPerLadder * (sensorBBox->GetDZ() + 0.02); // halfDepth + 0.02 ~= (dead edge + sensor gap)/2
139  StiShape *stiShape = new StiPlanarShape(geoPath.c_str(), sensorLength, 2*sensorBBox->GetDY(), sensorBBox->GetDX());
140 
141  StiPlacement *pPlacement= new StiPlacement(sensorMatrix);
142 
143  // Build final detector object
144  StiDetector *stiDetector = getDetectorFactory()->getInstance();
145  StiIsActiveFunctor* isActive = _active ? new StiSsdIsActiveFunctor :
146  static_cast<StiIsActiveFunctor*>(new StiNeverActiveFunctor);
147 
148  stiDetector->setProperties(geoPath, isActive, stiShape, pPlacement, getGasMat(), silicon);
149  stiDetector->setHitErrorCalculator(StiSstHitErrorCalculator::instance());
150 
151  add(stiRow, iLadder-1, stiDetector);
152  }
153 }
154 
155 
182 {
183  // StiCylindricalShape(const string &name, float halfDepth_, float thickness_, float outerRadius_, float openingAngle_)
184  StiCylindricalShape* sfmoCntrInnShape = new StiCylindricalShape("SFMO_CNTR_INN", fabs(34.25+34.25)/2., 23.5-23.2, 23.5, 2*M_PI);
185  StiCylindricalShape* sfmoCntrMidShape = new StiCylindricalShape("SFMO_CNTR_MID", fabs(34.25+34.25)/2., 25.8-23.5, 25.8, 2*M_PI);
186  StiCylindricalShape* sfmoCntrOutShape = new StiCylindricalShape("SFMO_CNTR_OUT", fabs(34.25+34.25)/2., 27.0-25.8, 27.0, 2*M_PI);
187 
188  StiCylindricalShape* sfmoLeftInnShape = new StiCylindricalShape("SFMO_LEFT_INN", fabs(51.50-34.25)/2., 23.5-22.2, 23.5, 2*M_PI);
189  StiCylindricalShape* sfmoLeftMidShape = new StiCylindricalShape("SFMO_LEFT_MID", fabs(49.50-34.25)/2., 25.0-23.5, 25.0, 2*M_PI);
190  StiCylindricalShape* sfmoLeftOutShape = new StiCylindricalShape("SFMO_LEFT_OUT", fabs(49.50-34.25)/2., 26.5-25.0, 26.5, 2*M_PI);
191 
192  StiCylindricalShape* sfmoRghtInnShape = new StiCylindricalShape("SFMO_RGHT_INN", fabs(51.50-34.25)/2., 23.5-22.2, 23.5, 2*M_PI);
193  StiCylindricalShape* sfmoRghtMidShape = new StiCylindricalShape("SFMO_RGHT_MID", fabs(49.50-34.25)/2., 25.0-23.5, 25.0, 2*M_PI);
194  StiCylindricalShape* sfmoRghtOutShape = new StiCylindricalShape("SFMO_RGHT_OUT", fabs(49.50-34.25)/2., 26.5-25.0, 26.5, 2*M_PI);
195 
196  // StiPlacement(float normRefAngle, float normRadius, float normYOffset, float centralZ, StiRegion region)
197  StiPlacement* sfmoCntrInnPlacement = new StiPlacement(0, (23.5+23.2)/2., 0, (-34.25+34.25)/2.);
198  StiPlacement* sfmoCntrMidPlacement = new StiPlacement(0, (25.8+23.5)/2., 0, (-34.25+34.25)/2.);
199  StiPlacement* sfmoCntrOutPlacement = new StiPlacement(0, (27.0+25.8)/2., 0, (-34.25+34.25)/2.);
200 
201  StiPlacement* sfmoLeftInnPlacement = new StiPlacement(0, (23.5+22.2)/2., 0, (-51.50-34.25)/2.);
202  StiPlacement* sfmoLeftMidPlacement = new StiPlacement(0, (25.0+23.5)/2., 0, (-49.50-34.25)/2.);
203  StiPlacement* sfmoLeftOutPlacement = new StiPlacement(0, (26.5+25.0)/2., 0, (-49.50-34.25)/2.);
204 
205  StiPlacement* sfmoRghtInnPlacement = new StiPlacement(0, (23.5+22.2)/2., 0, (+51.50+34.25)/2.);
206  StiPlacement* sfmoRghtMidPlacement = new StiPlacement(0, (25.0+23.5)/2., 0, (+49.50+34.25)/2.);
207  StiPlacement* sfmoRghtOutPlacement = new StiPlacement(0, (26.5+25.0)/2., 0, (+49.50+34.25)/2.);
208 
209  // StiMaterial(const string &name, double z, double a, double density, double X0)
210  StiMaterial* sfmoCntrInnMaterial = new StiMaterial("SFMO_CNTR_INN", 7.38471, 14.7875, 0.7536000, 28128.1);
211  StiMaterial* sfmoCntrMidMaterial = new StiMaterial("SFMO_CNTR_MID", 7.29364, 14.5971, 0.0147153, 30146.9);
212  StiMaterial* sfmoCntrOutMaterial = new StiMaterial("SFMO_CNTR_OUT", 7.27831, 14.5655, 0.0372666, 29681.4);
213 
214  StiMaterial* sfmoLeftInnMaterial = new StiMaterial("SFMO_LEFT_INN", 7.90551, 15.8598, 0.5131150, 21711.5);
215  StiMaterial* sfmoLeftMidMaterial = new StiMaterial("SFMO_LEFT_MID", 7.67447, 15.3544, 0.3013760, 23510.2);
216  StiMaterial* sfmoLeftOutMaterial = new StiMaterial("SFMO_LEFT_OUT", 7.52669, 15.0602, 0.2235500, 25904.3);
217 
218  StiMaterial* sfmoRghtInnMaterial = new StiMaterial("SFMO_RGHT_INN", 7.92641, 15.9019, 0.5298270, 21402.6);
219  StiMaterial* sfmoRghtMidMaterial = new StiMaterial("SFMO_RGHT_MID", 7.66531, 15.3361, 0.2953080, 23582.3);
220  StiMaterial* sfmoRghtOutMaterial = new StiMaterial("SFMO_RGHT_OUT", 7.53069, 15.0682, 0.2273420, 25831.5);
221 
222  // Define a prefix for detector name for consistency with automatic TGeo to Sti conversion
223  std::string pfx("/HALL_1/CAVE_1/TpcRefSys_1/IDSM_1/");
224 
225  StiDetector* stiDetector = getDetectorFactory()->getInstance();
226  stiDetector->setProperties(pfx+"SFMO_CNTR_INN", new StiNeverActiveFunctor, sfmoCntrInnShape, sfmoCntrInnPlacement, getGasMat(), sfmoCntrInnMaterial);
227  add(getNRows(), 0, stiDetector);
228 
229  stiDetector = getDetectorFactory()->getInstance();
230  stiDetector->setProperties(pfx+"SFMO_CNTR_MID", new StiNeverActiveFunctor, sfmoCntrMidShape, sfmoCntrMidPlacement, getGasMat(), sfmoCntrMidMaterial);
231  add(getNRows(), 0, stiDetector);
232 
233  stiDetector = getDetectorFactory()->getInstance();
234  stiDetector->setProperties(pfx+"SFMO_CNTR_OUT", new StiNeverActiveFunctor, sfmoCntrOutShape, sfmoCntrOutPlacement, getGasMat(), sfmoCntrOutMaterial);
235  add(getNRows(), 0, stiDetector);
236 
237 
238  stiDetector = getDetectorFactory()->getInstance();
239  stiDetector->setProperties(pfx+"SFMO_LEFT_INN", new StiNeverActiveFunctor, sfmoLeftInnShape, sfmoLeftInnPlacement, getGasMat(), sfmoLeftInnMaterial);
240  add(getNRows(), 0, stiDetector);
241 
242  stiDetector = getDetectorFactory()->getInstance();
243  stiDetector->setProperties(pfx+"SFMO_LEFT_MID", new StiNeverActiveFunctor, sfmoLeftMidShape, sfmoLeftMidPlacement, getGasMat(), sfmoLeftMidMaterial);
244  add(getNRows(), 0, stiDetector);
245 
246  stiDetector = getDetectorFactory()->getInstance();
247  stiDetector->setProperties(pfx+"SFMO_LEFT_OUT", new StiNeverActiveFunctor, sfmoLeftOutShape, sfmoLeftOutPlacement, getGasMat(), sfmoLeftOutMaterial);
248  add(getNRows(), 0, stiDetector);
249 
250 
251  stiDetector = getDetectorFactory()->getInstance();
252  stiDetector->setProperties(pfx+"SFMO_RGHT_INN", new StiNeverActiveFunctor, sfmoRghtInnShape, sfmoRghtInnPlacement, getGasMat(), sfmoRghtInnMaterial);
253  add(getNRows(), 0, stiDetector);
254 
255  stiDetector = getDetectorFactory()->getInstance();
256  stiDetector->setProperties(pfx+"SFMO_RGHT_MID", new StiNeverActiveFunctor, sfmoRghtMidShape, sfmoRghtMidPlacement, getGasMat(), sfmoRghtMidMaterial);
257  add(getNRows(), 0, stiDetector);
258 
259  stiDetector = getDetectorFactory()->getInstance();
260  stiDetector->setProperties(pfx+"SFMO_RGHT_OUT", new StiNeverActiveFunctor, sfmoRghtOutShape, sfmoRghtOutPlacement, getGasMat(), sfmoRghtOutMaterial);
261  add(getNRows(), 0, stiDetector);
262 }
263 
264 
270 std::string StiSstDetectorBuilder::formTGeoPath(int ladder, int sensor)
271 {
272  const std::string tgeoPathToMother("/HALL_1/CAVE_1/TpcRefSys_1/IDSM_1/SFMO_1");
273 
274  std::ostringstream geoPath;
275 
276  geoPath << tgeoPathToMother << "/SFLM_" << ladder
277  << "/SFSW_" << sensor
278  << "/SFSL_1/SFSD_1";
279 
280  bool found = gGeoManager->cd( geoPath.str().c_str() );
281 
282  // Look for sensors staged in the mother volume
283  if ( !found )
284  {
285  geoPath.str("");
286  geoPath << tgeoPathToMother << "/SFSW_" << (ladder - 1)*16 + sensor
287  << "/SFSL_1/SFSD_1";
288  found = gGeoManager->cd( geoPath.str().c_str() );
289  }
290 
291  return found ? geoPath.str() : "";
292 }
static std::string formTGeoPath(int ladder, int sensor)
Returns a TGeo path to the sensor in the given ladder.
void setProperties(std::string name, StiIsActiveFunctor *activeFunctor, StiShape *shape, StiPlacement *placement, StiMaterial *gas, StiMaterial *material)
virtual void buildDetectors(StMaker &source)
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
function object for determine a detector&#39;s active regions
Abstract interface for a STI toolkit.
static const TGeoHMatrix * getHMatrixSensorOnGlobal(int ladder, int sensor)
StiSstDetectorBuilder(bool active, bool buildIdealGeom=true)
Class implements an object which is never active.