Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:28

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   if ( m_have_rotation )    {
0051     auto callback = std::bind(&Geant4PlacementParameterisation::operator(),
0052                   this, std::placeholders::_1);
0053     if ( dim.size() == 1 )
0054       generate_placements(m_start.delta,
0055               dim[0].delta, dim[0].count, callback);
0056     else if ( dim.size() == 2 )
0057       generate_placements(m_start.delta,
0058               dim[0].delta, dim[0].count,
0059               dim[1].delta, dim[1].count, callback);
0060     else if ( dim.size() == 3 )
0061       generate_placements(m_start.delta,
0062               dim[0].delta, dim[0].count,
0063               dim[1].delta, dim[1].count,
0064               dim[2].delta, dim[2].count, callback);
0065   }
0066 }
0067 
0068 /// Access number of replicas
0069 std::size_t dd4hep::sim::Geant4PlacementParameterisation::count()  const   {
0070   return m_num_cells;
0071 }
0072 
0073 /// Callback to store resulting rotation
0074 void dd4hep::sim::Geant4PlacementParameterisation::operator()(const G4Transform3D& transform)   {
0075   this->m_translations.emplace_back(transform.getTranslation());
0076   if ( this->m_have_rotation )   {
0077     G4RotationMatrix rot = transform.inverse().getRotation();
0078     this->m_rotations.emplace_back(rot);
0079   }
0080 }
0081 
0082 /// G4VPVParameterisation overload: Callback to place sub-volumes
0083 void dd4hep::sim::Geant4PlacementParameterisation::ComputeTransformation(const G4int copy, G4VPhysicalVolume *pv) const  {
0084   const auto& dim = m_dimensions;
0085   std::size_t nd  = dim.size();
0086   if ( !m_have_rotation )    {
0087     G4ThreeVector tra = m_start.translation;
0088     if ( nd >= 1 )   {
0089       std::size_t d1 = 0;
0090       if (nd == 1) d1 = copy;
0091       else if (nd >= 2) d1 = copy%dim[1].count;
0092       tra = tra + (dim[0].translation * d1);
0093     }
0094     if ( nd >= 2 )   {
0095       std::size_t d2 = 0;
0096       if (nd == 2) d2 = copy / dim[0].count;
0097       else if (nd >= 3 ) d2 = copy%dim[2].count / dim[0].count;
0098       tra = tra + (dim[1].translation * d2);
0099     }
0100     if ( nd >= 3 )   {
0101       std::size_t d3 = 0;
0102       if ( nd == 3 ) d3 = copy / (dim[0].count*dim[1].count);
0103       tra = tra + (dim[2].translation * d3);
0104     }
0105     pv->SetTranslation(tra);
0106     return;
0107   }
0108   G4RotationMatrix& rot = m_rotations.at(copy);
0109   pv->SetTranslation(m_translations.at(copy));
0110   pv->SetRotation(&rot);
0111 }