Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/dna/chem4/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 // Any report or published results obtained using the Geant4-DNA software
 28 // shall cite the following Geant4-DNA collaboration publication:
 29 // Med. Phys. 37 (2010) 4692-4708
 30 // J. Comput. Phys. 274 (2014) 841-882
 31 // The Geant4-DNA web site is available at http://geant4-dna.org
 32 //
 33 // ScoreSpecies.cc
 34 //
 35 #include "ScoreSpecies.hh"
 36 
 37 #include "G4Event.hh"
 38 #include "G4UnitsTable.hh"
 39 
 40 #include <G4AnalysisManager.hh>
 41 #include <G4EventManager.hh>
 42 #include <G4MolecularConfiguration.hh>
 43 #include <G4MoleculeCounter.hh>
 44 #include <G4SystemOfUnits.hh>
 45 #include <globals.hh>
 46 
 47 /**
 48  \file ScoreSpecies.cc
 49  \class ScoreSpecies
 50   This is a primitive scorer class for molecular species.
 51   The number of species is recorded for all times (predetermined or
 52   user chosen). It also scores the energy deposition in order to compute the
 53   radiochemical yields.
 54 */
 55 
 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 57 
 58 ScoreSpecies::ScoreSpecies(G4String name, G4int depth)
 59   : G4VPrimitiveScorer(name, depth),
 60     fEdep(0),
 61     fOutputType("root"),  // other options: "csv", "hdf5", "xml"
 62     fHCID(-1),
 63     fEvtMap(0)
 64 {
 65   fNEvent = 0;
 66   AddTimeToRecord(1 * CLHEP::picosecond);
 67   AddTimeToRecord(10 * CLHEP::picosecond);
 68   AddTimeToRecord(100 * CLHEP::picosecond);
 69   AddTimeToRecord(1000 * CLHEP::picosecond);
 70   AddTimeToRecord(10000 * CLHEP::picosecond);
 71   AddTimeToRecord(100000 * CLHEP::picosecond);
 72   AddTimeToRecord(999999 * CLHEP::picosecond);
 73   fEdep = 0;
 74 }
 75 
 76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 77 
 78 ScoreSpecies::~ScoreSpecies()
 79 {
 80   ;
 81 }
 82 
 83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 84 
 85 G4bool ScoreSpecies::ProcessHits(G4Step* aStep, G4TouchableHistory*)
 86 {
 87   G4double edep = aStep->GetTotalEnergyDeposit();
 88 
 89   if (edep == 0.) return FALSE;
 90 
 91   edep *= aStep->GetPreStepPoint()->GetWeight();  // (Particle Weight)
 92   G4int index = GetIndex(aStep);
 93   fEvtMap->add(index, edep);
 94   fEdep += edep;
 95 
 96   return TRUE;
 97 }
 98 
 99 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
