Warning, file /geant4/examples/advanced/dna/moleculardna/src/SteppingAction.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "SteppingAction.hh"
0030
0031 #include "ChromosomeMapper.hh"
0032 #include "DNAGeometry.hh"
0033 #include "DNAHit.hh"
0034 #include "DetectorConstruction.hh"
0035 #include "EventAction.hh"
0036 #include "OctreeNode.hh"
0037 #include "PlacementVolumeInfo.hh"
0038 #include "UtilityFunctions.hh"
0039
0040 #include "G4AffineTransform.hh"
0041 #include "G4LogicalVolume.hh"
0042 #include "G4RunManager.hh"
0043 #include "G4StepPoint.hh"
0044 #include "G4ThreeVector.hh"
0045 #include "G4VPhysicalVolume.hh"
0046 #include "G4VTouchable.hh"
0047 #include "Randomize.hh"
0048
0049
0050
0051 SteppingAction::SteppingAction(EventAction* evt) : fEventAction(evt)
0052 {
0053 const auto* det = dynamic_cast<const DetectorConstruction*>(
0054 G4RunManager::GetRunManager()->GetUserDetectorConstruction());
0055
0056 fDNAGeometry = det->GetDNAGeometry();
0057 }
0058
0059
0060
0061 void SteppingAction::UserSteppingAction(const G4Step* aStep)
0062 {
0063 G4double edep = aStep->GetTotalEnergyDeposit();
0064 if (edep == 0) {
0065 return;
0066 }
0067
0068
0069 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
0070
0071
0072 G4LogicalVolume* dnaVol = fDNAGeometry->GetDNAChemVolumePointer();
0073 G4int depth = touch->GetHistoryDepth();
0074 G4bool isInDNARegion = false;
0075
0076 if (depth >= 0) {
0077 fEventAction->AddCellEdep(edep);
0078 }
0079
0080 while ((depth >= 0) && !isInDNARegion) {
0081 if (touch->GetVolume(depth) != nullptr) {
0082 isInDNARegion = isInDNARegion || (touch->GetVolume(depth)->GetLogicalVolume() == dnaVol);
0083 }
0084 else {
0085 G4cout << "Null pointer volume in mother with depth of " << touch->GetHistoryDepth()
0086 << " looking for volume at depth " << depth << G4endl;
0087 assert(depth < 0);
0088 }
0089 depth--;
0090 }
0091
0092 if (isInDNARegion) {
0093 ProcessDNARegionHit(aStep);
0094 }
0095
0096 G4ThreeVector prepos = aStep->GetPreStepPoint()->GetPosition();
0097 if (fDNAGeometry->GetChromosomeMapper()->GetChromosome(prepos) != nullptr) {
0098 DoChromosomeRegionHit(prepos, edep, false);
0099 }
0100
0101 if (aStep->GetTrack()->GetTrackID() == 1) {
0102 fEventAction->SetPrimStopPos(prepos);
0103 G4double tl = aStep->GetStepLength();
0104 fEventAction->AddTrackLengthCell(tl);
0105 if (fDNAGeometry->GetChromosomeMapper()->GetChromosome(prepos) != nullptr) {
0106 fEventAction->AddTrackLengthChro(tl);
0107 }
0108 }
0109 }
0110
0111
0112
0113 void SteppingAction::ProcessDNARegionHit(const G4Step* aStep)
0114 {
0115 G4double edep = aStep->GetTotalEnergyDeposit();
0116 const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
0117 G4ThreeVector pos =
0118 aStep->GetPreStepPoint()->GetPosition()
0119 + G4UniformRand()
0120 * (aStep->GetPostStepPoint()->GetPosition() - aStep->GetPreStepPoint()->GetPosition());
0121 G4VPhysicalVolume* pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
0122 G4LogicalVolume* lv = pv->GetLogicalVolume();
0123
0124 std::vector<G4VPhysicalVolume*> molvec;
0125 OctreeNode* parentNode;
0126 G4AffineTransform transform = touch->GetHistory()->GetTopTransform();
0127 parentNode = fDNAGeometry->GetTopOctreeNode(lv);
0128 if (parentNode == nullptr) {
0129 parentNode = fDNAGeometry->GetTopOctreeNode(pv->GetMotherLogical());
0130 if (parentNode != nullptr) {
0131
0132
0133
0134 pv = touch->GetVolume(1);
0135 transform = touch->GetHistory()->GetTransform(touch->GetHistoryDepth() - 1);
0136 }
0137 }
0138
0139 G4ThreeVector localPos = transform.TransformPoint(pos);
0140
0141 if (parentNode != nullptr) {
0142 molvec = parentNode->SearchOctree(localPos, fDNAGeometry->GetDirectInteractionRange());
0143 }
0144
0145
0146 if (fDNAGeometry->GetVerbosity() > 1) {
0147 if (parentNode != nullptr) {
0148 G4String lvname = pv->GetLogicalVolume()->GetName();
0149 G4cout << "Found octree for logical volume: " << lvname << G4endl;
0150 }
0151 else {
0152
0153
0154
0155 if (pv->GetLogicalVolume() != fDNAGeometry->GetDNAChemVolumePointer()) {
0156 G4String lvname = pv->GetLogicalVolume()->GetName();
0157 G4String motherlvname;
0158 if (lv != nullptr) {
0159 motherlvname = lv->GetName();
0160 }
0161 G4cout << "Could not find octree for logical volume." << G4endl
0162 << "Particle in LV: " << lvname << ", with mother LV: " << motherlvname << G4endl;
0163 }
0164 }
0165 }
0166
0167 if (!molvec.empty()) {
0168
0169 G4VPhysicalVolume* closest = molvec[0];
0170 G4double dist = (closest->GetTranslation() - localPos).mag();
0171 if (molvec.size() > 1) {
0172 G4double newdist;
0173 for (auto it = molvec.begin() + 1; it != molvec.end(); it++) {
0174 newdist = ((*it)->GetTranslation() - localPos).mag();
0175 if (newdist < dist) {
0176 dist = newdist;
0177 closest = (*it);
0178 }
0179 }
0180 }
0181 G4bool isDNAHit = (dist < fDNAGeometry->GetDirectInteractionRange());
0182 if (isDNAHit) {
0183 DoChromosomeDNAHit(pos, localPos, edep, dist, closest->GetName(), pv->GetName());
0184 DoChromosomeRegionHit(pos, edep, true);
0185 }
0186 }
0187 }
0188
0189
0190
0191 void SteppingAction::DoChromosomeRegionHit(const G4ThreeVector& pos, const G4double& edep,
0192 const G4bool& dnahit)
0193 {
0194
0195
0196 G4String chromosome = fDNAGeometry->GetChromosomeMapper()->GetCurrentChromosomeKey(pos);
0197 if (!(chromosome.empty())) {
0198 fEventAction->AddChromosomeEdep(chromosome, edep, dnahit);
0199 }
0200 }
0201
0202
0203
0204 void SteppingAction::DoChromosomeDNAHit(const G4ThreeVector& pos, const G4ThreeVector& localPos,
0205 const G4double& edep, const G4double& dist,
0206 const G4String& pvName, const G4String& motherName)
0207 {
0208 G4int placementIdx = std::stoi(utility::Split(motherName, '-').at(1));
0209 std::vector<G4String> pvNameVec = utility::Split(pvName, '-');
0210 molecule mol = utility::GetMoleculeEnum(pvNameVec.at(0));
0211 G4int chainIdx = std::stoi(pvNameVec.at(1));
0212 G4int strandIdx = std::stoi(pvNameVec.at(2));
0213 int64_t baseIdx = std::stoll(pvNameVec.at(3));
0214
0215
0216 chainIdx = fDNAGeometry->GetGlobalChain(placementIdx, chainIdx);
0217 baseIdx += fDNAGeometry->GetStartIdx(placementIdx, chainIdx);
0218
0219 if (fDNAGeometry->GetStrandsFlipped(placementIdx)) {
0220 strandIdx = (strandIdx + 1) % 2;
0221 }
0222 G4String chromosome = fDNAGeometry->GetChromosomeMapper()->GetCurrentChromosomeKey(pos);
0223 const DNAHit* dnaHit = new DNAHit(mol, placementIdx, chainIdx, strandIdx, baseIdx, pos, localPos,
0224 edep, dist, chromosome);
0225
0226 fEventAction->AddDNAHit(dnaHit);
0227 }
0228
0229