|
17 | 17 | #include <G4FieldManager.hh>
|
18 | 18 | #include <G4RegionStore.hh>
|
19 | 19 | #include <G4TouchableHandle.hh>
|
| 20 | +#include <G4PVReplica.hh> |
| 21 | +#include <G4ReplicaNavigation.hh> |
20 | 22 |
|
21 | 23 | #include <G4HepEmState.hh>
|
22 | 24 | #include <G4HepEmData.hh>
|
@@ -183,16 +185,42 @@ void visitGeometry(G4VPhysicalVolume const *g4_pvol, vecgeom::VPlacedVolume cons
|
183 | 185 | const auto g4_lvol = g4_pvol->GetLogicalVolume();
|
184 | 186 | const auto vg_lvol = vg_pvol->GetLogicalVolume();
|
185 | 187 |
|
186 |
| - const size_t nd = g4_lvol->GetNoDaughters(); |
| 188 | + // Geant4 Parameterised/Replica volumes are represented with direct placements in VecGeom |
| 189 | + // To accurately compare the number of daughters, we need to sum multiplicity on Geant4 side |
| 190 | + const size_t nd = g4_lvol->GetNoDaughters(); |
| 191 | + size_t nd_converted = 0; |
| 192 | + for (size_t daughter_id = 0; daughter_id < nd; ++daughter_id) { |
| 193 | + const G4VPhysicalVolume *daughter_pvol = g4_lvol->GetDaughter(daughter_id); |
| 194 | + nd_converted += daughter_pvol->GetMultiplicity(); |
| 195 | + } |
| 196 | + |
187 | 197 | const auto daughters = vg_lvol->GetDaughters();
|
188 | 198 |
|
189 |
| - if (nd != daughters.size()) throw std::runtime_error("Fatal: CheckGeometry: Mismatch in number of daughters"); |
| 199 | + if (nd_converted != daughters.size()) |
| 200 | + throw std::runtime_error("Fatal: CheckGeometry: Mismatch in number of daughters"); |
| 201 | + |
190 | 202 | // Check if transformations are matching
|
| 203 | + // As above, with Parameterized/Replica volumes, we need to compare the transforms between |
| 204 | + // the VG direct placement and that for the Parameterised/Replicated volume given the same copy |
| 205 | + // number as that of the VG physical volume. |
| 206 | + // NOTE: |
| 207 | + // 1. Nasty const_cast as currently known way to get transform is to directly transform the |
| 208 | + // Geant4 phys vol before extracting, which is non-const.... |
| 209 | + // 2. ...this does modify the physical volume, but this is _probably_ o.k. as actual navigation |
| 210 | + // will reset things o.k. |
| 211 | + if (G4VPVParameterisation *param = g4_pvol->GetParameterisation()) { |
| 212 | + param->ComputeTransformation(vg_pvol->GetCopyNo(), const_cast<G4VPhysicalVolume *>(g4_pvol)); |
| 213 | + } else if (auto *replica = dynamic_cast<G4PVReplica *>(const_cast<G4VPhysicalVolume *>(g4_pvol))) { |
| 214 | + G4ReplicaNavigation nav; |
| 215 | + nav.ComputeTransformation(vg_pvol->GetCopyNo(), replica); |
| 216 | + } |
| 217 | + |
191 | 218 | const auto g4trans = g4_pvol->GetTranslation();
|
192 | 219 | const G4RotationMatrix *g4rot = g4_pvol->GetRotation();
|
193 | 220 | G4RotationMatrix idrot;
|
194 | 221 | const auto vgtransformation = vg_pvol->GetTransformation();
|
195 | 222 | constexpr double epsil = 1.e-8;
|
| 223 | + |
196 | 224 | for (int i = 0; i < 3; ++i) {
|
197 | 225 | if (std::abs(g4trans[i] - vgtransformation->Translation(i)) > epsil)
|
198 | 226 | throw std::runtime_error(
|
|
0 commit comments