File indexing completed on 2025-02-23 09:21:49
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 G4MoleculeCounter::Instance()->ResetCounter();
0119 return;
0120 }
0121
0122 auto species = G4MoleculeCounter::Instance()->GetRecordedMolecules();
0123
0124 if (species.get() == 0 || species->size() == 0) {
0125 G4cout << "No molecule recorded, energy deposited= " << G4BestUnit(fEdep, "Energy") << G4endl;
0126 ++fNEvent;
0127 fEdep = 0.;
0128 G4MoleculeCounter::Instance()->ResetCounter();
0129 return;
0130 }
0131
0132
0133
0134
0135
0136 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0137 int eventID = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
0138 #endif
0139
0140 for (auto molecule : *species) {
0141 for (auto time_mol : fTimeToRecord) {
0142 double n_mol = G4MoleculeCounter::Instance()->GetNMoleculesAtTime(molecule, time_mol);
0143
0144 if (n_mol < 0) {
0145 G4cerr << "N molecules not valid < 0 " << G4endl;
0146 G4Exception("", "N<0", FatalException, "");
0147 }
0148
0149 SpeciesInfo& molInfo = fSpeciesInfoPerTime[time_mol][molecule];
0150 molInfo.fNumber += n_mol;
0151 double gValue = (n_mol / (fEdep / eV)) * 100.;
0152 molInfo.fG += gValue;
0153 molInfo.fG2 += gValue * gValue;
0154
0155 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0156 SpeciesInfoSOA& molInfoPerEvent = fSpeciesInfoPerEvent[time_mol][molecule];
0157 molInfoPerEvent.fNumber.push_back(n_mol);
0158 molInfoPerEvent.fG.push_back(gValue);
0159 molInfoPerEvent.fG2.push_back(gValue * gValue);
0160 molInfoPerEvent.fEventID.push_back(eventID);
0161 #endif
0162
0163
0164
0165
0166 }
0167 }
0168
0169 ++fNEvent;
0170
0171
0172
0173
0174 fEdep = 0.;
0175 G4MoleculeCounter::Instance()->ResetCounter();
0176 }
0177
0178
0179
0180 void ScoreSpecies::AbsorbResultsFromWorkerScorer(G4VPrimitiveScorer* workerScorer)
0181 {
0182 ScoreSpecies* right =
0183 dynamic_cast<ScoreSpecies*>(dynamic_cast<G4VPrimitiveScorer*>(workerScorer));
0184
0185 if (right == 0) {
0186 return;
0187 }
0188 if (right == this) {
0189 return;
0190 }
0191
0192
0193 {
0194 SpeciesMap::iterator it_map1 = right->fSpeciesInfoPerTime.begin();
0195 SpeciesMap::iterator end_map1 = right->fSpeciesInfoPerTime.end();
0196
0197 for (; it_map1 != end_map1; ++it_map1) {
0198 InnerSpeciesMap& map2 = it_map1->second;
0199 InnerSpeciesMap::iterator it_map2 = map2.begin();
0200 InnerSpeciesMap::iterator end_map2 = map2.end();
0201
0202 for (; it_map2 != end_map2; ++it_map2) {
0203 SpeciesInfo& molInfo = fSpeciesInfoPerTime[it_map1->first][it_map2->first];
0204 molInfo.fNumber += it_map2->second.fNumber;
0205 molInfo.fG += it_map2->second.fG;
0206 molInfo.fG2 += it_map2->second.fG2;
0207
0208
0209
0210
0211
0212
0213 }
0214 }
0215 }
0216
0217 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0218 {
0219 SpeciesMapPerEvent::iterator it_map1 = right->fSpeciesInfoPerEvent.begin();
0220 SpeciesMapPerEvent::iterator end_map1 = right->fSpeciesInfoPerEvent.end();
0221
0222 for (; it_map1 != end_map1; ++it_map1) {
0223 auto& map2 = it_map1->second;
0224 InnerSpeciesMapPerEvent::iterator it_map2 = map2.begin();
0225 InnerSpeciesMapPerEvent::iterator end_map2 = map2.end();
0226
0227 for (; it_map2 != end_map2; ++it_map2) {
0228 SpeciesInfoSOA& molInfo = fSpeciesInfoPerEvent[it_map1->first][it_map2->first];
0229 molInfo.fNumber.insert(molInfo.fNumber.end(), it_map2->second.fNumber.begin(),
0230 it_map2->second.fNumber.end());
0231 molInfo.fG.insert(molInfo.fG.end(), it_map2->second.fG.begin(), it_map2->second.fG.end());
0232 molInfo.fG2.insert(molInfo.fG2.end(), it_map2->second.fG2.begin(),
0233 it_map2->second.fG2.end());
0234 molInfo.fEventID.insert(molInfo.fEventID.end(), it_map2->second.fEventID.begin(),
0235 it_map2->second.fEventID.end());
0236
0237
0238
0239
0240
0241 }
0242 }
0243 right->fSpeciesInfoPerEvent.clear();
0244 }
0245 #endif
0246
0247 fNEvent += right->fNEvent;
0248 right->fNEvent = 0;
0249 right->fEdep = 0.;
0250 }
0251
0252
0253
0254 void ScoreSpecies::DrawAll()
0255 {
0256 ;
0257 }
0258
0259
0260
0261 void ScoreSpecies::PrintAll()
0262 {
0263 G4cout << " MultiFunctionalDet " << detector->GetName() << G4endl;
0264 G4cout << " PrimitiveScorer " << GetName() << G4endl;
0265 G4cout << " Number of events " << fNEvent << G4endl;
0266 G4cout << " Number of energy deposition recorded " << fEvtMap->entries() << G4endl;
0267
0268 for (auto itr : *fEvtMap->GetMap()) {
0269 G4cout << " copy no.: " << itr.first << " energy deposit: " << *(itr.second) / GetUnitValue()
0270 << " [" << GetUnit() << "]" << G4endl;
0271 }
0272 }
0273
0274
0275
0276 void ScoreSpecies::ASCII()
0277 {
0278 std::ofstream out("Species.Txt");
0279 if (!out) return;
0280
0281 out << "Time is in ns" << G4endl;
0282
0283 for (auto it_map1 : fSpeciesInfoPerTime) {
0284 InnerSpeciesMap& map2 = it_map1.second;
0285
0286 out << it_map1.first << G4endl;
0287
0288 for (auto it_map2 : map2) {
0289 out << it_map2.first->GetName() << " " << it_map2.second.fNumber << G4endl;
0290 }
0291 }
0292
0293 out.close();
0294 }
0295
0296
0297
0298 void ScoreSpecies::OutputAndClear()
0299 {
0300 if (G4Threading::IsWorkerThread()) return;
0301
0302
0303
0304
0305 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0306 analysisManager->SetDefaultFileType(fOutputType);
0307
0308 if (analysisManager) {
0309 this->WriteWithAnalysisManager(analysisManager);
0310 }
0311
0312 fNEvent = 0;
0313 fSpeciesInfoPerTime.clear();
0314 }
0315
0316
0317
0318 void ScoreSpecies::WriteWithAnalysisManager(G4VAnalysisManager* analysisManager)
0319 {
0320
0321 analysisManager->OpenFile("Species.root");
0322 int fNtupleID = analysisManager->CreateNtuple("species", "species");
0323 analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
0324 analysisManager->CreateNtupleIColumn(fNtupleID, "number");
0325 analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
0326 analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
0327 analysisManager->CreateNtupleDColumn(fNtupleID, "time");
0328 analysisManager->CreateNtupleDColumn(fNtupleID, "sumG");
0329 analysisManager->CreateNtupleDColumn(fNtupleID, "sumG2");
0330 analysisManager->FinishNtuple(fNtupleID);
0331
0332 for (auto it_map1 : fSpeciesInfoPerTime) {
0333 InnerSpeciesMap& map2 = it_map1.second;
0334
0335 for (auto it_map2 : map2) {
0336 double time = it_map1.first;
0337 auto species = it_map2.first;
0338 const G4String& name = species->GetName();
0339 int molID = it_map2.first->GetMoleculeID();
0340 int number = it_map2.second.fNumber;
0341 double G = it_map2.second.fG;
0342 double G2 = it_map2.second.fG2;
0343
0344 analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);
0345 analysisManager->FillNtupleIColumn(fNtupleID, 1, number);
0346 analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);
0347 analysisManager->FillNtupleSColumn(fNtupleID, 3, name);
0348 analysisManager->FillNtupleDColumn(fNtupleID, 4, time);
0349 analysisManager->FillNtupleDColumn(fNtupleID, 5, G);
0350 analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);
0351 analysisManager->AddNtupleRow(fNtupleID);
0352 }
0353 }
0354
0355
0356
0357 #ifdef _ScoreSpecies_FOR_ALL_EVENTS
0358 fNtupleID = analysisManager->CreateNtuple("species_all", "species_all");
0359 analysisManager->CreateNtupleIColumn(fNtupleID, "speciesID");
0360 analysisManager->CreateNtupleIColumn(fNtupleID, "number");
0361 analysisManager->CreateNtupleIColumn(fNtupleID, "nEvent");
0362 analysisManager->CreateNtupleSColumn(fNtupleID, "speciesName");
0363 analysisManager->CreateNtupleDColumn(fNtupleID, "time");
0364 analysisManager->CreateNtupleDColumn(fNtupleID, "G");
0365 analysisManager->CreateNtupleDColumn(fNtupleID, "G2");
0366 analysisManager->CreateNtupleIColumn(fNtupleID, "eventID");
0367 analysisManager->FinishNtuple(fNtupleID);
0368
0369 for (auto it_map1 : fSpeciesInfoPerEvent) {
0370 InnerSpeciesMapPerEvent& map2 = it_map1.second;
0371
0372 for (auto it_map2 : map2) {
0373 double time = it_map1.first;
0374 const Species& species = it_map2.first;
0375 const G4String& name = species->GetName();
0376 int molID = it_map2.first->GetMoleculeID();
0377
0378 size_t nG = it_map2.second.fG.size();
0379
0380 for (size_t i = 0; i < nG; ++i) {
0381 int number = it_map2.second.fNumber[i];
0382 double G = it_map2.second.fG[i];
0383 double G2 = it_map2.second.fG2[i];
0384 int eventID = it_map2.second.fEventID[i];
0385
0386 analysisManager->FillNtupleIColumn(fNtupleID, 0, molID);
0387 analysisManager->FillNtupleIColumn(fNtupleID, 1, number);
0388 analysisManager->FillNtupleIColumn(fNtupleID, 2, fNEvent);
0389 analysisManager->FillNtupleSColumn(fNtupleID, 3, name);
0390 analysisManager->FillNtupleDColumn(fNtupleID, 4, time);
0391 analysisManager->FillNtupleDColumn(fNtupleID, 5, G);
0392 analysisManager->FillNtupleDColumn(fNtupleID, 6, G2);
0393 analysisManager->FillNtupleIColumn(fNtupleID, 7, eventID);
0394 analysisManager->AddNtupleRow(fNtupleID);
0395 }
0396 }
0397 }
0398 #endif
0399
0400 analysisManager->Write();
0401 analysisManager->CloseFile();
0402 }