Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4hCoulombScatteringModel.cc 93567 2015-10-26 14:51:41Z gcosmo $ >> 27 // 26 // ------------------------------------------- 28 // ------------------------------------------------------------------- 27 // 29 // 28 // GEANT4 Class file 30 // GEANT4 Class file 29 // 31 // 30 // 32 // 31 // File name: G4hCoulombScatteringModel 33 // File name: G4hCoulombScatteringModel 32 // 34 // 33 // Author: Vladimir Ivanchenko 35 // Author: Vladimir Ivanchenko 34 // 36 // 35 // Creation date: 08.06.2012 from G4eCoulombSc 37 // Creation date: 08.06.2012 from G4eCoulombScatteringModel 36 // 38 // 37 // Modifications: 39 // Modifications: 38 // 40 // 39 // 41 // 40 // Class Description: 42 // Class Description: 41 // 43 // 42 // ------------------------------------------- 44 // ------------------------------------------------------------------- 43 // 45 // 44 //....oooOO0OOooo........oooOO0OOooo........oo 46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 45 //....oooOO0OOooo........oooOO0OOooo........oo 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 46 48 47 #include "G4hCoulombScatteringModel.hh" 49 #include "G4hCoulombScatteringModel.hh" 48 #include "G4PhysicalConstants.hh" 50 #include "G4PhysicalConstants.hh" 49 #include "G4SystemOfUnits.hh" 51 #include "G4SystemOfUnits.hh" 50 #include "Randomize.hh" 52 #include "Randomize.hh" 51 #include "G4DataVector.hh" 53 #include "G4DataVector.hh" 52 #include "G4ElementTable.hh" 54 #include "G4ElementTable.hh" 53 #include "G4ParticleChangeForGamma.hh" 55 #include "G4ParticleChangeForGamma.hh" 54 #include "G4Proton.hh" 56 #include "G4Proton.hh" 55 #include "G4ParticleTable.hh" 57 #include "G4ParticleTable.hh" 56 #include "G4IonTable.hh" 58 #include "G4IonTable.hh" 57 #include "G4ProductionCutsTable.hh" 59 #include "G4ProductionCutsTable.hh" 58 #include "G4NucleiProperties.hh" 60 #include "G4NucleiProperties.hh" 59 #include "G4Pow.hh" 61 #include "G4Pow.hh" >> 62 #include "G4LossTableManager.hh" >> 63 #include "G4LossTableBuilder.hh" 60 #include "G4NistManager.hh" 64 #include "G4NistManager.hh" 61 65 62 //....oooOO0OOooo........oooOO0OOooo........oo 66 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 63 67 >> 68 using namespace std; >> 69 64 G4hCoulombScatteringModel::G4hCoulombScatterin 70 G4hCoulombScatteringModel::G4hCoulombScatteringModel(G4bool combined) 65 : G4VEmModel("hCoulombScattering"), 71 : G4VEmModel("hCoulombScattering"), 66 cosThetaMin(1.0), 72 cosThetaMin(1.0), 67 cosThetaMax(-1.0), 73 cosThetaMax(-1.0), 68 isCombined(combined) 74 isCombined(combined) 69 { 75 { 70 fParticleChange = nullptr; << 76 fParticleChange = 0; 71 fNistManager = G4NistManager::Instance(); 77 fNistManager = G4NistManager::Instance(); 72 theIonTable = G4ParticleTable::GetParticleT 78 theIonTable = G4ParticleTable::GetParticleTable()->GetIonTable(); 73 theProton = G4Proton::Proton(); 79 theProton = G4Proton::Proton(); 74 currentMaterial = nullptr; << 80 currentMaterial = 0; 75 fixedCut = -1.0; 81 fixedCut = -1.0; 76 82 77 pCuts = nullptr; << 83 pCuts = 0; 78 84 79 recoilThreshold = 0.0; // by default does no << 85 recoilThreshold = 0.*keV; // by default does not work 80 86 81 particle = nullptr; << 87 particle = 0; 82 currentCouple = nullptr; << 88 currentCouple = 0; 83 wokvi = new G4WentzelVIRelXSection(); << 89 wokvi = new G4WentzelVIRelXSection(combined); 84 90 85 currentMaterialIndex = 0; 91 currentMaterialIndex = 0; 86 mass = CLHEP::proton_mass_c2; << 92 mass = proton_mass_c2; 87 elecRatio = 0.0; 93 elecRatio = 0.0; 88 } 94 } 89 95 90 //....oooOO0OOooo........oooOO0OOooo........oo 96 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 91 97 92 G4hCoulombScatteringModel::~G4hCoulombScatteri 98 G4hCoulombScatteringModel::~G4hCoulombScatteringModel() 93 { 99 { 94 delete wokvi; 100 delete wokvi; 95 } 101 } 96 102 97 //....oooOO0OOooo........oooOO0OOooo........oo 103 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 98 104 99 void G4hCoulombScatteringModel::Initialise(con 105 void G4hCoulombScatteringModel::Initialise(const G4ParticleDefinition* part, 100 const G4DataVector& cuts) 106 const G4DataVector& cuts) 101 { 107 { 102 SetupParticle(part); 108 SetupParticle(part); 103 currentCouple = nullptr; << 109 currentCouple = 0; 104 110 105 // defined theta limit between single and mu << 111 if(isCombined) { 106 isCombined = true; << 112 cosThetaMin = 1.0; 107 G4double tet = PolarAngleLimit(); << 113 G4double tet = PolarAngleLimit(); 108 << 114 if(tet >= pi) { cosThetaMin = -1.0; } 109 if(tet <= 0.0) { << 115 else if(tet > 0.0) { cosThetaMin = cos(tet); } 110 cosThetaMin = 1.0; << 111 isCombined = false; << 112 } else if(tet >= CLHEP::pi) { << 113 cosThetaMin = -1.0; << 114 } else { << 115 cosThetaMin = std::cos(tet); << 116 } 116 } 117 117 118 wokvi->Initialise(part, cosThetaMin); 118 wokvi->Initialise(part, cosThetaMin); 119 /* 119 /* 120 G4cout << "G4hCoulombScatteringModel: " << p 120 G4cout << "G4hCoulombScatteringModel: " << particle->GetParticleName() 121 << " 1-cos(ThetaLimit)= " << 1 - cos 121 << " 1-cos(ThetaLimit)= " << 1 - cosThetaMin 122 << " cos(thetaMax)= " << cosThetaMax 122 << " cos(thetaMax)= " << cosThetaMax 123 << G4endl; 123 << G4endl; 124 */ 124 */ 125 pCuts = &cuts; 125 pCuts = &cuts; 126 //G4ProductionCutsTable::GetProductionCutsTa 126 //G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(3); 127 /* 127 /* 128 G4cout << "!!! G4hCoulombScatteringModel::In 128 G4cout << "!!! G4hCoulombScatteringModel::Initialise for " 129 << part->GetParticleName() << " cos(TetM 129 << part->GetParticleName() << " cos(TetMin)= " << cosThetaMin 130 << " cos(TetMax)= " << cosThetaMax <<G4e 130 << " cos(TetMax)= " << cosThetaMax <<G4endl; 131 G4cout << "cut= " << (*pCuts)[0] << " cut1= 131 G4cout << "cut= " << (*pCuts)[0] << " cut1= " << (*pCuts)[1] << G4endl; 132 */ 132 */ 133 if(!fParticleChange) { 133 if(!fParticleChange) { 134 fParticleChange = GetParticleChangeForGamm 134 fParticleChange = GetParticleChangeForGamma(); 135 } 135 } 136 if(IsMaster() && mass < CLHEP::GeV && part-> << 136 if(IsMaster() && mass < GeV && part->GetParticleName() != "GenericIon") { 137 InitialiseElementSelectors(part, cuts); 137 InitialiseElementSelectors(part, cuts); 138 } 138 } 139 } 139 } 140 140 141 //....oooOO0OOooo........oooOO0OOooo........oo 141 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 142 142 143 void G4hCoulombScatteringModel::InitialiseLoca 143 void G4hCoulombScatteringModel::InitialiseLocal(const G4ParticleDefinition*, 144 G4VEmModel* masterModel) 144 G4VEmModel* masterModel) 145 { 145 { 146 SetElementSelectors(masterModel->GetElementS 146 SetElementSelectors(masterModel->GetElementSelectors()); 147 } 147 } 148 148 149 //....oooOO0OOooo........oooOO0OOooo........oo 149 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 150 150 151 G4double 151 G4double 152 G4hCoulombScatteringModel::MinPrimaryEnergy(co 152 G4hCoulombScatteringModel::MinPrimaryEnergy(const G4Material* material, 153 const G4ParticleDefinition* part 153 const G4ParticleDefinition* part, 154 G4double) 154 G4double) 155 { 155 { 156 SetupParticle(part); 156 SetupParticle(part); 157 157 158 // define cut using cuts for proton 158 // define cut using cuts for proton 159 G4double cut = 159 G4double cut = 160 std::max(recoilThreshold, (*pCuts)[Current 160 std::max(recoilThreshold, (*pCuts)[CurrentCouple()->GetIndex()]); 161 161 162 // find out lightest element 162 // find out lightest element 163 const G4ElementVector* theElementVector = ma 163 const G4ElementVector* theElementVector = material->GetElementVector(); 164 std::size_t nelm = material->GetNumberOfElem << 164 G4int nelm = material->GetNumberOfElements(); 165 165 166 // select lightest element 166 // select lightest element 167 G4int Z = 300; 167 G4int Z = 300; 168 for (std::size_t j=0; j<nelm; ++j) { << 168 for (G4int j=0; j<nelm; ++j) { 169 Z = std::min(Z,(*theElementVector)[j]->Get << 169 G4int iz = G4lrint((*theElementVector)[j]->GetZ()); >> 170 if(iz < Z) { Z = iz; } 170 } 171 } 171 G4int A = G4lrint(fNistManager->GetAtomicMas 172 G4int A = G4lrint(fNistManager->GetAtomicMassAmu(Z)); 172 G4double targetMass = G4NucleiProperties::Ge 173 G4double targetMass = G4NucleiProperties::GetNuclearMass(A, Z); 173 G4double t = std::max(cut, 0.5*(cut + std::s << 174 G4double t = std::max(cut, 0.5*(cut + sqrt(2*cut*targetMass))); 174 175 175 return t; 176 return t; 176 } 177 } 177 178 178 //....oooOO0OOooo........oooOO0OOooo........oo 179 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 179 180 180 G4double G4hCoulombScatteringModel::ComputeCro 181 G4double G4hCoulombScatteringModel::ComputeCrossSectionPerAtom( 181 const G4ParticleDefinition* p, 182 const G4ParticleDefinition* p, 182 G4double kinEnergy, 183 G4double kinEnergy, 183 G4double Z, G4double, 184 G4double Z, G4double, 184 G4double cutEnergy, G4double) 185 G4double cutEnergy, G4double) 185 { 186 { 186 //G4cout << "### G4hCoulombScatteringModel:: 187 //G4cout << "### G4hCoulombScatteringModel::ComputeCrossSectionPerAtom for " 187 //<< p->GetParticleName()<<" Z= "<<Z<<" e(Me 188 //<< p->GetParticleName()<<" Z= "<<Z<<" e(MeV)= "<< kinEnergy/MeV << G4endl; 188 G4double cross = 0.0; 189 G4double cross = 0.0; 189 elecRatio = 0.0; 190 elecRatio = 0.0; 190 if(p != particle) { SetupParticle(p); } 191 if(p != particle) { SetupParticle(p); } 191 192 192 // cross section is set to zero to avoid pro 193 // cross section is set to zero to avoid problems in sample secondary 193 if(kinEnergy <= 0.0) { return cross; } 194 if(kinEnergy <= 0.0) { return cross; } 194 DefineMaterial(CurrentCouple()); 195 DefineMaterial(CurrentCouple()); 195 196 196 G4int iz = G4lrint(Z); << 197 G4int iz = G4int(Z); 197 G4double tmass = (1 == iz) ? proton_mass_c2 << 198 G4double tmass = proton_mass_c2; 198 fNistManager->GetAtomicMassAmu(iz)*amu_c2; << 199 if(1 < iz) { 199 wokvi->SetTargetMass(tmass); << 200 tmass = fNistManager->GetAtomicMassAmu(iz)*amu_c2; 200 << 201 } 201 G4double costmin = 202 G4double costmin = 202 wokvi->SetupKinematic(kinEnergy, currentMa << 203 wokvi->SetupKinematic(kinEnergy, currentMaterial, cutEnergy, tmass); 203 << 204 if(cosThetaMax < costmin) { 204 if(cosThetaMax < costmin) { 205 G4double cut = (0.0 < fixedCut) ? fixedCut << 205 G4double cut = cutEnergy; >> 206 if(fixedCut > 0.0) { cut = fixedCut; } 206 costmin = wokvi->SetupTarget(iz, cut); 207 costmin = wokvi->SetupTarget(iz, cut); 207 G4double costmax = << 208 G4double costmax = cosThetaMax; 208 (1 == iz && particle == theProton && cos << 209 if(iz == 1 && costmax < 0.0 && particle == theProton) { 209 ? 0.0 : cosThetaMax; << 210 costmax = 0.0; >> 211 } 210 if(costmin > costmax) { 212 if(costmin > costmax) { 211 cross = wokvi->ComputeNuclearCrossSectio 213 cross = wokvi->ComputeNuclearCrossSection(costmin, costmax) 212 + wokvi->ComputeElectronCrossSection(costmin 214 + wokvi->ComputeElectronCrossSection(costmin, costmax); 213 } 215 } 214 /* 216 /* 215 if(p->GetParticleName() == "mu+") 217 if(p->GetParticleName() == "mu+") 216 G4cout << "e(MeV)= " << kinEnergy/MeV << " c 218 G4cout << "e(MeV)= " << kinEnergy/MeV << " cross(b)= " << cross/barn 217 << " 1-costmin= " << 1-costmin 219 << " 1-costmin= " << 1-costmin 218 << " 1-costmax= " << 1-costmax 220 << " 1-costmax= " << 1-costmax 219 << " 1-cosThetaMax= " << 1-cosThetaMax 221 << " 1-cosThetaMax= " << 1-cosThetaMax 220 << G4endl; 222 << G4endl; 221 */ 223 */ 222 } 224 } 223 return cross; 225 return cross; 224 } 226 } 225 227 226 //....oooOO0OOooo........oooOO0OOooo........oo 228 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 227 229 228 void G4hCoulombScatteringModel::SampleSecondar 230 void G4hCoulombScatteringModel::SampleSecondaries( 229 std::vector<G4DynamicParticle* 231 std::vector<G4DynamicParticle*>* fvect, 230 const G4MaterialCutsCouple* couple, 232 const G4MaterialCutsCouple* couple, 231 const G4DynamicParticle* dp, 233 const G4DynamicParticle* dp, 232 G4double cutEnergy, 234 G4double cutEnergy, 233 G4double) 235 G4double) 234 { 236 { 235 G4double kinEnergy = dp->GetKineticEnergy(); 237 G4double kinEnergy = dp->GetKineticEnergy(); 236 SetupParticle(dp->GetDefinition()); 238 SetupParticle(dp->GetDefinition()); 237 DefineMaterial(couple); 239 DefineMaterial(couple); 238 240 239 // Choose nucleus 241 // Choose nucleus 240 G4double cut = (0.0 < fixedCut) ? fixedCut : << 241 << 242 const G4Element* elm = SelectRandomAtom(coup 242 const G4Element* elm = SelectRandomAtom(couple,particle, 243 kinEnergy,cut,kinEnergy); << 243 kinEnergy,cutEnergy,kinEnergy); 244 244 245 G4int iz = elm->GetZasInt(); << 245 G4double Z = elm->GetZ(); >> 246 >> 247 G4int iz = G4int(Z); 246 G4int ia = SelectIsotopeNumber(elm); 248 G4int ia = SelectIsotopeNumber(elm); 247 G4double mass2 = G4NucleiProperties::GetNucl 249 G4double mass2 = G4NucleiProperties::GetNuclearMass(ia, iz); 248 250 249 wokvi->SetTargetMass(mass2); << 251 wokvi->SetupKinematic(kinEnergy, currentMaterial, cutEnergy, mass2); 250 wokvi->SetupKinematic(kinEnergy, currentMate << 252 G4double costmin = wokvi->SetupTarget(iz, cutEnergy); 251 G4double costmin = wokvi->SetupTarget(iz, cu << 253 G4double costmax = cosThetaMax; 252 G4double costmax = (1 == iz && particle == t << 254 if(iz == 1 && costmax < 0.0 && particle == theProton) { 253 ? 0.0 : cosThetaMax; << 255 costmax = 0.0; >> 256 } >> 257 254 if(costmin <= costmax) { return; } 258 if(costmin <= costmax) { return; } 255 << 256 G4double cross = wokvi->ComputeNuclearCrossS 259 G4double cross = wokvi->ComputeNuclearCrossSection(costmin, costmax); 257 G4double ecross = wokvi->ComputeElectronCros 260 G4double ecross = wokvi->ComputeElectronCrossSection(costmin, costmax); 258 G4double ratio = ecross/(cross + ecross); 261 G4double ratio = ecross/(cross + ecross); 259 262 260 G4ThreeVector newDirection = 263 G4ThreeVector newDirection = 261 wokvi->SampleSingleScattering(costmin, cos 264 wokvi->SampleSingleScattering(costmin, costmax, ratio); 262 265 263 // kinematics in the Lab system 266 // kinematics in the Lab system 264 G4double ptot = std::sqrt(kinEnergy*(kinEner << 267 G4double ptot = dp->GetTotalMomentum(); 265 G4double e1 = mass + kinEnergy; << 268 G4double e1 = dp->GetTotalEnergy(); 266 269 267 // Lab. system kinematics along projectile d 270 // Lab. system kinematics along projectile direction 268 G4LorentzVector v0 = G4LorentzVector(0, 0, p << 271 G4LorentzVector v0 = G4LorentzVector(0, 0, ptot, e1 + mass2); 269 G4LorentzVector v1 = G4LorentzVector(0, 0, p << 272 G4double bet = ptot/v0.e(); 270 G4ThreeVector bst = v0.boostVector(); << 273 G4double gam = 1.0/sqrt((1.0 - bet)*(1.0 + bet)); 271 v1.boost(-bst); << 274 272 // CM projectile 275 // CM projectile 273 G4double momCM = v1.pz(); << 276 G4double momCM = gam*(ptot - bet*e1); 274 << 277 G4double eCM = gam*(e1 - bet*ptot); 275 // Momentum after scattering of incident par << 278 // energy & momentum after scattering of incident particle 276 v1.setX(momCM*newDirection.x()); << 279 G4double pxCM = momCM*newDirection.x(); 277 v1.setY(momCM*newDirection.y()); << 280 G4double pyCM = momCM*newDirection.y(); 278 v1.setZ(momCM*newDirection.z()); << 281 G4double pzCM = momCM*newDirection.z(); 279 282 280 // CM--->Lab 283 // CM--->Lab 281 v1.boost(bst); << 284 G4LorentzVector v1(pxCM , pyCM, gam*(pzCM + bet*eCM), gam*(eCM + bet*pzCM)); 282 285 283 G4ThreeVector dir = dp->GetMomentumDirection 286 G4ThreeVector dir = dp->GetMomentumDirection(); 284 newDirection = v1.vect().unit(); 287 newDirection = v1.vect().unit(); 285 newDirection.rotateUz(dir); 288 newDirection.rotateUz(dir); 286 289 287 fParticleChange->ProposeMomentumDirection(ne 290 fParticleChange->ProposeMomentumDirection(newDirection); 288 291 289 // recoil 292 // recoil 290 v0 -= v1; 293 v0 -= v1; 291 G4double trec = std::max(v0.e() - mass2, 0.0 << 294 G4double trec = v0.e() - mass2; 292 G4double edep = 0.0; 295 G4double edep = 0.0; 293 296 294 G4double tcut = recoilThreshold; 297 G4double tcut = recoilThreshold; 295 if(pCuts) { tcut= std::max(tcut,(*pCuts)[cur << 298 if(pCuts) { >> 299 tcut= std::max(tcut,(*pCuts)[currentMaterialIndex]); >> 300 //G4cout<<" tcut eV "<<tcut/eV<<endl; >> 301 } 296 302 297 if(trec > tcut) { 303 if(trec > tcut) { 298 G4ParticleDefinition* ion = theIonTable->G 304 G4ParticleDefinition* ion = theIonTable->GetIon(iz, ia, 0); 299 newDirection = v0.vect().unit(); 305 newDirection = v0.vect().unit(); 300 newDirection.rotateUz(dir); 306 newDirection.rotateUz(dir); 301 auto newdp = new G4DynamicParticle(ion, ne << 307 G4DynamicParticle* newdp = new G4DynamicParticle(ion, newDirection, trec); 302 fvect->push_back(newdp); 308 fvect->push_back(newdp); 303 } else if(trec > 0.0) { 309 } else if(trec > 0.0) { 304 edep = trec; 310 edep = trec; 305 fParticleChange->ProposeNonIonizingEnergyD 311 fParticleChange->ProposeNonIonizingEnergyDeposit(edep); 306 } 312 } 307 313 308 // finelize primary energy and energy balanc 314 // finelize primary energy and energy balance 309 G4double finalT = v1.e() - mass; 315 G4double finalT = v1.e() - mass; 310 if(finalT < 0.0) { 316 if(finalT < 0.0) { 311 edep += finalT; 317 edep += finalT; 312 finalT = 0.0; 318 finalT = 0.0; 313 } 319 } 314 edep = std::max(edep, 0.0); 320 edep = std::max(edep, 0.0); 315 fParticleChange->SetProposedKineticEnergy(fi 321 fParticleChange->SetProposedKineticEnergy(finalT); 316 fParticleChange->ProposeLocalEnergyDeposit(e 322 fParticleChange->ProposeLocalEnergyDeposit(edep); 317 } 323 } 318 324 319 //....oooOO0OOooo........oooOO0OOooo........oo 325 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 320 326