Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-13 08:27:56

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // The `molcounters` example(s) are provided as part of Geant4-DNA
0027 // and any report or published result obtained using it shall cite
0028 // the respective Geant4-DNA collaboration publications.
0029 //
0030 // Reports or results obtained using the spatially-aware `MoleculeCounter`
0031 // provided in this example, shall further cite:
0032 //
0033 // Velten & Tomé, Radiation Physics and Chemistry, 2023 (10.1016/j.radphyschem.2023.111194)
0034 //
0035 //
0036 // Author: Christian Velten (2025)
0037 //
0038 
0039 #ifndef MoleculeCounter_hh
0040 #define MoleculeCounter_hh 1
0041 
0042 #include "G4MolecularConfiguration.hh"
0043 #include "G4VPhysicalVolume.hh"
0044 #include "G4VTouchable.hh"
0045 #include "G4VUserMoleculeCounter.hh"
0046 
0047 #include <map>
0048 #include <set>
0049 #include <vector>
0050 
0051 class G4Navigator;
0052 
0053 class G4StepPoint;
0054 
0055 class G4Material;
0056 
0057 class G4Track;
0058 
0059 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0060 struct MoleculeCounterIndex : G4VMoleculeCounter::G4VMoleculeCounterIndex
0061 {
0062     const G4MolecularConfiguration* Molecule;
0063     const G4VPhysicalVolume* Volume;
0064     std::vector<G4int> CopyNumbers;
0065 
0066     MoleculeCounterIndex() : Molecule(nullptr), Volume(nullptr), CopyNumbers() {}
0067 
0068     MoleculeCounterIndex(const MoleculeCounterIndex&) = default;
0069 
0070     MoleculeCounterIndex(MoleculeCounterIndex&&) = default;
0071 
0072     MoleculeCounterIndex(const G4MolecularConfiguration* molecule, const G4VTouchable* touchable)
0073       : Molecule(molecule), CopyNumbers()
0074     {
0075       if (touchable == nullptr) {
0076         Volume = nullptr;
0077       }
0078       else {
0079         Volume = touchable->GetVolume();
0080         CopyNumbers.reserve(touchable->GetHistoryDepth());
0081         for (auto i = 0; i < touchable->GetHistoryDepth(); ++i)
0082           CopyNumbers.push_back(touchable->GetCopyNumber(i));
0083       }
0084     }
0085 
0086     MoleculeCounterIndex(const G4MolecularConfiguration* molecule,
0087                          const G4VPhysicalVolume* volume,  // should be removed ?
0088                          const std::vector<G4int>& copyNumbers)
0089       : Molecule(molecule), Volume(volume), CopyNumbers(copyNumbers)
0090     {}
0091 
0092     ~MoleculeCounterIndex() override = default;
0093 
0094     MoleculeCounterIndex& operator=(const MoleculeCounterIndex&) = default;
0095 
0096     MoleculeCounterIndex& operator=(MoleculeCounterIndex&&) = default;
0097 
0098     G4bool operator<(G4VMoleculeCounterIndex const& other) const override
0099     {
0100       return *this < dynamic_cast<MoleculeCounterIndex const&>(other);
0101     }
0102 
0103     G4bool operator<(MoleculeCounterIndex const& other) const
0104     {
0105       if (std::less<>{}(Molecule, other.Molecule)) return true;
0106       if (std::less<>{}(other.Molecule, Molecule)) return false;
0107 
0108       if (std::less<>{}(Volume, other.Volume)) return true;
0109       if (std::less<>{}(other.Volume, Volume)) return false;
0110 
0111       return CopyNumbers < other.CopyNumbers;
0112     }
0113 
0114     G4bool operator==(G4VMoleculeCounterIndex const& other) const override
0115     {
0116       return *this == dynamic_cast<MoleculeCounterIndex const&>(other);
0117     }
0118 
0119     G4bool operator==(const MoleculeCounterIndex& other) const
0120     {
0121       return std::tie(Molecule, Volume) == std::tie(other.Molecule, other.Volume)
0122              && CopyNumbers == other.CopyNumbers;
0123     }
0124 
0125     G4String GetInfo() const override
0126     {
0127       G4String info = "(";
0128       const G4String& null = "null";
0129       info += Molecule == nullptr ? null : Molecule->GetName();
0130       info += ", ";
0131       info += Volume == nullptr ? null : Volume->GetName();
0132       info += ")";
0133       return info;
0134     }
0135 
0136     const G4MolecularConfiguration* GetMolecule() const override { return Molecule; }
0137 };
0138 
0139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0140 class MoleculeCounter : public G4VUserMoleculeCounter<MoleculeCounterIndex>
0141 {
0142   public:
0143     MoleculeCounter(G4String = "MoleculeCounter");
0144 
0145     ~MoleculeCounter() override = default;
0146 
0147   public:
0148     void InitializeUser() override;
0149 
0150     std::unique_ptr<G4VMoleculeCounterIndex> BuildIndex(const G4Track*) const override;
0151 
0152     std::unique_ptr<G4VMoleculeCounterIndex> BuildIndex(const G4Track*,
0153                                                         const G4StepPoint*) const override;
0154 
0155     std::unique_ptr<G4VMoleculeCounterIndex>
0156     BuildSimpleIndex(const G4MolecularConfiguration*) const override;
0157 
0158     G4bool GetIgnoreMoleculePosition() const;
0159 
0160     void SetIgnoreMoleculePosition(G4bool);
0161 
0162     void SetNegativeCountsAreFatal(G4bool);
0163 
0164   protected:
0165     static G4ThreadLocal std::unique_ptr<G4Navigator> fNavigator;
0166 
0167     G4bool fIgnoreMoleculePosition{false};
0168     G4bool fIgnoreCopyNumbers{false};
0169 };
0170 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0171 #endif