// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4ProductionCutsTable.cc,v 1.27 2010/01/22 11:10:26 kurasige Exp $ // GEANT4 tag $Name: geant4-09-04-beta-cand-01 $ // // // -------------------------------------------------------------- // GEANT 4 class implementation file/ History: // 06/Oct. 2002, M.Asai : First implementation // 02/Mar. 2008, H.Kurashige : Add messenger // -------------------------------------------------------------- #include "G4ProductionCutsTable.hh" #include "G4ProductionCuts.hh" #include "G4MCCIndexConversionTable.hh" #include "G4ProductionCutsTableMessenger.hh" #include "G4ParticleDefinition.hh" #include "G4ParticleTable.hh" #include "G4RegionStore.hh" #include "G4LogicalVolume.hh" #include "G4VPhysicalVolume.hh" #include "G4RToEConvForElectron.hh" #include "G4RToEConvForGamma.hh" #include "G4RToEConvForPositron.hh" #include "G4RToEConvForProton.hh" #include "G4MaterialTable.hh" #include "G4Material.hh" #include "G4UnitsTable.hh" #include "G4Timer.hh" #include "G4ios.hh" #include #include G4ProductionCutsTable* G4ProductionCutsTable::fG4ProductionCutsTable = 0; ///////////////////////////////////////////////////////////// G4ProductionCutsTable* G4ProductionCutsTable::GetProductionCutsTable() { static G4ProductionCutsTable theProductionCutsTable; if(!fG4ProductionCutsTable){ fG4ProductionCutsTable = &theProductionCutsTable; } return fG4ProductionCutsTable; } ///////////////////////////////////////////////////////////// G4ProductionCutsTable::G4ProductionCutsTable() : firstUse(true),verboseLevel(1),fMessenger(0) { for(size_t i=0;i< NumberOfG4CutIndex;i++) { rangeCutTable.push_back(new G4CutVectorForAParticle); energyCutTable.push_back(new G4CutVectorForAParticle); rangeDoubleVector[i] = 0; energyDoubleVector[i] = 0; converters[i] = 0; } fG4RegionStore = G4RegionStore::GetInstance(); defaultProductionCuts = new G4ProductionCuts(); // add messenger for UI fMessenger = new G4ProductionCutsTableMessenger(this); } ///////////////////////////////////////////////////////////// G4ProductionCutsTable::G4ProductionCutsTable(const G4ProductionCutsTable& ) {;} ///////////////////////////////////////////////////////////// G4ProductionCutsTable::~G4ProductionCutsTable() { if (defaultProductionCuts !=0) { delete defaultProductionCuts; defaultProductionCuts =0; } for(CoupleTableIterator itr=coupleTable.begin();itr!=coupleTable.end();itr++){ delete (*itr); } coupleTable.clear(); for(size_t i=0;i< NumberOfG4CutIndex;i++){ delete rangeCutTable[i]; delete energyCutTable[i]; delete converters[i]; if(rangeDoubleVector[i]!=0) delete [] rangeDoubleVector[i]; if(energyDoubleVector[i]!=0) delete [] energyDoubleVector[i]; } fG4ProductionCutsTable =0; if (fMessenger !=0) delete fMessenger; fMessenger = 0; } void G4ProductionCutsTable::UpdateCoupleTable(G4VPhysicalVolume* currentWorld) { if(firstUse){ if(G4ParticleTable::GetParticleTable()->FindParticle("gamma")){ converters[0] = new G4RToEConvForGamma(); converters[0]->SetVerboseLevel(GetVerboseLevel()); } if(G4ParticleTable::GetParticleTable()->FindParticle("e-")){ converters[1] = new G4RToEConvForElectron(); converters[1]->SetVerboseLevel(GetVerboseLevel()); } if(G4ParticleTable::GetParticleTable()->FindParticle("e+")){ converters[2] = new G4RToEConvForPositron(); converters[2]->SetVerboseLevel(GetVerboseLevel()); } if(G4ParticleTable::GetParticleTable()->FindParticle("proton")){ converters[3] = new G4RToEConvForProton(); converters[3]->SetVerboseLevel(GetVerboseLevel()); } firstUse = false; } // Reset "used" flags of all couples for(CoupleTableIterator CoupleItr=coupleTable.begin(); CoupleItr!=coupleTable.end();CoupleItr++) { (*CoupleItr)->SetUseFlag(false); } // Update Material-Cut-Couple typedef std::vector::iterator regionIterator; for(regionIterator rItr=fG4RegionStore->begin(); rItr!=fG4RegionStore->end();rItr++) { // Material scan is to be done only for the regions appear in the // current tracking world. if((*rItr)->GetWorldPhysical()!=currentWorld) continue; G4ProductionCuts* fProductionCut = (*rItr)->GetProductionCuts(); std::vector::const_iterator mItr = (*rItr)->GetMaterialIterator(); size_t nMaterial = (*rItr)->GetNumberOfMaterials(); (*rItr)->ClearMap(); for(size_t iMate=0;iMateGetMaterial()==(*mItr) && (*cItr)->GetProductionCuts()==fProductionCut){ coupleAlreadyDefined = true; aCouple = *cItr; break; } } // If this combination is new, cleate and register a couple if(!coupleAlreadyDefined){ aCouple = new G4MaterialCutsCouple((*mItr),fProductionCut); coupleTable.push_back(aCouple); aCouple->SetIndex(coupleTable.size()-1); } // Register this couple to the region (*rItr)->RegisterMaterialCouplePair((*mItr),aCouple); // Set the couple to the proper logical volumes in that region aCouple->SetUseFlag(); std::vector::iterator rootLVItr = (*rItr)->GetRootLogicalVolumeIterator(); size_t nRootLV = (*rItr)->GetNumberOfRootVolumes(); for(size_t iLV=0;iLVsize(); G4bool newCoupleAppears = nCouple>nTable; if(newCoupleAppears) { for(size_t n=nCouple-nTable;n>0;n--) { for(size_t nn=0;nn< NumberOfG4CutIndex;nn++){ rangeCutTable[nn]->push_back(-1.); energyCutTable[nn]->push_back(-1.); } } } // Update RangeEnergy cuts tables size_t idx = 0; G4Timer timer; if (verboseLevel>2) { timer.Start(); } for(CoupleTableIterator cItr=coupleTable.begin(); cItr!=coupleTable.end();cItr++){ G4ProductionCuts* aCut = (*cItr)->GetProductionCuts(); const G4Material* aMat = (*cItr)->GetMaterial(); if((*cItr)->IsRecalcNeeded()) { for(size_t ptcl=0;ptcl< NumberOfG4CutIndex;ptcl++){ G4double rCut = aCut->GetProductionCut(ptcl); (*(rangeCutTable[ptcl]))[idx] = rCut; // if(converters[ptcl] && (*cItr)->IsUsed()) if(converters[ptcl]) { (*(energyCutTable[ptcl]))[idx] = converters[ptcl]->Convert(rCut,aMat); } else { (*(energyCutTable[ptcl]))[idx] = -1.; } } } idx++; } if (verboseLevel>2) { timer.Stop(); G4cout << "G4ProductionCutsTable::UpdateCoupleTable " << " elapsed time for calculation of energy cuts " << G4endl; G4cout << timer <1) { G4cout << "G4ProductionCutsTable::ConvertRangeToEnergy" ; G4cout << particle->GetParticleName() << " has no cut value " << G4endl; } #endif return -1.0; } return converters[index]->Convert(range, material); } ///////////////////////////////////////////////////////////// void G4ProductionCutsTable::ResetConverters() { for(size_t i=0;i< NumberOfG4CutIndex;i++){ if (converters[i]!=0) converters[i]->Reset(); } } ///////////////////////////////////////////////////////////// void G4ProductionCutsTable::SetEnergyRange(G4double lowedge, G4double highedge) { G4VRangeToEnergyConverter::SetEnergyRange(lowedge,highedge); } ///////////////////////////////////////////////////////////// G4double G4ProductionCutsTable::GetLowEdgeEnergy() const { return G4VRangeToEnergyConverter::GetLowEdgeEnergy(); } ///////////////////////////////////////////////////////////// G4double G4ProductionCutsTable::GetHighEdgeEnergy() const { return G4VRangeToEnergyConverter::GetHighEdgeEnergy(); } ///////////////////////////////////////////////////////////// void G4ProductionCutsTable::ScanAndSetCouple(G4LogicalVolume* aLV, G4MaterialCutsCouple* aCouple, G4Region* aRegion) { //Check whether or not this logical volume belongs to the same region if((aRegion!=0) && aLV->GetRegion()!=aRegion) return; //Check if this particular volume has a material matched to the couple if(aLV->GetMaterial()==aCouple->GetMaterial()) { aLV->SetMaterialCutsCouple(aCouple); } size_t noDaughters = aLV->GetNoDaughters(); if(noDaughters==0) return; //Loop over daughters with same region for(size_t i=0;iGetDaughter(i)->GetLogicalVolume(); ScanAndSetCouple(daughterLVol,aCouple,aRegion); } } ///////////////////////////////////////////////////////////// void G4ProductionCutsTable::DumpCouples() const { G4cout << G4endl; G4cout << "========= Table of registered couples ==============================" << G4endl; for(CoupleTableIterator cItr=coupleTable.begin(); cItr!=coupleTable.end();cItr++) { G4MaterialCutsCouple* aCouple = (*cItr); G4ProductionCuts* aCut = aCouple->GetProductionCuts(); G4cout << G4endl; G4cout << "Index : " << aCouple->GetIndex() << " used in the geometry : "; if(aCouple->IsUsed()) G4cout << "Yes"; else G4cout << "No "; G4cout << " recalculation needed : "; if(aCouple->IsRecalcNeeded()) G4cout << "Yes"; else G4cout << "No "; G4cout << G4endl; G4cout << " Material : " << aCouple->GetMaterial()->GetName() << G4endl; G4cout << " Range cuts : " << " gamma " << G4BestUnit(aCut->GetProductionCut("gamma"),"Length") << " e- " << G4BestUnit(aCut->GetProductionCut("e-"),"Length") << " e+ " << G4BestUnit(aCut->GetProductionCut("e+"),"Length") << " proton " << G4BestUnit(aCut->GetProductionCut("proton"),"Length") << G4endl; G4cout << " Energy thresholds : " ; if(aCouple->IsRecalcNeeded()) { G4cout << " is not ready to print"; } else { G4cout << " gamma " << G4BestUnit((*(energyCutTable[0]))[aCouple->GetIndex()],"Energy") << " e- " << G4BestUnit((*(energyCutTable[1]))[aCouple->GetIndex()],"Energy") << " e+ " << G4BestUnit((*(energyCutTable[2]))[aCouple->GetIndex()],"Energy") << " proton " << G4BestUnit((*(energyCutTable[3]))[aCouple->GetIndex()],"Energy"); } G4cout << G4endl; if(aCouple->IsUsed()) { G4cout << " Region(s) which use this couple : " << G4endl; typedef std::vector::iterator regionIterator; for(regionIterator rItr=fG4RegionStore->begin(); rItr!=fG4RegionStore->end();rItr++) { if (IsCoupleUsedInTheRegion(aCouple, *rItr) ){ G4cout << " " << (*rItr)->GetName() << G4endl; } } } } G4cout << G4endl; G4cout << "====================================================================" << G4endl; G4cout << G4endl; } ///////////////////////////////////////////////////////////// // Store cuts and material information in files under the specified directory. G4bool G4ProductionCutsTable::StoreCutsTable(const G4String& dir, G4bool ascii) { if (!StoreMaterialInfo(dir, ascii)) return false; if (!StoreMaterialCutsCoupleInfo(dir, ascii)) return false; if (!StoreCutsInfo(dir, ascii)) return false; #ifdef G4VERBOSE if (verboseLevel >2) { G4cout << "G4ProductionCutsTable::StoreCutsTable " ; G4cout << " Material/Cuts information have been succesfully stored "; if (ascii) { G4cout << " in Ascii mode "; }else{ G4cout << " in Binary mode "; } G4cout << " under " << dir << G4endl; } #endif return true; } ///////////////////////////////////////////////////////////// G4bool G4ProductionCutsTable::RetrieveCutsTable(const G4String& dir, G4bool ascii) { if (!CheckForRetrieveCutsTable(dir, ascii)) return false; if (!RetrieveCutsInfo(dir, ascii)) return false; #ifdef G4VERBOSE if (verboseLevel >2) { G4cout << "G4ProductionCutsTable::RetrieveCutsTable " ; G4cout << " Material/Cuts information have been succesfully retreived "; if (ascii) { G4cout << " in Ascii mode "; }else{ G4cout << " in Binary mode "; } G4cout << " under " << dir << G4endl; } #endif return true; } ///////////////////////////////////////////////////////////// // check stored material and cut values are consistent // with the current detector setup. // G4bool G4ProductionCutsTable::CheckForRetrieveCutsTable(const G4String& directory, G4bool ascii) { G4cerr << "G4ProductionCutsTable::CheckForRetrieveCutsTable!!"<< G4endl; // isNeedForRestoreCoupleInfo = false; if (!CheckMaterialInfo(directory, ascii)) return false; if (verboseLevel >2) { G4cerr << "G4ProductionCutsTable::CheckMaterialInfo passed !!"<< G4endl; } if (!CheckMaterialCutsCoupleInfo(directory, ascii)) return false; if (verboseLevel >2) { G4cerr << "G4ProductionCutsTable::CheckMaterialCutsCoupleInfo passed !!"<< G4endl; } return true; } ///////////////////////////////////////////////////////////// // Store material information in files under the specified directory. // G4bool G4ProductionCutsTable::StoreMaterialInfo(const G4String& directory, G4bool ascii) { const G4String fileName = directory + "/" + "material.dat"; const G4String key = "MATERIAL-V3.0"; std::ofstream fOut; // open output file // if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary); else fOut.open(fileName,std::ios::out); // check if the file has been opened successfully if (!fOut) { #ifdef G4VERBOSE if (verboseLevel>0) { G4cerr << "G4ProductionCutsTable::StoreMaterialInfo "; G4cerr << " Can not open file " << fileName << G4endl; } #endif return false; } const G4MaterialTable* matTable = G4Material::GetMaterialTable(); // number of materials in the table G4int numberOfMaterial = matTable->size(); if (ascii) { /////////////// ASCII mode ///////////////// // key word fOut << key << G4endl; // number of materials in the table fOut << numberOfMaterial << G4endl; fOut.setf(std::ios::scientific); // material name and density for (size_t idx=0; G4int(idx)GetName(); fOut << std::setw(FixedStringLengthForStore) << ((*matTable)[idx])->GetDensity()/(g/cm3) << G4endl; } fOut.unsetf(std::ios::scientific); } else { /////////////// Binary mode ///////////////// char temp[FixedStringLengthForStore]; size_t i; // key word for (i=0; iGetName(); G4double density = ((*matTable)[imat])->GetDensity(); for (i=0; i0) { G4cerr << "G4ProductionCutsTable::CheckMaterialInfo "; G4cerr << " Can not open file " << fileName << G4endl; } #endif return false; } char temp[FixedStringLengthForStore]; // key word G4String keyword; if (ascii) { fIn >> keyword; } else { fIn.read(temp, FixedStringLengthForStore); keyword = (const char*)(temp); } if (key!=keyword) { #ifdef G4VERBOSE if (verboseLevel >0) { G4cout << "G4ProductionCutsTable::CheckMaterialInfo "; G4cout << " Key word in " << fileName << "= " << keyword ; G4cout <<"( should be "<< key << ")" <> nmat; } else { fIn.read( (char*)(&nmat), sizeof (G4int)); } // list of material for (G4int idx=0; idx0) { G4cout << "G4ProductionCutsTable::CheckMaterialInfo "; G4cout << " encountered End of File " ; G4cout << " at " << idx+1 << "th material "<< G4endl; } #endif fIn.close(); return false; } // check material name and density char name[FixedStringLengthForStore]; double density; if (ascii) { fIn >> name >> density; density *= (g/cm3); } else { fIn.read(name, FixedStringLengthForStore); fIn.read((char*)(&density), sizeof (G4double)); } if (fIn.fail()) { #ifdef G4VERBOSE if (verboseLevel >0) { G4cout << "G4ProductionCutsTable::CheckMaterialInfo "; G4cout << " Bad data format "; G4cout << " at " << idx+1 << "th material "<< G4endl; } #endif fIn.close(); return false; } G4Material* aMaterial = G4Material::GetMaterial(name); if (aMaterial ==0 ) continue; G4double ratio = std::fabs(density/aMaterial->GetDensity() ); if ((0.999>ratio) || (ratio>1.001) ){ #ifdef G4VERBOSE if (verboseLevel >0) { G4cout << "G4ProductionCutsTable::CheckMaterialInfo "; G4cout << " Inconsistent material density" << G4endl;; G4cout << " at " << idx+1 << "th material "<< G4endl; G4cout << "Name: " << name << G4endl; G4cout << "Density:" << std::setiosflags(std::ios::scientific) << density / (g/cm3) ; G4cout << "(should be " << aMaterial->GetDensity()/(g/cm3)<< ")" << " [g/cm3]"<< G4endl; G4cout << std::resetiosflags(std::ios::scientific); } #endif fIn.close(); return false; } } fIn.close(); return true; } ///////////////////////////////////////////////////////////// // Store materialCutsCouple information in files under the specified directory. // G4bool G4ProductionCutsTable::StoreMaterialCutsCoupleInfo(const G4String& directory, G4bool ascii) { const G4String fileName = directory + "/" + "couple.dat"; const G4String key = "COUPLE-V3.0"; std::ofstream fOut; char temp[FixedStringLengthForStore]; // open output file // if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary); else fOut.open(fileName,std::ios::out); // check if the file has been opened successfully if (!fOut) { #ifdef G4VERBOSE if (verboseLevel >0) { G4cerr << "G4ProductionCutsTable::StoreMaterialCutsCoupleInfo "; G4cerr << " Can not open file " << fileName << G4endl; } #endif return false; } G4int numberOfCouples = coupleTable.size(); if (ascii) { /////////////// ASCII mode ///////////////// // key word fOut << std::setw(FixedStringLengthForStore) << key << G4endl; // number of couples in the table fOut << numberOfCouples << G4endl; } else { /////////////// Binary mode ///////////////// // key word size_t i; for (i=0; iGetIndex(); // cut value G4ProductionCuts* aCut = aCouple->GetProductionCuts(); G4double cutValues[NumberOfG4CutIndex]; for (size_t idx=0; idx GetProductionCut(idx); } // material/region info G4String materialName = aCouple->GetMaterial()->GetName(); G4String regionName = "NONE"; if (aCouple->IsUsed()){ typedef std::vector::iterator regionIterator; for(regionIterator rItr=fG4RegionStore->begin(); rItr!=fG4RegionStore->end();rItr++){ if (IsCoupleUsedInTheRegion(aCouple, *rItr) ){ regionName = (*rItr)->GetName(); break; } } } if (ascii) { /////////////// ASCII mode ///////////////// // index number fOut << index << G4endl; // material name fOut << std::setw(FixedStringLengthForStore) << materialName<< G4endl; // region name fOut << std::setw(FixedStringLengthForStore) << regionName<< G4endl; fOut.setf(std::ios::scientific); // cut values for (size_t idx=0; idx< NumberOfG4CutIndex; idx++) { fOut << std::setw(FixedStringLengthForStore) << cutValues[idx]/(mm) << G4endl; } fOut.unsetf(std::ios::scientific); } else { /////////////// Binary mode ///////////////// // index fOut.write( (char*)(&index), sizeof (G4int)); // material name size_t i; for (i=0; i0) { G4cerr << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo "; G4cerr << " Can not open file " << fileName << G4endl; } #endif return false; } char temp[FixedStringLengthForStore]; // key word G4String keyword; if (ascii) { fIn >> keyword; } else { fIn.read(temp, FixedStringLengthForStore); keyword = (const char*)(temp); } if (key!=keyword) { #ifdef G4VERBOSE if (verboseLevel >0) { G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo "; G4cout << " Key word in " << fileName << "= " << keyword ; G4cout <<"( should be "<< key << ")" <> numberOfCouples; } else { fIn.read( (char*)(&numberOfCouples), sizeof (G4int)); } // Reset MCCIndexConversionTable mccConversionTable.Reset(numberOfCouples); // Read in couple information for (G4int idx=0; idx> index; } else { fIn.read( (char*)(&index), sizeof (G4int)); } // read in index material name char mat_name[FixedStringLengthForStore]; if (ascii) { fIn >> mat_name; } else { fIn.read(mat_name, FixedStringLengthForStore); } // read in index and region name char region_name[FixedStringLengthForStore]; if (ascii) { fIn >> region_name; } else { fIn.read(region_name, FixedStringLengthForStore); } // cut value G4double cutValues[NumberOfG4CutIndex]; for (size_t i=0; i< NumberOfG4CutIndex; i++) { if (ascii) { fIn >> cutValues[i]; cutValues[i] *= (mm); } else { fIn.read( (char*)(&(cutValues[i])), sizeof (G4double)); } } // Loop over all couples CoupleTableIterator cItr; G4bool fOK = false; G4MaterialCutsCouple* aCouple =0; for (cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++){ aCouple = (*cItr); // check material name if ( mat_name != aCouple->GetMaterial()->GetName() ) continue; // check cut values G4ProductionCuts* aCut = aCouple->GetProductionCuts(); G4bool fRatio = true; for (size_t j=0; j< NumberOfG4CutIndex; j++) { // check ratio only if values are not the same if (cutValues[j] != aCut->GetProductionCut(j)) { G4double ratio = cutValues[j]/aCut->GetProductionCut(j); fRatio = fRatio && (0.999GetIndex()); break; } #ifdef G4VERBOSE // debug information if (verboseLevel >1) { if (fOK) { G4String regionname(region_name); G4Region* fRegion = 0; if ( regionname != "NONE" ) fRegion = fG4RegionStore->GetRegion(region_name); if ( (( regionname == "NONE" ) && (aCouple->IsUsed()) ) || (( regionname != "NONE" ) && (fRegion==0) ) || !IsCoupleUsedInTheRegion(aCouple, fRegion) ) { G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo "; G4cout << "A Couple is used differnt region in the current setup "; G4cout << index << ": in " << fileName << G4endl; G4cout << " material: " << mat_name ; G4cout << " region: " << region_name << G4endl; for (size_t ii=0; ii< NumberOfG4CutIndex; ii++) { G4cout << "cut[" << ii << "]=" << cutValues[ii]/mm; G4cout << " mm : "; } G4cout << G4endl; } else if ( index != aCouple->GetIndex() ) { G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo "; G4cout << "Index of couples was modified "<< G4endl; G4cout << aCouple->GetIndex() << ":" <GetMaterial()->GetName(); G4cout <<" is defined as " ; G4cout << index << ":" << mat_name << " in " << fileName << G4endl; } else { G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo "; G4cout << index << ":" << mat_name << " in " << fileName ; G4cout << " is consistent with current setup" << G4endl; } } } if ((!fOK) && (verboseLevel >0)) { G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo "; G4cout << "Couples is not defined in the current detector setup "; G4cout << index << ": in " << fileName << G4endl; G4cout << " material: " << mat_name ; G4cout << " region: " << region_name << G4endl; for (size_t ii=0; ii< NumberOfG4CutIndex; ii++) { G4cout << "cut[" << ii << "]=" << cutValues[ii]/mm; G4cout << " mm : "; } G4cout << G4endl; } #endif } fIn.close(); return true; } ///////////////////////////////////////////////////////////// // Store cut values information in files under the specified directory. // G4bool G4ProductionCutsTable::StoreCutsInfo(const G4String& directory, G4bool ascii) { const G4String fileName = directory + "/" + "cut.dat"; const G4String key = "CUT-V3.0"; std::ofstream fOut; char temp[FixedStringLengthForStore]; // open output file // if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary); else fOut.open(fileName,std::ios::out); // check if the file has been opened successfully if (!fOut) { if(verboseLevel>0) { G4cerr << "G4ProductionCutsTable::StoreCutsInfo "; G4cerr << " Can not open file " << fileName << G4endl; } return false; } G4int numberOfCouples = coupleTable.size(); if (ascii) { /////////////// ASCII mode ///////////////// // key word fOut << key << G4endl; // number of couples in the table fOut << numberOfCouples << G4endl; } else { /////////////// Binary mode ///////////////// // key word size_t i; for (i=0; i* fRange = GetRangeCutsVector(idx); const std::vector* fEnergy = GetEnergyCutsVector(idx); size_t i=0; // Loop over all couples CoupleTableIterator cItr; for (cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++, i++){ if (ascii) { /////////////// ASCII mode ///////////////// fOut.setf(std::ios::scientific); fOut << std::setw(20) << (*fRange)[i]/mm ; fOut << std::setw(20) << (*fEnergy)[i]/keV << G4endl; fOut.unsetf(std::ios::scientific); } else { /////////////// Binary mode ///////////////// G4double cut = (*fRange)[i]; fOut.write((char*)(&cut), sizeof (G4double)); cut = (*fEnergy)[i]; fOut.write((char*)(&cut), sizeof (G4double)); } } } fOut.close(); return true; } ///////////////////////////////////////////////////////////// // Retrieve cut values information in files under the specified directory. // G4bool G4ProductionCutsTable::RetrieveCutsInfo(const G4String& directory, G4bool ascii) { const G4String fileName = directory + "/" + "cut.dat"; const G4String key = "CUT-V3.0"; std::ifstream fIn; // open input file // if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary); else fIn.open(fileName,std::ios::in); // check if the file has been opened successfully if (!fIn) { if (verboseLevel >0) { G4cerr << "G4ProductionCutTable::RetrieveCutsInfo "; G4cerr << " Can not open file " << fileName << G4endl; } return false; } char temp[FixedStringLengthForStore]; // key word G4String keyword; if (ascii) { fIn >> keyword; } else { fIn.read(temp, FixedStringLengthForStore); keyword = (const char*)(temp); } if (key!=keyword) { if (verboseLevel >0) { G4cout << "G4ProductionCutTable::RetrieveCutsInfo "; G4cout << " Key word in " << fileName << "= " << keyword ; G4cout <<"( should be "<< key << ")" <> numberOfCouples; } else { fIn.read( (char*)(&numberOfCouples), sizeof (G4int)); } for (size_t idx=0; G4int(idx) clear(); fEnergy->clear(); // Loop over all couples for (size_t i=0; G4int(i)< numberOfCouples; i++){ G4double rcut, ecut; if (ascii) { fIn >> rcut >> ecut; rcut *= mm; ecut *= keV; } else { fIn.read((char*)(&rcut), sizeof (G4double)); fIn.read((char*)(&ecut), sizeof (G4double)); } if (!mccConversionTable.IsUsed(i)) continue; size_t new_index = mccConversionTable.GetIndex(i); (*fRange)[new_index] = rcut; (*fEnergy)[new_index] = ecut; } } return true; } ///////////////////////////////////////////////////////////// // Set Verbose Level // set same verbosity to all registered RangeToEnergyConverters void G4ProductionCutsTable::SetVerboseLevel(G4int value) { verboseLevel = value; for (int ip=0; ip< NumberOfG4CutIndex; ip++) { if (converters[ip] !=0 ){ converters[ip]->SetVerboseLevel(value); } } } ///////////////////////////////////////////////////////////// G4double G4ProductionCutsTable::GetMaxEnergyCut() { return G4VRangeToEnergyConverter::GetMaxEnergyCut(); } ///////////////////////////////////////////////////////////// void G4ProductionCutsTable::SetMaxEnergyCut(G4double value) { G4VRangeToEnergyConverter::SetMaxEnergyCut(value); }