File indexing completed on 2026-04-08 07:53:56
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 "TSRunAction.hh"
0030
0031 #include "TSActionInitialization.hh"
0032 #include "TSDetectorConstruction.hh"
0033 #include "TSRun.hh"
0034
0035 #include "G4Run.hh"
0036 #include "G4RunManager.hh"
0037 #include "G4StatAnalysis.hh"
0038 #include "G4TaskRunManager.hh"
0039 #include "G4Timer.hh"
0040
0041
0042
0043 TSRunAction::TSRunAction()
0044 : fDetector(TSDetectorConstruction::Instance()), fName(fDetector->GetMFDName())
0045 {}
0046
0047
0048
0049 TSRunAction::~TSRunAction() {}
0050
0051
0052
0053 G4Run* TSRunAction::GenerateRun()
0054 {
0055 return new TSRun(fName);
0056 }
0057
0058
0059
0060 void TSRunAction::BeginOfRunAction(const G4Run* aRun)
0061 {
0062
0063
0064
0065 if (IsMaster() && aRun != nullptr) G4PrintEnv();
0066 }
0067
0068
0069
0070 void TSRunAction::EndOfRunAction(const G4Run* aRun)
0071 {
0072 if (IsMaster()) {
0073 G4cout << " ###### EndOfTSRunAction ###### " << G4endl;
0074
0075 aRun->GetNumberOfEvent();
0076 std::ofstream fileout;
0077 G4String fname = "";
0078 std::stringstream separator;
0079
0080 separator << "============================================================";
0081
0082 typedef std::set<G4int> IDSet_t;
0083 IDSet_t IDs;
0084
0085
0086 const TSRun* tsRun = static_cast<const TSRun*>(aRun);
0087
0088
0089
0090
0091
0092 std::vector<G4String> primScorerNames{"EnergyDeposit", "NumberOfSteps"};
0093 std::vector<G4String> fnames{"mfd_tl", "mfd_tg"};
0094 std::vector<G4double> units{CLHEP::eV, CLHEP::keV, 1, 1};
0095 std::vector<G4String> unitstr{"keV", "steps"};
0096
0097
0098
0099 auto print = [](std::ostream& fout, G4int first, G4double second, G4double unit1,
0100 G4double unit2, G4String unit2str) {
0101 if (fout) fout << first << " " << second / unit1 << G4endl;
0102
0103 G4cout << " " << std::setw(10) << first << " " << std::setw(15) << std::setprecision(6)
0104 << std::fixed << second / unit2 << " " << unit2str << G4endl;
0105 G4cout.unsetf(std::ios::fixed);
0106 };
0107
0108
0109 auto stat_print = [](std::ostream& fout, G4int first, G4StatAnalysis* stat,
0110 G4ConvergenceTester* conv, G4double unit1, G4double unit2,
0111 G4String unit2str) {
0112 if (!stat || !conv) return;
0113 auto fsecond = (*stat);
0114 auto psecond = (*stat);
0115 fsecond /= unit1;
0116 psecond /= unit2;
0117 if (fout) {
0118 fout << first << " " << fsecond << G4endl;
0119 conv->ShowResult(fout);
0120 }
0121 std::stringstream ss;
0122 ss << " " << std::setw(10) << first << " " << std::setw(15) << std::setprecision(6)
0123 << std::fixed << psecond << " " << unit2str;
0124
0125 G4cout << ss.str() << G4endl;
0126 };
0127
0128
0129 for (unsigned i = 0; i < primScorerNames.size(); ++i) {
0130 for (unsigned j = 0; j < fnames.size(); ++j) {
0131 fname = fnames.at(j) + "_" + primScorerNames.at(i) + ".out";
0132 fileout.open(fname);
0133 G4cout << separator.str() << G4endl;
0134 G4cout << " opened file " << fname << " for output" << G4endl;
0135 G4cout << separator.str() << G4endl;
0136
0137 G4bool valid = true;
0138 if (j == 0) {
0139 G4THitsMap<G4double>* hitmap = tsRun->GetHitsMap(fName + "/" + primScorerNames.at(i));
0140 G4StatContainer<G4StatAnalysis>* statmap =
0141 tsRun->GetStatMap(fName + "/" + primScorerNames.at(i));
0142 G4StatContainer<G4ConvergenceTester>* convmap =
0143 tsRun->GetConvMap(fName + "/" + primScorerNames.at(i));
0144
0145 if (hitmap && hitmap->size() != 0) {
0146 for (auto itr = hitmap->begin(); itr != hitmap->end(); itr++) {
0147 if (!hitmap->GetObject(itr)) continue;
0148 IDs.insert(itr->first);
0149 std::get<0>(fTypeCompare[primScorerNames.at(i)][itr->first]) =
0150 *itr->second / units.at(i);
0151 print(fileout, itr->first, *itr->second, units.at(i), units.at(i + 1), unitstr.at(i));
0152 }
0153 }
0154 else {
0155 valid = false;
0156 }
0157
0158 if (statmap && statmap->size() != 0 && convmap && convmap->size() != 0) {
0159 auto stat_fname = "stat_" + fname;
0160 std::ofstream statout;
0161 statout.open(stat_fname);
0162 for (auto itr = statmap->begin(); itr != statmap->end(); itr++) {
0163 G4int _f = statmap->GetIndex(itr);
0164 G4StatAnalysis* _s = statmap->GetObject(itr);
0165 G4ConvergenceTester* _c = convmap->GetObject(_f);
0166 stat_print(statout, _f, _s, _c, units.at(i), units.at(i + 1), unitstr.at(i));
0167 }
0168 statout.close();
0169 }
0170 else {
0171 std::stringstream ss;
0172 ss << " StatMap/ConvMap is either not "
0173 << "created or the StatMap/ConvMap was empty";
0174 if (statmap) ss << " (StatMap size == " << statmap->size() << ")";
0175 if (convmap) ss << " (ConvMap size == " << convmap->size() << ")";
0176
0177 G4Exception("TSRunAction", "002", JustWarning,
0178 G4String(primScorerNames.at(i) + ss.str()).c_str());
0179 }
0180
0181 if (!valid) {
0182 G4Exception("TSRunAction", "000", JustWarning,
0183 G4String(primScorerNames.at(i)
0184 + " HitsMap is either not "
0185 "created or the HitsMap was empty")
0186 .c_str());
0187 }
0188 }
0189 else {
0190 G4TAtomicHitsMap<G4double>* hitmap =
0191 tsRun->GetAtomicHitsMap(fName + "/" + primScorerNames.at(i));
0192 if (hitmap && hitmap->size() != 0) {
0193 for (auto itr = hitmap->begin(); itr != hitmap->end(); itr++) {
0194 IDs.insert(itr->first);
0195 std::get<1>(fTypeCompare[primScorerNames.at(i)][itr->first]) =
0196 *itr->second / units.at(i);
0197 print(fileout, itr->first, *itr->second, units.at(i), units.at(i + 1), unitstr.at(i));
0198 }
0199 }
0200 else {
0201 valid = false;
0202 }
0203
0204 if (!valid) {
0205 G4Exception("TSRunAction", "001", JustWarning,
0206 G4String(primScorerNames.at(i)
0207 + " HitsMap is either not "
0208 "created or the HitsMap was empty")
0209 .c_str());
0210 }
0211 }
0212
0213 fileout.close();
0214 G4cout << separator.str() << G4endl;
0215 G4cout << " closed file " << fname << " for output" << G4endl;
0216 }
0217
0218 TSRun::MutexHitsMap_t* hitmap = tsRun->GetMutexHitsMap(fName + "/" + primScorerNames.at(i));
0219 if (hitmap && hitmap->size() != 0) {
0220 for (auto itr = hitmap->begin(); itr != hitmap->end(); itr++) {
0221 IDs.insert(itr->first);
0222 std::get<2>(fTypeCompare[primScorerNames.at(i)][itr->first]) = itr->second / units.at(i);
0223 }
0224 }
0225 }
0226
0227
0228
0229
0230
0231
0232 fname = "mfd_diff.out";
0233 fileout.open(fname);
0234
0235 G4cout << separator.str() << G4endl;
0236 G4cout << " opened file " << fname << " for difference output" << G4endl;
0237 G4cout << separator.str() << G4endl;
0238
0239 fileout << " " << std::setw(10) << "ID"
0240 << " " << std::setw(30) << std::setprecision(12) << std::fixed << "MFD value"
0241 << " " << std::setw(30) << std::setprecision(12) << std::fixed
0242 << "Atomic Hits Map value"
0243 << " " << std::setw(30) << std::setprecision(8) << std::scientific << "Difference"
0244 << " " << std::setw(30) << std::setprecision(8) << std::scientific
0245 << "Diff (MFD - MUTEXED)"
0246 << " " << std::setw(30) << std::setprecision(8) << std::scientific
0247 << "Diff (ATOM_HIT_MAP - MUTEXED)" << G4endl << G4endl;
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 auto tm = dynamic_cast<G4TaskRunManager*>(G4RunManager::GetRunManager());
0263
0264 auto tp = (tm) ? tm->GetThreadPool() : nullptr;
0265
0266 auto join_output = [](std::string& lhs, std::string&& rhs) {
0267 return (lhs += rhs);
0268 };
0269
0270
0271 auto report_type_comparison = [=](const G4String& id, const IDcompare_t& comp) {
0272
0273 auto report_subtype_comparison = [](const G4int& idx, const Compare_t& value) {
0274 std::stringstream streamout;
0275 G4double d01 = std::fabs(std::get<0>(value) - std::get<1>(value));
0276 G4double d02 = std::fabs(std::get<0>(value) - std::get<2>(value));
0277 G4double d03 = std::fabs(std::get<1>(value) - std::get<2>(value));
0278
0279 auto _print_diff = [&](const G4double& _dval) {
0280 if (_dval > 0.0)
0281 streamout << std::setprecision(8) << std::scientific << std::setw(30) << _dval
0282 << " ";
0283 else
0284 streamout << std::setprecision(1) << std::fixed << std::setw(30) << _dval << " ";
0285 };
0286
0287 streamout << " " << std::setw(10) << idx << " " << std::setw(30)
0288 << std::setprecision(12) << std::fixed << std::get<0>(value) << " "
0289 << std::setw(30) << std::setprecision(12) << std::fixed << std::get<1>(value)
0290 << " ";
0291
0292 _print_diff(d01);
0293 _print_diff(d02);
0294 _print_diff(d03);
0295
0296 streamout << G4endl;
0297 return streamout.str();
0298 };
0299
0300 std::stringstream streamout;
0301 streamout << "\n\nType = " << id << "\n" << G4endl;
0302 if (tp) {
0303
0304 G4TaskGroup<std::string> tg(join_output, tp);
0305
0306 for (auto titr = comp.begin(); titr != comp.end(); ++titr)
0307 tg.exec(report_subtype_comparison, titr->first, titr->second);
0308
0309
0310
0311 streamout << tg.join();
0312 }
0313 else {
0314
0315
0316 for (auto titr = comp.begin(); titr != comp.end(); ++titr)
0317 streamout << report_subtype_comparison(titr->first, titr->second);
0318 }
0319
0320 return streamout.str();
0321 };
0322
0323 G4String tasking_result = "";
0324 if (tp) {
0325 G4cout << "\n\nGenerating diff output via tasking... ";
0326
0327 G4TaskGroup<std::string> tg(join_output, tp);
0328 for (auto itr = fTypeCompare.begin(); itr != fTypeCompare.end(); ++itr)
0329 tg.exec(report_type_comparison, itr->first, itr->second);
0330
0331 tasking_result = tg.join();
0332 }
0333
0334
0335
0336 if (tp) {
0337
0338 G4String serial_result = "";
0339 for (auto itr = fTypeCompare.begin(); itr != fTypeCompare.end(); ++itr)
0340 serial_result += report_type_comparison(itr->first, itr->second);
0341
0342
0343 fileout << tasking_result;
0344
0345
0346 if (serial_result != tasking_result) {
0347 G4Exception("TSRunAction", "003", JustWarning,
0348 "Output written via tasking did not match output written "
0349 "serially. Appending serial result to output file");
0350 fileout << "\n\n#================CORRECT_SERIAL_OUTPUT================#\n\n";
0351 fileout << serial_result;
0352 }
0353 }
0354 else {
0355
0356 for (auto itr = fTypeCompare.begin(); itr != fTypeCompare.end(); ++itr)
0357 fileout << report_type_comparison(itr->first, itr->second);
0358 }
0359
0360 fileout.close();
0361 G4cout << " closed file " << fname << " for difference output" << G4endl;
0362 G4cout << separator.str() << G4endl;
0363 }
0364 }
0365
0366