100 
101 void ScoreSpecies::Initialize(G4HCofThisEvent* HCE)
102 {
103   fEvtMap = new G4THitsMap<G4double>(GetMultiFunctionalDetector()->GetName(), GetName());
104 
105   if (fHCID < 0) {
106     fHCID = GetCollectionID(0);
107   }
108 
109   HCE->AddHitsCollection(fHCID, (G4VHitsCollection*)fEvtMap);
110 }
111 
112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
113 
114 void ScoreSpecies::EndOfEvent(G4HCofThisEvent*)
115 {
116   if (G4EventManager::GetEventManager()->GetConstCurrentEvent()->IsAborted()) {
117     fEdep = 0.;
118     G4MoleculeCounter::Instance()->ResetCounter();
119     return;
120   }
121 
122   auto species = G4MoleculeCounter::Instance()->GetRecordedMolecules();
123 
124   if (species.get() == 0 || species->size() == 0) {
125     G4cout << "No molecule recorded, energy deposited= " << G4BestUnit(fEdep, "Energy") << G4endl;
126     ++fNEvent;
127     fEdep = 0.;
128     G4MoleculeCounter::Instance()->ResetCounter();
129     return;
130   }
131 
132   //  G4cout << "ScoreSpecies::EndOfEvent"<<G4endl;
133   //  G4cout << "End of event, deposited energy: "
134   //  << G4BestUnit(fEdep, "Energy") << G4endl;
135 
136 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
137   int eventID = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
138 #endif
139 
140   for (auto molecule : *species) {
141     for (auto time_mol : fTimeToRecord) {
142       double n_mol = G4MoleculeCounter::Instance()->GetNMoleculesAtTime(molecule, time_mol);
143 
144       if (n_mol < 0) {
145         G4cerr << "N molecules not valid < 0 " << G4endl;
146         G4Exception("", "N<0", FatalException, "");
147       }
148 
149       SpeciesInfo& molInfo = fSpeciesInfoPerTime[time_mol][molecule];
150       molInfo.fNumber += n_mol;
151       double gValue = (n_mol / (fEdep / eV)) * 100.;
152       molInfo.fG += gValue;
153       molInfo.fG2 += gValue * gValue;
154 
155 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
156       SpeciesInfoSOA& molInfoPerEvent = fSpeciesInfoPerEvent[time_mol][molecule];
157       molInfoPerEvent.fNumber.push_back(n_mol);
158       molInfoPerEvent.fG.push_back(gValue);
159       molInfoPerEvent.fG2.push_back(gValue * gValue);
160       molInfoPerEvent.fEventID.push_back(eventID);
161 #endif
162       //      G4cout << "In Save molucule: fNumber " << molInfo.fNumber
163       //            << " fG " << molInfo.fG
164       //            << " fEdep " << fEdep/eV
165       //            << G4endl;
166     }
167   }
168 
169   ++fNEvent;
170 
171   //  G4cout << "End of event " << fNEvent
172   //         << ", energy deposited=" << G4BestUnit(fEdep, "Energy") << G4endl;
173 
174   fEdep = 0.;
175   G4MoleculeCounter::Instance()->ResetCounter();
176 }
177 
178 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
179 
180 void ScoreSpecies::AbsorbResultsFromWorkerScorer(G4VPrimitiveScorer* workerScorer)
181 {
182   ScoreSpecies* right =
183     dynamic_cast<ScoreSpecies*>(dynamic_cast<G4VPrimitiveScorer*>(workerScorer));
184 
185   if (right == 0) {
186     return;
187   }
188   if (right == this) {
189     return;
190   }
191 
192   // G4cout<<"ScoreSpecies::AbsorbResultsFromWorkerScorer"<<G4endl;
193   {
194     SpeciesMap::iterator it_map1 = right->fSpeciesInfoPerTime.begin();
195     SpeciesMap::iterator end_map1 = right->fSpeciesInfoPerTime.end();
196 
197     for (; it_map1 != end_map1; ++it_map1) {
198       InnerSpeciesMap& map2 = it_map1->second;
199       InnerSpeciesMap::iterator it_map2 = map2.begin();
200       InnerSpeciesMap::iterator end_map2 = map2.end();
201 
202       for (; it_map2 != end_map2; ++it_map2) {
203         SpeciesInfo& molInfo = fSpeciesInfoPerTime[it_map1->first][it_map2->first];
204         molInfo.fNumber += it_map2->second.fNumber;
205         molInfo.fG += it_map2->second.fG;
206         molInfo.fG2 += it_map2->second.fG2;
207 
208         //      G4cout << "In AbsorbeResultsFromWorkerScorer: fNumber "
209         //             << molInfo.fNumber
210         //             << " fG "
211         //             << molInfo.fG
212         //             << G4endl;
213       }
214     }
215   }
216   //---------------------------------------------------------
217 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
218   {
219     SpeciesMapPerEvent::iterator it_map1 = right->fSpeciesInfoPerEvent.begin();
220     SpeciesMapPerEvent::iterator end_map1 = right->fSpeciesInfoPerEvent.end();
221 
222     for (; it_map1 != end_map1; ++it_map1) {
223       auto& map2 = it_map1->second;
224       InnerSpeciesMapPerEvent::iterator it_map2 = map2.begin();
225       InnerSpeciesMapPerEvent::iterator end_map2 = map2.end();
226 
227       for (; it_map2 != end_map2; ++it_map2) {
228         SpeciesInfoSOA& molInfo = fSpeciesInfoPerEvent[it_map1->first][it_map2->first];
229         molInfo.fNumber.insert(molInfo.fNumber.end(), it_map2->second.fNumber.begin(),
230                                it_map2->second.fNumber.end());
231         molInfo.fG.insert(molInfo.fG.end(), it_map2->second.fG.begin(), it_map2->second.fG.end());
232         molInfo.fG2.insert(molInfo.fG2.end(), it_map2->second.fG2.begin(),
233                            it_map2->second.fG2.end());
234         molInfo.fEventID.insert(molInfo.fEventID.end(), it_map2->second.fEventID.begin(),
235                                 it_map2->second.fEventID.end());
236         // G4cout << "In AbsorbeResultsFromWorkerScorer: fNumber "
237         //        << molInfo.fNumber
238         //        << " fG "
239         //        << molInfo.fG
240         //        << G4endl;
241       }
242     }
243     right->fSpeciesInfoPerEvent.clear();
244   }
245 #endif
246 
247   fNEvent += right->fNEvent;
248   right->fNEvent = 0;
249   right->fEdep = 0.;
250 }
251 
252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
253 
254 void ScoreSpecies::DrawAll()
255 {
256   ;
257 }
258 
259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
260 
261 void ScoreSpecies::PrintAll()
262 {
263   G4cout << " MultiFunctionalDet  " << detector->GetName() << G4endl;
264   G4cout << " PrimitiveScorer " << GetName() << G4endl;
265   G4cout << " Number of events " << fNEvent << G4endl;
266   G4cout << " Number of energy deposition recorded " << fEvtMap->entries() << G4endl;
267 
268   for (auto itr : *fEvtMap->GetMap()) {
269     G4cout << "  copy no.: " << itr.first << "  energy deposit: " << *(itr.second) / GetUnitValue()
270            << " [" << GetUnit() << "]" << G4endl;
271   }
272 }
273 
274 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
275 
276 void ScoreSpecies::ASCII()
277 {
278   std::ofstream out("Species.Txt");
279   if (!out) return;
280 
281   out << "Time is in ns" << G4endl;
282 
283   for (auto it_map1 : fSpeciesInfoPerTime) {
284     InnerSpeciesMap& map2 = it_map1.second;
285 
286     out << it_map1.first << G4endl;
287 
288     for (auto it_map2 : map2) {
289       out << it_map2.first->GetName() << " " << it_map2.second.fNumber << G4endl;
290     }
291   }
292 
293   out.close();
294 }
295 
296 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
297 
298 void ScoreSpecies::OutputAndClear()
299 {
300   if (G4Threading::IsWorkerThread()) return;
301 
302   //----------------------------------------------------------------------------
303   // Save results
304 
305   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
306   analysisManager->SetDefaultFileType(fOutputType);
307 
308   if (analysisManager) {
309     this->WriteWithAnalysisManager(analysisManager);
310   }
311 
312   fNEvent = 0;
313   fSpeciesInfoPerTime.clear();
314 }
315 
316 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
317 
318 void ScoreSpecies::WriteWithAnalysisManager(G4VAnalysisManager* analysisManager)
319 {
320   //  G4cout << "ScoreSpecies::WriteWithAnalysisManager" << G4endl;
321   analysisManager->OpenFile("Species.root");
322   int fNtupleID = analysisManager->CreateNtuple("species", "species");
323   analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
324   analysisManager->CreateNtupleIColumn(fNtupleID, "number");
325   analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
326   analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
327   analysisManager->CreateNtupleDColumn(fNtupleID, "time");
328   analysisManager->CreateNtupleDColumn(fNtupleID, "sumG");
329   analysisManager->CreateNtupleDColumn(fNtupleID, "sumG2");
330   analysisManager->FinishNtuple(fNtupleID);
331 
332   for (auto it_map1 : fSpeciesInfoPerTime) {
333     InnerSpeciesMap& map2 = it_map1.second;
334 
335     for (auto it_map2 : map2) {
336       double time = it_map1.first;
337       auto species = it_map2.first;
338       const G4String& name = species->GetName();
339       int molID = it_map2.first->GetMoleculeID();
340       int number = it_map2.second.fNumber;
341       double G = it_map2.second.fG;
342       double G2 = it_map2.second.fG2;
343 
344       analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);  // MolID
345       analysisManager->FillNtupleIColumn(fNtupleID, 1, number);  // Number
346       analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);  // Total nb events
347       analysisManager->FillNtupleSColumn(fNtupleID, 3, name);  // molName
348       analysisManager->FillNtupleDColumn(fNtupleID, 4, time);  // time
349       analysisManager->FillNtupleDColumn(fNtupleID, 5, G);  // G
350       analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);  // G2
351       analysisManager->AddNtupleRow(fNtupleID);
352     }
353   }
354 
355   //----------------------------------------------------------------------------
356 
357 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
358   fNtupleID = analysisManager->CreateNtuple("species_all", "species_all");
359   analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
360   analysisManager->CreateNtupleIColumn(fNtupleID, "number");
361   analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
362   analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
363   analysisManager->CreateNtupleDColumn(fNtupleID, "time");
364   analysisManager->CreateNtupleDColumn(fNtupleID, "G");
365   analysisManager->CreateNtupleDColumn(fNtupleID, "G2");
366   analysisManager->CreateNtupleIColumn(fNtupleID, "eventID");
367   analysisManager->FinishNtuple(fNtupleID);
368 
369   for (auto it_map1 : fSpeciesInfoPerEvent) {
370     InnerSpeciesMapPerEvent& map2 = it_map1.second;
371 
372     for (auto it_map2 : map2) {
373       double time = it_map1.first;
374       const Species& species = it_map2.first;
375       const G4String& name = species->GetName();
376       int molID = it_map2.first->GetMoleculeID();
377 
378       size_t nG = it_map2.second.fG.size();
379 
380       for (size_t i = 0; i < nG; ++i) {
381         int number = it_map2.second.fNumber[i];
382         double G = it_map2.second.fG[i];
383         double G2 = it_map2.second.fG2[i];
384         int eventID = it_map2.second.fEventID[i];
385 
386         analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);  // MolID
387         analysisManager->FillNtupleIColumn(fNtupleID, 1, number);  // Number
388         analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);  // Total nb events
389         analysisManager->FillNtupleSColumn(fNtupleID, 3, name);  // molName
390         analysisManager->FillNtupleDColumn(fNtupleID, 4, time);  // time
391         analysisManager->FillNtupleDColumn(fNtupleID, 5, G);  // G
392         analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);  // G2
393         analysisManager->FillNtupleIColumn(fNtupleID, 7, eventID);  // EventID
394         analysisManager->AddNtupleRow(fNtupleID);
395       }
396     }
397   }
398 #endif
399 
400   analysisManager->Write();
401   analysisManager->CloseFile();
402 }
403