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