@@ -169,14 +169,26 @@ G4VPhysicalVolume* DetectorConstruction::Construct() {
169169 exit (1 );
170170 }
171171
172- fGeneratorTranslation = gdmlPhysicalVolume->GetTranslation ();
172+ TVector3 genTranslation = geometryInfo.GetPosition (
173+ primaryGeneratorInfo.GetSpatialGeneratorFrom ().Data ()); // in world coordinates
174+ fGeneratorTranslation = {genTranslation.x (), genTranslation.y (), genTranslation.z ()};
175+ TRotation genRotation = geometryInfo.GetRotation (
176+ primaryGeneratorInfo.GetSpatialGeneratorFrom ().Data ()); // in world coordinates
177+ double angle;
178+ TVector3 axis;
179+ genRotation.AngleAxis (angle, axis);
180+ fGeneratorRotation = G4RotationMatrix (G4ThreeVector (axis.X (), axis.Y (), axis.Z ()), angle);
173181 if (spatialGeneratorTypeEnum == TRestGeant4PrimaryGeneratorTypes::SpatialGeneratorTypes::SURFACE ||
174182 spatialGeneratorTypeEnum == TRestGeant4PrimaryGeneratorTypes::SpatialGeneratorTypes::VOLUME) {
175183 restG4Metadata->fGeant4PrimaryGeneratorInfo .fSpatialGeneratorPosition = {
176184 fGeneratorTranslation .x (), fGeneratorTranslation .y (), fGeneratorTranslation .z ()};
185+ restG4Metadata->fGeant4PrimaryGeneratorInfo .fSpatialGeneratorRotationAxis = {axis.X (), axis.Y (),
186+ axis.Z ()};
187+ restG4Metadata->fGeant4PrimaryGeneratorInfo .fSpatialGeneratorRotationValue = angle;
177188 }
178189
179190 fGeneratorSolid = gdmlPhysicalVolume->GetLogicalVolume ()->GetSolid ();
191+ fGeneratorLogicalVolume = gdmlPhysicalVolume->GetLogicalVolume ();
180192
181193 fBoundBoxXMax = -1 .e30 ;
182194 fBoundBoxYMax = -1 .e30 ;
@@ -314,26 +326,64 @@ void DetectorConstruction::ConstructSDandField() {
314326 }
315327}
316328
329+ bool DetectorConstruction::IsPointInsideAnyDaughterVolume (const G4LogicalVolume* logVol,
330+ const G4ThreeVector& point) const {
331+ if (!logVol) {
332+ G4cout << " DetectorConstruction::IsPointInsideAnyDaughterVolume : logVol is nullptr" << G4endl;
333+ return false ;
334+ }
335+
336+ for (size_t i = 0 ; i < logVol->GetNoDaughters (); ++i) {
337+ G4VPhysicalVolume* daughter = logVol->GetDaughter (i);
338+ G4LogicalVolume* daughterLogVol = daughter->GetLogicalVolume ();
339+ G4VSolid* daughterSolid = daughterLogVol->GetSolid ();
340+
341+ // localPoint will be the point in the daughter volume reference system
342+ // which is the one used by the solid to determine if the point is inside or not
343+ G4ThreeVector localPoint = point - daughter->GetTranslation ();
344+ if (daughter->GetRotation ()) {
345+ localPoint = daughter->GetRotation ()->inverse () * localPoint;
346+ }
347+
348+ if (daughterSolid->Inside (localPoint) == kInside ) {
349+ return true ;
350+ }
351+ }
352+ return false ;
353+ }
354+
317355void TRestGeant4GeometryInfo::PopulateFromGeant4World (const G4VPhysicalVolume* world) {
318356 auto detector = (DetectorConstruction*)G4RunManager::GetRunManager ()->GetUserDetectorConstruction ();
319357 TRestGeant4Metadata* restG4Metadata = detector->fSimulationManager ->GetRestMetadata ();
320358
321359 // Recursive function to traverse the nested volume geometry
322- std::function<void (const G4VPhysicalVolume*, size_t &, const G4String pathSoFar, const G4ThreeVector&)>
360+ std::function<void (const G4VPhysicalVolume*, size_t &, const G4String pathSoFar, const G4ThreeVector&,
361+ const G4RotationMatrix&)>
323362 ProcessVolumeRecursively = [&](const G4VPhysicalVolume* volume, size_t & index,
324- const G4String pathSoFar, const G4ThreeVector& parentPosition) {
363+ const G4String pathSoFar, const G4ThreeVector& parentPosition,
364+ const G4RotationMatrix& parentRotation) {
325365 G4String currentPath = pathSoFar;
326366 if (volume->GetName () != world->GetName ()) { // avoid all paths including 'world_PV/' at the
327367 // beginning
328368 currentPath += (currentPath.empty () ? " " : fPathSeparator .Data ()) + volume->GetName ();
329369 }
330- G4ThreeVector positionInWorld = volume->GetTranslation () + parentPosition;
370+ G4ThreeVector localPosition = volume->GetTranslation ();
371+ localPosition = parentRotation * localPosition;
372+ G4RotationMatrix localRotation =
373+ volume->GetRotation () ? *volume->GetRotation () : G4RotationMatrix (); // identity if nullptr
374+
375+ // accumulate the position
376+ G4ThreeVector positionInWorld = parentPosition + localPosition;
377+
378+ // accumulate the rotation
379+ G4RotationMatrix rotationInWorld = parentRotation;
380+ rotationInWorld *= localRotation;
331381
332382 // First process the daughters to have the same order in volume IDs as before
333383 G4LogicalVolume* logVol = volume->GetLogicalVolume ();
334384 for (size_t i = 0 ; i < logVol->GetNoDaughters (); ++i) {
335385 G4VPhysicalVolume* daughter = logVol->GetDaughter (i);
336- ProcessVolumeRecursively (daughter, index, currentPath, positionInWorld);
386+ ProcessVolumeRecursively (daughter, index, currentPath, positionInWorld, rotationInWorld );
337387 }
338388
339389 // Process this volume
@@ -351,6 +401,14 @@ void TRestGeant4GeometryInfo::PopulateFromGeant4World(const G4VPhysicalVolume* w
351401 fLogicalToPhysicalMap [nameLogical].emplace_back (namePhysical);
352402 fPhysicalToPositionInWorldMap [physicalNewName] = {positionInWorld.x (), positionInWorld.y (),
353403 positionInWorld.z ()};
404+ // Convert G4RotationMatrix to TRotation and store it
405+ double angle;
406+ G4ThreeVector axis;
407+ rotationInWorld.getAngleAxis (angle, axis);
408+ TRotation rotInWorld;
409+ rotInWorld.Rotate (angle, TVector3 (axis.x (), axis.y (), axis.z ()));
410+ fPhysicalToRotationInWorldMap [physicalNewName] = rotInWorld;
411+
354412 InsertVolumeName (index, physicalNewName);
355413 /*
356414 std::cout << "Index: " << index << std::endl;
@@ -360,6 +418,9 @@ void TRestGeant4GeometryInfo::PopulateFromGeant4World(const G4VPhysicalVolume* w
360418 std::cout << "\tMaterial: " << nameMaterial << std::endl;
361419 std::cout << "\tPosition: (" << positionInWorld.x() << ", " << positionInWorld.y() << ", " <<
362420 positionInWorld.z() << ")mm" << std::endl;
421+ std::cout << "\tRotation (angle, axis): (" << angle << ", (" << axis.x() << ", " << axis.y() << ",
422+ "
423+ << axis.z() << "))" << std::endl;
363424 */
364425 if (!fIsAssembly &&
365426 GetAlternativeNameFromGeant4PhysicalName (namePhysical).Data () != namePhysical) {
@@ -378,5 +439,5 @@ void TRestGeant4GeometryInfo::PopulateFromGeant4World(const G4VPhysicalVolume* w
378439
379440 // Start recursion from world volume
380441 size_t index = 0 ;
381- ProcessVolumeRecursively (world, index, " " , G4ThreeVector (0 , 0 , 0 ));
442+ ProcessVolumeRecursively (world, index, " " , G4ThreeVector (0 , 0 , 0 ), G4RotationMatrix () );
382443}
0 commit comments