10 #include <vxd/geometry/GeoCache.h>
11 #include <vxd/simulation/SensitiveDetectorBase.h>
12 #include <framework/gearbox/Unit.h>
13 #include <framework/logging/Logger.h>
18 #include <G4LogicalVolume.hh>
19 #include <G4VPhysicalVolume.hh>
20 #include <G4NavigationHistory.hh>
21 #include <G4Transform3D.hh>
34 m_vxdAlignments.addCallback(
this, &VXD::GeoCache::setupReconstructionTransformations);
37 void GeoCache::clear()
46 m_halfShellPlacements.clear();
47 m_ladderPlacements.clear();
48 m_sensorPlacements.clear();
53 id.setSegmentNumber(0);
54 SensorInfoMap::const_iterator info = m_sensorInfo.find(
id);
55 return (info != m_sensorInfo.end());
58 const vector<VxdID> GeoCache::getListOfSensors()
const
60 vector<VxdID> sensors;
61 for (
auto entry : m_sensorInfo)
62 sensors.push_back(entry.first);
68 id.setSegmentNumber(0);
69 SensorInfoMap::const_iterator info = m_sensorInfo.find(
id);
70 if (info == m_sensorInfo.end()) {
71 B2WARNING(
"VXD Sensor " <<
id <<
" does not exist.");
72 return *(m_sensorInfo.begin()->second);
74 return *(info->second);
77 void GeoCache::findVolumes(G4VPhysicalVolume* envelope)
82 G4NavigationHistory nav;
85 stack<G4VPhysicalVolume*> volumes;
86 volumes.push(envelope);
89 while (!volumes.empty()) {
90 G4VPhysicalVolume* physical = volumes.top();
102 nav.NewLevel(physical);
104 G4LogicalVolume* logical = physical->GetLogicalVolume();
111 if (!info) B2FATAL(
"No SensorInfo found for Volume " << logical->GetName());
114 const G4AffineTransform g4transform = nav.GetTopTransform().Inverse();
115 TGeoHMatrix transform;
116 double rotation[9] = {
117 g4transform[0], g4transform[4], g4transform[8],
118 g4transform[1], g4transform[5], g4transform[9],
119 g4transform[2], g4transform[6], g4transform[10]
121 transform.SetRotation(rotation);
122 transform.SetDx(g4transform[12]*Unit::mm);
123 transform.SetDy(g4transform[13]*Unit::mm);
124 transform.SetDz(g4transform[14]*Unit::mm);
125 info->setTransformation(transform);
126 info->setTransformation(transform,
true);
131 int nDaughters = logical->GetNoDaughters();
136 for (
int i = nDaughters - 1; i >= 0; --i) {
137 G4VPhysicalVolume* daughter = logical->GetDaughter(i);
138 volumes.push(daughter);
143 setupReconstructionTransformations();
151 VxdID ladderID = sensorID;
153 VxdID layerID = ladderID;
156 m_sensorInfo[sensorID] = sensorinfo;
158 switch (sensorinfo->
getType()) {
159 case SensorInfoBase::PXD:
160 m_pxdLayers.insert(layerID);
162 case SensorInfoBase::SVD:
163 m_svdLayers.insert(layerID);
165 case SensorInfoBase::TEL:
166 m_telLayers.insert(layerID);
169 B2FATAL(
"Cannot use anything else as SensorTypes PXD, SVD, or TEL when creating VXD Sensors");
171 m_ladders[layerID].insert(ladderID);
172 m_sensors[ladderID].insert(sensorID);
178 case SensorInfoBase::PXD:
180 case SensorInfoBase::SVD:
182 case SensorInfoBase::TEL:
185 std::set<VxdID> allLayers = m_pxdLayers;
186 allLayers.insert(m_svdLayers.begin(), m_svdLayers.end());
187 allLayers.insert(m_telLayers.begin(), m_telLayers.end());
192 const set<VxdID>& GeoCache::getLadders(
VxdID layer)
const
195 layer.setLadderNumber(0);
196 layer.setSensorNumber(0);
197 layer.setSegmentNumber(0);
198 SensorHierachy::const_iterator info = m_ladders.find(layer);
199 if (info == m_ladders.end()) B2FATAL(
"VXD Layer " << layer <<
"does not exist.");
203 const set<VxdID>& GeoCache::getSensors(
VxdID ladder)
const
206 ladder.setSensorNumber(0);
207 ladder.setSegmentNumber(0);
208 SensorHierachy::const_iterator info = m_sensors.find(ladder);
209 if (info == m_sensors.end()) B2FATAL(
"VXD Ladder " << ladder <<
"does not exist.");
215 static unique_ptr<GeoCache> instance(
new GeoCache());
219 void GeoCache::addSensorPlacement(
VxdID ladder,
VxdID sensor,
const G4Transform3D& placement)
221 m_sensorPlacements[ladder].push_back(std::make_pair(sensor, g4Transform3DToTGeo(placement)));
224 void GeoCache::addLadderPlacement(
VxdID halfShell,
VxdID ladder,
const G4Transform3D& placement)
226 m_ladderPlacements[halfShell].push_back(std::make_pair(ladder, g4Transform3DToTGeo(placement)));
228 m_sensorPlacements[ladder] = std::vector<std::pair<VxdID, TGeoHMatrix>>();
231 void GeoCache::addHalfShellPlacement(
VxdID halfShell,
const G4Transform3D& placement)
233 m_halfShellPlacements[halfShell] = g4Transform3DToTGeo(placement);
235 m_ladderPlacements[halfShell] = std::vector<std::pair<VxdID, TGeoHMatrix>>();
238 const map<VxdID, TGeoHMatrix>& GeoCache::getHalfShellPlacements()
const {
return m_halfShellPlacements;}
240 const vector< pair< VxdID, TGeoHMatrix > >& GeoCache::getSensorPlacements(
VxdID ladder)
const
242 auto placements = m_sensorPlacements.find(ladder);
243 if (placements == m_sensorPlacements.end())
244 throw std::invalid_argument(
"Invalid ladder id " + (std::string) ladder);
246 return placements->second;
249 const vector< pair< VxdID, TGeoHMatrix > >& GeoCache::getLadderPlacements(
VxdID halfShell)
const
251 auto placements = m_ladderPlacements.find(halfShell);
252 if (placements == m_ladderPlacements.end())
253 throw std::invalid_argument(
"Invalid half-shelve id " + (std::string) halfShell);
255 return placements->second;
258 void GeoCache::setupReconstructionTransformations()
260 if (!m_vxdAlignments.isValid()) {
261 B2WARNING(
"No VXD alignment data. Defaults (0's) will be used!");
266 for (
auto& sensorID : getListOfSensors()) {
267 std::vector<double> planarParameters = {
273 m_vxdAlignments->get(sensorID, 31),
274 m_vxdAlignments->get(sensorID, 32),
275 m_vxdAlignments->get(sensorID, 33),
276 m_vxdAlignments->get(sensorID, 41),
277 m_vxdAlignments->get(sensorID, 42),
278 m_vxdAlignments->get(sensorID, 43),
279 m_vxdAlignments->get(sensorID, 44),
280 m_vxdAlignments->get(sensorID, 51),
281 m_vxdAlignments->get(sensorID, 52),
282 m_vxdAlignments->get(sensorID, 53),
283 m_vxdAlignments->get(sensorID, 54),
284 m_vxdAlignments->get(sensorID, 55),
303 for (
auto& halfShellPlacement : getHalfShellPlacements()) {
304 TGeoHMatrix trafoHalfShell = halfShellPlacement.second;
305 trafoHalfShell *= getTGeoFromRigidBodyParams(
306 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dU),
307 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dV),
308 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dW),
309 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dAlpha),
310 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dBeta),
311 m_vxdAlignments->get(halfShellPlacement.first, VXDAlignment::dGamma)
314 for (
auto& ladderPlacement : getLadderPlacements(halfShellPlacement.first)) {
316 TGeoHMatrix trafoLadder = ladderPlacement.second;
317 trafoLadder *= getTGeoFromRigidBodyParams(
318 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dU),
319 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dV),
320 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dW),
321 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dAlpha),
322 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dBeta),
323 m_vxdAlignments->get(ladderPlacement.first, VXDAlignment::dGamma)
326 for (
auto& sensorPlacement : getSensorPlacements(ladderPlacement.first)) {
328 TGeoHMatrix trafoSensor = sensorPlacement.second;
329 trafoSensor *= getTGeoFromRigidBodyParams(
330 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dU),
331 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dV),
332 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dW),
333 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dAlpha),
334 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dBeta),
335 m_vxdAlignments->get(sensorPlacement.first, VXDAlignment::dGamma)
340 geometry.setTransformation(trafoHalfShell * trafoLadder * trafoSensor,
true);
348 TGeoHMatrix GeoCache::g4Transform3DToTGeo(
const G4Transform3D& g4)
352 TGeoTranslation translation;
354 TGeoRotation rotation;
357 trafo.SetDx(g4.getTranslation()[0] / 10.);
358 trafo.SetDy(g4.getTranslation()[1] / 10.);
359 trafo.SetDz(g4.getTranslation()[2] / 10.);
361 Double_t rotMatrix[9];
362 for (
int i = 0; i < 3; ++i) {
363 for (
int j = 0; j < 3; ++j) {
364 rotMatrix[i * 3 + j] = g4.getRotation()[i][j];
367 trafo.SetRotation(rotMatrix);
371 TGeoHMatrix GeoCache::getTGeoFromRigidBodyParams(
double dU,
double dV,
double dW,
double dAlpha,
double dBeta,
double dGamma)
374 TGeoTranslation translation;
376 TGeoRotation rotation;
378 translation.SetTranslation(dU, dV, dW);
379 rotation.RotateX(- dAlpha * TMath::RadToDeg());
380 rotation.RotateY(- dBeta * TMath::RadToDeg());
381 rotation.RotateZ(- dGamma * TMath::RadToDeg());
384 TGeoCombiTrans combi(translation, rotation);
386 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.