Geant4-11
G4ProductionCutsTable.cc
Go to the documentation of this file.
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// G4ProductionCutsTable class implementation
27//
28// Author: M.Asai, 5 October 2002 - First implementation
29// Modifications: H.Kurashige, 2004-2008
30// --------------------------------------------------------------------
31
33#include "G4ProductionCuts.hh"
37#include "G4ParticleTable.hh"
38#include "G4RegionStore.hh"
39#include "G4LogicalVolume.hh"
40#include "G4VPhysicalVolume.hh"
42#include "G4RToEConvForGamma.hh"
45#include "G4MaterialTable.hh"
46#include "G4Material.hh"
47#include "G4UnitsTable.hh"
48
49#include "G4Timer.hh"
50#include "G4SystemOfUnits.hh"
51#include "G4ios.hh"
52#include <iomanip>
53#include <fstream>
54
56
57// --------------------------------------------------------------------
59{
60 static G4ProductionCutsTable theProductionCutsTable;
61 if(fProductionCutsTable == nullptr)
62 {
63 fProductionCutsTable = &theProductionCutsTable;
64 }
66}
67
68// --------------------------------------------------------------------
70{
71 for(std::size_t i=0; i< NumberOfG4CutIndex; ++i)
72 {
73 rangeCutTable.push_back(new std::vector<G4double>);
74 energyCutTable.push_back(new std::vector<G4double>);
75 rangeDoubleVector[i] = nullptr;
76 energyDoubleVector[i] = nullptr;
77 converters[i] = nullptr;
78 }
81
82 // add messenger for UI
84}
85
86// --------------------------------------------------------------------
88{
90 defaultProductionCuts = nullptr;
91
92 for(auto itr=coupleTable.cbegin(); itr!=coupleTable.cend(); ++itr)
93 {
94 delete (*itr);
95 }
96 coupleTable.clear();
97
98 for(std::size_t i=0; i< NumberOfG4CutIndex; ++i)
99 {
100 delete rangeCutTable[i];
101 delete energyCutTable[i];
102 delete converters[i];
103 if(rangeDoubleVector[i] != nullptr) delete [] rangeDoubleVector[i];
104 if(energyDoubleVector[i] != nullptr) delete [] energyDoubleVector[i];
105 rangeCutTable[i] = nullptr;
106 energyCutTable[i] = nullptr;
107 converters[i] = nullptr;
108 rangeDoubleVector[i] = nullptr;
109 energyDoubleVector[i] = nullptr;
110 }
111 fProductionCutsTable = nullptr;
112
113 delete fMessenger;
114 fMessenger = nullptr;
115}
116
117// --------------------------------------------------------------------
119{
120 if(firstUse)
121 {
122 if(G4ParticleTable::GetParticleTable()->FindParticle("gamma"))
123 {
124 converters[0] = new G4RToEConvForGamma();
126 }
127 if(G4ParticleTable::GetParticleTable()->FindParticle("e-"))
128 {
131 }
132 if(G4ParticleTable::GetParticleTable()->FindParticle("e+"))
133 {
136 }
137 if(G4ParticleTable::GetParticleTable()->FindParticle("proton"))
138 {
141 }
142 firstUse = false;
143 }
144
145 // Reset "used" flags of all couples
146 for(auto CoupleItr=coupleTable.cbegin();
147 CoupleItr!=coupleTable.cend(); ++CoupleItr)
148 {
149 (*CoupleItr)->SetUseFlag(false);
150 }
151
152 // Update Material-Cut-Couple
153 for(auto rItr=fG4RegionStore->cbegin(); rItr!=fG4RegionStore->cend(); ++rItr)
154 {
155 // Material scan is to be done only for the regions appear in the
156 // current tracking world.
157 // if((*rItr)->GetWorldPhysical()!=currentWorld) continue;
158
159 if( (*rItr)->IsInMassGeometry() || (*rItr)->IsInParallelGeometry() )
160 {
161 G4ProductionCuts* fProductionCut = (*rItr)->GetProductionCuts();
162 auto mItr = (*rItr)->GetMaterialIterator();
163 std::size_t nMaterial = (*rItr)->GetNumberOfMaterials();
164 (*rItr)->ClearMap();
165
166 for(std::size_t iMate=0; iMate<nMaterial; ++iMate)
167 {
168 //check if this material cut couple has already been made
169 G4bool coupleAlreadyDefined = false;
170 G4MaterialCutsCouple* aCouple;
171 for(auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
172 {
173 if( (*cItr)->GetMaterial()==(*mItr)
174 && (*cItr)->GetProductionCuts()==fProductionCut)
175 {
176 coupleAlreadyDefined = true;
177 aCouple = *cItr;
178 break;
179 }
180 }
181
182 // If this combination is new, cleate and register a couple
183 if(!coupleAlreadyDefined)
184 {
185 aCouple = new G4MaterialCutsCouple((*mItr),fProductionCut);
186 coupleTable.push_back(aCouple);
187 aCouple->SetIndex(coupleTable.size()-1);
188 }
189
190 // Register this couple to the region
191 (*rItr)->RegisterMaterialCouplePair((*mItr),aCouple);
192
193 // Set the couple to the proper logical volumes in that region
194 aCouple->SetUseFlag();
195
196 auto rootLVItr = (*rItr)->GetRootLogicalVolumeIterator();
197 std::size_t nRootLV = (*rItr)->GetNumberOfRootVolumes();
198 for(std::size_t iLV=0; iLV<nRootLV; ++iLV)
199 {
200 // Set the couple to the proper logical volumes in that region
201 G4LogicalVolume* aLV = *rootLVItr;
202 G4Region* aR = *rItr;
203
204 ScanAndSetCouple(aLV,aCouple,aR);
205
206 // Proceed to the next root logical volume in this region
207 ++rootLVItr;
208 }
209
210 // Proceed to next material in this region
211 ++mItr;
212 }
213 }
214 }
215
216 // Check if sizes of Range/Energy cuts tables are equal to the size of
217 // the couple table. If new couples are made during the previous procedure,
218 // nCouple becomes larger then nTable
219
220 std::size_t nCouple = coupleTable.size();
221 std::size_t nTable = energyCutTable[0]->size();
222 G4bool newCoupleAppears = nCouple>nTable;
223 if(newCoupleAppears)
224 {
225 for(std::size_t n=nCouple-nTable; n>0; --n)
226 {
227 for(std::size_t nn=0; nn< NumberOfG4CutIndex; ++nn)
228 {
229 rangeCutTable[nn]->push_back(-1.);
230 energyCutTable[nn]->push_back(-1.);
231 }
232 }
233 }
234
235 // Update RangeEnergy cuts tables
236 std::size_t idx = 0;
237 G4Timer timer;
238 if (verboseLevel>2)
239 {
240 timer.Start();
241 }
242 for(auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
243 {
244 G4ProductionCuts* aCut = (*cItr)->GetProductionCuts();
245 const G4Material* aMat = (*cItr)->GetMaterial();
246 if((*cItr)->IsRecalcNeeded())
247 {
248 for(std::size_t ptcl=0; ptcl< NumberOfG4CutIndex; ++ptcl)
249 {
250 G4double rCut = aCut->GetProductionCut(ptcl);
251 (*(rangeCutTable[ptcl]))[idx] = rCut;
252 // if(converters[ptcl] && (*cItr)->IsUsed())
253 if(converters[ptcl])
254 {
255 (*(energyCutTable[ptcl]))[idx] = converters[ptcl]->Convert(rCut,aMat);
256 }
257 else
258 {
259 (*(energyCutTable[ptcl]))[idx] = -1.;
260 }
261 }
262 }
263 ++idx;
264 }
265 if (verboseLevel>2)
266 {
267 timer.Stop();
268 G4cout << "G4ProductionCutsTable::UpdateCoupleTable() - "
269 << "Elapsed time for calculation of energy cuts: " << G4endl;
270 G4cout << timer << G4endl;
271 }
272
273 // resize Range/Energy cuts double vectors if new couple is made
274 if(newCoupleAppears)
275 {
276 for(std::size_t ix=0; ix<NumberOfG4CutIndex; ++ix)
277 {
278 G4double* rangeVOld = rangeDoubleVector[ix];
279 G4double* energyVOld = energyDoubleVector[ix];
280 if(rangeVOld) delete [] rangeVOld;
281 if(energyVOld) delete [] energyVOld;
282 rangeDoubleVector[ix] = new G4double[(*(rangeCutTable[ix])).size()];
283 energyDoubleVector[ix] = new G4double[(*(energyCutTable[ix])).size()];
284 }
285 }
286
287 // Update Range/Energy cuts double vectors
288 for(std::size_t ix=0; ix<NumberOfG4CutIndex; ++ix)
289 {
290 for(std::size_t ixx=0; ixx<(*(rangeCutTable[ix])).size(); ++ixx)
291 {
292 rangeDoubleVector[ix][ixx] = (*(rangeCutTable[ix]))[ixx];
293 energyDoubleVector[ix][ixx] = (*(energyCutTable[ix]))[ixx];
294 }
295 }
296}
297
298// --------------------------------------------------------------------
300 const G4ParticleDefinition* particle,
301 const G4Material* material,
302 G4double range )
303{
304 // This method gives energy corresponding to range value
305
306 // protection against premature call
307 if(firstUse)
308 {
309#ifdef G4VERBOSE
310 if(verboseLevel>0)
311 {
313 ed << "Invoked prematurely before it is fully initialized.";
314 G4Exception("G4ProductionCutsTable::ConvertRangeToEnergy()",
315 "CUTS0100", JustWarning, ed);
316 }
317#endif
318 return -1.0;
319 }
320
321 // check material
322 if (material == nullptr) return -1.0;
323
324 // check range
325 if (range == 0.0) return 0.0;
326 if (range <0.0) return -1.0;
327
328 // check particle
329 G4int index = G4ProductionCuts::GetIndex(particle);
330
331 if (index<0 || converters[index] == nullptr)
332 {
333#ifdef G4VERBOSE
334 if(verboseLevel>0)
335 {
337 ed << "Invoked ";
338 if(particle != nullptr)
339 { ed << "for particle <" << particle->GetParticleName() << ">."; }
340 else
341 { ed << "without valid particle pointer."; }
342 G4Exception("G4ProductionCutsTable::ConvertRangeToEnergy()",
343 "CUTS0101", JustWarning, ed);
344 }
345#endif
346 return -1.0;
347 }
348
349 return converters[index]->Convert(range, material);
350}
351
352// --------------------------------------------------------------------
354{}
355
356// --------------------------------------------------------------------
358{
360}
361
362// --------------------------------------------------------------------
364{
366}
367
368// --------------------------------------------------------------------
370{
372}
373
374// --------------------------------------------------------------------
376 G4MaterialCutsCouple* aCouple,
377 G4Region* aRegion)
378{
379 // Check whether or not this logical volume belongs to the same region
380 if((aRegion!=nullptr) && aLV->GetRegion()!=aRegion) return;
381
382 // Check if this particular volume has a material matched to the couple
383 if(aLV->GetMaterial()==aCouple->GetMaterial())
384 {
385 aLV->SetMaterialCutsCouple(aCouple);
386 }
387
388 std::size_t noDaughters = aLV->GetNoDaughters();
389 if(noDaughters==0) return;
390
391 // Loop over daughters with same region
392 for(std::size_t i=0; i<noDaughters; ++i)
393 {
394 G4LogicalVolume* daughterLVol = aLV->GetDaughter(i)->GetLogicalVolume();
395 ScanAndSetCouple(daughterLVol,aCouple,aRegion);
396 }
397}
398
399// --------------------------------------------------------------------
401{
402 G4cout << G4endl;
403 G4cout << "========= Table of registered couples ============================"
404 << G4endl;
405 for(auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
406 {
407 G4MaterialCutsCouple* aCouple = (*cItr);
408 G4ProductionCuts* aCut = aCouple->GetProductionCuts();
409 G4cout << G4endl;
410 G4cout << "Index : " << aCouple->GetIndex()
411 << " used in the geometry : ";
412 if(aCouple->IsUsed()) G4cout << "Yes";
413 else G4cout << "No ";
417 G4cout << G4endl;
418 G4cout << " Material : " << aCouple->GetMaterial()->GetName() << G4endl;
419 G4cout << " Range cuts : "
420 << " gamma " << G4BestUnit(aCut->GetProductionCut("gamma"),"Length")
421 << " e- " << G4BestUnit(aCut->GetProductionCut("e-"),"Length")
422 << " e+ " << G4BestUnit(aCut->GetProductionCut("e+"),"Length")
423 << " proton " << G4BestUnit(aCut->GetProductionCut("proton"),"Length")
424 << G4endl;
425 G4cout << " Energy thresholds : " ;
429 G4cout << " gamma " << G4BestUnit((*(energyCutTable[0]))[aCouple->GetIndex()],"Energy")
430 << " e- " << G4BestUnit((*(energyCutTable[1]))[aCouple->GetIndex()],"Energy")
431 << " e+ " << G4BestUnit((*(energyCutTable[2]))[aCouple->GetIndex()],"Energy")
432 << " proton " << G4BestUnit((*(energyCutTable[3]))[aCouple->GetIndex()],"Energy");
434 G4cout << G4endl;
435
436 if(aCouple->IsUsed())
437 {
438 G4cout << " Region(s) which use this couple : " << G4endl;
439 for(auto rItr=fG4RegionStore->cbegin();
440 rItr!=fG4RegionStore->cend(); ++rItr)
441 {
442 if (IsCoupleUsedInTheRegion(aCouple, *rItr) )
443 {
444 G4cout << " " << (*rItr)->GetName() << G4endl;
445 }
446 }
447 }
448 }
449 G4cout << G4endl;
450 G4cout << "==================================================================" << G4endl;
451 G4cout << G4endl;
452}
453
454// --------------------------------------------------------------------
456 G4bool ascii)
457{
458 // Store cuts and material information in files under the specified directory
459
460 if (!StoreMaterialInfo(dir, ascii)) return false;
461 if (!StoreMaterialCutsCoupleInfo(dir, ascii)) return false;
462 if (!StoreCutsInfo(dir, ascii)) return false;
463
464#ifdef G4VERBOSE
465 if (verboseLevel >2)
466 {
467 G4cout << "G4ProductionCutsTable::StoreCutsTable()" << G4endl;
468 G4cout << " Material/Cuts information have been successfully stored ";
469 if (ascii)
470 {
471 G4cout << " in Ascii mode ";
472 }
473 else
474 {
475 G4cout << " in Binary mode ";
476 }
477 G4cout << " under " << dir << G4endl;
478 }
479#endif
480 return true;
481}
482
483// --------------------------------------------------------------------
485 G4bool ascii)
486{
487 if (!CheckForRetrieveCutsTable(dir, ascii)) return false;
488 if (!RetrieveCutsInfo(dir, ascii)) return false;
489#ifdef G4VERBOSE
490 if (verboseLevel >2)
491 {
492 G4cout << "G4ProductionCutsTable::RetrieveCutsTable()" << G4endl;
493 G4cout << " Material/Cuts information have been successfully retrieved ";
494 if (ascii)
495 {
496 G4cout << " in Ascii mode ";
497 }
498 else
499 {
500 G4cout << " in Binary mode ";
501 }
502 G4cout << " under " << dir << G4endl;
503 }
504#endif
505 return true;
506}
507
508// --------------------------------------------------------------------
509G4bool
511 G4bool ascii)
512{
513 // check stored material and cut values are consistent
514 // with the current detector setup
515
516 G4cerr << "G4ProductionCutsTable::CheckForRetrieveCutsTable()"<< G4endl;
517 // isNeedForRestoreCoupleInfo = false;
518 if (!CheckMaterialInfo(directory, ascii)) return false;
519 if (verboseLevel >2)
520 {
521 G4cerr << "G4ProductionCutsTable::CheckMaterialInfo passed !!"<< G4endl;
522 }
523 if (!CheckMaterialCutsCoupleInfo(directory, ascii)) return false;
524 if (verboseLevel >2)
525 {
526 G4cerr << "G4ProductionCutsTable::CheckMaterialCutsCoupleInfo passed !!"
527 << G4endl;
528 }
529 return true;
530}
531
532// --------------------------------------------------------------------
534 G4bool ascii)
535{
536 // Store material information in files under the specified directory
537
538 const G4String fileName = directory + "/" + "material.dat";
539 const G4String key = "MATERIAL-V3.0";
540 std::ofstream fOut;
541
542 // open output file
543 if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary);
544 else fOut.open(fileName,std::ios::out);
545
546 // check if the file has been opened successfully
547 if (!fOut)
548 {
549#ifdef G4VERBOSE
550 if (verboseLevel>0)
551 {
552 G4cerr << "G4ProductionCutsTable::StoreMaterialInfo() - ";
553 G4cerr << "Cannot open file: " << fileName << G4endl;
554 }
555#endif
556 G4Exception( "G4ProductionCutsTable::StoreMaterialInfo()",
557 "ProcCuts102", JustWarning, "Cannot open file!");
558 return false;
559 }
560
562 // number of materials in the table
563 G4int numberOfMaterial = matTable->size();
564
565 if (ascii)
566 {
568 // key word
569 fOut << key << G4endl;
570
571 // number of materials in the table
572 fOut << numberOfMaterial << G4endl;
573
574 fOut.setf(std::ios::scientific);
575
576 // material name and density
577 for (std::size_t idx=0; static_cast<G4int>(idx)<numberOfMaterial; ++idx)
578 {
579 fOut << std::setw(FixedStringLengthForStore)
580 << ((*matTable)[idx])->GetName();
581 fOut << std::setw(FixedStringLengthForStore)
582 << ((*matTable)[idx])->GetDensity()/(g/cm3) << G4endl;
583 }
584
585 fOut.unsetf(std::ios::scientific);
586
587 }
588 else
589 {
591 char temp[FixedStringLengthForStore];
592 std::size_t i;
593
594 // key word
595 for (i=0; i<FixedStringLengthForStore; ++i)
596 {
597 temp[i] = '\0';
598 }
599 for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i)
600 {
601 temp[i]=key[i];
602 }
603 fOut.write(temp, FixedStringLengthForStore);
604
605 // number of materials in the table
606 fOut.write( (char*)(&numberOfMaterial), sizeof(G4int));
607
608 // material name and density
609 for (std::size_t imat=0; static_cast<G4int>(imat)<numberOfMaterial; ++imat)
610 {
611 G4String name = ((*matTable)[imat])->GetName();
612 G4double density = ((*matTable)[imat])->GetDensity();
613 for (i=0; i<FixedStringLengthForStore; ++i)
614 temp[i] = '\0';
615 for (i=0; i<name.length() && i<FixedStringLengthForStore-1; ++i)
616 temp[i]=name[i];
617 fOut.write(temp, FixedStringLengthForStore);
618 fOut.write( (char*)(&density), sizeof(G4double));
619 }
620 }
621
622 fOut.close();
623 return true;
624}
625
626// --------------------------------------------------------------------
628 G4bool ascii)
629{
630 // Check stored material is consistent with the current detector setup
631
632 const G4String fileName = directory + "/" + "material.dat";
633 const G4String key = "MATERIAL-V3.0";
634 std::ifstream fIn;
635
636 // open input file
637 if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary);
638 else fIn.open(fileName,std::ios::in);
639
640 // check if the file has been opened successfully
641 if (!fIn)
642 {
643#ifdef G4VERBOSE
644 if (verboseLevel >0)
645 {
646 G4cerr << "G4ProductionCutsTable::CheckMaterialInfo() - ";
647 G4cerr << "Cannot open file: " << fileName << G4endl;
648 }
649#endif
650 G4Exception( "G4ProductionCutsTable::CheckMaterialInfo()",
651 "ProcCuts102", JustWarning, "Cannot open file!");
652 return false;
653 }
654
655 char temp[FixedStringLengthForStore];
656
657 // key word
658 G4String keyword;
659 if (ascii)
660 {
661 fIn >> keyword;
662 }
663 else
664 {
665 fIn.read(temp, FixedStringLengthForStore);
666 keyword = (const char*)(temp);
667 }
668 if (key!=keyword)
669 {
670#ifdef G4VERBOSE
671 if (verboseLevel >0)
672 {
673 G4cerr << "G4ProductionCutsTable::CheckMaterialInfo() - ";
674 G4cerr << "Key word in " << fileName << "= " << keyword ;
675 G4cerr <<"( should be "<< key << ")" <<G4endl;
676 }
677#endif
678 G4Exception( "G4ProductionCutsTable::CheckMaterialInfo()",
679 "ProcCuts103", JustWarning, "Bad Data Format");
680 return false;
681 }
682
683 // number of materials in the table
684 G4int nmat;
685 if (ascii)
686 {
687 fIn >> nmat;
688 }
689 else
690 {
691 fIn.read( (char*)(&nmat), sizeof(G4int));
692 }
693 if ((nmat<=0) || (nmat >100000))
694 {
695 G4Exception( "G4ProductionCutsTable::CheckMaterialInfo()",
696 "ProcCuts108", JustWarning,
697 "Number of materials is less than zero or too big");
698 return false;
699 }
700
701 // list of material
702 for (G4int idx=0; idx<nmat ; ++idx)
703 {
704 // check eof
705 if(fIn.eof())
706 {
707#ifdef G4VERBOSE
708 if (verboseLevel >0)
709 {
710 G4cout << "G4ProductionCutsTable::CheckMaterialInfo() - ";
711 G4cout << "Encountered End of File " ;
712 G4cout << " at " << idx+1 << "th material "<< G4endl;
713 }
714#endif
715 fIn.close();
716 return false;
717 }
718
719 // check material name and density
721 G4double density;
722 if (ascii)
723 {
724 fIn >> name >> density;
725 density *= (g/cm3);
726
727 }
728 else
729 {
731 fIn.read((char*)(&density), sizeof(G4double));
732 }
733 if (fIn.fail())
734 {
735#ifdef G4VERBOSE
736 if (verboseLevel >0)
737 {
738 G4cerr << "G4ProductionCutsTable::CheckMaterialInfo() - ";
739 G4cerr << "Bad data format ";
740 G4cerr << " at " << idx+1 << "th material "<< G4endl;
741 }
742#endif
743 G4Exception( "G4ProductionCutsTable::CheckMaterialInfo()",
744 "ProcCuts103", JustWarning, "Bad Data Format");
745 fIn.close();
746 return false;
747 }
748
750 if (aMaterial == nullptr ) continue;
751
752 G4double ratio = std::fabs(density/aMaterial->GetDensity() );
753 if ((0.999>ratio) || (ratio>1.001) )
754 {
755#ifdef G4VERBOSE
756 if (verboseLevel >0)
757 {
758 G4cerr << "G4ProductionCutsTable::CheckMaterialInfo() - ";
759 G4cerr << "Inconsistent material density" << G4endl;;
760 G4cerr << " at " << idx+1 << "th material "<< G4endl;
761 G4cerr << "Name: " << name << G4endl;
762 G4cerr << "Density:" << std::setiosflags(std::ios::scientific)
763 << density / (g/cm3) ;
764 G4cerr << "(should be " << aMaterial->GetDensity()/(g/cm3)<< ")"
765 << " [g/cm3]"<< G4endl;
766 G4cerr << std::resetiosflags(std::ios::scientific);
767 }
768#endif
769 G4Exception( "G4ProductionCutsTable::CheckMaterialInfo()",
770 "ProcCuts104", JustWarning, "Inconsistent material density");
771 fIn.close();
772 return false;
773 }
774 }
775
776 fIn.close();
777 return true;
778}
779
780// --------------------------------------------------------------------
781G4bool
783 G4bool ascii)
784{
785 // Store materialCutsCouple information in files under the specified directory
786
787 const G4String fileName = directory + "/" + "couple.dat";
788 const G4String key = "COUPLE-V3.0";
789 std::ofstream fOut;
790 char temp[FixedStringLengthForStore];
791
792 // open output file
793 if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary);
794 else fOut.open(fileName,std::ios::out);
795
796
797 // check if the file has been opened successfully
798 if (!fOut)
799 {
800#ifdef G4VERBOSE
801 if (verboseLevel >0)
802 {
803 G4cerr << "G4ProductionCutsTable::StoreMaterialCutsCoupleInfo() - ";
804 G4cerr << "Cannot open file: " << fileName << G4endl;
805 }
806#endif
807 G4Exception( "G4ProductionCutsTable::StoreMaterialCutsCoupleInfo()",
808 "ProcCuts102",
809 JustWarning, "Cannot open file!");
810 return false;
811 }
812 G4int numberOfCouples = coupleTable.size();
813 if (ascii)
814 {
816 // key word
817 fOut << std::setw(FixedStringLengthForStore) << key << G4endl;
818
819 // number of couples in the table
820 fOut << numberOfCouples << G4endl;
821 }
822 else
823 {
825 // key word
826 std::size_t i;
827 for (i=0; i<FixedStringLengthForStore; ++i)
828 temp[i] = '\0';
829 for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i)
830 temp[i]=key[i];
831 fOut.write(temp, FixedStringLengthForStore);
832
833 // number of couples in the table
834 fOut.write( (char*)(&numberOfCouples), sizeof(G4int));
835 }
836
837 // Loop over all couples
838 for (auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
839 {
840 G4MaterialCutsCouple* aCouple = (*cItr);
841 G4int index = aCouple->GetIndex();
842 // cut value
843 G4ProductionCuts* aCut = aCouple->GetProductionCuts();
844 G4double cutValues[NumberOfG4CutIndex];
845 for (std::size_t idx=0; idx <NumberOfG4CutIndex; ++idx)
846 {
847 cutValues[idx] = aCut->GetProductionCut(idx);
848 }
849 // material/region info
850 G4String materialName = aCouple->GetMaterial()->GetName();
851 G4String regionName = "NONE";
852 if (aCouple->IsUsed())
853 {
854 for(auto rItr=fG4RegionStore->cbegin();
855 rItr!=fG4RegionStore->cend(); ++rItr)
856 {
857 if (IsCoupleUsedInTheRegion(aCouple, *rItr))
858 {
859 regionName = (*rItr)->GetName();
860 break;
861 }
862 }
863 }
864
865 if (ascii)
866 {
868 // index number
869 fOut << index << G4endl;
870
871 // material name
872 fOut << std::setw(FixedStringLengthForStore) << materialName<< G4endl;
873
874 // region name
875 fOut << std::setw(FixedStringLengthForStore) << regionName<< G4endl;
876
877 fOut.setf(std::ios::scientific);
878 // cut values
879 for (std::size_t idx=0; idx< NumberOfG4CutIndex; ++idx)
880 {
881 fOut << std::setw(FixedStringLengthForStore) << cutValues[idx]/(mm)
882 << G4endl;
883 }
884 fOut.unsetf(std::ios::scientific);
885
886 }
887 else
888 {
890 // index
891 fOut.write( (char*)(&index), sizeof(G4int));
892
893 // material name
894 std::size_t i;
895 for (i=0; i<FixedStringLengthForStore; ++i)
896 temp[i] = '\0';
897 for (i=0; i<materialName.length() && i<FixedStringLengthForStore-1; ++i)
898 temp[i]=materialName[i];
899 fOut.write(temp, FixedStringLengthForStore);
900
901 // region name
902 for (i=0; i<FixedStringLengthForStore; ++i)
903 temp[i] = '\0';
904 for (i=0; i<regionName.length() && i<FixedStringLengthForStore-1; ++i)
905 temp[i]=regionName[i];
906 fOut.write(temp, FixedStringLengthForStore);
907
908 // cut values
909 for (std::size_t idx=0; idx< NumberOfG4CutIndex; ++idx)
910 {
911 fOut.write( (char*)(&(cutValues[idx])), sizeof(G4double));
912 }
913 }
914 }
915 fOut.close();
916 return true;
917}
918
919// --------------------------------------------------------------------
920G4bool
922 G4bool ascii)
923{
924 // Check stored materialCutsCouple is consistent
925 // with the current detector setup.
926
927 const G4String fileName = directory + "/" + "couple.dat";
928 const G4String key = "COUPLE-V3.0";
929 std::ifstream fIn;
930
931 // open input file
932 if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary);
933 else fIn.open(fileName,std::ios::in);
934
935 // check if the file has been opened successfully
936 if (!fIn)
937 {
938#ifdef G4VERBOSE
939 if (verboseLevel >0)
940 {
941 G4cerr << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
942 G4cerr << "Cannot open file!" << fileName << G4endl;
943 }
944#endif
945 G4Exception( "G4ProductionCutsTable::CheckMaterialCutsCoupleInfo()",
946 "ProcCuts102", JustWarning, "Cannot open file!");
947 return false;
948 }
949
950 char temp[FixedStringLengthForStore];
951
952 // key word
953 G4String keyword;
954 if (ascii)
955 {
956 fIn >> keyword;
957 }
958 else
959 {
960 fIn.read(temp, FixedStringLengthForStore);
961 keyword = (const char*)(temp);
962 }
963 if (key!=keyword)
964 {
965#ifdef G4VERBOSE
966 if (verboseLevel >0)
967 {
968 G4cerr << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
969 G4cerr << "Key word in " << fileName << "= " << keyword ;
970 G4cerr <<"( should be "<< key << ")" << G4endl;
971 }
972#endif
973 G4Exception( "G4ProductionCutsTable::CheckMaterialCutsCoupleInfo()",
974 "ProcCuts103", JustWarning, "Bad Data Format");
975 fIn.close();
976 return false;
977 }
978
979 // numberOfCouples
980 G4int numberOfCouples;
981 if (ascii)
982 {
983 fIn >> numberOfCouples;
984 }
985 else
986 {
987 fIn.read( (char*)(&numberOfCouples), sizeof(G4int));
988 }
989
990 // Reset MCCIndexConversionTable
991 mccConversionTable.Reset(numberOfCouples);
992
993 // Read in couple information
994 for (G4int idx=0; idx<numberOfCouples; ++idx)
995 {
996 // read in index
997 G4int index;
998 if (ascii)
999 {
1000 fIn >> index;
1001 }
1002 else
1003 {
1004 fIn.read( (char*)(&index), sizeof(G4int));
1005 }
1006 // read in index material name
1007 char mat_name[FixedStringLengthForStore];
1008 if (ascii)
1009 {
1010 fIn >> mat_name;
1011 }
1012 else
1013 {
1014 fIn.read(mat_name, FixedStringLengthForStore);
1015 }
1016 // read in index and region name
1017 char region_name[FixedStringLengthForStore];
1018 if (ascii)
1019 {
1020 fIn >> region_name;
1021 }
1022 else
1023 {
1024 fIn.read(region_name, FixedStringLengthForStore);
1025 }
1026 // cut value
1027 G4double cutValues[NumberOfG4CutIndex];
1028 for (std::size_t i=0; i< NumberOfG4CutIndex; ++i)
1029 {
1030 if (ascii)
1031 {
1032 fIn >> cutValues[i];
1033 cutValues[i] *= (mm);
1034 }
1035 else
1036 {
1037 fIn.read( (char*)(&(cutValues[i])), sizeof(G4double));
1038 }
1039 }
1040
1041 // Loop over all couples
1042 G4bool fOK = false;
1043 G4MaterialCutsCouple* aCouple = nullptr;
1044 for (auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
1045 {
1046 aCouple = (*cItr);
1047 // check material name
1048 if ( mat_name != aCouple->GetMaterial()->GetName() ) continue;
1049 // check cut values
1050 G4ProductionCuts* aCut = aCouple->GetProductionCuts();
1051 G4bool fRatio = true;
1052 for (std::size_t j=0; j< NumberOfG4CutIndex; ++j)
1053 {
1054 // check ratio only if values are not the same
1055 if (cutValues[j] != aCut->GetProductionCut(j))
1056 {
1057 G4double ratio = cutValues[j]/aCut->GetProductionCut(j);
1058 fRatio = fRatio && (0.999<ratio) && (ratio<1.001) ;
1059 }
1060 }
1061 if (!fRatio) continue;
1062 // MCC matched
1063 fOK = true;
1064 mccConversionTable.SetNewIndex(index, aCouple->GetIndex());
1065 break;
1066 }
1067
1068 if (fOK)
1069 {
1070#ifdef G4VERBOSE
1071 // debug information
1072 if (verboseLevel >1)
1073 {
1074 G4String regionname(region_name);
1075 G4Region* fRegion = nullptr;
1076 if ( regionname != "NONE" )
1077 {
1078 fRegion = fG4RegionStore->GetRegion(region_name);
1079 if (fRegion == nullptr)
1080 {
1081 G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1082 G4cout << "Region " << regionname << " is not found ";
1083 G4cout << index << ": in " << fileName << G4endl;
1084 }
1085 }
1086 if (((regionname == "NONE") && (aCouple->IsUsed()))
1087 || ((fRegion!=nullptr) && !IsCoupleUsedInTheRegion(aCouple, fRegion)))
1088 {
1089 G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo()"
1090 << G4endl;
1091 G4cout << "A Couple is used different region in the current setup ";
1092 G4cout << index << ": in " << fileName << G4endl;
1093 G4cout << " material: " << mat_name ;
1094 G4cout << " region: " << region_name << G4endl;
1095 for (std::size_t ii=0; ii< NumberOfG4CutIndex; ++ii)
1096 {
1097 G4cout << "cut[" << ii << "]=" << cutValues[ii]/mm;
1098 G4cout << " mm : ";
1099 }
1100 G4cout << G4endl;
1101 }
1102 else if ( index != aCouple->GetIndex() )
1103 {
1104 G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1105 G4cout << "Index of couples was modified "<< G4endl;
1106 G4cout << aCouple->GetIndex() << ":"
1107 << aCouple->GetMaterial()->GetName();
1108 G4cout <<" is defined as " ;
1109 G4cout << index << ":" << mat_name << " in " << fileName << G4endl;
1110 }
1111 else
1112 {
1113 G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1114 G4cout << index << ":" << mat_name << " in " << fileName ;
1115 G4cout << " is consistent with current setup" << G4endl;
1116 }
1117 }
1118#endif
1119 }
1120 else
1121 {
1122#ifdef G4VERBOSE
1123 if (verboseLevel >0)
1124 {
1125 G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo()"
1126 << G4endl;
1127 G4cout << "Couples are not defined in the current detector setup ";
1128 G4cout << index << ": in " << fileName << G4endl;
1129 G4cout << " material: " << mat_name ;
1130 G4cout << " region: " << region_name << G4endl;
1131 for (std::size_t ii=0; ii< NumberOfG4CutIndex; ++ii)
1132 {
1133 G4cout << "cut[" << ii << "]=" << cutValues[ii]/mm;
1134 G4cout << " mm : ";
1135 }
1136 G4cout << G4endl;
1137 }
1138#endif
1139 }
1140 }
1141 fIn.close();
1142 return true;
1143}
1144
1145// --------------------------------------------------------------------
1147 G4bool ascii)
1148{
1149 // Store cut values information in files under the specified directory
1150
1151 const G4String fileName = directory + "/" + "cut.dat";
1152 const G4String key = "CUT-V3.0";
1153 std::ofstream fOut;
1154 char temp[FixedStringLengthForStore];
1155
1156 // open output file
1157 if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary);
1158 else fOut.open(fileName,std::ios::out);
1159
1160 // check if the file has been opened successfully
1161 if (!fOut)
1162 {
1163 if(verboseLevel>0)
1164 {
1165 G4cerr << "G4ProductionCutsTable::StoreCutsInfo() - ";
1166 G4cerr << "Cannot open file: " << fileName << G4endl;
1167 }
1168 G4Exception( "G4ProductionCutsTable::StoreCutsInfo()",
1169 "ProcCuts102", JustWarning, "Cannot open file!");
1170 return false;
1171 }
1172
1173 G4int numberOfCouples = coupleTable.size();
1174 if (ascii)
1175 {
1177 // key word
1178 fOut << key << G4endl;
1179
1180 // number of couples in the table
1181 fOut << numberOfCouples << G4endl;
1182 }
1183 else
1184 {
1186 // key word
1187 std::size_t i;
1188 for (i=0; i<FixedStringLengthForStore; ++i)
1189 temp[i] = '\0';
1190 for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i)
1191 temp[i]=key[i];
1192 fOut.write(temp, FixedStringLengthForStore);
1193
1194 // number of couples in the table
1195 fOut.write( (char*)(&numberOfCouples), sizeof(G4int));
1196 }
1197
1198 for (std::size_t idx=0; idx <NumberOfG4CutIndex; ++idx)
1199 {
1200 const std::vector<G4double>* fRange = GetRangeCutsVector(idx);
1201 const std::vector<G4double>* fEnergy = GetEnergyCutsVector(idx);
1202 std::size_t i=0;
1203 // Loop over all couples
1204 for (auto cItr=coupleTable.cbegin();cItr!=coupleTable.cend(); ++cItr, ++i)
1205 {
1206 if (ascii)
1207 {
1209 fOut.setf(std::ios::scientific);
1210 fOut << std::setw(20) << (*fRange)[i]/mm ;
1211 fOut << std::setw(20) << (*fEnergy)[i]/keV << G4endl;
1212 fOut.unsetf(std::ios::scientific);
1213 }
1214 else
1215 {
1217 G4double cut = (*fRange)[i];
1218 fOut.write((char*)(&cut), sizeof(G4double));
1219 cut = (*fEnergy)[i];
1220 fOut.write((char*)(&cut), sizeof(G4double));
1221 }
1222 }
1223 }
1224 fOut.close();
1225 return true;
1226}
1227
1228// --------------------------------------------------------------------
1230 G4bool ascii)
1231{
1232 // Retrieve cut values information in files under the specified directory
1233
1234 const G4String fileName = directory + "/" + "cut.dat";
1235 const G4String key = "CUT-V3.0";
1236 std::ifstream fIn;
1237
1238 // open input file
1239 if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary);
1240 else fIn.open(fileName,std::ios::in);
1241
1242 // check if the file has been opened successfully
1243 if (!fIn)
1244 {
1245 if (verboseLevel >0)
1246 {
1247 G4cerr << "G4ProductionCutTable::RetrieveCutsInfo() - ";
1248 G4cerr << "Cannot open file: " << fileName << G4endl;
1249 }
1250 G4Exception( "G4ProductionCutsTable::RetrieveCutsInfo()",
1251 "ProcCuts102", JustWarning, "Cannot open file!");
1252 return false;
1253 }
1254
1255 char temp[FixedStringLengthForStore];
1256
1257 // key word
1258 G4String keyword;
1259 if (ascii)
1260 {
1261 fIn >> keyword;
1262 }
1263 else
1264 {
1265 fIn.read(temp, FixedStringLengthForStore);
1266 keyword = (const char*)(temp);
1267 }
1268 if (key!=keyword)
1269 {
1270 if (verboseLevel >0)
1271 {
1272 G4cerr << "G4ProductionCutTable::RetrieveCutsInfo() - ";
1273 G4cerr << "Key word in " << fileName << "= " << keyword ;
1274 G4cerr <<"( should be "<< key << ")" << G4endl;
1275 }
1276 G4Exception( "G4ProductionCutsTable::RetrieveCutsInfo()",
1277 "ProcCuts103", JustWarning, "Bad Data Format");
1278 return false;
1279 }
1280
1281 // numberOfCouples
1282 G4int numberOfCouples;
1283 if (ascii)
1284 {
1285 fIn >> numberOfCouples;
1286 if (fIn.fail())
1287 {
1288 G4Exception( "G4ProductionCutsTable::RetrieveCutsInfo()",
1289 "ProcCuts103", JustWarning, "Bad Data Format");
1290 return false;
1291 }
1292 }
1293 else
1294 {
1295 fIn.read( (char*)(&numberOfCouples), sizeof(G4int));
1296 }
1297
1298 if (numberOfCouples > static_cast<G4int>(mccConversionTable.size()) )
1299 {
1300 G4Exception( "G4ProductionCutsTable::RetrieveCutsInfo()",
1301 "ProcCuts109", JustWarning,
1302 "Number of Couples in the file exceeds defined couples");
1303 }
1304 numberOfCouples = mccConversionTable.size();
1305
1306 for (std::size_t idx=0; static_cast<G4int>(idx) <NumberOfG4CutIndex; ++idx)
1307 {
1308 std::vector<G4double>* fRange = rangeCutTable[idx];
1309 std::vector<G4double>* fEnergy = energyCutTable[idx];
1310 fRange->clear();
1311 fEnergy->clear();
1312
1313 // Loop over all couples
1314 for (std::size_t i=0; static_cast<G4int>(i)< numberOfCouples; ++i)
1315 {
1316 G4double rcut, ecut;
1317 if (ascii)
1318 {
1319 fIn >> rcut >> ecut;
1320 if (fIn.fail())
1321 {
1322 G4Exception( "G4ProductionCutsTable::RetrieveCutsInfo()",
1323 "ProcCuts103", JustWarning, "Bad Data Format");
1324 return false;
1325 }
1326 rcut *= mm;
1327 ecut *= keV;
1328 }
1329 else
1330 {
1331 fIn.read((char*)(&rcut), sizeof(G4double));
1332 fIn.read((char*)(&ecut), sizeof(G4double));
1333 }
1334 if (!mccConversionTable.IsUsed(i)) continue;
1335 std::size_t new_index = mccConversionTable.GetIndex(i);
1336 (*fRange)[new_index] = rcut;
1337 (*fEnergy)[new_index] = ecut;
1338 }
1339 }
1340 return true;
1341}
1342
1343// --------------------------------------------------------------------
1345{
1346 // Set same verbosity to all registered RangeToEnergyConverters
1347
1348 verboseLevel = value;
1349 for (G4int ip=0; ip< NumberOfG4CutIndex; ++ip)
1350 {
1351 if (converters[ip] != nullptr )
1352 {
1353 converters[ip]->SetVerboseLevel(value);
1354 }
1355 }
1356}
1357
1358// --------------------------------------------------------------------
1360{
1362}
1363
1364// --------------------------------------------------------------------
1366{
1368}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
std::vector< G4Material * > G4MaterialTable
@ NumberOfG4CutIndex
static constexpr double cm3
Definition: G4SIunits.hh:101
static constexpr double mm
Definition: G4SIunits.hh:95
static constexpr double keV
Definition: G4SIunits.hh:202
static constexpr double g
Definition: G4SIunits.hh:168
#define G4BestUnit(a, b)
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
size_t GetNoDaughters() const
G4Region * GetRegion() const
G4Material * GetMaterial() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
void SetMaterialCutsCouple(G4MaterialCutsCouple *cuts)
void SetNewIndex(std::size_t index, std::size_t new_value)
G4bool IsUsed(std::size_t index) const
G4int GetIndex(std::size_t index) const
const G4Material * GetMaterial() const
void SetUseFlag(G4bool flg=true)
G4ProductionCuts * GetProductionCuts() const
G4double GetDensity() const
Definition: G4Material.hh:176
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:672
const G4String & GetName() const
Definition: G4Material.hh:173
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:686
const G4String & GetParticleName() const
static G4ParticleTable * GetParticleTable()
const std::vector< G4double > * GetRangeCutsVector(std::size_t pcIdx) const
virtual G4bool RetrieveCutsInfo(const G4String &directory, G4bool ascii=false)
std::vector< G4MaterialCutsCouple * > coupleTable
G4bool RetrieveCutsTable(const G4String &directory, G4bool ascii=false)
virtual G4bool StoreCutsInfo(const G4String &directory, G4bool ascii=false)
std::vector< std::vector< G4double > * > rangeCutTable
G4double GetLowEdgeEnergy() const
void SetMaxEnergyCut(G4double value)
void UpdateCoupleTable(G4VPhysicalVolume *currentWorld)
G4MCCIndexConversionTable mccConversionTable
void SetVerboseLevel(G4int value)
G4double * energyDoubleVector[NumberOfG4CutIndex]
G4VRangeToEnergyConverter * converters[NumberOfG4CutIndex]
virtual G4bool CheckMaterialInfo(const G4String &directory, G4bool ascii=false)
virtual G4bool StoreMaterialInfo(const G4String &directory, G4bool ascii=false)
G4double GetHighEdgeEnergy() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * fProductionCutsTable
G4bool StoreCutsTable(const G4String &directory, G4bool ascii=false)
G4double * rangeDoubleVector[NumberOfG4CutIndex]
G4bool CheckForRetrieveCutsTable(const G4String &directory, G4bool ascii=false)
void ScanAndSetCouple(G4LogicalVolume *aLV, G4MaterialCutsCouple *aCouple, G4Region *aRegion)
void SetEnergyRange(G4double lowedge, G4double highedge)
static G4ProductionCutsTable * GetProductionCutsTable()
virtual G4bool CheckMaterialCutsCoupleInfo(const G4String &directory, G4bool ascii=false)
G4bool IsCoupleUsedInTheRegion(const G4MaterialCutsCouple *aCouple, const G4Region *aRegion) const
G4ProductionCuts * defaultProductionCuts
G4double ConvertRangeToEnergy(const G4ParticleDefinition *particle, const G4Material *material, G4double range)
virtual G4bool StoreMaterialCutsCoupleInfo(const G4String &directory, G4bool ascii=false)
G4ProductionCutsTableMessenger * fMessenger
std::vector< std::vector< G4double > * > energyCutTable
static G4int GetIndex(const G4String &name)
G4double GetProductionCut(G4int index) const
const std::vector< G4double > & GetProductionCuts() const
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
void Stop()
void Start()
G4LogicalVolume * GetLogicalVolume() const
static void SetMaxEnergyCut(const G4double value)
virtual G4double Convert(const G4double rangeCut, const G4Material *material)
static void SetEnergyRange(const G4double lowedge, const G4double highedge)
const char * name(G4int ptype)
string material
Definition: eplot.py:19