Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-21 08:29:59

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file orange/g4org/Transformer.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <G4AffineTransform.hh>
0010 #include <G4RotationMatrix.hh>
0011 #include <G4ThreeVector.hh>
0012 #include <G4Transform3D.hh>
0013 
0014 #include "geocel/Types.hh"
0015 #include "orange/transform/VariantTransform.hh"
0016 
0017 #include "Scaler.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace g4org
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Return an ORANGE transformation from a Geant4 transformation.
0026  *
0027  * In Geant4, "object" or "direct" transform refers to daughter-to-parent, how
0028  * to place the daughter object in the parent. The "frame" transform (raw \c
0029  * GetTransform or the \c fPtrTransform object) is how to transform from parent
0030  * to daughter and is the inverse of that transform.
0031  *
0032  * Even though the affine transform's matrix has a \c operator() which does a
0033  * matrix-vector multiply (aka \c gemv), this is *not* the same as the affine
0034  * transform's rotation, which applies the *inverse* of the stored matrix.
0035  *
0036  * All ORANGE/Celeritas transforms are "daughter to parent". The transforms
0037  * returned from this function \em must be daughter-to-parent!
0038  */
0039 class Transformer
0040 {
0041   public:
0042     //!@{
0043     //! \name Type aliases
0044     using Real3 = Array<double, 3>;
0045     //!@}
0046 
0047   public:
0048     // Construct with a scale
0049     inline explicit Transformer(Scaler const& scale);
0050 
0051     // Convert a translation
0052     inline Translation operator()(G4ThreeVector const& t) const;
0053 
0054     // Convert a pure rotation
0055     inline Transformation operator()(G4RotationMatrix const& rot) const;
0056 
0057     // Convert a translation + rotation
0058     inline Transformation
0059     operator()(G4ThreeVector const& t, G4RotationMatrix const& rot) const;
0060 
0061     // Convert a more general transform (includes reflection)
0062     inline Transformation operator()(G4Transform3D const& tran) const;
0063 
0064     // Convert an affine transform
0065     inline Transformation operator()(G4AffineTransform const& at) const;
0066 
0067   private:
0068     //// DATA ////
0069 
0070     Scaler const& scale_;
0071 };
0072 
0073 //---------------------------------------------------------------------------//
0074 // FREE FUNCTIONS
0075 //---------------------------------------------------------------------------//
0076 // Convert a rotation matrix
0077 inline SquareMatrixReal3 convert_from_geant(G4RotationMatrix const& rot);
0078 
0079 //---------------------------------------------------------------------------//
0080 // Get the transpose/inverse of a rotation matrix
0081 inline SquareMatrixReal3 transposed_from_geant(G4RotationMatrix const& rot);
0082 
0083 //---------------------------------------------------------------------------//
0084 // INLINE DEFINITIONS
0085 //---------------------------------------------------------------------------//
0086 /*!
0087  * Construct with a scaling function.
0088  */
0089 Transformer::Transformer(Scaler const& scale) : scale_{scale} {}
0090 
0091 //---------------------------------------------------------------------------//
0092 /*!
0093  * Create a transform from a translation.
0094  */
0095 auto Transformer::operator()(G4ThreeVector const& t) const -> Translation
0096 {
0097     return Translation{scale_.to<Real3>(t[0], t[1], t[2])};
0098 }
0099 
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Create a transform from a translation plus rotation.
0103  */
0104 auto Transformer::operator()(G4ThreeVector const& trans,
0105                              G4RotationMatrix const& rot) const
0106     -> Transformation
0107 {
0108     return Transformation{convert_from_geant(rot), scale_.to<Real3>(trans)};
0109 }
0110 
0111 //---------------------------------------------------------------------------//
0112 /*!
0113  * Convert a more general transform (including possibly reflection).
0114  */
0115 Transformation Transformer::operator()(G4Transform3D const& tran) const
0116 {
0117     SquareMatrixReal3 rot{Real3{{tran.xx(), tran.xy(), tran.xz()}},
0118                           Real3{{tran.yx(), tran.yy(), tran.yz()}},
0119                           Real3{{tran.zx(), tran.zy(), tran.zz()}}};
0120 
0121     return Transformation{rot,
0122                           scale_.to<Real3>(tran.dx(), tran.dy(), tran.dz())};
0123 }
0124 
0125 //---------------------------------------------------------------------------//
0126 /*!
0127  * Create a transform from an affine transform.
0128  *
0129  * The affine transform's stored rotation matrix is \em inverted!
0130  */
0131 auto Transformer::operator()(G4AffineTransform const& affine) const
0132     -> Transformation
0133 {
0134     return Transformation{transposed_from_geant(affine.NetRotation()),
0135                           scale_.to<Real3>(affine.NetTranslation())};
0136 }
0137 
0138 //---------------------------------------------------------------------------//
0139 /*!
0140  * Convert a rotation matrix.
0141  */
0142 SquareMatrixReal3 convert_from_geant(G4RotationMatrix const& rot)
0143 {
0144     return {Real3{{rot.xx(), rot.xy(), rot.xz()}},
0145             Real3{{rot.yx(), rot.yy(), rot.yz()}},
0146             Real3{{rot.zx(), rot.zy(), rot.zz()}}};
0147 }
0148 
0149 //---------------------------------------------------------------------------//
0150 /*!
0151  * Get a transposed rotation matrix.
0152  */
0153 SquareMatrixReal3 transposed_from_geant(G4RotationMatrix const& rot)
0154 {
0155     return {Real3{{rot.xx(), rot.yx(), rot.zx()}},
0156             Real3{{rot.xy(), rot.yy(), rot.zy()}},
0157             Real3{{rot.xz(), rot.yz(), rot.zz()}}};
0158 }
0159 
0160 //---------------------------------------------------------------------------//
0161 }  // namespace g4org
0162 }  // namespace celeritas