File indexing completed on 2025-11-03 09:04:59
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 
0030 
0031 
0032 
0033 
0034 
0035 #include "ScoreSpecies.hh"
0036 
0037 #include "G4Event.hh"
0038 #include "G4UnitsTable.hh"
0039 
0040 #include <G4AnalysisManager.hh>
0041 #include <G4EventManager.hh>
0042 #include <G4MolecularConfiguration.hh>
0043 #include <G4MoleculeCounter.hh>
0044 #include <G4SystemOfUnits.hh>
0045 #include <globals.hh>
0046 
0047 
0048 
0049 
0050 
0051 
0052 
0053 
0054 
0055 
0056 
0057 
0058 ScoreSpecies::ScoreSpecies(G4String name, G4int depth)
0059   : G4VPrimitiveScorer(name, depth),
0060     fEdep(0),
0061     fOutputType("root"),  
0062     fHCID(-1),
0063     fEvtMap(0)
0064 {
0065   fNEvent = 0;
0066   AddTimeToRecord(1 * CLHEP::picosecond);
0067   AddTimeToRecord(10 * CLHEP::picosecond);
0068   AddTimeToRecord(100 * CLHEP::picosecond);
0069   AddTimeToRecord(1000 * CLHEP::picosecond);
0070   AddTimeToRecord(10000 * CLHEP::picosecond);
0071   AddTimeToRecord(100000 * CLHEP::picosecond);
0072   AddTimeToRecord(999999 * CLHEP::picosecond);
0073   fEdep = 0;
0074 }
0075 
0076 
0077 
0078 ScoreSpecies::~ScoreSpecies()
0079 {
0080   ;
0081 }
0082 
0083 
0084 
0085 G4bool ScoreSpecies::ProcessHits(G4Step* aStep, G4TouchableHistory*)
0086 {
0087   G4double edep = aStep->GetTotalEnergyDeposit();
0088 
0089   if (edep == 0.) return FALSE;
0090 
0091   edep *= aStep->GetPreStepPoint()->GetWeight();  
0092   G4int index = GetIndex(aStep);
0093   fEvtMap->add(index, edep);
0094   fEdep += edep;
0095 
0096   return TRUE;
0097 }
0098 
0099 
0100 
0101 void ScoreSpecies::Initialize(G4HCofThisEvent* HCE)
0102 {
0103   fEvtMap = new G4THitsMap<G4double>(GetMultiFunctionalDetector()->GetName(), GetName());
0104 
0105   if (fHCID < 0) {
0106     fHCID = GetCollectionID(0);
0107   }
0108 
0109   HCE->AddHitsCollection(fHCID, (G4VHitsCollection*)fEvtMap);
0110 }
0111 
0112 
0113 
0114 void ScoreSpecies::EndOfEvent(G4HCofThisEvent*)
0115 {
0116   if (G4EventManager::GetEventManager()->GetConstCurrentEvent()->IsAborted()) {
0117     fEdep = 0.;
0118     return;
0119   }
0120 
0121   
0122   auto counter = G4MoleculeCounterManager::Instance()->GetMoleculeCounter<G4MoleculeCounter>(0);
0123   if (counter == nullptr) {
0124     G4Exception("ScoreSpecies::EndOfEvent", "BAD_REFERENCE", FatalException,
0125                 "The molecule counter could not be received!");
0126   }
0127 
0128   auto indices = counter->GetMapIndices();
0129 
0130   if (indices.empty()) {
0131     G4cout << "No molecule recorded, energy deposited= " << G4BestUnit(fEdep, "Energy") << G4endl;
0132     ++fNEvent;
0133     fEdep = 0.;
0134     return;
0135   }
0136 
0137   
0138   
0139   
0140 
0141 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0142   int eventID = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
0143 #endif
0144 
0145   for (auto idx : indices) {
0146     for (auto time_mol : fTimeToRecord) {
0147       double n_mol = counter->GetNbMoleculesAtTime(idx, time_mol);
0148 
0149       if (n_mol < 0) {
0150         G4cerr << "N molecules not valid < 0 " << G4endl;
0151         G4Exception("", "N<0", FatalException, "");
0152       }
0153 
0154       SpeciesInfo& molInfo = fSpeciesInfoPerTime[time_mol][idx.Molecule];
0155       molInfo.fNumber += n_mol;
0156       double gValue = (n_mol / (fEdep / eV)) * 100.;
0157       molInfo.fG += gValue;
0158       molInfo.fG2 += gValue * gValue;
0159 
0160 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0161       SpeciesInfoSOA& molInfoPerEvent = fSpeciesInfoPerEvent[time_mol][molecule];
0162       molInfoPerEvent.fNumber.push_back(n_mol);
0163       molInfoPerEvent.fG.push_back(gValue);
0164       molInfoPerEvent.fG2.push_back(gValue * gValue);
0165       molInfoPerEvent.fEventID.push_back(eventID);
0166 #endif
0167       
0168       
0169       
0170       
0171     }
0172   }
0173 
0174   ++fNEvent;
0175 
0176   
0177   
0178 
0179   fEdep = 0.;
0180 }
0181 
0182 
0183 
0184 void ScoreSpecies::AbsorbResultsFromWorkerScorer(G4VPrimitiveScorer* workerScorer)
0185 {
0186   ScoreSpecies* right =
0187     dynamic_cast<ScoreSpecies*>(dynamic_cast<G4VPrimitiveScorer*>(workerScorer));
0188 
0189   if (right == 0) {
0190     return;
0191   }
0192   if (right == this) {
0193     return;
0194   }
0195 
0196   
0197   {
0198     SpeciesMap::iterator it_map1 = right->fSpeciesInfoPerTime.begin();
0199     SpeciesMap::iterator end_map1 = right->fSpeciesInfoPerTime.end();
0200 
0201     for (; it_map1 != end_map1; ++it_map1) {
0202       InnerSpeciesMap& map2 = it_map1->second;
0203       InnerSpeciesMap::iterator it_map2 = map2.begin();
0204       InnerSpeciesMap::iterator end_map2 = map2.end();
0205 
0206       for (; it_map2 != end_map2; ++it_map2) {
0207         SpeciesInfo& molInfo = fSpeciesInfoPerTime[it_map1->first][it_map2->first];
0208         molInfo.fNumber += it_map2->second.fNumber;
0209         molInfo.fG += it_map2->second.fG;
0210         molInfo.fG2 += it_map2->second.fG2;
0211 
0212         
0213         
0214         
0215         
0216         
0217       }
0218     }
0219   }
0220   
0221 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0222   {
0223     SpeciesMapPerEvent::iterator it_map1 = right->fSpeciesInfoPerEvent.begin();
0224     SpeciesMapPerEvent::iterator end_map1 = right->fSpeciesInfoPerEvent.end();
0225 
0226     for (; it_map1 != end_map1; ++it_map1) {
0227       auto& map2 = it_map1->second;
0228       InnerSpeciesMapPerEvent::iterator it_map2 = map2.begin();
0229       InnerSpeciesMapPerEvent::iterator end_map2 = map2.end();
0230 
0231       for (; it_map2 != end_map2; ++it_map2) {
0232         SpeciesInfoSOA& molInfo = fSpeciesInfoPerEvent[it_map1->first][it_map2->first];
0233         molInfo.fNumber.insert(molInfo.fNumber.end(), it_map2->second.fNumber.begin(),
0234                                it_map2->second.fNumber.end());
0235         molInfo.fG.insert(molInfo.fG.end(), it_map2->second.fG.begin(), it_map2->second.fG.end());
0236         molInfo.fG2.insert(molInfo.fG2.end(), it_map2->second.fG2.begin(),
0237                            it_map2->second.fG2.end());
0238         molInfo.fEventID.insert(molInfo.fEventID.end(), it_map2->second.fEventID.begin(),
0239                                 it_map2->second.fEventID.end());
0240         
0241         
0242         
0243         
0244         
0245       }
0246     }
0247     right->fSpeciesInfoPerEvent.clear();
0248   }
0249 #endif
0250 
0251   fNEvent += right->fNEvent;
0252   right->fNEvent = 0;
0253   right->fEdep = 0.;
0254 }
0255 
0256 
0257 
0258 void ScoreSpecies::DrawAll()
0259 {
0260   ;
0261 }
0262 
0263 
0264 
0265 void ScoreSpecies::PrintAll()
0266 {
0267   G4cout << " MultiFunctionalDet  " << detector->GetName() << G4endl;
0268   G4cout << " PrimitiveScorer " << GetName() << G4endl;
0269   G4cout << " Number of events " << fNEvent << G4endl;
0270   G4cout << " Number of energy deposition recorded " << fEvtMap->entries() << G4endl;
0271 
0272   for (auto itr : *fEvtMap->GetMap()) {
0273     G4cout << "  copy no.: " << itr.first << "  energy deposit: " << *(itr.second) / GetUnitValue()
0274            << " [" << GetUnit() << "]" << G4endl;
0275   }
0276 }
0277 
0278 
0279 
0280 void ScoreSpecies::ASCII()
0281 {
0282   std::ofstream out("Species.Txt");
0283   if (!out) return;
0284 
0285   out << "Time is in ns" << G4endl;
0286 
0287   for (auto it_map1 : fSpeciesInfoPerTime) {
0288     InnerSpeciesMap& map2 = it_map1.second;
0289 
0290     out << it_map1.first << G4endl;
0291 
0292     for (auto it_map2 : map2) {
0293       out << it_map2.first->GetName() << " " << it_map2.second.fNumber << G4endl;
0294     }
0295   }
0296 
0297   out.close();
0298 }
0299 
0300 
0301 
0302 void ScoreSpecies::OutputAndClear()
0303 {
0304   if (G4Threading::IsWorkerThread()) return;
0305 
0306   
0307   
0308 
0309   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0310   analysisManager->SetDefaultFileType(fOutputType);
0311 
0312   if (analysisManager) {
0313     this->WriteWithAnalysisManager(analysisManager);
0314   }
0315 
0316   fNEvent = 0;
0317   fSpeciesInfoPerTime.clear();
0318 }
0319 
0320 
0321 
0322 void ScoreSpecies::WriteWithAnalysisManager(G4VAnalysisManager* analysisManager)
0323 {
0324   
0325   analysisManager->OpenFile("Species.root");
0326   int fNtupleID = analysisManager->CreateNtuple("species", "species");
0327   analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
0328   analysisManager->CreateNtupleIColumn(fNtupleID, "number");
0329   analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
0330   analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
0331   analysisManager->CreateNtupleDColumn(fNtupleID, "time");
0332   analysisManager->CreateNtupleDColumn(fNtupleID, "sumG");
0333   analysisManager->CreateNtupleDColumn(fNtupleID, "sumG2");
0334   analysisManager->FinishNtuple(fNtupleID);
0335 
0336   for (auto it_map1 : fSpeciesInfoPerTime) {
0337     InnerSpeciesMap& map2 = it_map1.second;
0338 
0339     for (auto it_map2 : map2) {
0340       double time = it_map1.first;
0341       auto species = it_map2.first;
0342       const G4String& name = species->GetName();
0343       int molID = it_map2.first->GetMoleculeID();
0344       int number = it_map2.second.fNumber;
0345       double G = it_map2.second.fG;
0346       double G2 = it_map2.second.fG2;
0347 
0348       analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);  
0349       analysisManager->FillNtupleIColumn(fNtupleID, 1, number);  
0350       analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);  
0351       analysisManager->FillNtupleSColumn(fNtupleID, 3, name);  
0352       analysisManager->FillNtupleDColumn(fNtupleID, 4, time);  
0353       analysisManager->FillNtupleDColumn(fNtupleID, 5, G);  
0354       analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);  
0355       analysisManager->AddNtupleRow(fNtupleID);
0356     }
0357   }
0358 
0359   
0360 
0361 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0362   fNtupleID = analysisManager->CreateNtuple("species_all", "species_all");
0363   analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
0364   analysisManager->CreateNtupleIColumn(fNtupleID, "number");
0365   analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
0366   analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
0367   analysisManager->CreateNtupleDColumn(fNtupleID, "time");
0368   analysisManager->CreateNtupleDColumn(fNtupleID, "G");
0369   analysisManager->CreateNtupleDColumn(fNtupleID, "G2");
0370   analysisManager->CreateNtupleIColumn(fNtupleID, "eventID");
0371   analysisManager->FinishNtuple(fNtupleID);
0372 
0373   for (auto it_map1 : fSpeciesInfoPerEvent) {
0374     InnerSpeciesMapPerEvent& map2 = it_map1.second;
0375 
0376     for (auto it_map2 : map2) {
0377       double time = it_map1.first;
0378       const Species& species = it_map2.first;
0379       const G4String& name = species->GetName();
0380       int molID = it_map2.first->GetMoleculeID();
0381 
0382       size_t nG = it_map2.second.fG.size();
0383 
0384       for (size_t i = 0; i < nG; ++i) {
0385         int number = it_map2.second.fNumber[i];
0386         double G = it_map2.second.fG[i];
0387         double G2 = it_map2.second.fG2[i];
0388         int eventID = it_map2.second.fEventID[i];
0389 
0390         analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);  
0391         analysisManager->FillNtupleIColumn(fNtupleID, 1, number);  
0392         analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);  
0393         analysisManager->FillNtupleSColumn(fNtupleID, 3, name);  
0394         analysisManager->FillNtupleDColumn(fNtupleID, 4, time);  
0395         analysisManager->FillNtupleDColumn(fNtupleID, 5, G);  
0396         analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);  
0397         analysisManager->FillNtupleIColumn(fNtupleID, 7, eventID);  
0398         analysisManager->AddNtupleRow(fNtupleID);
0399       }
0400     }
0401   }
0402 #endif
0403 
0404   analysisManager->Write();
0405   analysisManager->CloseFile();
0406 }