10 #include <vxd/geometry/GeoCache.h>
11 #include <vxd/simulation/SensitiveDetectorBase.h>
12 #include <framework/gearbox/Unit.h>
13 #include <framework/logging/Logger.h>
19 #include <G4LogicalVolume.hh>
20 #include <G4VPhysicalVolume.hh>
21 #include <G4NavigationHistory.hh>
22 #include <G4Transform3D.hh>
35 m_vxdAlignments.addCallback(
this, &VXD::GeoCache::setupReconstructionTransformations);
38 void GeoCache::clear()
47 m_halfShellPlacements.clear();
48 m_ladderPlacements.clear();
49 m_sensorPlacements.clear();
54 id.setSegmentNumber(0);
55 SensorInfoMap::const_iterator info = m_sensorInfo.find(
id);
56 return (info != m_sensorInfo.end());
59 const vector<VxdID> GeoCache::getListOfSensors()
const
61 vector<VxdID> sensors;
62 for (
auto entry : m_sensorInfo)
63 sensors.push_back(entry.first);
69 id.setSegmentNumber(0);
70 SensorInfoMap::const_iterator info = m_sensorInfo.find(
id);
71 if (info == m_sensorInfo.end()) {
72 B2WARNING(
"VXD Sensor " <<
id <<
" does not exist.");
73 return *(m_sensorInfo.begin()->second);
75 return *(info->second);
78 void GeoCache::findVolumes(G4VPhysicalVolume* envelope)
83 G4NavigationHistory nav;
86 stack<G4VPhysicalVolume*> volumes;
87 volumes.push(envelope);
90 while (!volumes.empty()) {
91 G4VPhysicalVolume* physical = volumes.top();
103 nav.NewLevel(physical);
105 G4LogicalVolume* logical = physical->GetLogicalVolume();
112 if (!info) B2FATAL(
"No SensorInfo found for Volume " << logical->GetName());
115 const G4AffineTransform g4transform = nav.GetTopTransform().Inverse();
116 TGeoHMatrix transform;
117 double rotation[9] = {
118 g4transform[0], g4transform[4], g4transform[8],
119 g4transform[1], g4transform[5], g4transform[9],
120 g4transform[2], g4transform[6], g4transform[10]
122 transform.SetRotation(rotation);
123 transform.SetDx(g4transform[12]*Unit::mm);
124 transform.SetDy(g4transform[13]*Unit::mm);
125 transform.SetDz(g4transform[14]*Unit::mm);
126 info->setTransformation(transform);
127 info->setTransformation(transform,
true);
132 int nDaughters = logical->GetNoDaughters();
137 for (
int i = nDaughters - 1; i >= 0; --i) {
138 G4VPhysicalVolume* daughter = logical->GetDaughter(i);
139 volumes.push(daughter);
144 setupReconstructionTransformations();
152 VxdID ladderID = sensorID;
154 VxdID layerID = ladderID;
157 m_sensorInfo[sensorID] = sensorinfo;
159 switch (sensorinfo->
getType()) {
160 case SensorInfoBase::PXD:
161 m_pxdLayers.insert(layerID);
163 case SensorInfoBase::SVD:
164 m_svdLayers.insert(layerID);
166 case SensorInfoBase::TEL:
167 m_telLayers.insert(layerID);
170 B2FATAL(
"Cannot use anything else as SensorTypes PXD, SVD, or TEL when creating VXD Sensors");
172 m_ladders[layerID].insert(ladderID);
173 m_sensors[ladderID].insert(sensorID);
179 case SensorInfoBase::PXD:
181 case SensorInfoBase::SVD:
183 case SensorInfoBase::TEL:
186 std::set<VxdID> allLayers = m_pxdLayers;
187 allLayers.insert(m_svdLayers.begin(), m_svdLayers.end());
188 allLayers.insert(m_telLayers.begin(), m_telLayers.end());
193 const set<VxdID>& GeoCache::getLadders(
VxdID layer)
const
196 layer.setLadderNumber(0);
197 layer.setSensorNumber(0);
198 layer.setSegmentNumber(0);
199 SensorHierachy::const_iterator info = m_ladders.find(layer);
200 if (info == m_ladders.end()) B2FATAL(
"VXD Layer " << layer <<
"does not exist.");
204 const set<VxdID>& GeoCache::getSensors(
VxdID ladder)
const
207 ladder.setSensorNumber(0);
208 ladder.setSegmentNumber(0);
209 SensorHierachy::const_iterator info = m_sensors.find(ladder);
210 if (info == m_sensors.end()) B2FATAL(
"VXD Ladder " << ladder <<
"does not exist.");
216 static unique_ptr<GeoCache> instance(
new GeoCache());
220 void GeoCache::addSensorPlacement(
VxdID ladder,
VxdID sensor,
const G4Transform3D& placement)
222 m_sensorPlacements[ladder].push_back(std::make_pair(sensor, g4Transform3DToTGeo(placement)));
225 void GeoCache::addLadderPlacement(
VxdID halfShell,
VxdID ladder,
const G4Transform3D& placement)
227 m_ladderPlacements[halfShell].push_back(std::make_pair(ladder, g4Transform3DToTGeo(placement)));
229 m_sensorPlacements[ladder] = std::vector<std::pair<VxdID, TGeoHMatrix>>();
232 void GeoCache::addHalfShellPlacement(
VxdID halfShell,
const G4Transform3D& placement)
234 m_halfShellPlacements[halfShell] = g4Transform3DToTGeo(placement);
236 m_ladderPlacements[halfShell] = std::vector<std::pair<VxdID, TGeoHMatrix>>();
239 const map<VxdID, TGeoHMatrix>& GeoCache::getHalfShellPlacements()
const {
return m_halfShellPlacements;}
241 const vector< pair< VxdID, TGeoHMatrix > >& GeoCache::getSensorPlacements(
VxdID ladder)
const
243 auto placements = m_sensorPlacements.find(ladder);
244 if (placements == m_sensorPlacements.end())
245 throw std::invalid_argument(
"Invalid ladder id " + (std::string) ladder);
247 return placements->second;
250 const vector< pair< VxdID, TGeoHMatrix > >& GeoCache::getLadderPlacements(
VxdID halfShell)
const
252 auto placements = m_ladderPlacements.find(halfShell);
253 if (placements == m_ladderPlacements.end())
254 throw std::invalid_argument(
"Invalid half-shelve id " + (std::string) halfShell);
256 return placements->second;
259 void GeoCache::setupReconstructionTransformations()
261 if (!m_vxdAlignments.isValid()) {
262 B2WARNING(
"No VXD alignment data. Defaults (0's) will be used!");
267 for (
auto& sensorID : getListOfSensors()) {
268 std::vector<double> planarParameters = {
274 m_vxdAlignments->get(sensorID, 31),
275 m_vxdAlignments->get(sensorID, 32),
276 m_vxdAlignments->get(sensorID, 33),
277 m_vxdAlignments->get(sensorID, 41),
278 m_vxdAlignments->get(sensorID, 42),
279 m_vxdAlignments->get(sensorID, 43),
280 m_vxdAlignments->get(sensorID, 44),
281 m_vxdAlignments->get(sensorID, 51),
282 m_vxdAlignments->get(sensorID, 52),
283 m_vxdAlignments->get(sensorID, 53),
284 m_vxdAlignments->get(sensorID, 54),
285 m_vxdAlignments->get(sensorID, 55),
304 for (
auto& halfShellPlacement : getHalfShellPlacements()) {
305 TGeoHMatrix trafoHalfShell = halfShellPlacement.second;
306 trafoHalfShell *= getTGeoFromRigidBodyParams(
307 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dU),
308 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dV),
309 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dW),
310 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dAlpha),
311 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dBeta),
312 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dGamma)
315 for (
auto& ladderPlacement : getLadderPlacements(halfShellPlacement.first)) {
317 TGeoHMatrix trafoLadder = ladderPlacement.second;
318 trafoLadder *= getTGeoFromRigidBodyParams(
319 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dU),
320 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dV),
321 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dW),
322 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dAlpha),
323 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dBeta),
324 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dGamma)
327 for (
auto& sensorPlacement : getSensorPlacements(ladderPlacement.first)) {
329 TGeoHMatrix trafoSensor = sensorPlacement.second;
330 trafoSensor *= getTGeoFromRigidBodyParams(
331 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dU),
332 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dV),
333 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dW),
334 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dAlpha),
335 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dBeta),
336 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dGamma)
341 geometry.setTransformation(trafoHalfShell * trafoLadder * trafoSensor,
true);
349 TGeoHMatrix GeoCache::g4Transform3DToTGeo(
const G4Transform3D& g4)
353 TGeoTranslation translation;
355 TGeoRotation rotation;
358 trafo.SetDx(g4.getTranslation()[0] / 10.);
359 trafo.SetDy(g4.getTranslation()[1] / 10.);
360 trafo.SetDz(g4.getTranslation()[2] / 10.);
362 Double_t rotMatrix[9];
363 for (
int i = 0; i < 3; ++i) {
364 for (
int j = 0; j < 3; ++j) {
365 rotMatrix[i * 3 + j] = g4.getRotation()[i][j];
368 trafo.SetRotation(rotMatrix);
372 TGeoHMatrix GeoCache::getTGeoFromRigidBodyParams(
double dU,
double dV,
double dW,
double dAlpha,
double dBeta,
double dGamma)
375 TGeoTranslation translation;
377 TGeoRotation rotation;
379 translation.SetTranslation(dU, dV, dW);
380 rotation.RotateX(- dAlpha * TMath::RadToDeg());
381 rotation.RotateY(- dBeta * TMath::RadToDeg());
382 rotation.RotateZ(- dGamma * TMath::RadToDeg());
385 TGeoCombiTrans combi(translation, rotation);
387 trafo = trafo * combi;
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Base class for Sensitive Detector implementation of PXD and SVD.
SensorInfoBase * getSensorInfo()
Return a pointer to the SensorInfo associated with this instance.
Base class to provide Sensor Information for PXD and SVD.
SensorType getType() const
Return the Type of the Sensor.
SensorType
Enum specifing the type of sensor the SensorInfo represents.
VxdID getID() const
Return the ID of the Sensor.
void setSurfaceParameters(const std::vector< double > &planarParameters)
Fill parameters of planar deformation to vector.
Class to uniquely identify a any structure of the PXD and SVD.
void setSensorNumber(baseType sensor)
Set the sensor id.
void setLadderNumber(baseType ladder)
Set the ladder id.
Abstract base class for different kinds of events.