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: G4NuElNucleusCcModel.cc 91806 2015-08- 26 // $Id: G4NuElNucleusCcModel.cc 91806 2015-08-06 12:20:45Z gcosmo $ 27 // 27 // 28 // Geant4 Header : G4NuElNucleusCcModel 28 // Geant4 Header : G4NuElNucleusCcModel 29 // 29 // 30 // Author : V.Grichine 12.2.19 30 // Author : V.Grichine 12.2.19 31 // 31 // 32 32 33 #include <iostream> 33 #include <iostream> 34 #include <fstream> 34 #include <fstream> 35 #include <sstream> 35 #include <sstream> 36 36 37 #include "G4NuElNucleusCcModel.hh" 37 #include "G4NuElNucleusCcModel.hh" 38 // #include "G4NuMuNuclCcDistrKR.hh" 38 // #include "G4NuMuNuclCcDistrKR.hh" 39 39 40 // #include "G4NuMuResQX.hh" 40 // #include "G4NuMuResQX.hh" 41 41 42 #include "G4SystemOfUnits.hh" 42 #include "G4SystemOfUnits.hh" 43 #include "G4ParticleTable.hh" 43 #include "G4ParticleTable.hh" 44 #include "G4ParticleDefinition.hh" 44 #include "G4ParticleDefinition.hh" 45 #include "G4IonTable.hh" 45 #include "G4IonTable.hh" 46 #include "Randomize.hh" 46 #include "Randomize.hh" 47 #include "G4RandomDirection.hh" 47 #include "G4RandomDirection.hh" 48 // #include "G4Threading.hh" 48 // #include "G4Threading.hh" 49 49 50 // #include "G4Integrator.hh" 50 // #include "G4Integrator.hh" 51 #include "G4DataVector.hh" 51 #include "G4DataVector.hh" 52 #include "G4PhysicsTable.hh" 52 #include "G4PhysicsTable.hh" 53 /* 53 /* 54 #include "G4CascadeInterface.hh" 54 #include "G4CascadeInterface.hh" 55 // #include "G4BinaryCascade.hh" 55 // #include "G4BinaryCascade.hh" 56 #include "G4TheoFSGenerator.hh" 56 #include "G4TheoFSGenerator.hh" 57 #include "G4LundStringFragmentation.hh" 57 #include "G4LundStringFragmentation.hh" 58 #include "G4ExcitedStringDecay.hh" 58 #include "G4ExcitedStringDecay.hh" 59 #include "G4FTFModel.hh" 59 #include "G4FTFModel.hh" 60 // #include "G4BinaryCascade.hh" 60 // #include "G4BinaryCascade.hh" 61 #include "G4HadFinalState.hh" 61 #include "G4HadFinalState.hh" 62 #include "G4HadSecondary.hh" 62 #include "G4HadSecondary.hh" 63 #include "G4HadronicInteractionRegistry.hh" 63 #include "G4HadronicInteractionRegistry.hh" 64 // #include "G4INCLXXInterface.hh" 64 // #include "G4INCLXXInterface.hh" 65 #include "G4QGSModel.hh" 65 #include "G4QGSModel.hh" 66 #include "G4QGSMFragmentation.hh" 66 #include "G4QGSMFragmentation.hh" 67 #include "G4QGSParticipants.hh" 67 #include "G4QGSParticipants.hh" 68 */ 68 */ 69 #include "G4KineticTrack.hh" 69 #include "G4KineticTrack.hh" 70 #include "G4DecayKineticTracks.hh" 70 #include "G4DecayKineticTracks.hh" 71 #include "G4KineticTrackVector.hh" 71 #include "G4KineticTrackVector.hh" 72 #include "G4Fragment.hh" 72 #include "G4Fragment.hh" 73 #include "G4NucleiProperties.hh" 73 #include "G4NucleiProperties.hh" 74 #include "G4ReactionProductVector.hh" 74 #include "G4ReactionProductVector.hh" 75 75 76 #include "G4GeneratorPrecompoundInterface.hh" 76 #include "G4GeneratorPrecompoundInterface.hh" 77 #include "G4PreCompoundModel.hh" 77 #include "G4PreCompoundModel.hh" 78 #include "G4ExcitationHandler.hh" 78 #include "G4ExcitationHandler.hh" 79 79 80 80 81 #include "G4Electron.hh" 81 #include "G4Electron.hh" 82 // #include "G4MuonPlus.hh" 82 // #include "G4MuonPlus.hh" 83 #include "G4Nucleus.hh" 83 #include "G4Nucleus.hh" 84 #include "G4LorentzVector.hh" 84 #include "G4LorentzVector.hh" 85 85 86 using namespace std; 86 using namespace std; 87 using namespace CLHEP; 87 using namespace CLHEP; 88 88 89 #ifdef G4MULTITHREADED 89 #ifdef G4MULTITHREADED 90 G4Mutex G4NuElNucleusCcModel::numuNucleusM 90 G4Mutex G4NuElNucleusCcModel::numuNucleusModel = G4MUTEX_INITIALIZER; 91 #endif 91 #endif 92 92 93 93 94 G4NuElNucleusCcModel::G4NuElNucleusCcModel(con 94 G4NuElNucleusCcModel::G4NuElNucleusCcModel(const G4String& name) 95 : G4NeutrinoNucleusModel(name) 95 : G4NeutrinoNucleusModel(name) 96 { 96 { 97 theElectron = G4Electron::Electron(); 97 theElectron = G4Electron::Electron(); 98 fData = fMaster = false; 98 fData = fMaster = false; 99 fMel = electron_mass_c2; 99 fMel = electron_mass_c2; 100 InitialiseModel(); 100 InitialiseModel(); 101 } 101 } 102 102 103 103 104 G4NuElNucleusCcModel::~G4NuElNucleusCcModel() 104 G4NuElNucleusCcModel::~G4NuElNucleusCcModel() 105 {} 105 {} 106 106 107 107 108 void G4NuElNucleusCcModel::ModelDescription(st 108 void G4NuElNucleusCcModel::ModelDescription(std::ostream& outFile) const 109 { 109 { 110 110 111 outFile << "G4NuElNucleusCcModel is a neut 111 outFile << "G4NuElNucleusCcModel is a neutrino-nucleus (charge current) scattering\n" 112 << "model which uses the standard 112 << "model which uses the standard model \n" 113 << "transfer parameterization. Th 113 << "transfer parameterization. The model is fully relativistic\n"; 114 114 115 } 115 } 116 116 117 ////////////////////////////////////////////// 117 ///////////////////////////////////////////////////////// 118 // 118 // 119 // Read data from G4PARTICLEXSDATA (locally PA 119 // Read data from G4PARTICLEXSDATA (locally PARTICLEXSDATA) 120 120 121 void G4NuElNucleusCcModel::InitialiseModel() 121 void G4NuElNucleusCcModel::InitialiseModel() 122 { 122 { 123 G4String pName = "nu_e"; 123 G4String pName = "nu_e"; 124 124 125 G4int nSize(0), i(0), j(0), k(0); 125 G4int nSize(0), i(0), j(0), k(0); 126 126 127 if(!fData) 127 if(!fData) 128 { 128 { 129 #ifdef G4MULTITHREADED 129 #ifdef G4MULTITHREADED 130 G4MUTEXLOCK(&numuNucleusModel); 130 G4MUTEXLOCK(&numuNucleusModel); 131 if(!fData) 131 if(!fData) 132 { 132 { 133 #endif 133 #endif 134 fMaster = true; 134 fMaster = true; 135 #ifdef G4MULTITHREADED 135 #ifdef G4MULTITHREADED 136 } 136 } 137 G4MUTEXUNLOCK(&numuNucleusModel); 137 G4MUTEXUNLOCK(&numuNucleusModel); 138 #endif 138 #endif 139 } 139 } 140 140 141 if(fMaster) 141 if(fMaster) 142 { 142 { 143 const char* path = G4FindDataDir("G4PARTIC << 143 char* path = getenv("G4PARTICLEXSDATA"); 144 std::ostringstream ost1, ost2, ost3, ost4; 144 std::ostringstream ost1, ost2, ost3, ost4; 145 ost1 << path << "/" << "neutrino" << "/" < 145 ost1 << path << "/" << "neutrino" << "/" << pName << "/xarraycckr"; 146 146 147 std::ifstream filein1( ost1.str().c_str() 147 std::ifstream filein1( ost1.str().c_str() ); 148 148 149 // filein.open("$PARTICLEXSDATA/"); 149 // filein.open("$PARTICLEXSDATA/"); 150 150 151 filein1>>nSize; 151 filein1>>nSize; 152 152 153 for( k = 0; k < fNbin; ++k ) 153 for( k = 0; k < fNbin; ++k ) 154 { 154 { 155 for( i = 0; i <= fNbin; ++i ) 155 for( i = 0; i <= fNbin; ++i ) 156 { 156 { 157 filein1 >> fNuMuXarrayKR[k][i]; 157 filein1 >> fNuMuXarrayKR[k][i]; 158 // G4cout<< fNuMuXarrayKR[k][i] << " 158 // G4cout<< fNuMuXarrayKR[k][i] << " "; 159 } 159 } 160 } 160 } 161 // G4cout<<G4endl<<G4endl; 161 // G4cout<<G4endl<<G4endl; 162 162 163 ost2 << path << "/" << "neutrino" << "/" < 163 ost2 << path << "/" << "neutrino" << "/" << pName << "/xdistrcckr"; 164 std::ifstream filein2( ost2.str().c_str() 164 std::ifstream filein2( ost2.str().c_str() ); 165 165 166 filein2>>nSize; 166 filein2>>nSize; 167 167 168 for( k = 0; k < fNbin; ++k ) 168 for( k = 0; k < fNbin; ++k ) 169 { 169 { 170 for( i = 0; i < fNbin; ++i ) 170 for( i = 0; i < fNbin; ++i ) 171 { 171 { 172 filein2 >> fNuMuXdistrKR[k][i]; 172 filein2 >> fNuMuXdistrKR[k][i]; 173 // G4cout<< fNuMuXdistrKR[k][i] << " 173 // G4cout<< fNuMuXdistrKR[k][i] << " "; 174 } 174 } 175 } 175 } 176 // G4cout<<G4endl<<G4endl; 176 // G4cout<<G4endl<<G4endl; 177 177 178 ost3 << path << "/" << "neutrino" << "/" < 178 ost3 << path << "/" << "neutrino" << "/" << pName << "/q2arraycckr"; 179 std::ifstream filein3( ost3.str().c_str() 179 std::ifstream filein3( ost3.str().c_str() ); 180 180 181 filein3>>nSize; 181 filein3>>nSize; 182 182 183 for( k = 0; k < fNbin; ++k ) 183 for( k = 0; k < fNbin; ++k ) 184 { 184 { 185 for( i = 0; i <= fNbin; ++i ) 185 for( i = 0; i <= fNbin; ++i ) 186 { 186 { 187 for( j = 0; j <= fNbin; ++j ) 187 for( j = 0; j <= fNbin; ++j ) 188 { 188 { 189 filein3 >> fNuMuQarrayKR[k][i][j]; 189 filein3 >> fNuMuQarrayKR[k][i][j]; 190 // G4cout<< fNuMuQarrayKR[k][i][j] < 190 // G4cout<< fNuMuQarrayKR[k][i][j] << " "; 191 } 191 } 192 } 192 } 193 } 193 } 194 // G4cout<<G4endl<<G4endl; 194 // G4cout<<G4endl<<G4endl; 195 195 196 ost4 << path << "/" << "neutrino" << "/" < 196 ost4 << path << "/" << "neutrino" << "/" << pName << "/q2distrcckr"; 197 std::ifstream filein4( ost4.str().c_str() 197 std::ifstream filein4( ost4.str().c_str() ); 198 198 199 filein4>>nSize; 199 filein4>>nSize; 200 200 201 for( k = 0; k < fNbin; ++k ) 201 for( k = 0; k < fNbin; ++k ) 202 { 202 { 203 for( i = 0; i <= fNbin; ++i ) 203 for( i = 0; i <= fNbin; ++i ) 204 { 204 { 205 for( j = 0; j < fNbin; ++j ) 205 for( j = 0; j < fNbin; ++j ) 206 { 206 { 207 filein4 >> fNuMuQdistrKR[k][i][j]; 207 filein4 >> fNuMuQdistrKR[k][i][j]; 208 // G4cout<< fNuMuQdistrKR[k][i][j] < 208 // G4cout<< fNuMuQdistrKR[k][i][j] << " "; 209 } 209 } 210 } 210 } 211 } 211 } 212 fData = true; 212 fData = true; 213 } 213 } 214 } 214 } 215 215 216 ////////////////////////////////////////////// 216 ///////////////////////////////////////////////////////// 217 217 218 G4bool G4NuElNucleusCcModel::IsApplicable(cons 218 G4bool G4NuElNucleusCcModel::IsApplicable(const G4HadProjectile & aPart, 219 G4Nucleus & ) << 219 G4Nucleus & targetNucleus) 220 { 220 { 221 G4bool result = false; 221 G4bool result = false; 222 G4String pName = aPart.GetDefinition()->GetP 222 G4String pName = aPart.GetDefinition()->GetParticleName(); 223 G4double energy = aPart.GetTotalEnergy(); 223 G4double energy = aPart.GetTotalEnergy(); 224 fMinNuEnergy = GetMinNuElEnergy(); 224 fMinNuEnergy = GetMinNuElEnergy(); 225 225 226 if( pName == "nu_e" 226 if( pName == "nu_e" 227 && 227 && 228 energy > fMinNuEnergy 228 energy > fMinNuEnergy ) 229 { 229 { 230 result = true; 230 result = true; 231 } 231 } >> 232 G4int Z = targetNucleus.GetZ_asInt(); >> 233 Z *= 1; 232 234 233 return result; 235 return result; 234 } 236 } 235 237 236 /////////////////////////////////////////// Cl 238 /////////////////////////////////////////// ClusterDecay //////////////////////////////////////////////////////////// 237 // 239 // 238 // 240 // 239 241 240 G4HadFinalState* G4NuElNucleusCcModel::ApplyYo 242 G4HadFinalState* G4NuElNucleusCcModel::ApplyYourself( 241 const G4HadProjectile& aTrack, G4Nucleus& 243 const G4HadProjectile& aTrack, G4Nucleus& targetNucleus) 242 { 244 { 243 theParticleChange.Clear(); 245 theParticleChange.Clear(); 244 fProton = f2p2h = fBreak = false; 246 fProton = f2p2h = fBreak = false; 245 fCascade = fString = false; 247 fCascade = fString = false; 246 fLVh = fLVl = fLVt = fLVcpi = G4LorentzVecto 248 fLVh = fLVl = fLVt = fLVcpi = G4LorentzVector(0.,0.,0.,0.); 247 249 248 const G4HadProjectile* aParticle = &aTrack; 250 const G4HadProjectile* aParticle = &aTrack; 249 G4double energy = aParticle->GetTotalEnergy( 251 G4double energy = aParticle->GetTotalEnergy(); 250 252 251 G4String pName = aParticle->GetDefinition() 253 G4String pName = aParticle->GetDefinition()->GetParticleName(); 252 254 253 if( energy < fMinNuEnergy ) 255 if( energy < fMinNuEnergy ) 254 { 256 { 255 theParticleChange.SetEnergyChange(energy); 257 theParticleChange.SetEnergyChange(energy); 256 theParticleChange.SetMomentumChange(aTrack 258 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 257 return &theParticleChange; 259 return &theParticleChange; 258 } 260 } 259 261 260 SampleLVkr( aTrack, targetNucleus); 262 SampleLVkr( aTrack, targetNucleus); 261 263 262 if( fBreak == true || fEmu < fMel ) // ~5*10 264 if( fBreak == true || fEmu < fMel ) // ~5*10^-6 263 { 265 { 264 // G4cout<<"ni, "; 266 // G4cout<<"ni, "; 265 theParticleChange.SetEnergyChange(energy); 267 theParticleChange.SetEnergyChange(energy); 266 theParticleChange.SetMomentumChange(aTrack 268 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 267 return &theParticleChange; 269 return &theParticleChange; 268 } 270 } 269 271 270 // LVs of initial state 272 // LVs of initial state 271 273 272 G4LorentzVector lvp1 = aParticle->Get4Moment 274 G4LorentzVector lvp1 = aParticle->Get4Momentum(); 273 G4LorentzVector lvt1( 0., 0., 0., fM1 ); 275 G4LorentzVector lvt1( 0., 0., 0., fM1 ); 274 G4double mPip = G4ParticleTable::GetParticle 276 G4double mPip = G4ParticleTable::GetParticleTable()->FindParticle(211)->GetPDGMass(); 275 277 276 // 1-pi by fQtransfer && nu-energy 278 // 1-pi by fQtransfer && nu-energy 277 G4LorentzVector lvpip1( 0., 0., 0., mPip ); 279 G4LorentzVector lvpip1( 0., 0., 0., mPip ); 278 G4LorentzVector lvsum, lv2, lvX; 280 G4LorentzVector lvsum, lv2, lvX; 279 G4ThreeVector eP; 281 G4ThreeVector eP; 280 G4double cost(1.), sint(0.), phi(0.), muMom( 282 G4double cost(1.), sint(0.), phi(0.), muMom(0.), massX2(0.), massX(0.), massR(0.), eCut(0.); 281 G4DynamicParticle* aLept = nullptr; // lepto 283 G4DynamicParticle* aLept = nullptr; // lepton lv 282 284 283 G4int Z = targetNucleus.GetZ_asInt(); 285 G4int Z = targetNucleus.GetZ_asInt(); 284 G4int A = targetNucleus.GetA_asInt(); 286 G4int A = targetNucleus.GetA_asInt(); 285 G4double mTarg = targetNucleus.AtomicMass(A 287 G4double mTarg = targetNucleus.AtomicMass(A,Z); 286 G4int pdgP(0), qB(0); 288 G4int pdgP(0), qB(0); 287 // G4double mSum = G4ParticleTable::GetParti 289 // G4double mSum = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass() + mPip; 288 290 289 G4int iPi = GetOnePionIndex(energy); 291 G4int iPi = GetOnePionIndex(energy); 290 G4double p1pi = GetNuMuOnePionProb( iPi, ene 292 G4double p1pi = GetNuMuOnePionProb( iPi, energy); 291 293 292 if( p1pi > G4UniformRand() && fCosTheta > 0 294 if( p1pi > G4UniformRand() && fCosTheta > 0.9 ) // && fQtransfer < 0.95*GeV ) // mu- & coherent pion + nucleus 293 { 295 { 294 // lvsum = lvp1 + lvpip1; 296 // lvsum = lvp1 + lvpip1; 295 lvsum = lvp1 + lvt1; 297 lvsum = lvp1 + lvt1; 296 // cost = fCosThetaPi; 298 // cost = fCosThetaPi; 297 cost = fCosTheta; 299 cost = fCosTheta; 298 sint = std::sqrt( (1.0 - cost)*(1.0 + cost 300 sint = std::sqrt( (1.0 - cost)*(1.0 + cost) ); 299 phi = G4UniformRand()*CLHEP::twopi; 301 phi = G4UniformRand()*CLHEP::twopi; 300 eP = G4ThreeVector( sint*std::cos(phi), 302 eP = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost ); 301 303 302 // muMom = sqrt(fEmuPi*fEmuPi-fMel*fMel); 304 // muMom = sqrt(fEmuPi*fEmuPi-fMel*fMel); 303 muMom = sqrt(fEmu*fEmu-fMel*fMel); 305 muMom = sqrt(fEmu*fEmu-fMel*fMel); 304 306 305 eP *= muMom; 307 eP *= muMom; 306 308 307 // lv2 = G4LorentzVector( eP, fEmuPi ); 309 // lv2 = G4LorentzVector( eP, fEmuPi ); 308 // lv2 = G4LorentzVector( eP, fEmu ); 310 // lv2 = G4LorentzVector( eP, fEmu ); 309 lv2 = fLVl; 311 lv2 = fLVl; 310 312 311 // lvX = lvsum - lv2; 313 // lvX = lvsum - lv2; 312 lvX = fLVh; 314 lvX = fLVh; 313 massX2 = lvX.m2(); 315 massX2 = lvX.m2(); 314 massX = lvX.m(); 316 massX = lvX.m(); 315 massR = fLVt.m(); 317 massR = fLVt.m(); 316 318 317 if ( massX2 <= 0. ) // vmg: very rarely ~ 319 if ( massX2 <= 0. ) // vmg: very rarely ~ (1-4)e-6 due to big Q2/x, to be improved 318 { 320 { 319 fCascade = true; 321 fCascade = true; 320 theParticleChange.SetEnergyChange(energy 322 theParticleChange.SetEnergyChange(energy); 321 theParticleChange.SetMomentumChange(aTra 323 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 322 return &theParticleChange; 324 return &theParticleChange; 323 } 325 } 324 fW2 = massX2; 326 fW2 = massX2; 325 327 326 if( pName == "nu_e" ) aLept = new 328 if( pName == "nu_e" ) aLept = new G4DynamicParticle( theElectron, lv2 ); 327 else 329 else 328 { 330 { 329 theParticleChange.SetEnergyChange(energy 331 theParticleChange.SetEnergyChange(energy); 330 theParticleChange.SetMomentumChange(aTra 332 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 331 return &theParticleChange; 333 return &theParticleChange; 332 } 334 } 333 if( pName == "nu_e" ) pdgP = 211; 335 if( pName == "nu_e" ) pdgP = 211; 334 // else pdgP = -211; 336 // else pdgP = -211; 335 // eCut = fMpi + 0.5*(fMpi*fMpi-massX2)/mT 337 // eCut = fMpi + 0.5*(fMpi*fMpi-massX2)/mTarg; // massX -> fMpi 336 338 337 if( A > 1 ) 339 if( A > 1 ) 338 { 340 { 339 eCut = (fMpi + mTarg)*(fMpi + mTarg) - ( 341 eCut = (fMpi + mTarg)*(fMpi + mTarg) - (massX + massR)*(massX + massR); 340 eCut /= 2.*massR; 342 eCut /= 2.*massR; 341 eCut += massX; 343 eCut += massX; 342 } 344 } 343 else eCut = fM1 + fMpi; 345 else eCut = fM1 + fMpi; 344 346 345 if ( lvX.e() > eCut ) // && sqrt( GetW2() 347 if ( lvX.e() > eCut ) // && sqrt( GetW2() ) < 1.4*GeV ) // 346 { 348 { 347 CoherentPion( lvX, pdgP, targetNucleus); 349 CoherentPion( lvX, pdgP, targetNucleus); 348 } 350 } 349 else 351 else 350 { 352 { 351 fCascade = true; 353 fCascade = true; 352 theParticleChange.SetEnergyChange(energy 354 theParticleChange.SetEnergyChange(energy); 353 theParticleChange.SetMomentumChange(aTra 355 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 354 return &theParticleChange; 356 return &theParticleChange; 355 } 357 } 356 theParticleChange.AddSecondary( aLept, fSe << 358 theParticleChange.AddSecondary( aLept ); 357 359 358 return &theParticleChange; 360 return &theParticleChange; 359 } 361 } 360 else // lepton part in lab 362 else // lepton part in lab 361 { 363 { 362 lvsum = lvp1 + lvt1; 364 lvsum = lvp1 + lvt1; 363 cost = fCosTheta; 365 cost = fCosTheta; 364 sint = std::sqrt( (1.0 - cost)*(1.0 + cost 366 sint = std::sqrt( (1.0 - cost)*(1.0 + cost) ); 365 phi = G4UniformRand()*CLHEP::twopi; 367 phi = G4UniformRand()*CLHEP::twopi; 366 eP = G4ThreeVector( sint*std::cos(phi), 368 eP = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost ); 367 369 368 muMom = sqrt(fEmu*fEmu-fMel*fMel); 370 muMom = sqrt(fEmu*fEmu-fMel*fMel); 369 371 370 eP *= muMom; 372 eP *= muMom; 371 373 372 lv2 = G4LorentzVector( eP, fEmu ); 374 lv2 = G4LorentzVector( eP, fEmu ); 373 lv2 = fLVl; 375 lv2 = fLVl; 374 lvX = lvsum - lv2; 376 lvX = lvsum - lv2; 375 lvX = fLVh; 377 lvX = fLVh; 376 massX2 = lvX.m2(); 378 massX2 = lvX.m2(); 377 379 378 if ( massX2 <= 0. ) // vmg: very rarely ~ 380 if ( massX2 <= 0. ) // vmg: very rarely ~ (1-4)e-6 due to big Q2/x, to be improved 379 { 381 { 380 fCascade = true; 382 fCascade = true; 381 theParticleChange.SetEnergyChange(energy 383 theParticleChange.SetEnergyChange(energy); 382 theParticleChange.SetMomentumChange(aTra 384 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 383 return &theParticleChange; 385 return &theParticleChange; 384 } 386 } 385 fW2 = massX2; 387 fW2 = massX2; 386 388 387 if( pName == "nu_e" ) aLept = new 389 if( pName == "nu_e" ) aLept = new G4DynamicParticle( theElectron, lv2 ); 388 else 390 else 389 { 391 { 390 theParticleChange.SetEnergyChange(energy 392 theParticleChange.SetEnergyChange(energy); 391 theParticleChange.SetMomentumChange(aTra 393 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 392 return &theParticleChange; 394 return &theParticleChange; 393 } 395 } 394 theParticleChange.AddSecondary( aLept, fSe << 396 theParticleChange.AddSecondary( aLept ); 395 } 397 } 396 398 397 // hadron part 399 // hadron part 398 400 399 fRecoil = nullptr; 401 fRecoil = nullptr; 400 402 401 if( A == 1 ) 403 if( A == 1 ) 402 { 404 { 403 if( pName == "nu_e" ) qB = 2; 405 if( pName == "nu_e" ) qB = 2; 404 // else qB = 0; 406 // else qB = 0; 405 407 406 // if( G4UniformRand() > 0.1 ) // > 0.999 408 // if( G4UniformRand() > 0.1 ) // > 0.9999 ) // > 0.0001 ) // 407 { 409 { 408 ClusterDecay( lvX, qB ); 410 ClusterDecay( lvX, qB ); 409 } 411 } 410 return &theParticleChange; 412 return &theParticleChange; 411 } 413 } 412 /* 414 /* 413 // else 415 // else 414 { 416 { 415 if( pName == "nu_mu" ) pdgP = 211; 417 if( pName == "nu_mu" ) pdgP = 211; 416 else pdgP = -211; 418 else pdgP = -211; 417 419 418 420 419 if ( fQtransfer < 0.95*GeV ) // < 0.35*G 421 if ( fQtransfer < 0.95*GeV ) // < 0.35*GeV ) // 420 { 422 { 421 if( lvX.m() > mSum ) CoherentPion( lvX, pdgP 423 if( lvX.m() > mSum ) CoherentPion( lvX, pdgP, targetNucleus); 422 } 424 } 423 } 425 } 424 return &theParticleChange; 426 return &theParticleChange; 425 } 427 } 426 */ 428 */ 427 G4Nucleus recoil; 429 G4Nucleus recoil; 428 G4double rM(0.), ratio = G4double(Z)/G4doubl 430 G4double rM(0.), ratio = G4double(Z)/G4double(A); 429 431 430 if( ratio > G4UniformRand() ) // proton is e 432 if( ratio > G4UniformRand() ) // proton is excited 431 { 433 { 432 fProton = true; 434 fProton = true; 433 recoil = G4Nucleus(A-1,Z-1); 435 recoil = G4Nucleus(A-1,Z-1); 434 fRecoil = &recoil; 436 fRecoil = &recoil; 435 rM = recoil.AtomicMass(A-1,Z-1); 437 rM = recoil.AtomicMass(A-1,Z-1); 436 438 437 if( pName == "nu_e" ) // (++) state -> p + 439 if( pName == "nu_e" ) // (++) state -> p + pi+ 438 { 440 { 439 fMt = G4ParticleTable::GetParticleTable( 441 fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass() 440 + G4ParticleTable::GetParticleTable( 442 + G4ParticleTable::GetParticleTable()->FindParticle(211)->GetPDGMass(); 441 } 443 } 442 else // (0) state -> p + pi-, n + pi0 444 else // (0) state -> p + pi-, n + pi0 443 { 445 { 444 // fMt = G4ParticleTable::GetParticleTab 446 // fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass() 445 // + G4ParticleTable::GetParticleTab 447 // + G4ParticleTable::GetParticleTable()->FindParticle(-211)->GetPDGMass(); 446 } 448 } 447 } 449 } 448 else // excited neutron 450 else // excited neutron 449 { 451 { 450 fProton = false; 452 fProton = false; 451 recoil = G4Nucleus(A-1,Z); 453 recoil = G4Nucleus(A-1,Z); 452 fRecoil = &recoil; 454 fRecoil = &recoil; 453 rM = recoil.AtomicMass(A-1,Z); 455 rM = recoil.AtomicMass(A-1,Z); 454 456 455 if( pName == "nu_e" ) // (+) state -> n + 457 if( pName == "nu_e" ) // (+) state -> n + pi+ 456 { 458 { 457 fMt = G4ParticleTable::GetParticleTable( 459 fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass() 458 + G4ParticleTable::GetParticleTable( 460 + G4ParticleTable::GetParticleTable()->FindParticle(211)->GetPDGMass(); 459 } 461 } 460 else // (-) state -> n + pi-, // n + pi0 462 else // (-) state -> n + pi-, // n + pi0 461 { 463 { 462 // fMt = G4ParticleTable::GetParticleTab 464 // fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass() 463 // + G4ParticleTable::GetParticleTab 465 // + G4ParticleTable::GetParticleTable()->FindParticle(-211)->GetPDGMass(); 464 } 466 } 465 } 467 } 466 // G4int index = GetEnergyIndex(energy << 468 G4int index = GetEnergyIndex(energy); 467 G4int nepdg = aParticle->GetDefinition()->Ge << 469 G4double qeTotRat = GetNuMuQeTotRat(index, energy); 468 << 469 G4double qeTotRat; // = GetNuMuQeTotRat(ind << 470 qeTotRat = CalculateQEratioA( Z, A, energy, << 471 470 472 G4ThreeVector dX = (lvX.vect()).unit(); 471 G4ThreeVector dX = (lvX.vect()).unit(); 473 G4double eX = lvX.e(); // excited nucleon 472 G4double eX = lvX.e(); // excited nucleon 474 G4double mX = sqrt(massX2); 473 G4double mX = sqrt(massX2); 475 // G4double pX = sqrt( eX*eX - mX*mX ); 474 // G4double pX = sqrt( eX*eX - mX*mX ); 476 // G4double sumE = eX + rM; 475 // G4double sumE = eX + rM; 477 476 478 if( qeTotRat > G4UniformRand() || mX <= fMt 477 if( qeTotRat > G4UniformRand() || mX <= fMt ) // || eX <= 1232.*MeV) // QE 479 { 478 { 480 fString = false; 479 fString = false; 481 480 482 if( fProton ) 481 if( fProton ) 483 { 482 { 484 fPDGencoding = 2212; 483 fPDGencoding = 2212; 485 fMr = proton_mass_c2; 484 fMr = proton_mass_c2; 486 recoil = G4Nucleus(A-1,Z-1); 485 recoil = G4Nucleus(A-1,Z-1); 487 fRecoil = &recoil; 486 fRecoil = &recoil; 488 rM = recoil.AtomicMass(A-1,Z-1); 487 rM = recoil.AtomicMass(A-1,Z-1); 489 } 488 } 490 else 489 else 491 { 490 { 492 fPDGencoding = 2112; 491 fPDGencoding = 2112; 493 fMr = G4ParticleTable::GetParticleTabl 492 fMr = G4ParticleTable::GetParticleTable()-> 494 FindParticle(fPDGencoding)->GetPDGMass(); // 493 FindParticle(fPDGencoding)->GetPDGMass(); // 939.5654133*MeV; 495 recoil = G4Nucleus(A-1,Z); 494 recoil = G4Nucleus(A-1,Z); 496 fRecoil = &recoil; 495 fRecoil = &recoil; 497 rM = recoil.AtomicMass(A-1,Z); 496 rM = recoil.AtomicMass(A-1,Z); 498 } 497 } 499 // sumE = eX + rM; 498 // sumE = eX + rM; 500 G4double eTh = fMr + 0.5*(fMr*fMr - mX*mX) 499 G4double eTh = fMr + 0.5*(fMr*fMr - mX*mX)/rM; 501 500 502 if( eX <= eTh ) // vmg, very rarely out of 501 if( eX <= eTh ) // vmg, very rarely out of kinematics 503 { 502 { 504 fString = true; 503 fString = true; 505 theParticleChange.SetEnergyChange(energy 504 theParticleChange.SetEnergyChange(energy); 506 theParticleChange.SetMomentumChange(aTra 505 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 507 return &theParticleChange; 506 return &theParticleChange; 508 } 507 } 509 // FinalBarion( fLVh, 0, fPDGencoding ); / 508 // FinalBarion( fLVh, 0, fPDGencoding ); // p(n)+deexcited recoil 510 FinalBarion( lvX, 0, fPDGencoding ); // p( 509 FinalBarion( lvX, 0, fPDGencoding ); // p(n)+deexcited recoil 511 } 510 } 512 else // if ( eX < 9500000.*GeV ) // < 25.*G 511 else // if ( eX < 9500000.*GeV ) // < 25.*GeV) // < 95.*GeV ) // < 2.5*GeV ) //cluster decay 513 { 512 { 514 if ( fProton && pName == "nu_e" ) 513 if ( fProton && pName == "nu_e" ) qB = 2; 515 else if( !fProton && pName == "nu_e" ) 514 else if( !fProton && pName == "nu_e" ) qB = 1; 516 515 517 ClusterDecay( lvX, qB ); 516 ClusterDecay( lvX, qB ); 518 } 517 } 519 return &theParticleChange; 518 return &theParticleChange; 520 } 519 } 521 520 522 521 523 ////////////////////////////////////////////// 522 ///////////////////////////////////////////////////////////////////// 524 ////////////////////////////////////////////// 523 //////////////////////////////////////////////////////////////////// 525 ////////////////////////////////////////////// 524 /////////////////////////////////////////////////////////////////// 526 525 527 ////////////////////////////////////////////// 526 ///////////////////////////////////////////////// 528 // 527 // 529 // sample x, then Q2 528 // sample x, then Q2 530 529 531 void G4NuElNucleusCcModel::SampleLVkr(const G4 530 void G4NuElNucleusCcModel::SampleLVkr(const G4HadProjectile & aTrack, G4Nucleus& targetNucleus) 532 { 531 { 533 fBreak = false; 532 fBreak = false; 534 G4int A = targetNucleus.GetA_asInt(), iTer(0 533 G4int A = targetNucleus.GetA_asInt(), iTer(0), iTerMax(100); 535 G4int Z = targetNucleus.GetZ_asInt(); 534 G4int Z = targetNucleus.GetZ_asInt(); 536 G4double e3(0.), pMu2(0.), pX2(0.), nMom(0.) 535 G4double e3(0.), pMu2(0.), pX2(0.), nMom(0.), rM(0.), hM(0.), tM = targetNucleus.AtomicMass(A,Z); 537 G4double Ex(0.), ei(0.), nm2(0.); 536 G4double Ex(0.), ei(0.), nm2(0.); 538 G4double cost(1.), sint(0.), phi(0.), muMom( 537 G4double cost(1.), sint(0.), phi(0.), muMom(0.); 539 G4ThreeVector eP, bst; 538 G4ThreeVector eP, bst; 540 const G4HadProjectile* aParticle = &aTrack; 539 const G4HadProjectile* aParticle = &aTrack; 541 G4LorentzVector lvp1 = aParticle->Get4Moment 540 G4LorentzVector lvp1 = aParticle->Get4Momentum(); 542 541 543 if( A == 1 ) // hydrogen, no Fermi motion ?? 542 if( A == 1 ) // hydrogen, no Fermi motion ??? 544 { 543 { 545 fNuEnergy = aParticle->GetTotalEnergy(); 544 fNuEnergy = aParticle->GetTotalEnergy(); 546 iTer = 0; 545 iTer = 0; 547 546 548 do 547 do 549 { 548 { 550 fXsample = SampleXkr(fNuEnergy); 549 fXsample = SampleXkr(fNuEnergy); 551 fQtransfer = SampleQkr(fNuEnergy, fXsamp 550 fQtransfer = SampleQkr(fNuEnergy, fXsample); 552 fQ2 = fQtransfer*fQtransfer; 551 fQ2 = fQtransfer*fQtransfer; 553 552 554 if( fXsample > 0. ) 553 if( fXsample > 0. ) 555 { 554 { 556 fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; // 555 fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; // sample excited hadron mass 557 fEmu = fNuEnergy - fQ2/2./fM1/fXsample 556 fEmu = fNuEnergy - fQ2/2./fM1/fXsample; 558 } 557 } 559 else 558 else 560 { 559 { 561 fW2 = fM1*fM1; 560 fW2 = fM1*fM1; 562 fEmu = fNuEnergy; 561 fEmu = fNuEnergy; 563 } 562 } 564 e3 = fNuEnergy + fM1 - fEmu; 563 e3 = fNuEnergy + fM1 - fEmu; 565 564 566 if( e3 < sqrt(fW2) ) G4cout<<"energyX = 565 if( e3 < sqrt(fW2) ) G4cout<<"energyX = "<<e3/GeV<<", fW = "<<sqrt(fW2)/GeV<<G4endl; 567 566 568 pMu2 = fEmu*fEmu - fMel*fMel; 567 pMu2 = fEmu*fEmu - fMel*fMel; 569 568 570 if(pMu2 < 0.) { fBreak = true; return; } 569 if(pMu2 < 0.) { fBreak = true; return; } 571 570 572 pX2 = e3*e3 - fW2; 571 pX2 = e3*e3 - fW2; 573 572 574 fCosTheta = fNuEnergy*fNuEnergy + pMu2 573 fCosTheta = fNuEnergy*fNuEnergy + pMu2 - pX2; 575 fCosTheta /= 2.*fNuEnergy*sqrt(pMu2); 574 fCosTheta /= 2.*fNuEnergy*sqrt(pMu2); 576 iTer++; 575 iTer++; 577 } 576 } 578 while( ( abs(fCosTheta) > 1. || fEmu < fMe 577 while( ( abs(fCosTheta) > 1. || fEmu < fMel ) && iTer < iTerMax ); 579 578 580 if( iTer >= iTerMax ) { fBreak = true; ret 579 if( iTer >= iTerMax ) { fBreak = true; return; } 581 580 582 if( abs(fCosTheta) > 1.) // vmg: due to bi 581 if( abs(fCosTheta) > 1.) // vmg: due to big Q2/x values. To be improved ... 583 { 582 { 584 G4cout<<"H2: fCosTheta = "<<fCosTheta<<" 583 G4cout<<"H2: fCosTheta = "<<fCosTheta<<", fEmu = "<<fEmu<<G4endl; 585 // fCosTheta = -1. + 2.*G4UniformRand(); 584 // fCosTheta = -1. + 2.*G4UniformRand(); 586 if(fCosTheta < -1.) fCosTheta = -1.; 585 if(fCosTheta < -1.) fCosTheta = -1.; 587 if(fCosTheta > 1.) fCosTheta = 1.; 586 if(fCosTheta > 1.) fCosTheta = 1.; 588 } 587 } 589 // LVs 588 // LVs 590 589 591 G4LorentzVector lvt1 = G4LorentzVector( 0 590 G4LorentzVector lvt1 = G4LorentzVector( 0., 0., 0., fM1 ); 592 G4LorentzVector lvsum = lvp1 + lvt1; 591 G4LorentzVector lvsum = lvp1 + lvt1; 593 592 594 cost = fCosTheta; 593 cost = fCosTheta; 595 sint = std::sqrt( (1.0 - cost)*(1.0 + cost 594 sint = std::sqrt( (1.0 - cost)*(1.0 + cost) ); 596 phi = G4UniformRand()*CLHEP::twopi; 595 phi = G4UniformRand()*CLHEP::twopi; 597 eP = G4ThreeVector( sint*std::cos(phi), 596 eP = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost ); 598 muMom = sqrt(fEmu*fEmu-fMel*fMel); 597 muMom = sqrt(fEmu*fEmu-fMel*fMel); 599 eP *= muMom; 598 eP *= muMom; 600 fLVl = G4LorentzVector( eP, fEmu ); 599 fLVl = G4LorentzVector( eP, fEmu ); 601 600 602 fLVh = lvsum - fLVl; 601 fLVh = lvsum - fLVl; 603 fLVt = G4LorentzVector( 0., 0., 0., 0. ); 602 fLVt = G4LorentzVector( 0., 0., 0., 0. ); // no recoil 604 } 603 } 605 else // Fermi motion, Q2 in nucleon rest fra 604 else // Fermi motion, Q2 in nucleon rest frame 606 { 605 { 607 G4Nucleus recoil1( A-1, Z ); 606 G4Nucleus recoil1( A-1, Z ); 608 rM = recoil1.AtomicMass(A-1,Z); 607 rM = recoil1.AtomicMass(A-1,Z); 609 do 608 do 610 { 609 { 611 // nMom = NucleonMomentumBR( targetNucle 610 // nMom = NucleonMomentumBR( targetNucleus ); // BR 612 nMom = GgSampleNM( targetNucleus ); // G 611 nMom = GgSampleNM( targetNucleus ); // Gg 613 Ex = GetEx(A-1, fProton); 612 Ex = GetEx(A-1, fProton); 614 ei = tM - sqrt( (rM + Ex)*(rM + Ex) + nM 613 ei = tM - sqrt( (rM + Ex)*(rM + Ex) + nMom*nMom ); 615 // ei = 0.5*( tM - s2M - 2*eX ); 614 // ei = 0.5*( tM - s2M - 2*eX ); 616 615 617 nm2 = ei*ei - nMom*nMom; 616 nm2 = ei*ei - nMom*nMom; 618 iTer++; 617 iTer++; 619 } 618 } 620 while( nm2 < 0. && iTer < iTerMax ); 619 while( nm2 < 0. && iTer < iTerMax ); 621 620 622 if( iTer >= iTerMax ) { fBreak = true; ret 621 if( iTer >= iTerMax ) { fBreak = true; return; } 623 622 624 G4ThreeVector nMomDir = nMom*G4RandomDirec 623 G4ThreeVector nMomDir = nMom*G4RandomDirection(); 625 624 626 if( !f2p2h || A < 3 ) // 1p1h 625 if( !f2p2h || A < 3 ) // 1p1h 627 { 626 { 628 // hM = tM - rM; 627 // hM = tM - rM; 629 628 630 fLVt = G4LorentzVector( -nMomDir, sqrt( 629 fLVt = G4LorentzVector( -nMomDir, sqrt( (rM + Ex)*(rM + Ex) + nMom*nMom ) ); // rM ); // 631 fLVh = G4LorentzVector( nMomDir, ei ); 630 fLVh = G4LorentzVector( nMomDir, ei ); // hM); // 632 } 631 } 633 else // 2p2h 632 else // 2p2h 634 { 633 { 635 G4Nucleus recoil(A-2,Z-1); 634 G4Nucleus recoil(A-2,Z-1); 636 rM = recoil.AtomicMass(A-2,Z-1)+sqrt(nMo 635 rM = recoil.AtomicMass(A-2,Z-1)+sqrt(nMom*nMom+fM1*fM1); 637 hM = tM - rM; 636 hM = tM - rM; 638 637 639 fLVt = G4LorentzVector( nMomDir, sqrt( r 638 fLVt = G4LorentzVector( nMomDir, sqrt( rM*rM+nMom*nMom ) ); 640 fLVh = G4LorentzVector(-nMomDir, sqrt( h 639 fLVh = G4LorentzVector(-nMomDir, sqrt( hM*hM+nMom*nMom ) ); 641 } 640 } 642 // G4cout<<hM<<", "; 641 // G4cout<<hM<<", "; 643 // bst = fLVh.boostVector(); 642 // bst = fLVh.boostVector(); 644 643 645 // lvp1.boost(-bst); // -> nucleon rest sy 644 // lvp1.boost(-bst); // -> nucleon rest system, where Q2 transfer is ??? 646 645 647 fNuEnergy = lvp1.e(); 646 fNuEnergy = lvp1.e(); 648 // G4double mN = fLVh.m(); // better mN = 647 // G4double mN = fLVh.m(); // better mN = fM1 !? vmg 649 iTer = 0; 648 iTer = 0; 650 649 651 do // no FM!?, 5.4.20 vmg 650 do // no FM!?, 5.4.20 vmg 652 { 651 { 653 fXsample = SampleXkr(fNuEnergy); 652 fXsample = SampleXkr(fNuEnergy); 654 fQtransfer = SampleQkr(fNuEnergy, fXsamp 653 fQtransfer = SampleQkr(fNuEnergy, fXsample); 655 fQ2 = fQtransfer*fQtransfer; 654 fQ2 = fQtransfer*fQtransfer; 656 655 657 // G4double mR = mN + fM1*(A-1.)*std::ex 656 // G4double mR = mN + fM1*(A-1.)*std::exp(-2.0*fQtransfer/mN); // recoil mass in+el 658 657 659 if( fXsample > 0. ) 658 if( fXsample > 0. ) 660 { 659 { 661 fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; // 660 fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; // sample excited hadron mass 662 661 663 // fW2 = mN*mN - fQ2 + fQ2/fXsample; / 662 // fW2 = mN*mN - fQ2 + fQ2/fXsample; // sample excited hadron mass 664 // fEmu = fNuEnergy - fQ2/2./mR/fXsamp 663 // fEmu = fNuEnergy - fQ2/2./mR/fXsample; // fM1->mN 665 664 666 fEmu = fNuEnergy - fQ2/2./fM1/fXsample 665 fEmu = fNuEnergy - fQ2/2./fM1/fXsample; // fM1->mN 667 } 666 } 668 else 667 else 669 { 668 { 670 // fW2 = mN*mN; 669 // fW2 = mN*mN; 671 670 672 fW2 = fM1*fM1; 671 fW2 = fM1*fM1; 673 fEmu = fNuEnergy; 672 fEmu = fNuEnergy; 674 } 673 } 675 // if(fEmu < 0.) G4cout<<"fEmu = "<<fEmu 674 // if(fEmu < 0.) G4cout<<"fEmu = "<<fEmu<<" hM = "<<hM<<G4endl; 676 // e3 = fNuEnergy + mR - fEmu; 675 // e3 = fNuEnergy + mR - fEmu; 677 676 678 e3 = fNuEnergy + fM1 - fEmu; 677 e3 = fNuEnergy + fM1 - fEmu; 679 678 680 // if( e3 < sqrt(fW2) ) G4cout<<"energy 679 // if( e3 < sqrt(fW2) ) G4cout<<"energyX = "<<e3/GeV<<", fW = "<<sqrt(fW2)/GeV<<G4endl; 681 680 682 pMu2 = fEmu*fEmu - fMel*fMel; 681 pMu2 = fEmu*fEmu - fMel*fMel; 683 pX2 = e3*e3 - fW2; 682 pX2 = e3*e3 - fW2; 684 683 685 if(pMu2 < 0.) { fBreak = true; return; } 684 if(pMu2 < 0.) { fBreak = true; return; } 686 685 687 fCosTheta = fNuEnergy*fNuEnergy + pMu2 686 fCosTheta = fNuEnergy*fNuEnergy + pMu2 - pX2; 688 fCosTheta /= 2.*fNuEnergy*sqrt(pMu2); 687 fCosTheta /= 2.*fNuEnergy*sqrt(pMu2); 689 iTer++; 688 iTer++; 690 } 689 } 691 while( ( abs(fCosTheta) > 1. || fEmu < fMe 690 while( ( abs(fCosTheta) > 1. || fEmu < fMel ) && iTer < iTerMax ); 692 691 693 if( iTer >= iTerMax ) { fBreak = true; ret 692 if( iTer >= iTerMax ) { fBreak = true; return; } 694 693 695 if( abs(fCosTheta) > 1.) // vmg: due to bi 694 if( abs(fCosTheta) > 1.) // vmg: due to big Q2/x values. To be improved ... 696 { 695 { 697 G4cout<<"FM: fCosTheta = "<<fCosTheta<<" 696 G4cout<<"FM: fCosTheta = "<<fCosTheta<<", fEmu = "<<fEmu<<G4endl; 698 // fCosTheta = -1. + 2.*G4UniformRand(); 697 // fCosTheta = -1. + 2.*G4UniformRand(); 699 if( fCosTheta < -1.) fCosTheta = -1.; 698 if( fCosTheta < -1.) fCosTheta = -1.; 700 if( fCosTheta > 1.) fCosTheta = 1.; 699 if( fCosTheta > 1.) fCosTheta = 1.; 701 } 700 } 702 // LVs 701 // LVs 703 // G4LorentzVector lvt1 = G4LorentzVector 702 // G4LorentzVector lvt1 = G4LorentzVector( 0., 0., 0., mN ); // fM1 ); 704 703 705 G4LorentzVector lvt1 = G4LorentzVector( 0 704 G4LorentzVector lvt1 = G4LorentzVector( 0., 0., 0., fM1 ); // fM1 ); 706 G4LorentzVector lvsum = lvp1 + lvt1; 705 G4LorentzVector lvsum = lvp1 + lvt1; 707 706 708 cost = fCosTheta; 707 cost = fCosTheta; 709 sint = std::sqrt( (1.0 - cost)*(1.0 + cost 708 sint = std::sqrt( (1.0 - cost)*(1.0 + cost) ); 710 phi = G4UniformRand()*CLHEP::twopi; 709 phi = G4UniformRand()*CLHEP::twopi; 711 eP = G4ThreeVector( sint*std::cos(phi), 710 eP = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost ); 712 muMom = sqrt(fEmu*fEmu-fMel*fMel); 711 muMom = sqrt(fEmu*fEmu-fMel*fMel); 713 eP *= muMom; 712 eP *= muMom; 714 fLVl = G4LorentzVector( eP, fEmu ); 713 fLVl = G4LorentzVector( eP, fEmu ); 715 fLVh = lvsum - fLVl; 714 fLVh = lvsum - fLVl; 716 715 717 // if( fLVh.e() < mN || fLVh.m2() < 0.) { 716 // if( fLVh.e() < mN || fLVh.m2() < 0.) { fBreak = true; return; } 718 717 719 if( fLVh.e() < fM1 || fLVh.m2() < 0.) { fB 718 if( fLVh.e() < fM1 || fLVh.m2() < 0.) { fBreak = true; return; } 720 719 721 // back to lab system 720 // back to lab system 722 721 723 // fLVl.boost(bst); 722 // fLVl.boost(bst); 724 // fLVh.boost(bst); 723 // fLVh.boost(bst); 725 } 724 } 726 //G4cout<<iTer<<", "<<fBreak<<"; "; 725 //G4cout<<iTer<<", "<<fBreak<<"; "; 727 } 726 } 728 727 729 // 728 // 730 // 729 // 731 /////////////////////////// 730 /////////////////////////// 732 731