Files
2024-12-06 11:11:40 +01:00

364 lines
12 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
/// file: DNAGeometry.hh
/// brief: This file handls MolecularDNA Geometry
#ifndef MOLECULAR_DNA_GEOMETRY_HH
#define MOLECULAR_DNA_GEOMETRY_HH
#include "ChromosomeMapper.hh"
#include "DNAWorld.hh"
#include "DamageModel.hh"
#include "MoleculeList.hh"
#include "UtilityFunctions.hh"
#include "G4LogicalVolume.hh"
#include "G4SystemOfUnits.hh"
#include "G4ThreeVector.hh"
#include "G4VDNAMolecularGeometry.hh"
#include "G4VPhysicalVolume.hh"
#include "G4VTouchable.hh"
#include "globals.hh"
#include <array>
#include <map>
#include <unordered_map>
#include <vector>
class G4Material;
class G4MolecularConfiguration;
class G4VisAttributes;
class OctreeNode;
class DNAGeometryMessenger;
class PlacementVolumeInfo;
using placement = std::tuple<G4LogicalVolume*, int64_t, int64_t, G4ThreeVector,
G4ThreeVector>; // dousatsu
// G4int, G4int, G4ThreeVector, G4ThreeVector> placement;//ORG
// Holder to describe the global co-ordinates of each DNA chain
// in a given placement volume
// Format << array of global chain indices for local indices 0, 1, 2, 3>
// < array of start indices for the base pairs along each chain,
// given by GLOBAL chain index>
// < array of end indices for the base pairs along each chain,
// given by GLOBAL chain index>
// < Boolean to indicate if the strand ID should be flipped due
// to a 180 degree rotation of the DNA >
// < Boolean to indicate if volume has actually been placed >
using placement_transform =
std::tuple<std::array<int, 8>, std::array<int64_t, 8>, std::array<int64_t, 8>, G4bool, G4bool>;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
struct molecule_t
{
G4String fname;
G4String fshape;
int64_t fchain_id;
int64_t fstrand_id;
int64_t fbase_idx;
G4ThreeVector fposition;
G4ThreeVector frotation;
G4ThreeVector fsize;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
struct compareLVByName
{
bool operator()(const G4LogicalVolume* lhs, const G4LogicalVolume* rhs) const;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DNAGeometry : public G4VDNAMolecularGeometry
{
public:
DNAGeometry();
~DNAGeometry() override;
void BuildDNA(G4LogicalVolume*);
inline DNAWorld* GetDNAWorld();
void AddVoxelFile(const G4String& vname, const G4String& fname, const G4bool& twist)
{
fVoxelNames[vname] = fname;
fVoxelTwist[vname] = twist;
}
void SetFractalFilename(const G4String& fname)
{
fFractalCurveFile = fname;
FillVoxelVectors();
}
void SetFractalAnglesAsPi(const G4bool& value) { fAnglesAsPi = value; }
void EnableCustomMoleculeSizes(const G4bool& value) { fEnableCustomMoleculeSizes = value; }
void AddChangeMoleculeSize(const G4String& name, const G4ThreeVector& size);
inline void SetVoxelSideLength(const G4ThreeVector& length) { fVoxelSideLength = length; }
inline void SetFractalScaling(const G4ThreeVector& length) { fFractalScaling = length; }
OctreeNode* GetTopOctreeNode(G4LogicalVolume*) const;
const PlacementVolumeInfo* GetPVInfo(const G4LogicalVolume*) const;
inline auto GetChromosomeMapper() const { return fpChromosomeMapper; };
inline void SetOverlaps(G4bool overlap) { fCheckOverlaps = overlap; };
inline G4bool GetOverlaps() const { return fCheckOverlaps; };
inline void SetDrawCellVolumes(G4bool b) { fDrawCellVolumes = b; };
inline G4bool GetDrawCellVolumes() const { return fDrawCellVolumes; };
inline void SetVerbosity(G4int i) { fVerbosity = i; };
inline G4int GetVerbosity() const { return fVerbosity; };
inline void SetSmartless(G4int i) { fSmartless = i; };
inline G4int GetSmartless() const { return fSmartless; };
inline void SetMediumMaterial(G4Material* mat) { fpMediumMaterial = mat; };
inline G4LogicalVolume* GetDNAChemVolumePointer() const;
inline G4LogicalVolume* GetDNAPhysicsVolumePointer() const;
G4LogicalVolume* GetMatchingChemVolume(G4LogicalVolume*) const;
G4LogicalVolume* GetMatchingPhysVolume(G4LogicalVolume*) const;
void PrintOctreeStats();
inline void SetDirectInteractionRange(G4double r) { fDirectInteractionRange = r; };
void SetRadicalKillDistance(G4double r) { fRadicalKillDistance = r; };
void SetHistoneScav(G4bool hf) { fUseHistoneScav = hf; };
inline G4double GetDirectInteractionRange() const { return fDirectInteractionRange; };
G4double GetRadicalKillDistance() const { return fRadicalKillDistance; };
const DamageModel* GetDamageModel() { return fpDamageModel; };
// Tests
void ChromosomeTest();
void BasePairIndexTest();
void UniqueIDTest();
int64_t GetGlobalUniqueIDTest( // dousatsu
int64_t, int64_t, int64_t, int64_t, int64_t) const; // dousatsu
private:
DNAGeometryMessenger* fpMessenger;
G4String fFractalCurveFile;
G4bool fAnglesAsPi = false;
G4bool fEnableCustomMoleculeSizes = false;
G4bool fCheckOverlaps = false;
G4bool fDrawCellVolumes = false;
G4int fVerbosity = 0;
G4bool fUseHistoneScav = true;
// vis attrs to draw cells
G4VisAttributes* fpDrawCellAttrs;
// Materials
G4Material* fpMediumMaterial;
G4Material *fpSugarMaterial, *fpPhosphateMaterial;
G4Material *fpGuanineMaterial, *fpAdenineMaterial, *fpThymineMaterial;
G4Material *fpCytosineMaterial, *fpHistoneMaterial;
// Placement of molecules
void FillParameterisedSpace();
G4VPhysicalVolume* PlacePhosphate(G4LogicalVolume*, const molecule_t&, const molecule_t&);
G4VPhysicalVolume* PlaceSugar(G4LogicalVolume*, const molecule_t&, const molecule_t&);
G4VPhysicalVolume* PlaceBase(G4LogicalVolume*, const molecule_t&, const molecule_t&,
const molecule_t&, const molecule_t&);
G4VPhysicalVolume* PlaceHistone(G4LogicalVolume*, // dousatsu
const molecule_t&);
// defining voxels
std::pair<G4LogicalVolume*, PlacementVolumeInfo*> LoadVoxelVolume(const G4String&,
const G4String&);
void FillVoxelVectors();
G4LogicalVolume *fpDNAVolumePhys{}, *fpDNAVolumeChem{};
std::map<const G4LogicalVolume*, G4LogicalVolume*> fPhysToChem;
std::map<const G4LogicalVolume*, G4LogicalVolume*> fChemToPhys;
std::vector<G4ThreeVector> fVoxelPositions;
std::vector<G4ThreeVector> fVoxelRotations;
std::vector<G4String> fVoxelTypes;
std::vector<G4int> fVoxelIndices;
// std::vector<G4LogicalVolume *> fVoxelLogicalVolumes;
G4ThreeVector fVoxelSideLength = G4ThreeVector(75 * nm, 75 * nm, 75 * nm);
G4ThreeVector fFractalScaling = G4ThreeVector(1, 1, 1);
std::map<G4String, G4String> fVoxelNames; // For these, the first el.
std::map<G4String, G4bool> fVoxelTwist; // is also lv->GetName()
std::map<const G4LogicalVolume*, PlacementVolumeInfo*> fInfoMap;
std::map<G4String, G4ThreeVector> fMoleculeSizes;
G4double fSmartless = 2.0;
G4double fRadicalKillDistance = 10 * nm, fDirectInteractionRange = 6 * angstrom;
G4double fHistoneInteractionRadius = 25 * angstrom;
ChromosomeMapper* fpChromosomeMapper;
DamageModel* fpDamageModel;
DNAWorld* fpDNAPhysicsWorld;
// Members for placement transformations
public:
inline int64_t GetNumberOfPlacements() const
{
return (int64_t)fPlacementTransformations.size();
}
G4int GetGlobalChain(G4int vol_idx, G4int local_chain) const
{
return std::get<0>(fPlacementTransformations[vol_idx])[local_chain];
};
G4int GetLocalChain(G4int vol_idx, G4int global_chain) const;
inline int64_t GetStartIdx(int64_t vol_idx,
int64_t global_chn) const // dousatsu
{
return std::get<1>(fPlacementTransformations[vol_idx])[global_chn];
};
inline int64_t GetEndIdx(int64_t vol_idx,
int64_t global_chn) const // dousatsu
{
return std::get<2>(fPlacementTransformations[vol_idx])[global_chn];
};
int64_t GetMaxBPIdx() const;
inline G4int GetNumberOfChains() const
{
return std::get<0>(fPlacementTransformations[0]).size();
};
inline G4bool GetStrandsFlipped(G4int vol_idx) const
{
return std::get<3>(fPlacementTransformations[vol_idx]);
};
private:
std::vector<placement_transform> fPlacementTransformations;
void AddNewPlacement(const G4LogicalVolume*, std::array<int, 8>, G4bool, G4bool);
void AddFourChainPlacement(std::vector<placement>::iterator, std::vector<placement>::iterator,
G4bool);
void AddSingleChainPlacement(std::vector<placement>::iterator, std::vector<placement>::iterator,
G4bool);
// Lookup methods for chemistry handling
public:
// Unique ID generators
inline int64_t GetGlobalPairID(G4int, G4int, int64_t) const;
int64_t GetGlobalUniqueID(G4VPhysicalVolume*, // dousatsu
const G4VTouchable*) const;
// And reconstructors from unique ID
int64_t GetBasePairFromUniqueID(int64_t) const;
static inline molecule GetMoleculeFromUniqueID(int64_t);
G4Material* GetMaterialFromUniqueID(int64_t) const;
G4int GetChainIDFromUniqueID(int64_t) const;
G4int GetStrandIDFromUniqueID(int64_t) const;
G4int GetPlacementIndexFromUniqueID(int64_t) const;
void FindNearbyMolecules(const G4LogicalVolume* motherLogical,
const G4ThreeVector& localPosition,
std::vector<G4VPhysicalVolume*>& out, double searchRange) override;
G4bool IsInsideHistone(const G4LogicalVolume* motherLogical,
const G4ThreeVector& localPosition) const;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline int64_t DNAGeometry::GetGlobalPairID(G4int place_idx, G4int chain_idx,
int64_t base_idx) const
{
return base_idx + this->GetStartIdx(place_idx, chain_idx);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline molecule DNAGeometry::GetMoleculeFromUniqueID(int64_t idx)
{
return (molecule)(idx % ::molecule::Count);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4LogicalVolume* DNAGeometry::GetDNAPhysicsVolumePointer() const
{
return fpDNAVolumePhys;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline DNAWorld* DNAGeometry::GetDNAWorld()
{
return fpDNAPhysicsWorld;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
inline G4LogicalVolume* DNAGeometry::GetDNAChemVolumePointer() const
{
return fpDNAVolumeChem;
}
#endif // MOLECULAR_DNA_GEOMETRY_HH