12 #include <vxd/geometry/GeoCache.h>
13 #include <vxd/simulation/SensitiveDetectorBase.h>
14 #include <framework/gearbox/Unit.h>
15 #include <framework/logging/Logger.h>
20 #include <G4LogicalVolume.hh>
21 #include <G4VPhysicalVolume.hh>
22 #include <G4NavigationHistory.hh>
23 #include <G4Transform3D.hh>
36 m_vxdAlignments.addCallback(
this, &VXD::GeoCache::setupReconstructionTransformations);
39 void GeoCache::clear()
48 m_halfShellPlacements.clear();
49 m_ladderPlacements.clear();
50 m_sensorPlacements.clear();
55 id.setSegmentNumber(0);
56 SensorInfoMap::const_iterator info = m_sensorInfo.find(
id);
57 return (info != m_sensorInfo.end());
60 const vector<VxdID> GeoCache::getListOfSensors()
const
62 vector<VxdID> sensors;
63 for (
auto entry : m_sensorInfo)
64 sensors.push_back(entry.first);
70 id.setSegmentNumber(0);
71 SensorInfoMap::const_iterator info = m_sensorInfo.find(
id);
72 if (info == m_sensorInfo.end()) {
73 B2WARNING(
"VXD Sensor " <<
id <<
" does not exist.");
74 return *(m_sensorInfo.begin()->second);
76 return *(info->second);
79 void GeoCache::findVolumes(G4VPhysicalVolume* envelope)
84 G4NavigationHistory nav;
87 stack<G4VPhysicalVolume*> volumes;
88 volumes.push(envelope);
91 while (!volumes.empty()) {
92 G4VPhysicalVolume* physical = volumes.top();
104 nav.NewLevel(physical);
106 G4LogicalVolume* logical = physical->GetLogicalVolume();
113 if (!info) B2FATAL(
"No SensorInfo found for Volume " << logical->GetName());
116 const G4AffineTransform g4transform = nav.GetTopTransform().Inverse();
117 TGeoHMatrix transform;
118 double rotation[9] = {
119 g4transform[0], g4transform[4], g4transform[8],
120 g4transform[1], g4transform[5], g4transform[9],
121 g4transform[2], g4transform[6], g4transform[10]
123 transform.SetRotation(rotation);
124 transform.SetDx(g4transform[12]*Unit::mm);
125 transform.SetDy(g4transform[13]*Unit::mm);
126 transform.SetDz(g4transform[14]*Unit::mm);
127 info->setTransformation(transform);
128 info->setTransformation(transform,
true);
133 int nDaughters = logical->GetNoDaughters();
138 for (
int i = nDaughters - 1; i >= 0; --i) {
139 G4VPhysicalVolume* daughter = logical->GetDaughter(i);
140 volumes.push(daughter);
145 setupReconstructionTransformations();
153 VxdID ladderID = sensorID;
155 VxdID layerID = ladderID;
158 m_sensorInfo[sensorID] = sensorinfo;
160 switch (sensorinfo->
getType()) {
161 case SensorInfoBase::PXD:
162 m_pxdLayers.insert(layerID);
164 case SensorInfoBase::SVD:
165 m_svdLayers.insert(layerID);
167 case SensorInfoBase::TEL:
168 m_telLayers.insert(layerID);
171 B2FATAL(
"Cannot use anything else as SensorTypes PXD, SVD, or TEL when creating VXD Sensors");
173 m_ladders[layerID].insert(ladderID);
174 m_sensors[ladderID].insert(sensorID);
180 case SensorInfoBase::PXD:
182 case SensorInfoBase::SVD:
184 case SensorInfoBase::TEL:
187 std::set<VxdID> allLayers = m_pxdLayers;
188 allLayers.insert(m_svdLayers.begin(), m_svdLayers.end());
189 allLayers.insert(m_telLayers.begin(), m_telLayers.end());
194 const set<VxdID>& GeoCache::getLadders(
VxdID layer)
const
197 layer.setLadderNumber(0);
198 layer.setSensorNumber(0);
199 layer.setSegmentNumber(0);
200 SensorHierachy::const_iterator info = m_ladders.find(layer);
201 if (info == m_ladders.end()) B2FATAL(
"VXD Layer " << layer <<
"does not exist.");
205 const set<VxdID>& GeoCache::getSensors(
VxdID ladder)
const
208 ladder.setSensorNumber(0);
209 ladder.setSegmentNumber(0);
210 SensorHierachy::const_iterator info = m_sensors.find(ladder);
211 if (info == m_sensors.end()) B2FATAL(
"VXD Ladder " << ladder <<
"does not exist.");
217 static unique_ptr<GeoCache> instance(
new GeoCache());
221 void GeoCache::addSensorPlacement(
VxdID ladder,
VxdID sensor,
const G4Transform3D& placement)
223 m_sensorPlacements[ladder].push_back(std::make_pair(sensor, g4Transform3DToTGeo(placement)));
226 void GeoCache::addLadderPlacement(
VxdID halfShell,
VxdID ladder,
const G4Transform3D& placement)
228 m_ladderPlacements[halfShell].push_back(std::make_pair(ladder, g4Transform3DToTGeo(placement)));
230 m_sensorPlacements[ladder] = std::vector<std::pair<VxdID, TGeoHMatrix>>();
233 void GeoCache::addHalfShellPlacement(
VxdID halfShell,
const G4Transform3D& placement)
235 m_halfShellPlacements[halfShell] = g4Transform3DToTGeo(placement);
237 m_ladderPlacements[halfShell] = std::vector<std::pair<VxdID, TGeoHMatrix>>();
240 const map<VxdID, TGeoHMatrix>& GeoCache::getHalfShellPlacements()
const {
return m_halfShellPlacements;}
242 const vector< pair< VxdID, TGeoHMatrix > >& GeoCache::getSensorPlacements(
VxdID ladder)
const
244 auto placements = m_sensorPlacements.find(ladder);
245 if (placements == m_sensorPlacements.end())
246 throw std::invalid_argument(
"Invalid ladder id " + (std::string) ladder);
248 return placements->second;
251 const vector< pair< VxdID, TGeoHMatrix > >& GeoCache::getLadderPlacements(
VxdID halfShell)
const
253 auto placements = m_ladderPlacements.find(halfShell);
254 if (placements == m_ladderPlacements.end())
255 throw std::invalid_argument(
"Invalid half-shelve id " + (std::string) halfShell);
257 return placements->second;
260 void GeoCache::setupReconstructionTransformations()
262 if (!m_vxdAlignments.isValid()) {
263 B2WARNING(
"No VXD alignment data. Defaults (0's) will be used!");
268 for (
auto& sensorID : getListOfSensors()) {
269 std::vector<double> planarParameters = {
275 m_vxdAlignments->get(sensorID, 31),
276 m_vxdAlignments->get(sensorID, 32),
277 m_vxdAlignments->get(sensorID, 33),
278 m_vxdAlignments->get(sensorID, 41),
279 m_vxdAlignments->get(sensorID, 42),
280 m_vxdAlignments->get(sensorID, 43),
281 m_vxdAlignments->get(sensorID, 44),
282 m_vxdAlignments->get(sensorID, 51),
283 m_vxdAlignments->get(sensorID, 52),
284 m_vxdAlignments->get(sensorID, 53),
285 m_vxdAlignments->get(sensorID, 54),
286 m_vxdAlignments->get(sensorID, 55),
305 for (
auto& halfShellPlacement : getHalfShellPlacements()) {
306 TGeoHMatrix trafoHalfShell = halfShellPlacement.second;
307 trafoHalfShell *= getTGeoFromRigidBodyParams(
308 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dU),
309 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dV),
310 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dW),
311 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dAlpha),
312 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dBeta),
313 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dGamma)
316 for (
auto& ladderPlacement : getLadderPlacements(halfShellPlacement.first)) {
318 TGeoHMatrix trafoLadder = ladderPlacement.second;
319 trafoLadder *= getTGeoFromRigidBodyParams(
320 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dU),
321 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dV),
322 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dW),
323 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dAlpha),
324 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dBeta),
325 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dGamma)
328 for (
auto& sensorPlacement : getSensorPlacements(ladderPlacement.first)) {
330 TGeoHMatrix trafoSensor = sensorPlacement.second;
331 trafoSensor *= getTGeoFromRigidBodyParams(
332 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dU),
333 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dV),
334 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dW),
335 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dAlpha),
336 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dBeta),
337 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dGamma)
342 geometry.setTransformation(trafoHalfShell * trafoLadder * trafoSensor,
true);
350 TGeoHMatrix GeoCache::g4Transform3DToTGeo(
const G4Transform3D& g4)
354 TGeoTranslation translation;
356 TGeoRotation rotation;
359 trafo.SetDx(g4.getTranslation()[0] / 10.);
360 trafo.SetDy(g4.getTranslation()[1] / 10.);
361 trafo.SetDz(g4.getTranslation()[2] / 10.);
363 Double_t rotMatrix[9];
364 for (
int i = 0; i < 3; ++i) {
365 for (
int j = 0; j < 3; ++j) {
366 rotMatrix[i * 3 + j] = g4.getRotation()[i][j];
369 trafo.SetRotation(rotMatrix);
373 TGeoHMatrix GeoCache::getTGeoFromRigidBodyParams(
double dU,
double dV,
double dW,
double dAlpha,
double dBeta,
double dGamma)
376 TGeoTranslation translation;
378 TGeoRotation rotation;
380 translation.SetTranslation(dU, dV, dW);
381 rotation.RotateX(- dAlpha * TMath::RadToDeg());
382 rotation.RotateY(- dBeta * TMath::RadToDeg());
383 rotation.RotateZ(- dGamma * TMath::RadToDeg());
386 TGeoCombiTrans combi(translation, rotation);
388 trafo = trafo * combi;