Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 08:20:11

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 /// Geant4 include files
0015 #include <G4LogicalVolume.hh>
0016 #include <G4VPhysicalVolume.hh>
0017 #include <G4ReflectionFactory.hh>
0018 
0019 /// C/C++ include files
0020 #include <sstream>
0021 #include <string>
0022 
0023 /// Framework include files
0024 #include <DD4hep/DetectorTools.h>
0025 #include <DDG4/Geant4Converter.h>
0026 #include <DDG4/Geant4GeometryInfo.h>
0027 #include <DDG4/Geant4AssemblyVolume.h>
0028 
0029 using namespace dd4hep::sim;
0030 
0031 /// Default constructor with initialization
0032 Geant4AssemblyVolume::Geant4AssemblyVolume() {
0033   m_assembly = new G4AssemblyVolume();
0034 }
0035 
0036       
0037 /// Default destructor
0038 Geant4AssemblyVolume::~Geant4AssemblyVolume()   {
0039   // Do not delete the G4 assembly. This is done by Geant4!
0040   m_assembly = nullptr;
0041 }
0042 
0043 /// Place logical daughter volume into the assembly
0044 long Geant4AssemblyVolume::placeVolume(const TGeoNode* n,
0045                                        G4LogicalVolume* pPlacedVolume,
0046                                        G4Transform3D& transformation)
0047 {
0048   size_t id = m_assembly->TotalTriplets();
0049   m_entries.emplace_back(n);
0050   m_places.emplace_back(nullptr);
0051   m_assembly->AddPlacedVolume(pPlacedVolume, transformation);
0052   return (long)id;
0053 }
0054 
0055 /// Place daughter assembly into the assembly
0056 long Geant4AssemblyVolume::placeAssembly(const TGeoNode* n,
0057                                          Geant4AssemblyVolume* pPlacedVolume,
0058                                          G4Transform3D& transformation)
0059 {
0060   size_t id = m_assembly->TotalTriplets();
0061   m_entries.emplace_back(n);
0062   m_places.emplace_back(pPlacedVolume);
0063   m_assembly->AddPlacedAssembly(pPlacedVolume->m_assembly, transformation);
0064   return (long)id;
0065 }
0066 
0067 /// Expand all daughter placements and expand the contained assemblies to imprints
0068 void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
0069                                    const TGeoNode*        parent,
0070                                    Chain                  chain,
0071                                    Geant4AssemblyVolume*  pParentAssembly,
0072                                    G4LogicalVolume*       pMotherLV,
0073                                    G4Transform3D&         transformation,
0074                                    G4bool                 surfCheck)
0075 {
0076   struct _Wrap : public G4AssemblyVolume  {
0077     static void imprintsCountPlus(G4AssemblyVolume* p)
0078     {  _Wrap* w = (_Wrap*)p; w->ImprintsCountPlus(); }
0079   };
0080   std::string       path;
0081   TGeoVolume*       vol = parent->GetVolume();
0082   G4AssemblyVolume* par_ass = pParentAssembly->m_assembly;
0083   Geant4GeometryInfo&  info = cnv.data();
0084 
0085   _Wrap::imprintsCountPlus(par_ass);
0086 
0087   path = detail::tools::placementPath(chain);
0088   printout(cnv.debugPlacements ? ALWAYS : DEBUG, "Geant4Converter",
0089            "++ Assembly: %s", path.c_str());
0090   std::vector<G4AssemblyTriplet>::iterator iter = par_ass->GetTripletsIterator();
0091   for( unsigned int i = 0, n = par_ass->TotalTriplets(); i < n; i++, iter++ )  {
0092     Chain            new_chain = chain;
0093     const auto&        triplet = *iter;
0094     const TGeoNode*       node = pParentAssembly->m_entries[i];
0095     Geant4AssemblyVolume* avol = pParentAssembly->m_places[i];
0096     
0097     new_chain.emplace_back(node);
0098     path = detail::tools::placementPath(new_chain);
0099     printout(cnv.debugPlacements ? ALWAYS : DEBUG, "Geant4Converter",
0100              " Assembly: Entry: %s", path.c_str());
0101 
0102     G4Transform3D Ta( *(triplet.GetRotation()), triplet.GetTranslation() );
0103     if( triplet.IsReflection() )  {
0104       Ta = Ta * G4ReflectZ3D();
0105     }
0106     G4Transform3D Tfinal = transformation * Ta;
0107     if( triplet.GetVolume() )  {
0108       // Generate the unique name for the next PV instance
0109       // The name has format:
0110       //
0111       // av_WWW_impr_XXX_YYY_ZZZ
0112       // where the fields mean:
0113       // WWW - assembly volume instance number
0114       // XXX - assembly volume imprint number
0115       // YYY - the name of a log. volume we want to make a placement of
0116       // ZZZ - the log. volume index inside the assembly volume
0117       //
0118       std::stringstream pvName;
0119       pvName << "AV_"
0120              << m_assembly->GetAssemblyID()
0121              << '!'
0122              << parent->GetName()
0123              << '#'
0124              << parent->GetNumber()
0125              << '!'
0126              << node->GetName()
0127              << '#'
0128              << node->GetNumber()
0129              << std::ends;
0130       // Generate a new physical volume instance inside a mother
0131       // (as we allow 3D transformation use G4ReflectionFactory to
0132       //  take into account eventual reflection)
0133       //
0134       G4PhysicalVolumesPair pvPlaced
0135         = G4ReflectionFactory::Instance()->Place( Tfinal,
0136                                                   pvName.str().c_str(),
0137                                                   triplet.GetVolume(),
0138                                                   pMotherLV,
0139                                                   false,
0140                                                   node->GetNumber(),
0141                                                   surfCheck );
0142 
0143       info.g4VolumeImprints[vol].emplace_back(new_chain, pvPlaced.first);
0144       printout(cnv.debugPlacements ? ALWAYS : DEBUG,
0145                "Geant4Converter", "++ Place %svolume %s in assembly.",
0146                triplet.IsReflection() ? "REFLECTED " : "", path.c_str());
0147       printout(cnv.debugPlacements ? ALWAYS : DEBUG,
0148                "Geant4Converter", " Assembly:Parent: %s %s %p G4:%s",
0149                parent->GetName(), node->GetName(),
0150                (void*)node, pvName.str().c_str());
0151       if( pvPlaced.second )  {
0152         G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException,
0153                     "Fancy construct popping new mother from the stack!");
0154       }
0155     }
0156     else if( triplet.GetAssembly() )  {
0157       // Place volumes in this assembly with composed transformation
0158       imprint(cnv, parent, std::move(new_chain), avol, pMotherLV, Tfinal, surfCheck );
0159     }
0160     else  {
0161       G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException,
0162                   "Triplet has no volume and no assembly");
0163     }
0164   }
0165 }