Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:17:10

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file orange/g4org/Transformer.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <G4AffineTransform.hh>
0011 #include <G4RotationMatrix.hh>
0012 #include <G4ThreeVector.hh>
0013 
0014 #include "orange/transform/VariantTransform.hh"
0015 
0016 #include "Scaler.hh"
0017 
0018 namespace celeritas
0019 {
0020 namespace g4org
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Return an ORANGE transformation from a Geant4 transformation.
0025  *
0026  * In Geant4, "object" or "direct" transform refers to daughter-to-parent, how
0027  * to place the daughter object in the parent. The "frame" transform (raw \c
0028  * GetTransform or the \c fPtrTransform object) is how to transform from parent
0029  * to daughter and is the inverse of that transform.
0030  *
0031  * Even though the affine transform's matrix has a \c operator() which does a
0032  * matrix-vector multiply (aka \c gemv), this is *not* the same as the affine
0033  * transform's rotation, which applies the *inverse* of the stored matrix.
0034  *
0035  * All ORANGE/Celeritas transforms are "daughter to parent". The transforms
0036  * returned from this function \em must be daughter-to-parent!
0037  */
0038 class Transformer
0039 {
0040   public:
0041     //!@{
0042     //! \name Type aliases
0043     using Real3 = Array<double, 3>;
0044     //!@}
0045 
0046   public:
0047     // Construct with a scale
0048     inline explicit Transformer(Scaler const& scale);
0049 
0050     // Convert a translation
0051     inline Translation operator()(G4ThreeVector const& t) const;
0052 
0053     // Convert a pure rotation
0054     inline Transformation operator()(G4RotationMatrix const& rot) const;
0055 
0056     // Convert a translation + rotation
0057     inline Transformation
0058     operator()(G4ThreeVector const& t, G4RotationMatrix const& rot) const;
0059 
0060     // Convert a translation + optional rotation
0061     inline VariantTransform
0062     operator()(G4ThreeVector const& t, G4RotationMatrix const* rot) 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 -> Transformation
0106 {
0107     return Transformation{convert_from_geant(rot), scale_.to<Real3>(trans)};
0108 }
0109 
0110 //---------------------------------------------------------------------------//
0111 /*!
0112  * Create a transform from an affine transform.
0113  *
0114  * The affine transform's stored rotation matrix is \em inverted!
0115  */
0116 auto Transformer::operator()(G4AffineTransform const& affine) const
0117     -> Transformation
0118 {
0119     return Transformation{transposed_from_geant(affine.NetRotation()),
0120                           scale_.to<Real3>(affine.NetTranslation())};
0121 }
0122 
0123 //---------------------------------------------------------------------------//
0124 /*!
0125  * Convert a rotation matrix.
0126  */
0127 SquareMatrixReal3 convert_from_geant(G4RotationMatrix const& rot)
0128 {
0129     return {Real3{{rot.xx(), rot.xy(), rot.xz()}},
0130             Real3{{rot.yx(), rot.yy(), rot.yz()}},
0131             Real3{{rot.zx(), rot.zy(), rot.zz()}}};
0132 }
0133 
0134 //---------------------------------------------------------------------------//
0135 /*!
0136  * Get a transposed rotation matrix.
0137  */
0138 SquareMatrixReal3 transposed_from_geant(G4RotationMatrix const& rot)
0139 {
0140     return {Real3{{rot.xx(), rot.yx(), rot.zx()}},
0141             Real3{{rot.xy(), rot.yy(), rot.zy()}},
0142             Real3{{rot.xz(), rot.yz(), rot.zz()}}};
0143 }
0144 
0145 //---------------------------------------------------------------------------//
0146 }  // namespace g4org
0147 }  // namespace celeritas