Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/dna/chem6/src/ScoreSpecies.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // This example is provided by the Geant4-DNA collaboration
 27 // chem6 example is derived from chem4 and chem5 examples
 28 //
 29 // Any report or published results obtained using the Geant4-DNA software
 30 // shall cite the following Geant4-DNA collaboration publication:
 31 // J. Appl. Phys. 125 (2019) 104301
 32 // Med. Phys. 45 (2018) e722-e739
 33 // J. Comput. Phys. 274 (2014) 841-882
 34 // Med. Phys. 37 (2010) 4692-4708
 35 // Int. J. Model. Simul. Sci. Comput. 1 (2010) 157-178
 36 // The Geant4-DNA web site is available at http://geant4-dna.org
 37 //
 38 // Authors: W. G. Shin and S. Incerti (CENBG, France)
 39 //
 40 // $Id$
 41 //
 42 /// \file ScoreSpecies.cc
 43 /// \brief Implementation of the ScoreSpecies class
 44 
 45 #include "ScoreSpecies.hh"
 46 
 47 #include "G4AnalysisManager.hh"
 48 #include "G4Event.hh"
 49 #include "G4Scheduler.hh"
 50 #include "G4TScoreNtupleWriter.hh"
 51 #include "G4UImessenger.hh"
 52 #include "G4UnitsTable.hh"
 53 
 54 #include <G4EventManager.hh>
 55 #include <G4MolecularConfiguration.hh>
 56 #include <G4MoleculeCounter.hh>
 57 #include <G4SystemOfUnits.hh>
 58 #include <globals.hh>
 59 
 60 /**
 61  \file ScoreSpecies.cc
 62  \class ScoreSpecies
 63   This is a primitive scorer class for molecular species.
 64   The number of species is recorded for all times (predetermined or
 65   user chosen). It also scores the energy deposition in order to compute the
 66   radiochemical yields.
 67 */
 68 extern std::ofstream out;
 69 
 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
 71 
 72 ScoreSpecies::ScoreSpecies(G4String name, G4int depth)
 73   : G4VPrimitiveScorer(name, depth),
 74     G4UImessenger(),
 75     fEdep(0),
 76     fOutputType("root"),  // other options: "csv", "hdf5", "xml"
 77     fHCID(-1),
 78     fEvtMap(0)
 79 {
 80   fSpeciesdir = new G4UIdirectory("/scorer/species/");
 81   fSpeciesdir->SetGuidance("ScoreSpecies commands");
 82 
 83   fAddTimeToRecordcmd = new G4UIcmdWithADoubleAndUnit("/scorer/species/addTimeToRecord", this);
 84 
 85   fTimeBincmd = new G4UIcmdWithAnInteger("/scorer/species/nOfTimeBins", this);
 86 
 87   fEdep = 0;
 88   fNEvent = 0;
 89   fRunID = 0;
 90   G4MoleculeCounter::Instance()->ResetCounter();
 91 }
 92 
 93 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
 94 
 95 ScoreSpecies::~ScoreSpecies()
 96 {
 97   delete fSpeciesdir;
 98   delete fAddTimeToRecordcmd;
 99   delete fTimeBincmd;
100 }
101 
102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
103 
104 void ScoreSpecies::SetNewValue(G4UIcommand* command, G4String newValue)
105 {
106   if (command == fAddTimeToRecordcmd) {
107     G4double cmdTime = fAddTimeToRecordcmd->GetNewDoubleValue(newValue);
108     AddTimeToRecord(cmdTime);
109   }
110   if (command == fTimeBincmd) {
111     ClearTimeToRecord();
112     G4int cmdBins = fTimeBincmd->GetNewIntValue(newValue);
113     G4double timeMin = 1 * ps;
114     G4double timeMax = G4Scheduler::Instance()->GetEndTime() - 1 * ps;
115     G4double timeLogMin = std::log10(timeMin);
116     G4double timeLogMax = std::log10(timeMax);
117     for (G4int i = 0; i < cmdBins; i++) {
118       AddTimeToRecord(std::pow(10, timeLogMin + i * (timeLogMax - timeLogMin) / (cmdBins - 1)));
119     }
120   }
121 }
122 
123 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
124 
125 G4bool ScoreSpecies::ProcessHits(G4Step* aStep, G4TouchableHistory*)
126 {
127   G4double edep = aStep->GetTotalEnergyDeposit();
128 
129   if (edep == 0.) return FALSE;
130 
131   edep *= aStep->GetPreStepPoint()->GetWeight();  // (Particle Weight)
132   G4int index = GetIndex(aStep);
133   fEvtMap->add(index, edep);
134   fEdep += edep;
135 
136   return TRUE;
137 }
138 
139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
140 
141 void ScoreSpecies::Initialize(G4HCofThisEvent* HCE)
142 {
143   fEvtMap = new G4THitsMap<G4double>(GetMultiFunctionalDetector()->GetName(), GetName());
144 
145   if (fHCID < 0) {
146     fHCID = GetCollectionID(0);
147   }
148 
149   HCE->AddHitsCollection(fHCID, (G4VHitsCollection*)fEvtMap);
150   G4MoleculeCounter::Instance()->ResetCounter();
151 }
152 
153 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
154 
155 void ScoreSpecies::EndOfEvent(G4HCofThisEvent*)
156 {
157   if (G4EventManager::GetEventManager()->GetConstCurrentEvent()->IsAborted()) {
158     fEdep = 0.;
159     G4MoleculeCounter::Instance()->ResetCounter();
160     return;
161   }
162 
163   auto species = G4MoleculeCounter::Instance()->GetRecordedMolecules();
164 
165   if (species.get() == 0 || species->size() == 0) {
166     G4cout << "No molecule recorded, energy deposited= " << G4BestUnit(fEdep, "Energy") << G4endl;
167     ++fNEvent;
168     fEdep = 0.;
169     G4MoleculeCounter::Instance()->ResetCounter();
170     return;
171   }
172 
173   //  G4cout << "ScoreSpecies::EndOfEvent"<<G4endl;
174   //  G4cout << "End of event, deposited energy: "
175   //  << G4BestUnit(fEdep, "Energy") << G4endl;
176 
177   for (auto molecule : *species) {
178     for (auto time_mol : fTimeToRecord) {
179       double n_mol = G4MoleculeCounter::Instance()->GetNMoleculesAtTime(molecule, time_mol);
180 
181       if (n_mol < 0) {
182         G4cerr << "N molecules not valid < 0 " << G4endl;
183         G4Exception("", "N<0", FatalException, "");
184       }
185 
186       SpeciesInfo& molInfo = fSpeciesInfoPerTime[time_mol][molecule];
187       molInfo.fNumber += n_mol;
188       double gValue = (n_mol / (fEdep / eV)) * 100.;
189       molInfo.fG += gValue;
190       molInfo.fG2 += gValue * gValue;
191 
192       //      G4cout << "In Save molucule: fNumber " << molInfo.fNumber
193       //            << " fG " << molInfo.fG
194       //            << " fEdep " << fEdep/eV
195       //            << G4endl;
196     }
197   }
198 
199   ++fNEvent;
200 
201   //  G4cout << "End of event " << fNEvent
202   //         << ", energy deposited=" << G4BestUnit(fEdep, "Energy") << G4endl;
203 
204   fEdep = 0.;
205   G4MoleculeCounter::Instance()->ResetCounter();
206 }
207 
208 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
209 
210 void ScoreSpecies::AbsorbResultsFromWorkerScorer(G4VPrimitiveScorer* workerScorer)
211 {
212   ScoreSpecies* right =
213     dynamic_cast<ScoreSpecies*>(dynamic_cast<G4VPrimitiveScorer*>(workerScorer));
214 
215   if (right == 0) {
216     return;
217   }
218   if (right == this) {
219     return;
220   }
221 
222   // G4cout<<"ScoreSpecies::AbsorbResultsFromWorkerScorer"<<G4endl;
223   SpeciesMap::iterator it_map1 = right->fSpeciesInfoPerTime.begin();
224   SpeciesMap::iterator end_map1 = right->fSpeciesInfoPerTime.end();
225 
226   for (; it_map1 != end_map1; ++it_map1) {
227     InnerSpeciesMap& map2 = it_map1->second;
228     InnerSpeciesMap::iterator it_map2 = map2.begin();
229     InnerSpeciesMap::iterator end_map2 = map2.end();
230 
231     for (; it_map2 != end_map2; ++it_map2) {
232       SpeciesInfo& molInfo = fSpeciesInfoPerTime[it_map1->first][it_map2->first];
233       molInfo.fNumber += it_map2->second.fNumber;
234       molInfo.fG += it_map2->second.fG;
235       molInfo.fG2 += it_map2->second.fG2;
236 
237       //      G4cout << "In AbsorbeResultsFromWorkerScorer: fNumber "
238       //             << molInfo.fNumber
239       //             << " fG "
240       //             << molInfo.fG
241       //             << G4endl;
242     }
243   }
244   right->fSpeciesInfoPerTime.clear();
245 
246   fNEvent += right->fNEvent;
247   right->fNEvent = 0;
248   right->fEdep = 0.;
249 }
250 
251 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
252 
253 void ScoreSpecies::DrawAll()
254 {
255   ;
256 }
257 
258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
259 
260 void ScoreSpecies::PrintAll()
261 {
262   G4cout << " MultiFunctionalDet  " << detector->GetName() << G4endl;
263   G4cout << " PrimitiveScorer " << GetName() << G4endl;
264   G4cout << " Number of events " << fNEvent << G4endl;
265   G4cout << " Number of energy deposition recorded " << fEvtMap->entries() << G4endl;
266 
267   for (auto itr : *fEvtMap->GetMap()) {
268     G4cout << "  copy no.: " << itr.first << "  energy deposit: " << *(itr.second) / GetUnitValue()
269            << " [" << GetUnit() << "]" << G4endl;
270   }
271 }
272 
273 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
274 
275 void ScoreSpecies::OutputAndClear()
276 {
277   if (G4Threading::IsWorkerThread()) return;
278 
279   //---------------------------------------------------------------------------
280   // Save results
281 
282   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
283   analysisManager->SetDefaultFileType(fOutputType);
284 
285   if (analysisManager) {
286     this->WriteWithAnalysisManager(analysisManager);
287   }
288 
289   fNEvent = 0;
290   fSpeciesInfoPerTime.clear();
291 }
292 
293 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
294 
295 void ScoreSpecies::WriteWithAnalysisManager(G4VAnalysisManager* analysisManager)
296 {
297   G4String fileN = "Species" + G4UIcommand::ConvertToString(fRunID);
298   analysisManager->OpenFile(fileN);
299   int fNtupleID = analysisManager->CreateNtuple("species", "species");
300   analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
301   analysisManager->CreateNtupleIColumn(fNtupleID, "number");
302   analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
303   analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
304   analysisManager->CreateNtupleDColumn(fNtupleID, "time");
305   analysisManager->CreateNtupleDColumn(fNtupleID, "sumG");
306   analysisManager->CreateNtupleDColumn(fNtupleID, "sumG2");
307   analysisManager->FinishNtuple(fNtupleID);
308 
309   for (auto it_map1 : fSpeciesInfoPerTime) {
310     InnerSpeciesMap& map2 = it_map1.second;
311 
312     if (it_map1.first == fSpeciesInfoPerTime.begin()->first) {
313       for (auto it_molname : map2) {
314         auto tmp_species = it_molname.first;
315         out << std::setw(12) << tmp_species->GetName() << std::setw(12)
316             << tmp_species->GetMoleculeID();
317       }
318       out << '\n';
319     }
320 
321     for (auto it_map2 : map2) {
322       double time = it_map1.first;
323       auto species = it_map2.first;
324       const G4String& name = species->GetName();
325       int molID = it_map2.first->GetMoleculeID();
326       int number = it_map2.second.fNumber;
327       double G = it_map2.second.fG;
328       double G2 = it_map2.second.fG2;
329       G4int N = fNEvent;
330 
331       if (time == *fTimeToRecord.rbegin()) {
332         if (N > 1) {
333           out << std::setw(12) << G / N << std::setw(12)
334               << std::sqrt(((G2 / N) - std::pow(G / N, 2)) / (N - 1));
335         }
336         else {
337           out << std::setw(12) << G / N << std::setw(12)
338               << std::sqrt(((G2 / N) - std::pow(G / N, 2)) / N);
339         }
340       }
341 
342       analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);  // MolID
343       analysisManager->FillNtupleIColumn(fNtupleID, 1, number);  // Number
344       analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);  // Total nb events
345       analysisManager->FillNtupleSColumn(fNtupleID, 3, name);  // molName
346       analysisManager->FillNtupleDColumn(fNtupleID, 4, time);  // time
347       analysisManager->FillNtupleDColumn(fNtupleID, 5, G);  // G
348       analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);  // G2
349       analysisManager->AddNtupleRow(fNtupleID);
350     }
351   }
352 
353   analysisManager->Write();
354   analysisManager->CloseFile();
355   fRunID++;
356 }
357 
358 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
359