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