File indexing completed on 2026-09-20 08:25:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Volumes.h>
0016 #include <DD4hep/Printout.h>
0017 #include <DDG4/Geant4Helpers.h>
0018 #include <DDG4/Geant4PlacementParameterisation.h>
0019
0020
0021 #include <G4Transform3D.hh>
0022
0023
0024 dd4hep::sim::Geant4PlacementParameterisation::Geant4PlacementParameterisation(PlacedVolume pv)
0025 : G4VPVParameterisation(), m_placement(pv), m_params(*pv.data()->params)
0026 {
0027 G4Transform3D tr;
0028 auto& dim = m_dimensions;
0029 g4Transform(m_params.start, m_start.delta);
0030 m_start.translation = m_start.delta.getTranslation();
0031
0032 g4Transform(m_params.trafo1D.first, tr);
0033 dim.emplace_back(Dimension(tr, m_params.trafo1D.second));
0034
0035 m_have_rotation = false;
0036 m_have_rotation |= !dim.back().delta.getRotation().isIdentity();
0037 m_num_cells = m_params.trafo1D.second;
0038 if ( m_params.trafo2D.second > 0 ) {
0039 g4Transform(m_params.trafo2D.first, tr);
0040 dim.emplace_back(Dimension(tr, m_params.trafo2D.second));
0041 m_have_rotation |= !dim.back().delta.getRotation().isIdentity();
0042 m_num_cells *= m_params.trafo2D.second;
0043 }
0044 if ( m_params.trafo3D.second > 0 ) {
0045 g4Transform(m_params.trafo3D.first, tr);
0046 dim.emplace_back(Dimension(tr, m_params.trafo3D.second));
0047 m_have_rotation |= !dim.back().delta.getRotation().isIdentity();
0048 m_num_cells *= m_params.trafo3D.second;
0049 }
0050
0051 if ( !m_have_rotation && dim.size() == 1 ) {
0052 const G4ThreeVector& t = dim[0].translation;
0053 if ( t.x() != 0.0 && t.y() == 0.0 && t.z() == 0.0 ) m_axis = kXAxis;
0054 else if ( t.x() == 0.0 && t.y() != 0.0 && t.z() == 0.0 ) m_axis = kYAxis;
0055 else if ( t.x() == 0.0 && t.y() == 0.0 && t.z() != 0.0 ) m_axis = kZAxis;
0056 }
0057 if ( m_have_rotation ) {
0058 auto callback = std::bind(&Geant4PlacementParameterisation::operator(),
0059 this, std::placeholders::_1);
0060 if ( dim.size() == 1 )
0061 generate_placements(m_start.delta,
0062 dim[0].delta, dim[0].count, callback);
0063 else if ( dim.size() == 2 )
0064 generate_placements(m_start.delta,
0065 dim[0].delta, dim[0].count,
0066 dim[1].delta, dim[1].count, callback);
0067 else if ( dim.size() == 3 )
0068 generate_placements(m_start.delta,
0069 dim[0].delta, dim[0].count,
0070 dim[1].delta, dim[1].count,
0071 dim[2].delta, dim[2].count, callback);
0072 }
0073 }
0074
0075
0076 std::size_t dd4hep::sim::Geant4PlacementParameterisation::count() const {
0077 return m_num_cells;
0078 }
0079
0080
0081 void dd4hep::sim::Geant4PlacementParameterisation::operator()(const G4Transform3D& transform) {
0082 this->m_translations.emplace_back(transform.getTranslation());
0083 if ( this->m_have_rotation ) {
0084 G4RotationMatrix rot = transform.inverse().getRotation();
0085 this->m_rotations.emplace_back(rot);
0086 }
0087 }
0088
0089
0090 void dd4hep::sim::Geant4PlacementParameterisation::ComputeTransformation(const G4int copy, G4VPhysicalVolume *pv) const {
0091 const auto& dim = m_dimensions;
0092 std::size_t nd = dim.size();
0093 if ( !m_have_rotation ) {
0094 G4ThreeVector tra = m_start.translation;
0095 if ( nd >= 1 ) {
0096 std::size_t d1 = 0;
0097 if (nd == 1) d1 = copy;
0098 else if (nd >= 2) d1 = copy%dim[1].count;
0099 tra = tra + (dim[0].translation * d1);
0100 }
0101 if ( nd >= 2 ) {
0102 std::size_t d2 = 0;
0103 if (nd == 2) d2 = copy / dim[0].count;
0104 else if (nd >= 3 ) d2 = copy%dim[2].count / dim[0].count;
0105 tra = tra + (dim[1].translation * d2);
0106 }
0107 if ( nd >= 3 ) {
0108 std::size_t d3 = 0;
0109 if ( nd == 3 ) d3 = copy / (dim[0].count*dim[1].count);
0110 tra = tra + (dim[2].translation * d3);
0111 }
0112 pv->SetTranslation(tra);
0113 return;
0114 }
0115 G4RotationMatrix& rot = m_rotations.at(copy);
0116 pv->SetTranslation(m_translations.at(copy));
0117 pv->SetRotation(&rot);
0118 }