Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:24:49

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