Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-20 08:25:03

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
0015 #include <DD4hep/Volumes.h>
0016 #include <DD4hep/Printout.h>
0017 #include <DDG4/Geant4Helpers.h>
0018 #include <DDG4/Geant4PlacementParameterisation.h>
0019 
0020 // Geant4 include files
0021 #include <G4Transform3D.hh>
0022 
0023 /// Initializing constructor
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   // Set axis for pure 1D translation along a single Cartesian axis
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 /// Access number of replicas
0076 std::size_t dd4hep::sim::Geant4PlacementParameterisation::count()  const   {
0077   return m_num_cells;
0078 }
0079 
0080 /// Callback to store resulting rotation
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 /// G4VPVParameterisation overload: Callback to place sub-volumes
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 }