Geant4 VMC Version 6.6
Loading...
Searching...
No Matches
TG4RegionsManager.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2014 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4RegionsManager.h"
16#include "TG4G3CutVector.h"
17#include "TG4G3PhysicsManager.h"
18#include "TG4G3Units.h"
19#include "TG4GeometryServices.h"
20#include "TG4Globals.h"
21#include "TG4Limits.h"
22#include "TG4Medium.h"
23#include "TG4PhysicsManager.h"
24#include "TG4RegionsMessenger.h"
25
26#include <G4Gamma.hh>
27#include <G4LogicalVolumeStore.hh>
28#include <G4ProductionCuts.hh>
29#include <G4RToEConvForElectron.hh>
30#include <G4RToEConvForGamma.hh>
31#include <G4Region.hh>
32#include <G4RegionStore.hh>
33#include <G4RunManager.hh>
34#include <G4SystemOfUnits.hh>
35#include <G4UnitsTable.hh>
36#include <G4VUserPhysicsList.hh>
37#include <G4Version.hh>
38
39#include <map>
40#include <set>
41#include <fstream>
42
43//_____________________________________________________________________________
45 : fMessenger(this)
46{}
47
48//
49// private methods
50//
51
52//_____________________________________________________________________________
53G4bool TG4RegionsManager::Iterate(G4double energyCut, G4double& lowerCut,
54 G4double& higherCut, G4double defaultRangeCut, G4double lowEdgeEnergy,
55 G4double highEdgeEnergy, G4int nbin,
56 std::map<G4double, G4double>& energyToRangeMap,
57 std::map<G4double, G4double>::const_iterator& it, G4Material* material,
58 G4VRangeToEnergyConverter& converter) const
59{
61
62 G4double step = (higherCut - lowerCut) / nbin;
63 energyToRangeMap.clear();
64 G4String indent(" ");
65 for (G4int i = 0; i <= nbin; i++) {
66 G4double rangeCut = lowerCut + i * step;
67 if (rangeCut < defaultRangeCut) continue;
68 G4double energy = converter.Convert(rangeCut, material);
69 if (VerboseLevel() > 2) {
70 G4cout << indent << "For range: " << rangeCut << " mm got energy "
71 << energy / MeV << " MeV" << G4endl;
72 }
73
74 if (energy < lowEdgeEnergy) energy = lowEdgeEnergy;
75 if (energy > highEdgeEnergy) energy = highEdgeEnergy;
76
77 energyToRangeMap.insert(
78 std::pair<G4double, G4double>(energy / MeV, rangeCut));
79 }
80
81 // Now find the closest value of energy
82 it = energyToRangeMap.lower_bound(energyCut);
83
84 if (it == energyToRangeMap.end()) {
85 if (VerboseLevel() > 2) {
86 G4cout << indent << "Range not found " << G4endl;
87 }
88 return false;
89 }
90 else {
91 if (VerboseLevel() > 2) {
92 G4cout << indent << "Found range limit: " << it->second << " mm"
93 << G4endl;
94 }
95 return true;
96 }
97}
98
99//_____________________________________________________________________________
100std::pair<G4double,G4double>
102 G4Material* material, G4VRangeToEnergyConverter& converter,
103 G4double defaultRangeCut) const
104{
107
108 G4double lowEdgeEnergy = converter.GetLowEdgeEnergy();
109 G4double highEdgeEnergy = converter.GetHighEdgeEnergy();
110
111 // First compute default energy cut
112 std::map<G4double, G4double> energyToRangeMap;
113 G4double energy = converter.Convert(defaultRangeCut, material);
114 if (energy < lowEdgeEnergy) energy = lowEdgeEnergy;
115 if (energy > highEdgeEnergy) energy = highEdgeEnergy;
116 energyToRangeMap.insert(
117 std::pair<G4double, G4double>(energy / MeV, defaultRangeCut));
118
119 // Compute the range order where we will start iterating
120 // withing the orders in between fgkMinRangeOrder and fgkMaxRangeOrder
121 // (1e-03mm, 1e-02, 1e-01, 1mm, 1cm, 10 cm, 1m, 10m, 100m, 1000m )
122 G4String indent(" ");
123 for (G4int i = fgkMinRangeOrder; i <= fgkMaxRangeOrder; i++) {
124 G4double rangeCut = pow(10., i);
125 if (rangeCut < defaultRangeCut) continue;
126 energy = converter.Convert(rangeCut, material);
127 if (VerboseLevel() > 2) {
128 G4cout << indent << "For range: " << std::setw(5) << rangeCut
129 << " mm got energy " << energy / MeV << " MeV" << G4endl;
130 }
131
132 if (energy < lowEdgeEnergy) energy = lowEdgeEnergy;
133 if (energy > highEdgeEnergy) energy = highEdgeEnergy;
134 energyToRangeMap.insert(
135 std::pair<G4double, G4double>(energy / MeV, rangeCut));
136 }
137
138 // If energyCut is above the maximum range order return the last
139 // computed value
140 if (energyToRangeMap.rbegin()->first < energyCut) {
141 if (VerboseLevel() > 2) {
142 G4cout << indent << "Outside range, return the highest value " << G4endl;
143 }
144 return *(energyToRangeMap.rbegin());
145 }
146
147 // Now find the closest value of energy which is
148 // equal or higher than given energyCut
149 std::map<G4double, G4double>::const_iterator it =
150 energyToRangeMap.lower_bound(energyCut);
151
152 if (it == energyToRangeMap.end()) {
153 if (VerboseLevel() > 2) {
154 G4cout << indent << "Range not found " << G4endl;
155 }
156 return {-1.0, -1.0};
157 }
158
159 if (VerboseLevel() > 2) {
160 G4cout << indent << "Found range limit: " << it->second << " mm" << G4endl;
161 }
162
163 // Now iterate up to desired precision of range
164 G4int iteration = 0;
165 while (iteration < fRangePrecision) {
166 G4int nbin = fgkNofBins;
167 if (iteration == 0) --nbin;
168
169 auto higherCutIt = it;
170 auto higherCut = it->second;
171 // G4cout << "higherCut = " << higherCut << G4endl;
172 if (it == energyToRangeMap.begin()) return *higherCutIt;
173
174 --it;
175 auto lowerCutIt = it;
176 auto lowerCut = it->second;
177 // G4cout << "lowerCut = " << lowerCut << G4endl;
178 G4bool found =
179 Iterate(energyCut, lowerCut, higherCut, defaultRangeCut, lowEdgeEnergy,
180 highEdgeEnergy, nbin, energyToRangeMap, it, material, converter);
181
182 if (!found) {
183 // Now we have to go one step back to get below the user cut value
184 // unless we are at the beginning of the map
185 if (it == energyToRangeMap.begin()) return *higherCutIt;
186 --it;
187 return *it;
188 ;
189 }
190 ++iteration;
191 }
192
193 // Now we have to go one step back to get below the user cut value
194 // unless we are at the beginning of the map
195 // if (it == energyToRangeMap.begin()) return it->second;
196 if (it == energyToRangeMap.begin()) return *it;
197 --it;
198 return *it;
199 ;
200}
201
202//_____________________________________________________________________________
203std::pair<G4double,G4double>
205 G4Material* material, G4VRangeToEnergyConverter& converter,
206 G4double defaultRangeCut) const
207{
210
211 if (energyCut == DBL_MAX) {
212 if (VerboseLevel() > 1) {
213 G4cout << " " << converter.GetParticleType()->GetParticleName()
214 << " energy cut not defined, keeping default range" << G4endl;
215 }
216 return {converter.GetLowEdgeEnergy(), defaultRangeCut};
217 }
218
219 if (VerboseLevel() > 1) {
220 G4cout << " " << converter.GetParticleType()->GetParticleName()
221 << ": energy cut = " << energyCut << " MeV" << G4endl;
222 }
223
224 if (fIsLoad) {
225 auto it = fRegionData.find(material->GetName());
226 if (it != fRegionData.end()) {
227 auto [rangeCut, energyCut] =
228 (converter.GetParticleType() == G4Gamma::Definition()) ?
229 std::pair(it->second[fgkRangeGamIdx], it->second[fgkCutGamIdx]) :
230 std::pair(it->second[fgkRangeEleIdx], it->second[fgkCutEleIdx]);
231
232 if (VerboseLevel() > 1) {
233 G4cout << " " << converter.GetParticleType()->GetParticleName()
234 << " loaded range, cut values: "
235 << rangeCut << ", " << energyCut << G4endl;
236 }
237 return {energyCut, rangeCut};
238 }
239 else {
240 if (VerboseLevel() > 1) {
241 G4cout << " " << converter.GetParticleType()->GetParticleName()
242 << " rangeCut not found, keeping default range" << G4endl;
243 }
244 return {converter.GetLowEdgeEnergy(), defaultRangeCut};
245 }
246 }
247
248 auto [calcEnergyCut, rangeCut] =
249 ConvertEnergyToRange(energyCut, material, converter, defaultRangeCut);
250
251 if (rangeCut < 0.) {
252 if (VerboseLevel() > 1) {
253 G4cout << " " << converter.GetParticleType()->GetParticleName()
254 << " rangeCut not found, keeping default range" << G4endl;
255 }
256 return {converter.GetLowEdgeEnergy(), defaultRangeCut};
257 }
258
259 if (rangeCut < defaultRangeCut) {
260 if (VerboseLevel() > 1) {
261 G4cout << " " << converter.GetParticleType()->GetParticleName()
262 << " rangeCut found " << rangeCut << " mm "
263 << " is below default value, it will be ignored" << G4endl;
264 }
265 return {converter.GetLowEdgeEnergy(), defaultRangeCut};
266 }
267
268 return {calcEnergyCut, rangeCut};
269}
270
271//_____________________________________________________________________________
273{
276
277 if (VerboseLevel() > 0) {
278 G4cout << ".. Checking energyCuts approximation, tolerance: "
279 << fEnergyTolerance << G4endl;
280 }
281
282 auto counter = 0;
283 for (auto& [regionName, values] : fRegionData) {
284 // check values for gamma and electron
285 for (size_t idx = fgkCutGamIdx; idx < fgkVmcCutGamIdx; ++idx ) {
286 auto vmcIdx = idx + 2;
287 auto factor = (idx == fgkCutGamIdx) ? 10. : 1.;
288 auto cutType = (idx == fgkCutGamIdx) ? "gam" : "ele";
289 if (fabs(values[idx] - values[vmcIdx]) >
290 (values[vmcIdx] * fEnergyTolerance * factor)) {
291
292 G4cout << std::setw(25) << std::left << regionName << " " << cutType
293 << " cut from range = " << std::scientific << values[idx] / MeV
294 << " from limits = " << std::scientific<< values[vmcIdx] / MeV
295 << " MeV" << " delta: "
296 << fabs(values[idx] - values[vmcIdx]) / values[vmcIdx] * 100.
297 << " %" << G4endl;
298 ++counter;
299 }
300 }
301 }
302
303 if (counter == 0) {
304 G4cout << ".. Cuts from ranges in regions are consistent with energy cuts."
305 << G4endl << " (precision fgkEnergyTolerance)" << G4endl;
306 }
307 else {
308 G4cout << ".. Found " << counter
309 << " inconsistencies between cut from ranges energy cuts." << G4endl;
310 }
311}
312
313//_____________________________________________________________________________
314void TG4RegionsManager::PrintFromMap(std::ostream& output) const
315{
318
319 if (fRegionData.empty()) {
320 G4cout << "No regions data in the map." << G4endl;
321 }
322
323 PrintLegend(output);
324
325 for (auto [regionName, values] : fRegionData) {
326 PrintRegionData(output, regionName, values);
327 }
328}
329
330
331//
332// public methods
333//
334
335//_____________________________________________________________________________
337{
339
340 // Do nothing if no option is activated
343 return;
344 }
345
346 if (VerboseLevel() > 0) {
347 G4cout << "Converting VMC cuts in regions" << G4endl;
348 }
349
350 if (fIsLoad) {
351 LoadRegions();
352 }
353
354 // Create G4 range to energy converters
355#if (G4VERSION_NUMBER == 1100 || G4VERSION_NUMBER == 1101 )
356 // Temporary work-around for a bug in G4VRangeToEnergyConverter
357 auto g4ConverterElePtr = new G4RToEConvForElectron();
358 auto g4ConverterGamPtr = new G4RToEConvForGamma();
359 auto& g4ConverterEle = *g4ConverterElePtr;
360 auto& g4ConverterGam = *g4ConverterGamPtr;
361#else
362 G4RToEConvForElectron g4ConverterEle;
363 G4RToEConvForGamma g4ConverterGam;
364#endif
365
366 // Get default range cut values from physics manager
367 G4double defaultRangeCutEle =
369 G4double defaultRangeCutGam = TG4PhysicsManager::Instance()->GetCutForGamma();
370 G4double defaultRangeCutPositron =
372 G4double defaultRangeCutProton =
374
375 // Create a new region with default cuts
376 G4Region* defaultRegion = new G4Region(fgkDefaultRegionName);
377 G4ProductionCuts* dcuts = new G4ProductionCuts();
378 dcuts->SetProductionCut(defaultRangeCutGam, 0);
379 dcuts->SetProductionCut(defaultRangeCutEle, 1);
380 dcuts->SetProductionCut(defaultRangeCutPositron, 2);
381 dcuts->SetProductionCut(defaultRangeCutProton, 3);
382 defaultRegion->SetProductionCuts(dcuts);
383
384 // Get world default region
385 G4LogicalVolume* worldLV =
386 TG4GeometryServices::Instance()->GetWorld()->GetLogicalVolume();
387 G4Region* worldRegion = worldLV->GetRegion();
388
389 // Get global energy cuts
390 G4double cutEleGlobal = GetGlobalEnergyCut(kCUTELE);
391 G4double cutGamGlobal = GetGlobalEnergyCut(kCUTGAM);
392 if (VerboseLevel() > 2) {
393 G4cout << "Global cut values: "
394 << " CUTELE = " << cutEleGlobal << " MeV"
395 << " CUTGAM = " << cutGamGlobal << " MeV" << G4endl;
396 }
397
398 G4int counter = 0;
399 std::set<G4Material*> processedMaterials;
400 std::set<G4Material*> processedMaterials2;
401
402 // Define region for each logical volume
403 //
404
405 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
406
407 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
408
409 G4LogicalVolume* lv = (*lvStore)[i];
410 G4bool isWorld = (lv == worldLV);
411
412 TG4Medium* medium =
414 if (!medium) continue;
415
416 G4Material* material = lv->GetMaterial();
417 if (VerboseLevel() > 1) {
418 G4cout << "-- Volume = " << i << " " << lv << " " << lv->GetName()
419 << " material = " << material->GetName() << G4endl;
420 }
421
422 // Get region, if it already exists, and add the logical volume
423 G4String regionName = material->GetName();
424 G4Region* region =
425 G4RegionStore::GetInstance()->GetRegion(regionName, false);
426 if (region && !isWorld) {
427 if (VerboseLevel() > 1) {
428 G4cout << " "
429 << "adding volume in region = " << regionName << G4endl;
430 }
431 if (lv->GetRegion() != region) region->AddRootLogicalVolume(lv);
432 // skip evaluation of cuts if this material was already processed
433 if (processedMaterials2.find(material) != processedMaterials2.end()) {
434 if (VerboseLevel() > 1) {
435 G4cout << " "
436 << "skipping cuts evaluation in region = " << regionName << G4endl;
437 }
438 continue;
439 }
440 }
441
442 // After this line, region either does not exist, or we deal with the
443 // world reagion
444
445 // If this material was already processed and did not result
446 // in a new region: add the logical volume to the default region
447 if (processedMaterials.find(material) != processedMaterials.end() &&
448 !isWorld) {
449 if (VerboseLevel() > 1) {
450 G4cout << " "
451 << "adding volume in the default region" << G4endl;
452 }
453 defaultRegion->AddRootLogicalVolume(lv);
454 continue;
455 }
456
457 // Get energy cuts defined in limits
458 TG4Limits* limits = (TG4Limits*)lv->GetUserLimits();
459 G4double cutEle = GetEnergyCut(limits, kCUTELE, cutEleGlobal);
460 G4double cutGam = GetEnergyCut(limits, kCUTGAM, cutGamGlobal);
461
462 // Convert energy cuts defined in limits in range cuts
463 auto [calcCutEle, rangeEle] =
464 GetRangeCut(cutEle, material, g4ConverterEle, defaultRangeCutEle);
465 auto [calcCutGam, rangeGam] =
466 GetRangeCut(cutGam, material, g4ConverterGam, defaultRangeCutGam);
467 if (VerboseLevel() > 1) {
468 G4cout << ".. converted in e- rangeCut = " << rangeEle << " mm "
469 << "gamma rangeCut = " << rangeGam << " mm" << G4endl;
470 }
471
472 if (fabs(rangeEle - defaultRangeCutEle) < 1e-03 &&
473 fabs(rangeGam - defaultRangeCutGam) < 1e-03 && !region) {
474 // Do not create a new region if range cuts do not differ
475 // from those in the default region and region was not defined
476 // before
477 if (!isWorld) {
478 if (VerboseLevel() > 1) {
479 G4cout << " "
480 << "adding volume in the default region" << G4endl;
481 }
482 defaultRegion->AddRootLogicalVolume(lv);
483 }
484 // Save the material in the processed materials not resulting
485 // in new region
486 processedMaterials.insert(material);
487 }
488 else {
489 // Create new production cuts
490 G4ProductionCuts* cuts = new G4ProductionCuts();
491
492 if (fApplyForGamma) {
493 cuts->SetProductionCut(rangeGam, 0);
494 }
495 else {
496 cuts->SetProductionCut(defaultRangeCutGam, 0);
497 }
498
499 if (fApplyForElectron) {
500 cuts->SetProductionCut(rangeEle, 1);
501 }
502 else {
503 cuts->SetProductionCut(defaultRangeCutEle, 1);
504 }
505
506 if (fApplyForPositron) {
507 cuts->SetProductionCut(rangeEle, 2);
508 }
509 else {
510 cuts->SetProductionCut(defaultRangeCutPositron, 2);
511 }
512
513 if (fApplyForProton) {
514 cuts->SetProductionCut(rangeEle, 3);
515 }
516 else {
517 cuts->SetProductionCut(defaultRangeCutProton, 2);
518 }
519
520 // save computed ranges in a map
521 if (! fIsLoad) {
522 fRegionData[regionName] =
523 {rangeGam, rangeEle, calcCutGam, calcCutEle, cutGam, cutEle};
524 }
525
526 if (isWorld) {
527 // set new production cuts to the world
528 worldRegion->SetProductionCuts(cuts);
529 worldRegion->RegionModified(true);
530 if (VerboseLevel() > 1) {
531 G4cout << " "
532 << "setting new production cuts to the world region" << G4endl;
533 }
534 continue;
535 }
536
537 G4String which;
538 // Create new region if it does not yet exist
539 if (region == nullptr) {
540 region = new G4Region(regionName);
541 ++counter;
542 which = "new ";
543 }
544 if (VerboseLevel() > 1) {
545 G4cout << " "
546 << "adding volume in " << which << "region " << regionName << G4endl;
547 }
548 // Set computed production cuts
549 region->SetProductionCuts(cuts);
550 region->AddRootLogicalVolume(lv);
551
552 // Save the material in the processed materials
553 processedMaterials2.insert(material);
554 }
555 }
556
557 processedMaterials.clear();
558 processedMaterials.clear();
559
560 if (VerboseLevel() > 0) {
561 G4cout << "Number of added regions: " << counter << G4endl;
562 }
563}
564
565//_____________________________________________________________________________
566void TG4RegionsManager::PrintRegions(std::ostream& output) const
567{
569
570 if (fIsG4Table) {
571 G4cout << "going to print/write from G4 Table" << G4endl;
572 PrintFromG4Table(output);
573 } else {
574 G4cout << "going to print/write from map" << G4endl;
575 PrintFromMap(output);
576 }
577}
578
579//_____________________________________________________________________________
589
590//_____________________________________________________________________________
592{
594
595 auto fileName = fFileName.empty() ? fgkDefaultFileName : fFileName;
596
597 std::ifstream input;
598 input.open(fileName, std::ios::in);
599
600 if (! input.is_open()) {
601 TG4Globals::Warning("TG4RegionsManager", "LoadRegions",
602 "Open input file " + TString(fileName.data()) + " has failed.");
603 fIsLoad = false;
604 return;
605 }
606
607 if (VerboseLevel() > 0) {
608 G4cout << "Loading regions from file: " << fileName << G4endl;
609 }
610
611 auto worldMaterialName = TG4GeometryServices::Instance()->GetWorld()->
612 GetLogicalVolume()->GetMaterial()->GetName();
613
614 G4String skipLine;
615 G4String regionName;
616 G4int counter;
617 TG4RegionData regionValues;
618
619 // skip comments
620 std::getline(input, skipLine);
621
622 // read data
623 while (! input.eof()) {
624 std::getline(input, regionName, ';');
625 for (auto& value : regionValues) {
626 input >> value;
627 }
628
629 if (input.good()) {
630 auto startPos = regionName.find('\'') + 1;
631 auto length = regionName.find_last_of('\'') - startPos;
632 regionName = regionName.substr(startPos, length);
633 if (VerboseLevel() > 0) {
634 G4cout << "Loading " << regionName << G4endl;
635 }
636
637 // update units
638 for (auto idx = fgkCutGamIdx; idx <= fgkVmcCutEleIdx; ++ idx) {
639 regionValues[idx] *= TG4G3Units::Energy();
640 }
641
642 auto it = fRegionData.find(regionName);
643 if (it == fRegionData.end()) {
644 fRegionData[regionName] = regionValues;
645 ++counter;
646 }
647 else {
648 // skip "fake" material couples originated from assemblies
649 // that are added in the regions in addition to the real material
650 if (regionName == worldMaterialName) {
651 if (VerboseLevel() > 0) {
652 G4cout << "Skipping " << regionName << " already in map." << G4endl;
653 }
654 }
655 else {
656 // print warning
657 TG4Globals::Warning("TG4RegionsManager", "LoadRegions",
658 "Duplicated region data: " + TString(regionName.data()) +
659 " will be skipped !!!.");
660
661 if (VerboseLevel() > 0) {
662 auto valuesInMap = it->second;
663 G4cout << " Already in map !!!" << G4endl << " data in map: ";
664 PrintRegionData(G4cout, regionName, valuesInMap);
665 G4cout << " loaded data: ";
666 PrintRegionData(G4cout, regionName, regionValues);
667 }
668 }
669 }
670 }
671 }
672
673 if (VerboseLevel() > 0) {
674 G4cout << "Loaded " << counter << " regions from file: " << fileName << G4endl;
675 }
676}
677
678//_____________________________________________________________________________
679void TG4RegionsManager::DumpRegion(const G4String& volName) const
680{
682
683 // Get volume
684 G4LogicalVolume* lv =
686 if (!lv) return;
687
688 // Get region
689 G4Region* region = lv->GetRegion();
690 if (!region) {
691 TG4Globals::Warning("TG4RegionsManager", "DumpRegion",
692 "Region for volume " + TString(volName) + "not found.");
693 return;
694 }
695
696 G4ProductionCuts* cuts = region->GetProductionCuts();
697
698 // Range cuts
699 G4cout << G4endl;
700 G4cout << " Region name: " << region->GetName() << G4endl;
701 G4cout << " Material : " << lv->GetMaterial()->GetName() << G4endl;
702 G4cout << " Range cuts : "
703 << " gamma " << G4BestUnit(cuts->GetProductionCut("gamma"), "Length")
704 << " e- " << G4BestUnit(cuts->GetProductionCut("e-"), "Length")
705 << " e+ " << G4BestUnit(cuts->GetProductionCut("e+"), "Length")
706 << " proton " << G4BestUnit(cuts->GetProductionCut("proton"), "Length")
707 << G4endl;
708
709 // Energy cuts
710 G4cout << " Energy thresholds : ";
711
712 G4ProductionCutsTable* productionCutsTable =
713 G4ProductionCutsTable::GetProductionCutsTable();
714
715 const G4MaterialCutsCouple* couple =
716 productionCutsTable->GetMaterialCutsCouple(lv->GetMaterial(), cuts);
717 // if ( ! couple || couple->IsRecalcNeeded() ) {
718 if (!couple) {
719 G4cout << " not ready to print" << G4endl;
720 return;
721 }
722
723 const std::vector<G4double>* energyCutsGam =
724 productionCutsTable->GetEnergyCutsVector(0);
725 const std::vector<G4double>* energyCutsEle =
726 productionCutsTable->GetEnergyCutsVector(1);
727 const std::vector<G4double>* energyCutsPos =
728 productionCutsTable->GetEnergyCutsVector(2);
729 const std::vector<G4double>* energyCutsPro =
730 productionCutsTable->GetEnergyCutsVector(3);
731
732 G4double cutGam = (*energyCutsGam)[couple->GetIndex()];
733 G4double cutEle = (*energyCutsEle)[couple->GetIndex()];
734 G4double cutPos = (*energyCutsPos)[couple->GetIndex()];
735 G4double cutPro = (*energyCutsPro)[couple->GetIndex()];
736
737 G4cout << " gamma " << G4BestUnit(cutGam, "Energy") << " e- "
738 << G4BestUnit(cutEle, "Energy") << " e+ "
739 << G4BestUnit(cutPos, "Energy") << " proton "
740 << G4BestUnit(cutPro, "Energy");
741 G4cout << G4endl;
742
743 G4RegionStore* regionStore = G4RegionStore::GetInstance();
744 if (couple->IsUsed()) {
745 G4cout << " Region(s) which use this couple : ";
746 std::vector<G4Region*>::iterator it;
747 for (it = regionStore->begin(); it != regionStore->end(); it++) {
748 if (IsCoupleUsedInTheRegion(couple, *it)) {
749 G4cout << " " << (*it)->GetName();
750 }
751 }
752 G4cout << G4endl;
753 }
754}
755
756//_____________________________________________________________________________
757void TG4RegionsManager::SetLoad(G4bool isLoad)
758{
760// The options fIsSave and fIsLoad cannot be activated both
761// in the same run.
762
763 if (fIsSave) {
764 TG4Globals::Warning("TG4RegionsManager", "SetLoad",
765 "\"Save\" option is active. The input file " + fFileName +
766 " will be overwritten.");
767 }
768
769 fIsLoad = isLoad;
770}
Definition of the TG4G3CutVector class.
Definition of the TG4G3PhysicsManager class.
Definition of the TG4G3Units class.
Definition of the TG4GeometryServices class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4Limits class.
Definition of the TG4Medium class.
Definition of the TG4PhysicsManager class.
Definition of the TG4RegionsManager class.
Definition of the TG4RegionsMessenger class.
static G4double Energy()
Definition TG4G3Units.h:105
G4VPhysicalVolume * GetWorld() const
G4LogicalVolume * FindLogicalVolume(const G4String &name, G4bool silent=false) const
static TG4GeometryServices * Instance()
TG4MediumMap * GetMediumMap() const
static void Warning(const TString &className, const TString &methodName, const TString &text)
Extended G4UserLimits class.
Definition TG4Limits.h:38
TG4Medium * GetMedium(G4int mediumID, G4bool warn=true) const
Helper class to keep medium data.
Definition TG4Medium.h:29
G4Material * GetMaterial() const
Definition TG4Medium.h:94
G4double GetCutForPositron() const
G4double GetCutForProton() const
static TG4PhysicsManager * Instance()
G4double GetCutForElectron() const
G4double GetCutForGamma() const
void PrintFromMap(std::ostream &output) const
std::pair< G4double, G4double > ConvertEnergyToRange(G4double energyCut, G4Material *material, G4VRangeToEnergyConverter &converter, G4double defaultRangeValue) const
G4int fRangePrecision
the precision for calculating ranges
void DefineRegions() override
void CheckRegionsRanges() const
void SetLoad(G4bool isLoad)
G4double fEnergyTolerance
the tolerance (relative) for comparing energy cut values
std::array< G4double, fgkValuesSize > TG4RegionData
void CheckRegions() const override
G4bool fIsLoad
option to load regions ranges from a file
static constexpr G4int fgkMinRangeOrder
the minimum range order
std::pair< G4double, G4double > GetRangeCut(G4double energyCut, G4Material *material, G4VRangeToEnergyConverter &converter, G4double defaultRangeValue) const
void DumpRegion(const G4String &volName) const
void PrintRegions(std::ostream &output) const override
static constexpr G4int fgkMaxRangeOrder
the maximum range order
std::map< G4String, TG4RegionData > fRegionData
map for computed or loaded regions data
G4bool Iterate(G4double energyCut, G4double &lowerCut, G4double &higherCut, G4double defaultRangeCut, G4double lowEdgeEnergy, G4double highEdgeEnergy, G4int nbin, std::map< G4double, G4double > &map, std::map< G4double, G4double >::const_iterator &it, G4Material *material, G4VRangeToEnergyConverter &converter) const
G4bool fIsG4Table
option to print or save regions from G4 production cuts table
static constexpr G4int fgkNofBins
the number of bins for search range iteration
static constexpr size_t fgkRangeGamIdx
G4bool fApplyForElectron
option to apply cuts for e- (default is true)
G4bool fIsSave
option to save all regions in a file
G4bool fApplyForPositron
option to apply cuts for e+ (default is true)
void PrintLegend(std::ostream &output) const
void PrintRegionData(std::ostream &output, const G4String &matName, const TG4RegionData &values) const
static const G4String fgkDefaultRegionName
the name of the region with default cuts
static const G4String fgkDefaultFileName
the name of the region with default cuts
static constexpr size_t fgkCutGamIdx
G4double GetEnergyCut(TG4Limits *limits, TG4G3Cut cutType, G4double globalCutValue) const
G4bool IsCoupleUsedInTheRegion(const G4MaterialCutsCouple *couple, const G4Region *region) const
G4bool fApplyForGamma
option to apply cuts for gamma (default is true)
static constexpr size_t fgkCutEleIdx
static constexpr size_t fgkVmcCutGamIdx
void PrintFromG4Table(std::ostream &output) const
void CheckRegionsInGeometry() const
G4bool fApplyForProton
option to apply cuts for proton (default is true)
G4double GetGlobalEnergyCut(TG4G3Cut cutType) const
static constexpr size_t fgkRangeEleIdx
G4String fFileName
file name for regions output
static constexpr size_t fgkVmcCutEleIdx
virtual G4int VerboseLevel() const
Definition TG4Verbose.h:78
@ kCUTGAM
Definition TG4G3Cut.h:27
@ kCUTELE
Definition TG4G3Cut.h:32