// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // $Id: G4NeutrinoElectronCcModel.cc 91806 2015-08-06 12:20:45Z gcosmo $ // // Geant4 Header : G4NeutrinoElectronCcModel // // Author : V.Grichine 26.4.17 // #include "G4NeutrinoElectronCcModel.hh" #include "G4SystemOfUnits.hh" #include "G4ParticleTable.hh" #include "G4ParticleDefinition.hh" #include "G4IonTable.hh" #include "Randomize.hh" #include "G4NeutrinoE.hh" #include "G4AntiNeutrinoE.hh" #include "G4MuonMinus.hh" #include "G4TauMinus.hh" using namespace std; using namespace CLHEP; G4NeutrinoElectronCcModel::G4NeutrinoElectronCcModel(const G4String& name) : G4HadronicInteraction(name) { SetMinEnergy( 0.0*GeV ); SetMaxEnergy( 100.*TeV ); SetMinEnergy(1.e-6*eV); theNeutrinoE = G4NeutrinoE::NeutrinoE(); theAntiNeutrinoE = G4AntiNeutrinoE::AntiNeutrinoE(); theMuonMinus = G4MuonMinus::MuonMinus(); theTauMinus = G4TauMinus::TauMinus(); // PDG2016: sin^2 theta Weinberg fSin2tW = 0.23129; // 0.2312; fCutEnergy = 0.; // default value } G4NeutrinoElectronCcModel::~G4NeutrinoElectronCcModel() {} void G4NeutrinoElectronCcModel::ModelDescription(std::ostream& outFile) const { outFile << "G4NeutrinoElectronCcModel is a neutrino-electron (neutral current) elastic scattering\n" << "model which uses the standard model \n" << "transfer parameterization. The model is fully relativistic\n"; } ///////////////////////////////////////////////////////// G4bool G4NeutrinoElectronCcModel::IsApplicable(const G4HadProjectile & aPart, G4Nucleus & targetNucleus) { G4bool result = false; G4String pName = aPart.GetDefinition()->GetParticleName(); G4double minEnergy = 0., energy = aPart.GetTotalEnergy(); G4double fmass, emass = electron_mass_c2; if( pName == "nu_mu" || pName == "anti_nu_mu" ) fmass = theMuonMinus->GetPDGMass(); else if( pName == "nu_tau" || pName == "anti_nu_tau" ) fmass = theTauMinus->GetPDGMass(); else fmass = emass; minEnergy = (fmass-emass)*(fmass+emass)/emass; SetMinEnergy( minEnergy ); if( ( pName == "nu_mu" || pName == "anti_nu_mu" || pName == "nu_tau" || pName == "anti_nu_tau" ) && energy > minEnergy ) { result = true; } G4int Z = targetNucleus.GetZ_asInt(); Z *= 1; return result; } //////////////////////////////////////////////// // // G4HadFinalState* G4NeutrinoElectronCcModel::ApplyYourself( const G4HadProjectile& aTrack, G4Nucleus& targetNucleus) { theParticleChange.Clear(); const G4HadProjectile* aParticle = &aTrack; G4double energy = aParticle->GetTotalEnergy(); G4String pName = aParticle->GetDefinition()->GetParticleName(); G4double minEnergy(0.), fmass(0.), emass = electron_mass_c2; if( pName == "nu_mu" || pName == "anti_nu_mu" ) fmass = theMuonMinus->GetPDGMass(); else if( pName == "nu_tau" || pName == "anti_nu_tau" ) fmass = theTauMinus->GetPDGMass(); else fmass = emass; minEnergy = (fmass-emass)*(fmass+emass)/emass; if( energy <= minEnergy ) { theParticleChange.SetEnergyChange(energy); theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); return &theParticleChange; } G4double massf(0.), massf2(0.); // , emass = electron_mass_c2; G4double sTot = 2.*energy*emass + emass*emass; G4LorentzVector lvp1 = aParticle->Get4Momentum(); G4LorentzVector lvt1(0.,0.,0.,electron_mass_c2); G4LorentzVector lvsum = lvp1+lvt1; G4ThreeVector bst = lvsum.boostVector(); // sample and make final state in CMS frame G4double cost = SampleCosCMS( aParticle ); G4double sint = std::sqrt( (1.0 - cost)*(1.0 + cost) ); G4double phi = G4UniformRand()*CLHEP::twopi; G4ThreeVector eP( sint*std::cos(phi), sint*std::sin(phi), cost ); if( pName == "nu_mu" || pName == "anti_nu_mu" ) massf = theMuonMinus->GetPDGMass(); else if( pName == "nu_tau" || pName == "anti_nu_tau") massf = theTauMinus->GetPDGMass(); massf2 = massf*massf; G4double epf = 0.5*(sTot - massf2)/sqrt(sTot); // G4double etf = epf*(sTot + massf2)/(sTot - massf2); eP *= epf; G4LorentzVector lvp2( eP, epf ); lvp2.boost(bst); // back to lab frame G4LorentzVector lvt2 = lvsum - lvp2; // ? G4DynamicParticle* aNu = nullptr; G4DynamicParticle* aLept = nullptr; if( pName == "nu_mu" || pName == "nu_tau") { aNu = new G4DynamicParticle( theNeutrinoE, lvp2 ); } else if( pName == "anti_nu_mu" || pName == "anti_nu_tau") { aNu = new G4DynamicParticle( theAntiNeutrinoE, lvp2 ); } if( pName == "nu_mu" || pName == "anti_nu_mu") { aLept = new G4DynamicParticle( theMuonMinus, lvt2 ); } else if( pName == "nu_tau" || pName == "anti_nu_tau") { aLept = new G4DynamicParticle( theTauMinus, lvt2 ); } if(aNu) { theParticleChange.AddSecondary( aNu ); } if(aLept) { theParticleChange.AddSecondary( aLept ); } G4int Z = targetNucleus.GetZ_asInt(); Z *= 1; return &theParticleChange; } ////////////////////////////////////////////////////// // // sample recoil electron energy in lab frame G4double G4NeutrinoElectronCcModel::SampleCosCMS(const G4HadProjectile* aParticle) { G4double result = 0., cofL, cofR, cofLR, massf2, sTot, emass = electron_mass_c2, emass2; G4double energy = aParticle->GetTotalEnergy(); if( energy == 0.) return result; // vmg: < th?? as in xsc G4String pName = aParticle->GetDefinition()->GetParticleName(); if( pName == "nu_mu" || pName == "nu_tau") { return 2.*G4UniformRand()-1.; // uniform scattering cos in CMS } else if( pName == "anti_nu_mu" || pName == "anti_nu_tau") { emass2 = emass*emass; sTot = 2.*energy*emass + emass2; cofL = (sTot-emass2)/(sTot+emass2); if(pName == "anti_nu_mu") massf2 = theMuonMinus->GetPDGMass()*theMuonMinus->GetPDGMass(); else massf2 = theTauMinus->GetPDGMass()*theTauMinus->GetPDGMass(); cofR = (sTot-massf2)/(sTot+massf2); cofLR = cofL*cofR/3.; // cofs of cos 3rd equation G4double a = cofLR; G4double b = 0.5*(cofR+cofL); G4double c = 1.; G4double d = -G4UniformRand()*2.*(1.+ cofLR); d += c - b + a; // G4cout<