Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/lepto_nuclear/src/G4NuMuNucleusNcModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/hadronic/models/lepto_nuclear/src/G4NuMuNucleusNcModel.cc (Version 11.3.0) and /processes/hadronic/models/lepto_nuclear/src/G4NuMuNucleusNcModel.cc (Version 10.6)


  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: G4NuMuNucleusNcModel.cc 91806 2015-08-     26 // $Id: G4NuMuNucleusNcModel.cc 91806 2015-08-06 12:20:45Z gcosmo $
 27 //                                                 27 //
 28 // Geant4 Header : G4NuMuNucleusNcModel            28 // Geant4 Header : G4NuMuNucleusNcModel
 29 //                                                 29 //
 30 // Author : V.Grichine 12.2.19                     30 // Author : V.Grichine 12.2.19
 31 //                                                 31 //  
 32                                                    32 
 33 #include "G4NuMuNucleusNcModel.hh"                 33 #include "G4NuMuNucleusNcModel.hh"
 34 #include "G4NeutrinoNucleusModel.hh"               34 #include "G4NeutrinoNucleusModel.hh" 
 35                                                    35 
 36 // #include "G4NuMuResQX.hh"                       36 // #include "G4NuMuResQX.hh" 
 37                                                    37 
 38 #include "G4SystemOfUnits.hh"                      38 #include "G4SystemOfUnits.hh"
 39 #include "G4ParticleTable.hh"                      39 #include "G4ParticleTable.hh"
 40 #include "G4ParticleDefinition.hh"                 40 #include "G4ParticleDefinition.hh"
 41 #include "G4IonTable.hh"                           41 #include "G4IonTable.hh"
 42 #include "Randomize.hh"                            42 #include "Randomize.hh"
 43 #include "G4RandomDirection.hh"                    43 #include "G4RandomDirection.hh"
 44                                                    44 
 45 // #include "G4Integrator.hh"                      45 // #include "G4Integrator.hh"
 46 #include "G4DataVector.hh"                         46 #include "G4DataVector.hh"
 47 #include "G4PhysicsTable.hh"                       47 #include "G4PhysicsTable.hh"
 48 #include "G4KineticTrack.hh"                       48 #include "G4KineticTrack.hh"
 49 #include "G4DecayKineticTracks.hh"                 49 #include "G4DecayKineticTracks.hh"
 50 #include "G4KineticTrackVector.hh"                 50 #include "G4KineticTrackVector.hh"
 51 #include "G4Fragment.hh"                           51 #include "G4Fragment.hh"
 52 #include "G4ReactionProductVector.hh"              52 #include "G4ReactionProductVector.hh"
 53                                                    53 
 54                                                    54 
 55 #include "G4NeutrinoMu.hh"                         55 #include "G4NeutrinoMu.hh"
 56 #include "G4AntiNeutrinoMu.hh"                     56 #include "G4AntiNeutrinoMu.hh"
 57 #include "G4Nucleus.hh"                            57 #include "G4Nucleus.hh"
 58 #include "G4LorentzVector.hh"                      58 #include "G4LorentzVector.hh"
 59                                                    59 
 60 using namespace std;                               60 using namespace std;
 61 using namespace CLHEP;                             61 using namespace CLHEP;
 62                                                    62 
                                                   >>  63 const G4int G4NuMuNucleusNcModel::fResNumber = 6;
                                                   >>  64 
                                                   >>  65 const G4double G4NuMuNucleusNcModel::fResMass[6] = // [fResNumber] = 
                                                   >>  66   {2190., 1920., 1700., 1600., 1440., 1232. };
                                                   >>  67 
                                                   >>  68 const G4int G4NuMuNucleusNcModel::fClustNumber = 4;
                                                   >>  69 
                                                   >>  70 const G4double G4NuMuNucleusNcModel::fMesMass[4] = {1260., 980., 770., 139.57};
                                                   >>  71 const G4int    G4NuMuNucleusNcModel::fMesPDG[4]  = {20213, 9000211, 213, 211};
                                                   >>  72 
                                                   >>  73 // const G4double G4NuMuNucleusNcModel::fBarMass[4] = {1905., 1600., 1232., 939.57};
                                                   >>  74 // const G4int    G4NuMuNucleusNcModel::fBarPDG[4]  = {2226, 32224, 2224, 2212};
                                                   >>  75 
                                                   >>  76 const G4double G4NuMuNucleusNcModel::fBarMass[4] = {1700., 1600., 1232., 939.57};
                                                   >>  77 const G4int    G4NuMuNucleusNcModel::fBarPDG[4]  = {12224, 32224, 2224, 2212};
                                                   >>  78 
                                                   >>  79 const G4double  G4NuMuNucleusNcModel::fNuMuEnergyLogVector[50] = {
                                                   >>  80 115.603, 133.424, 153.991, 177.729, 205.126, 236.746, 273.24, 315.361, 363.973, 420.08, 484.836, 559.573, 645.832, 
                                                   >>  81 745.387, 860.289, 992.903, 1145.96, 1322.61, 1526.49, 1761.8, 2033.38, 2346.83, 2708.59, 3126.12, 3608.02, 4164.19, 
                                                   >>  82 4806.1, 5546.97, 6402.04, 7388.91, 8527.92, 9842.5, 11359.7, 13110.8, 15131.9, 17464.5, 20156.6, 23263.8, 26849.9, 
                                                   >>  83 30988.8, 35765.7, 41279, 47642.2, 54986.3, 63462.4, 73245.2, 84536, 97567.2, 112607, 129966 };
                                                   >>  84 
                                                   >>  85 G4double G4NuMuNucleusNcModel::fNuMuXarrayKR[50][51] = {{1.0}};
                                                   >>  86 G4double G4NuMuNucleusNcModel::fNuMuXdistrKR[50][50] = {{1.0}};
                                                   >>  87 G4double G4NuMuNucleusNcModel::fNuMuQarrayKR[50][51][51] = {{{1.0}}};
                                                   >>  88 G4double G4NuMuNucleusNcModel::fNuMuQdistrKR[50][51][50] = {{{1.0}}};
                                                   >>  89 
 63 #ifdef G4MULTITHREADED                             90 #ifdef G4MULTITHREADED
 64     G4Mutex G4NuMuNucleusNcModel::numuNucleusM     91     G4Mutex G4NuMuNucleusNcModel::numuNucleusModel = G4MUTEX_INITIALIZER;
 65 #endif                                             92 #endif     
 66                                                    93 
 67                                                    94 
 68 G4NuMuNucleusNcModel::G4NuMuNucleusNcModel(con     95 G4NuMuNucleusNcModel::G4NuMuNucleusNcModel(const G4String& name) 
 69   : G4NeutrinoNucleusModel(name)                   96   : G4NeutrinoNucleusModel(name)
 70 {                                                  97 {
 71   SetMinEnergy( 0.0*GeV );                         98   SetMinEnergy( 0.0*GeV );
 72   SetMaxEnergy( 100.*TeV );                        99   SetMaxEnergy( 100.*TeV );
 73   SetMinEnergy(1.e-6*eV);                      << 100   SetMinEnergy(1.e-6*eV); 
 74                                                << 
 75   theNuMu =  G4NeutrinoMu::NeutrinoMu();       << 
 76   theANuMu =  G4AntiNeutrinoMu::AntiNeutrinoMu << 
 77                                                   101 
 78   fMnumu = 0.;                                    102   fMnumu = 0.; 
 79   fData = fMaster = false;                        103   fData = fMaster = false;
 80   InitialiseModel();                              104   InitialiseModel();  
 81                                                   105      
 82 }                                                 106 }
 83                                                   107 
 84                                                   108 
 85 G4NuMuNucleusNcModel::~G4NuMuNucleusNcModel()     109 G4NuMuNucleusNcModel::~G4NuMuNucleusNcModel()
 86 {}                                                110 {}
 87                                                   111 
 88                                                   112 
 89 void G4NuMuNucleusNcModel::ModelDescription(st    113 void G4NuMuNucleusNcModel::ModelDescription(std::ostream& outFile) const
 90 {                                                 114 {
 91                                                   115 
 92     outFile << "G4NuMuNucleusNcModel is a neut    116     outFile << "G4NuMuNucleusNcModel is a neutrino-nucleus (neutral current) scattering\n"
 93             << "model which uses the standard     117             << "model which uses the standard model \n"
 94             << "transfer parameterization.  Th    118             << "transfer parameterization.  The model is fully relativistic\n";
 95                                                   119 
 96 }                                                 120 }
 97                                                   121 
 98 //////////////////////////////////////////////    122 /////////////////////////////////////////////////////////
 99 //                                                123 //
100 // Read data from G4PARTICLEXSDATA (locally PA    124 // Read data from G4PARTICLEXSDATA (locally PARTICLEXSDATA)
101                                                   125 
102 void G4NuMuNucleusNcModel::InitialiseModel()      126 void G4NuMuNucleusNcModel::InitialiseModel()
103 {                                                 127 {
104   G4String pName  = "nu_mu";                      128   G4String pName  = "nu_mu";
105                                                   129   
106   G4int nSize(0), i(0), j(0), k(0);               130   G4int nSize(0), i(0), j(0), k(0);
107                                                   131 
108   if(!fData)                                      132   if(!fData)
109   {                                               133   { 
110 #ifdef G4MULTITHREADED                            134 #ifdef G4MULTITHREADED
111     G4MUTEXLOCK(&numuNucleusModel);               135     G4MUTEXLOCK(&numuNucleusModel);
112     if(!fData)                                    136     if(!fData)
113     {                                             137     { 
114 #endif                                            138 #endif     
115       fMaster = true;                             139       fMaster = true;
116 #ifdef G4MULTITHREADED                            140 #ifdef G4MULTITHREADED
117     }                                             141     }
118     G4MUTEXUNLOCK(&numuNucleusModel);             142     G4MUTEXUNLOCK(&numuNucleusModel);
119 #endif                                            143 #endif
120   }                                               144   }
121                                                   145 
122   if(fMaster)                                     146   if(fMaster)
123   {                                               147   {  
124     const char* path = G4FindDataDir("G4PARTIC << 148     char* path = getenv("G4PARTICLEXSDATA");
125     std::ostringstream ost1, ost2, ost3, ost4;    149     std::ostringstream ost1, ost2, ost3, ost4;
126     ost1 << path << "/" << "neutrino" << "/" <    150     ost1 << path << "/" << "neutrino" << "/" << pName << "/xarraynckr";
127                                                   151 
128     std::ifstream filein1( ost1.str().c_str()     152     std::ifstream filein1( ost1.str().c_str() );
129                                                   153 
130     // filein.open("$PARTICLEXSDATA/");           154     // filein.open("$PARTICLEXSDATA/");
131                                                   155 
132     filein1>>nSize;                               156     filein1>>nSize;
133                                                   157 
134     for( k = 0; k < fNbin; ++k )                  158     for( k = 0; k < fNbin; ++k )
135     {                                             159     {
136       for( i = 0; i <= fNbin; ++i )               160       for( i = 0; i <= fNbin; ++i )
137       {                                           161       {
138         filein1 >> fNuMuXarrayKR[k][i];           162         filein1 >> fNuMuXarrayKR[k][i];
139         // G4cout<< fNuMuXarrayKR[k][i] << "      163         // G4cout<< fNuMuXarrayKR[k][i] << "  ";
140       }                                           164       }
141     }                                             165     }
142     // G4cout<<G4endl<<G4endl;                    166     // G4cout<<G4endl<<G4endl;
143                                                   167 
144     ost2 << path << "/" << "neutrino" << "/" <    168     ost2 << path << "/" << "neutrino" << "/" << pName << "/xdistrnckr";
145     std::ifstream  filein2( ost2.str().c_str()    169     std::ifstream  filein2( ost2.str().c_str() );
146                                                   170 
147     filein2>>nSize;                               171     filein2>>nSize;
148                                                   172 
149     for( k = 0; k < fNbin; ++k )                  173     for( k = 0; k < fNbin; ++k )
150     {                                             174     {
151       for( i = 0; i < fNbin; ++i )                175       for( i = 0; i < fNbin; ++i )
152       {                                           176       {
153         filein2 >> fNuMuXdistrKR[k][i];           177         filein2 >> fNuMuXdistrKR[k][i];
154         // G4cout<< fNuMuXdistrKR[k][i] << "      178         // G4cout<< fNuMuXdistrKR[k][i] << "  ";
155       }                                           179       }
156     }                                             180     }
157     // G4cout<<G4endl<<G4endl;                    181     // G4cout<<G4endl<<G4endl;
158                                                   182 
159     ost3 << path << "/" << "neutrino" << "/" <    183     ost3 << path << "/" << "neutrino" << "/" << pName << "/q2arraynckr";
160     std::ifstream  filein3( ost3.str().c_str()    184     std::ifstream  filein3( ost3.str().c_str() );
161                                                   185 
162     filein3>>nSize;                               186     filein3>>nSize;
163                                                   187 
164     for( k = 0; k < fNbin; ++k )                  188     for( k = 0; k < fNbin; ++k )
165     {                                             189     {
166       for( i = 0; i <= fNbin; ++i )               190       for( i = 0; i <= fNbin; ++i )
167       {                                           191       {
168         for( j = 0; j <= fNbin; ++j )             192         for( j = 0; j <= fNbin; ++j )
169         {                                         193         {
170           filein3 >> fNuMuQarrayKR[k][i][j];      194           filein3 >> fNuMuQarrayKR[k][i][j];
171           // G4cout<< fNuMuQarrayKR[k][i][j] <    195           // G4cout<< fNuMuQarrayKR[k][i][j] << "  ";
172         }                                         196         }
173       }                                           197       }
174     }                                             198     }
175     // G4cout<<G4endl<<G4endl;                    199     // G4cout<<G4endl<<G4endl;
176                                                   200 
177     ost4 << path << "/" << "neutrino" << "/" <    201     ost4 << path << "/" << "neutrino" << "/" << pName << "/q2distrnckr";
178     std::ifstream  filein4( ost4.str().c_str()    202     std::ifstream  filein4( ost4.str().c_str() );
179                                                   203 
180     filein4>>nSize;                               204     filein4>>nSize;
181                                                   205 
182     for( k = 0; k < fNbin; ++k )                  206     for( k = 0; k < fNbin; ++k )
183     {                                             207     {
184       for( i = 0; i <= fNbin; ++i )               208       for( i = 0; i <= fNbin; ++i )
185       {                                           209       {
186         for( j = 0; j < fNbin; ++j )              210         for( j = 0; j < fNbin; ++j )
187         {                                         211         {
188           filein4 >> fNuMuQdistrKR[k][i][j];      212           filein4 >> fNuMuQdistrKR[k][i][j];
189           // G4cout<< fNuMuQdistrKR[k][i][j] <    213           // G4cout<< fNuMuQdistrKR[k][i][j] << "  ";
190         }                                         214         }
191       }                                           215       }
192     }                                             216     }
193     fData = true;                                 217     fData = true;
194   }                                               218   }
195 }                                                 219 }
196                                                   220 
197 //////////////////////////////////////////////    221 /////////////////////////////////////////////////////////
198                                                   222 
199 G4bool G4NuMuNucleusNcModel::IsApplicable(cons    223 G4bool G4NuMuNucleusNcModel::IsApplicable(const G4HadProjectile & aPart, 
200                   G4Nucleus & )                << 224                  G4Nucleus & targetNucleus)
201 {                                                 225 {
202   G4bool result  = false;                         226   G4bool result  = false;
203   G4String pName = aPart.GetDefinition()->GetP    227   G4String pName = aPart.GetDefinition()->GetParticleName();
204   G4double energy = aPart.GetTotalEnergy();       228   G4double energy = aPart.GetTotalEnergy();
205                                                   229   
206   if(  pName == "nu_mu" // || pName == "anti_n    230   if(  pName == "nu_mu" // || pName == "anti_nu_mu"   ) 
207         &&                                        231         &&
208         energy > fMinNuEnergy                     232         energy > fMinNuEnergy                                )
209   {                                               233   {
210     result = true;                                234     result = true;
211   }                                               235   }
                                                   >> 236   G4int Z = targetNucleus.GetZ_asInt();
                                                   >> 237         Z *= 1;
212                                                   238 
213   return result;                                  239   return result;
214 }                                                 240 }
215                                                   241 
216 /////////////////////////////////////////// Cl    242 /////////////////////////////////////////// ClusterDecay ////////////////////////////////////////////////////////////
217 //                                                243 //
218 //                                                244 //
219                                                   245 
220 G4HadFinalState* G4NuMuNucleusNcModel::ApplyYo    246 G4HadFinalState* G4NuMuNucleusNcModel::ApplyYourself(
221      const G4HadProjectile& aTrack, G4Nucleus&    247      const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
222 {                                                 248 {
223   theParticleChange.Clear();                      249   theParticleChange.Clear();
224   fProton = f2p2h = fBreak = false;               250   fProton = f2p2h = fBreak = false;
225   const G4HadProjectile* aParticle = &aTrack;     251   const G4HadProjectile* aParticle = &aTrack;
226   G4double energy = aParticle->GetTotalEnergy(    252   G4double energy = aParticle->GetTotalEnergy();
227                                                   253 
228   G4String pName  = aParticle->GetDefinition()    254   G4String pName  = aParticle->GetDefinition()->GetParticleName();
229                                                   255 
230   if( energy < fMinNuEnergy )                     256   if( energy < fMinNuEnergy ) 
231   {                                               257   {
232     theParticleChange.SetEnergyChange(energy);    258     theParticleChange.SetEnergyChange(energy);
233     theParticleChange.SetMomentumChange(aTrack    259     theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
234     return &theParticleChange;                    260     return &theParticleChange;
235   }                                               261   }
236   SampleLVkr( aTrack, targetNucleus);             262   SampleLVkr( aTrack, targetNucleus);
237                                                   263 
238   if( fBreak == true || fEmu < fMnumu ) // ~5*    264   if( fBreak == true || fEmu < fMnumu ) // ~5*10^-6
239   {                                               265   {
240     // G4cout<<"ni, ";                            266     // G4cout<<"ni, ";
241     theParticleChange.SetEnergyChange(energy);    267     theParticleChange.SetEnergyChange(energy);
242     theParticleChange.SetMomentumChange(aTrack    268     theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
243     return &theParticleChange;                    269     return &theParticleChange;
244   }                                               270   }
245                                                   271 
246   // LVs of initial state                         272   // LVs of initial state
247                                                   273 
248   G4LorentzVector lvp1 = aParticle->Get4Moment    274   G4LorentzVector lvp1 = aParticle->Get4Momentum();
249   G4LorentzVector lvt1( 0., 0., 0., fM1 );        275   G4LorentzVector lvt1( 0., 0., 0., fM1 );
250   G4double mPip = G4ParticleTable::GetParticle    276   G4double mPip = G4ParticleTable::GetParticleTable()->FindParticle(211)->GetPDGMass();
251                                                   277 
252   // 1-pi by fQtransfer && nu-energy              278   // 1-pi by fQtransfer && nu-energy
253   G4LorentzVector lvpip1( 0., 0., 0., mPip );     279   G4LorentzVector lvpip1( 0., 0., 0., mPip );
254   G4LorentzVector lvsum, lv2, lvX;                280   G4LorentzVector lvsum, lv2, lvX;
255   G4ThreeVector eP;                               281   G4ThreeVector eP;
256   G4double cost(1.), sint(0.), phi(0.), muMom(    282   G4double cost(1.), sint(0.), phi(0.), muMom(0.), massX2(0.);
257   G4DynamicParticle* aLept = nullptr; // lepto    283   G4DynamicParticle* aLept = nullptr; // lepton lv
258                                                   284 
259   G4int Z = targetNucleus.GetZ_asInt();           285   G4int Z = targetNucleus.GetZ_asInt();
260   G4int A = targetNucleus.GetA_asInt();           286   G4int A = targetNucleus.GetA_asInt();
261   G4double  mTarg = targetNucleus.AtomicMass(A    287   G4double  mTarg = targetNucleus.AtomicMass(A,Z);
262   G4int pdgP(0), qB(0);                           288   G4int pdgP(0), qB(0);
263   // G4double mSum = G4ParticleTable::GetParti    289   // G4double mSum = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass() + mPip;
264                                                   290 
265   G4int iPi     = GetOnePionIndex(energy);        291   G4int iPi     = GetOnePionIndex(energy);
266   G4double p1pi = GetNuMuOnePionProb( iPi, ene    292   G4double p1pi = GetNuMuOnePionProb( iPi, energy);
267                                                   293 
268   if( p1pi > G4UniformRand() && fCosTheta > 0. << 294   if( p1pi > G4UniformRand()  ) // && fQtransfer < 0.95*GeV ) // mu- & coherent pion + nucleus
269   {                                               295   {
270     // lvsum = lvp1 + lvpip1;                     296     // lvsum = lvp1 + lvpip1;
271     lvsum = lvp1 + lvt1;                          297     lvsum = lvp1 + lvt1;
272     // cost = fCosThetaPi;                        298     // cost = fCosThetaPi;
273     cost = fCosTheta;                             299     cost = fCosTheta;
274     sint = std::sqrt( (1.0 - cost)*(1.0 + cost    300     sint = std::sqrt( (1.0 - cost)*(1.0 + cost) );
275     phi  = G4UniformRand()*CLHEP::twopi;          301     phi  = G4UniformRand()*CLHEP::twopi;
276     eP   = G4ThreeVector( sint*std::cos(phi),     302     eP   = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost );
277                                                   303 
278     // muMom = sqrt(fEmuPi*fEmuPi-fMnumu*fMnum    304     // muMom = sqrt(fEmuPi*fEmuPi-fMnumu*fMnumu);
279     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);        305     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);
280                                                   306 
281     eP *= muMom;                                  307     eP *= muMom;
282                                                   308 
283     // lv2 = G4LorentzVector( eP, fEmuPi );       309     // lv2 = G4LorentzVector( eP, fEmuPi );
284     lv2 = G4LorentzVector( eP, fEmu );            310     lv2 = G4LorentzVector( eP, fEmu );
285     lv2 = fLVl;                                   311     lv2 = fLVl;
286                                                   312 
287     lvX = lvsum - lv2;                            313     lvX = lvsum - lv2;
288     lvX = fLVh;                                   314     lvX = fLVh;
289     massX2 = lvX.m2();                            315     massX2 = lvX.m2();
290     G4double massX = lvX.m();                  << 
291     G4double massR = fLVt.m();                 << 
292                                                   316 
293     // 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
294     if ( massX2 <= fM1*fM1 ) // 9-3-20 vmg: ve << 
295       if ( lvX.e() <= fM1 ) // 9-3-20 vmg: ver << 
296     {                                             318     {
297       theParticleChange.SetEnergyChange(energy    319       theParticleChange.SetEnergyChange(energy);
298       theParticleChange.SetMomentumChange(aTra    320       theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
299       return &theParticleChange;                  321       return &theParticleChange;
300     }                                             322     }
301     fW2 = massX2;                                 323     fW2 = massX2;
302                                                   324 
303     if(  pName == "nu_mu" )         aLept = ne    325     if(  pName == "nu_mu" )         aLept = new G4DynamicParticle( theNuMu, lv2 );  
304     else if( pName == "anti_nu_mu") aLept = ne    326     else if( pName == "anti_nu_mu") aLept = new G4DynamicParticle( theANuMu,  lv2 );
305     else                                          327     else
306     {                                             328     {
307       theParticleChange.SetEnergyChange(energy    329       theParticleChange.SetEnergyChange(energy);
308       theParticleChange.SetMomentumChange(aTra    330       theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
309       return &theParticleChange;                  331       return &theParticleChange;
310     }                                             332     } 
311                                                   333  
312     pdgP = 111;                                   334     pdgP = 111;
313                                                   335 
314     G4double eCut; // = fMpi + 0.5*(fMpi*fMpi  << 336     G4double eCut = fMpi + 0.5*(fMpi*fMpi - massX2)/mTarg; // massX -> fMpi
315                                                << 
316     if( A > 1 )                                << 
317     {                                          << 
318       eCut = (fMpi + mTarg)*(fMpi + mTarg) - ( << 
319       eCut /= 2.*massR;                        << 
320       eCut += massX;                           << 
321     }                                          << 
322     else  eCut = fM1 + fMpi;                   << 
323                                                   337 
324     if ( lvX.e() > eCut ) // && sqrt( GetW2()     338     if ( lvX.e() > eCut ) // && sqrt( GetW2() ) < 1.4*GeV ) // 
325     {                                             339     {
326       CoherentPion( lvX, pdgP, targetNucleus);    340       CoherentPion( lvX, pdgP, targetNucleus);
327     }                                             341     }
328     else                                          342     else
329     {                                             343     {
330       theParticleChange.SetEnergyChange(energy    344       theParticleChange.SetEnergyChange(energy);
331       theParticleChange.SetMomentumChange(aTra    345       theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
332       return &theParticleChange;                  346       return &theParticleChange;
333     }                                             347     } 
334     theParticleChange.AddSecondary( aLept, fSe << 348     theParticleChange.AddSecondary( aLept );
335                                                   349 
336     return &theParticleChange;                    350     return &theParticleChange;
337   }                                               351   }
338   else // lepton part in lab                      352   else // lepton part in lab
339   {                                               353   { 
340     lvsum = lvp1 + lvt1;                          354     lvsum = lvp1 + lvt1;
341     cost = fCosTheta;                             355     cost = fCosTheta;
342     sint = std::sqrt( (1.0 - cost)*(1.0 + cost    356     sint = std::sqrt( (1.0 - cost)*(1.0 + cost) );
343     phi  = G4UniformRand()*CLHEP::twopi;          357     phi  = G4UniformRand()*CLHEP::twopi;
344     eP   = G4ThreeVector( sint*std::cos(phi),     358     eP   = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost );
345                                                   359 
346     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);        360     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);
347                                                   361 
348     eP *= muMom;                                  362     eP *= muMom;
349                                                   363 
350     lv2 = G4LorentzVector( eP, fEmu );            364     lv2 = G4LorentzVector( eP, fEmu );
351                                                   365 
352     lvX = lvsum - lv2;                            366     lvX = lvsum - lv2;
353                                                   367 
354     massX2 = lvX.m2();                            368     massX2 = lvX.m2();
355                                                   369 
356     if ( massX2 <= 0. ) // vmg: very rarely ~     370     if ( massX2 <= 0. ) // vmg: very rarely ~ (1-4)e-6 due to big Q2/x, to be improved
357     {                                             371     {
358       theParticleChange.SetEnergyChange(energy    372       theParticleChange.SetEnergyChange(energy);
359       theParticleChange.SetMomentumChange(aTra    373       theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
360       return &theParticleChange;                  374       return &theParticleChange;
361     }                                             375     }
362     fW2 = massX2;                                 376     fW2 = massX2;
363                                                   377 
364     aLept = new G4DynamicParticle( theNuMu, lv << 378     if(  pName == "nu_mu" )         aLept = new G4DynamicParticle( theNuMu, lv2 );  
365                                                << 379     else if( pName == "anti_nu_mu") aLept = new G4DynamicParticle( theANuMu,  lv2 );
366     theParticleChange.AddSecondary( aLept, fSe << 380     
                                                   >> 381     theParticleChange.AddSecondary( aLept );
367   }                                               382   }
368                                                   383 
369   // hadron part                                  384   // hadron part
370                                                   385 
371   fRecoil  = nullptr;                             386   fRecoil  = nullptr;
372   fCascade = false;                               387   fCascade = false;
373   fString  = false;                               388   fString  = false;
374                                                   389   
375   if( A == 1 )                                    390   if( A == 1 )
376   {                                               391   {
377     qB = 1;                                       392     qB = 1;
378                                                   393 
379     // if( G4UniformRand() > 0.1 ) //  > 0.999    394     // if( G4UniformRand() > 0.1 ) //  > 0.9999 ) // > 0.0001 ) //
380     {                                             395     {
381       ClusterDecay( lvX, qB );                    396       ClusterDecay( lvX, qB );
382     }                                             397     }
383     return &theParticleChange;                    398     return &theParticleChange;
384   }                                               399   }
385   G4Nucleus recoil;                               400   G4Nucleus recoil;
386   G4double rM(0.), ratio = G4double(Z)/G4doubl    401   G4double rM(0.), ratio = G4double(Z)/G4double(A);
387                                                   402 
388   if( ratio > G4UniformRand() ) // proton is e    403   if( ratio > G4UniformRand() ) // proton is excited
389   {                                               404   {
390     fProton = true;                               405     fProton = true;
391     recoil = G4Nucleus(A-1,Z-1);                  406     recoil = G4Nucleus(A-1,Z-1);
392     fRecoil = &recoil;                            407     fRecoil = &recoil;
393     rM = recoil.AtomicMass(A-1,Z-1);              408     rM = recoil.AtomicMass(A-1,Z-1);
394                                                   409 
395     fMt = G4ParticleTable::GetParticleTable()-    410     fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
396           + G4ParticleTable::GetParticleTable(    411           + G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
397   }                                               412   }
398   else // excited neutron                         413   else // excited neutron
399   {                                               414   {
400     fProton = false;                              415     fProton = false;
401     recoil = G4Nucleus(A-1,Z);                    416     recoil = G4Nucleus(A-1,Z);
402     fRecoil = &recoil;                            417     fRecoil = &recoil;
403     rM = recoil.AtomicMass(A-1,Z);                418     rM = recoil.AtomicMass(A-1,Z);
404                                                   419 
405     fMt = G4ParticleTable::GetParticleTable()-    420     fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
406           + G4ParticleTable::GetParticleTable(    421           + G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass(); 
407   }                                               422   }
408   // G4int       index = GetEnergyIndex(energy << 423   G4int       index = GetEnergyIndex(energy);
409   G4int nepdg = aParticle->GetDefinition()->Ge << 424   G4double qeTotRat = GetNuMuQeTotRat(index, energy);
410                                                << 
411   G4double qeTotRat; //  = GetNuMuQeTotRat(ind << 
412   qeTotRat = CalculateQEratioA( Z, A, energy,  << 
413                                                   425 
414   G4ThreeVector dX = (lvX.vect()).unit();         426   G4ThreeVector dX = (lvX.vect()).unit();
415   G4double eX   = lvX.e();  // excited nucleon    427   G4double eX   = lvX.e();  // excited nucleon
416   G4double mX   = sqrt(massX2);                   428   G4double mX   = sqrt(massX2);
                                                   >> 429   G4double dP(0.), pX   = sqrt( eX*eX - mX*mX );
                                                   >> 430   G4double sumE = eX + rM;
                                                   >> 431   G4double a(0.), b(0.), c(0.), B(0.);
417                                                   432 
418   if( qeTotRat > G4UniformRand() || mX <= fMt     433   if( qeTotRat > G4UniformRand() || mX <= fMt ) // || eX <= 1232.*MeV) // QE
419   {                                               434   {  
420     fString = false;                              435     fString = false;
421                                                   436 
422     if( fProton )                              << 437     if( fProton ) // pName == "nu_mu" ) 
423     {                                             438     {  
424       fPDGencoding = 2212;                        439       fPDGencoding = 2212;
425       fMr =  proton_mass_c2;                      440       fMr =  proton_mass_c2;
426       recoil = G4Nucleus(A-1,Z-1);                441       recoil = G4Nucleus(A-1,Z-1);
427       fRecoil = &recoil;                          442       fRecoil = &recoil;
428       rM = recoil.AtomicMass(A-1,Z-1);            443       rM = recoil.AtomicMass(A-1,Z-1);
429     }                                             444     } 
430     else                                       << 445     else // if( pName == "anti_nu_mu" ) 
431     {                                             446     {  
432       fPDGencoding = 2112;                        447       fPDGencoding = 2112;
433       fMr =   G4ParticleTable::GetParticleTabl    448       fMr =   G4ParticleTable::GetParticleTable()->
434   FindParticle(fPDGencoding)->GetPDGMass(); //    449   FindParticle(fPDGencoding)->GetPDGMass(); // 939.5654133*MeV;
435       recoil = G4Nucleus(A-1,Z);                  450       recoil = G4Nucleus(A-1,Z);
436       fRecoil = &recoil;                          451       fRecoil = &recoil;
437       rM = recoil.AtomicMass(A-1,Z);              452       rM = recoil.AtomicMass(A-1,Z);
438     }                                             453     } 
                                                   >> 454     sumE = eX + rM; 
439     G4double eTh = fMr+0.5*(fMr*fMr-mX*mX)/rM;    455     G4double eTh = fMr+0.5*(fMr*fMr-mX*mX)/rM;
440                                                   456 
441     if(eX <= eTh) // vmg, very rarely out of k    457     if(eX <= eTh) // vmg, very rarely out of kinematics
442     {                                             458     {
443       theParticleChange.SetEnergyChange(energy    459       theParticleChange.SetEnergyChange(energy);
444       theParticleChange.SetMomentumChange(aTra    460       theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit());
445       return &theParticleChange;                  461       return &theParticleChange;
446     }                                             462     } 
447     FinalBarion( lvX, 0, fPDGencoding ); // p( << 463     B = sumE*sumE + rM*rM - fMr*fMr - pX*pX;
                                                   >> 464     a = 4.*(sumE*sumE - pX*pX);
                                                   >> 465     b = -4.*B*pX;
                                                   >> 466     c = 4.*sumE*sumE*rM*rM - B*B;
                                                   >> 467     G4double det2 = b*b-4.*a*c;
                                                   >> 468     if( det2 < 0.) det2 = 0.;
                                                   >> 469     dP = 0.5*(-b - sqrt(det2) )/a;
                                                   >> 470     pX -= dP;
                                                   >> 471     eX = sqrt( pX*pX + fMr*fMr );
                                                   >> 472     G4LorentzVector qeLV( pX*dX, eX );
                                                   >> 473 
                                                   >> 474     G4ParticleDefinition* qePart = G4ParticleTable::GetParticleTable()->
                                                   >> 475                                  FindParticle(fPDGencoding); 
                                                   >> 476  
                                                   >> 477     G4DynamicParticle* qeDyn = new G4DynamicParticle( qePart, qeLV);
                                                   >> 478     theParticleChange.AddSecondary(qeDyn); 
                                                   >> 479   
                                                   >> 480     G4double eRecoil = sqrt(rM*rM + dP*dP);
                                                   >> 481     G4ThreeVector vRecoil(dP*dX);
                                                   >> 482     G4LorentzVector lvTarg(vRecoil, eRecoil);
                                                   >> 483 
                                                   >> 484     if( eRecoil > 100.*MeV ) // add recoil nucleus
                                                   >> 485     {
                                                   >> 486       G4ParticleDefinition * recoilDef = 0;
                                                   >> 487       G4int Zr = recoil.GetZ_asInt();
                                                   >> 488       G4int Ar = recoil.GetA_asInt();
                                                   >> 489 
                                                   >> 490       if      ( Zr == 1 && Ar == 1 ) { recoilDef = G4Proton::Proton(); }
                                                   >> 491       else if ( Zr == 0 && Ar == 1 ) { recoilDef = G4Neutron::Neutron(); }
                                                   >> 492       else if ( Zr == 1 && Ar == 2 ) { recoilDef = G4Deuteron::Deuteron(); }
                                                   >> 493       else if ( Zr == 1 && Ar == 3 ) { recoilDef = G4Triton::Triton(); }
                                                   >> 494       else if ( Zr == 2 && Ar == 3 ) { recoilDef = G4He3::He3(); }
                                                   >> 495       else if ( Zr == 2 && Ar == 4 ) { recoilDef = G4Alpha::Alpha(); }
                                                   >> 496       else 
                                                   >> 497       {
                                                   >> 498         recoilDef = 
                                                   >> 499   G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon( Zr, Ar, 0.0 );
                                                   >> 500       }
                                                   >> 501       G4DynamicParticle * aSec = new G4DynamicParticle( recoilDef, lvTarg);
                                                   >> 502       theParticleChange.AddSecondary(aSec);
                                                   >> 503     } 
                                                   >> 504     else if( eRecoil > 0.0 ) 
                                                   >> 505     {
                                                   >> 506       theParticleChange.SetLocalEnergyDeposit( eRecoil );
                                                   >> 507     }
448   }                                               508   }
449   else // if ( eX < 9500000.*GeV ) // < 25.*Ge << 509   else if ( eX < 95000.*GeV ) // < 25.*GeV) //  < 95.*GeV ) // < 2.5*GeV ) //cluster decay
450   {                                               510   {  
451     if     (  fProton && pName == "nu_mu" )       511     if     (  fProton && pName == "nu_mu" )      qB =  1;
                                                   >> 512     else if(  fProton && pName == "anti_nu_mu" ) qB =  1;
452     else if( !fProton && pName == "nu_mu" )       513     else if( !fProton && pName == "nu_mu" )      qB =  0;
                                                   >> 514     else if( !fProton && pName == "anti_nu_mu" ) qB =  0;
453                                                   515 
454     ClusterDecay( lvX, qB );                   << 516     // if( G4UniformRand() > 0.1 )
                                                   >> 517     {
                                                   >> 518       ClusterDecay( lvX, qB );
                                                   >> 519     }
                                                   >> 520     // else
                                                   >> 521     {
                                                   >> 522        pdgP = 111;
                                                   >> 523 
                                                   >> 524       if ( fQtransfer < 0.95*GeV )  // < 0.99*GeV )  //
                                                   >> 525       {
                                                   >> 526         // if( lvX.m() > mSum ) CoherentPion( lvX, pdgP, targetNucleus);
                                                   >> 527       }
                                                   >> 528     }
455   }                                               529   }
                                                   >> 530   else // string
                                                   >> 531   {  
                                                   >> 532     return &theParticleChange;
                                                   >> 533 
                                                   >> 534   } 
456   return &theParticleChange;                      535   return &theParticleChange;
457 }                                                 536 }
458                                                   537 
459                                                   538 
460 //////////////////////////////////////////////    539 /////////////////////////////////////////////////////////////////////
461 //////////////////////////////////////////////    540 ////////////////////////////////////////////////////////////////////
462 //////////////////////////////////////////////    541 ///////////////////////////////////////////////////////////////////
463                                                   542 
464 //////////////////////////////////////////////    543 /////////////////////////////////////////////////
465 //                                                544 //
466 // sample x, then Q2                              545 // sample x, then Q2
467                                                   546 
468 void G4NuMuNucleusNcModel::SampleLVkr(const G4    547 void G4NuMuNucleusNcModel::SampleLVkr(const G4HadProjectile & aTrack, G4Nucleus& targetNucleus)
469 {                                                 548 {
470   fBreak = false;                                 549   fBreak = false;
471   G4int A = targetNucleus.GetA_asInt(), iTer(0    550   G4int A = targetNucleus.GetA_asInt(), iTer(0), iTerMax(100); 
472   G4int Z = targetNucleus.GetZ_asInt();           551   G4int Z = targetNucleus.GetZ_asInt(); 
473   G4double e3(0.), pMu2(0.), pX2(0.), nMom(0.)    552   G4double e3(0.), pMu2(0.), pX2(0.), nMom(0.), rM(0.), hM(0.), tM = targetNucleus.AtomicMass(A,Z);
474   G4double cost(1.), sint(0.), phi(0.), muMom(    553   G4double cost(1.), sint(0.), phi(0.), muMom(0.); 
475   G4ThreeVector eP, bst;                          554   G4ThreeVector eP, bst;
476   const G4HadProjectile* aParticle = &aTrack;     555   const G4HadProjectile* aParticle = &aTrack;
477   G4LorentzVector lvp1 = aParticle->Get4Moment    556   G4LorentzVector lvp1 = aParticle->Get4Momentum();
478   nMom = NucleonMomentum( targetNucleus );        557   nMom = NucleonMomentum( targetNucleus );
479                                                   558 
480   if( A == 1 || nMom == 0. ) // hydrogen, no F    559   if( A == 1 || nMom == 0. ) // hydrogen, no Fermi motion ???
481   {                                               560   {
482     fNuEnergy = aParticle->GetTotalEnergy();      561     fNuEnergy = aParticle->GetTotalEnergy();
483     iTer = 0;                                     562     iTer = 0;
484                                                   563 
485     do                                            564     do
486     {                                             565     {
487       fXsample = SampleXkr(fNuEnergy);            566       fXsample = SampleXkr(fNuEnergy);
488       fQtransfer = SampleQkr(fNuEnergy, fXsamp    567       fQtransfer = SampleQkr(fNuEnergy, fXsample);
489       fQ2 = fQtransfer*fQtransfer;                568       fQ2 = fQtransfer*fQtransfer;
490                                                   569 
491      if( fXsample > 0. )                          570      if( fXsample > 0. )
492       {                                           571       {
493         fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; //    572         fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; // sample excited hadron mass
494         fEmu = fNuEnergy - fQ2/2./fM1/fXsample    573         fEmu = fNuEnergy - fQ2/2./fM1/fXsample;
495       }                                           574       }
496       else                                        575       else
497       {                                           576       {
498         fW2 = fM1*fM1;                            577         fW2 = fM1*fM1;
499         fEmu = fNuEnergy;                         578         fEmu = fNuEnergy;
500       }                                           579       }
501       e3 = fNuEnergy + fM1 - fEmu;                580       e3 = fNuEnergy + fM1 - fEmu;
502                                                   581 
503       // if( e3 < sqrt(fW2) )  G4cout<<"energy    582       // if( e3 < sqrt(fW2) )  G4cout<<"energyX = "<<e3/GeV<<", fW = "<<sqrt(fW2)/GeV<<G4endl; // vmg ~10^-5 for NC
504                                                   583     
505       pMu2 = fEmu*fEmu - fMnumu*fMnumu;           584       pMu2 = fEmu*fEmu - fMnumu*fMnumu;
506       pX2  = e3*e3 - fW2;                         585       pX2  = e3*e3 - fW2;
507                                                   586 
508       fCosTheta  = fNuEnergy*fNuEnergy  + pMu2    587       fCosTheta  = fNuEnergy*fNuEnergy  + pMu2 - pX2;
509       fCosTheta /= 2.*fNuEnergy*sqrt(pMu2);       588       fCosTheta /= 2.*fNuEnergy*sqrt(pMu2);
510       iTer++;                                     589       iTer++;
511     }                                             590     }
512     while( ( abs(fCosTheta) > 1. || fEmu < fMn    591     while( ( abs(fCosTheta) > 1. || fEmu < fMnumu ) && iTer < iTerMax );
513                                                   592 
514     if( iTer >= iTerMax ) { fBreak = true; ret    593     if( iTer >= iTerMax ) { fBreak = true; return; }
515                                                   594 
516     if( abs(fCosTheta) > 1.) // vmg: due to bi    595     if( abs(fCosTheta) > 1.) // vmg: due to big Q2/x values. To be improved ...
517     {                                             596     { 
518       G4cout<<"H2: fCosTheta = "<<fCosTheta<<"    597       G4cout<<"H2: fCosTheta = "<<fCosTheta<<", fEmu = "<<fEmu<<G4endl;
519       // fCosTheta = -1. + 2.*G4UniformRand();    598       // fCosTheta = -1. + 2.*G4UniformRand(); 
520       if(fCosTheta < -1.) fCosTheta = -1.;        599       if(fCosTheta < -1.) fCosTheta = -1.;
521       if(fCosTheta >  1.) fCosTheta =  1.;        600       if(fCosTheta >  1.) fCosTheta =  1.;
522     }                                             601     }
523     // LVs                                        602     // LVs
524                                                   603 
525     G4LorentzVector lvt1  = G4LorentzVector( 0    604     G4LorentzVector lvt1  = G4LorentzVector( 0., 0., 0., fM1 );
526     G4LorentzVector lvsum = lvp1 + lvt1;          605     G4LorentzVector lvsum = lvp1 + lvt1;
527                                                   606 
528     cost = fCosTheta;                             607     cost = fCosTheta;
529     sint = std::sqrt( (1.0 - cost)*(1.0 + cost    608     sint = std::sqrt( (1.0 - cost)*(1.0 + cost) );
530     phi  = G4UniformRand()*CLHEP::twopi;          609     phi  = G4UniformRand()*CLHEP::twopi;
531     eP   = G4ThreeVector( sint*std::cos(phi),     610     eP   = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost );
532     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);        611     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);
533     eP *= muMom;                                  612     eP *= muMom;
534     fLVl = G4LorentzVector( eP, fEmu );           613     fLVl = G4LorentzVector( eP, fEmu );
535                                                   614 
536     fLVh = lvsum - fLVl;                          615     fLVh = lvsum - fLVl;
537     fLVt = G4LorentzVector( 0., 0., 0., 0. );     616     fLVt = G4LorentzVector( 0., 0., 0., 0. ); // no recoil
538   }                                               617   }
539   else // Fermi motion, Q2 in nucleon rest fra    618   else // Fermi motion, Q2 in nucleon rest frame
540   {                                               619   {
541     G4ThreeVector nMomDir = nMom*G4RandomDirec    620     G4ThreeVector nMomDir = nMom*G4RandomDirection();
542                                                   621 
543     if( !f2p2h ) // 1p1h                          622     if( !f2p2h ) // 1p1h
544     {                                             623     {
545       G4Nucleus recoil(A-1,Z);                    624       G4Nucleus recoil(A-1,Z);
546       rM = sqrt( recoil.AtomicMass(A-1,Z)*reco    625       rM = sqrt( recoil.AtomicMass(A-1,Z)*recoil.AtomicMass(A-1,Z) + nMom*nMom );
547       hM = tM - rM;                               626       hM = tM - rM;
548                                                   627 
549       fLVt = G4LorentzVector( nMomDir, sqrt( r    628       fLVt = G4LorentzVector( nMomDir, sqrt( rM*rM+nMom*nMom ) );
550       fLVh = G4LorentzVector(-nMomDir, sqrt( h    629       fLVh = G4LorentzVector(-nMomDir, sqrt( hM*hM+nMom*nMom ) ); 
551     }                                             630     }
552     else // 2p2h                                  631     else // 2p2h
553     {                                             632     {
554       G4Nucleus recoil(A-2,Z-1);                  633       G4Nucleus recoil(A-2,Z-1);
555       rM = recoil.AtomicMass(A-2,Z-1)+sqrt(nMo    634       rM = recoil.AtomicMass(A-2,Z-1)+sqrt(nMom*nMom+fM1*fM1);
556       hM = tM - rM;                               635       hM = tM - rM;
557                                                   636 
558       fLVt = G4LorentzVector( nMomDir, sqrt( r    637       fLVt = G4LorentzVector( nMomDir, sqrt( rM*rM+nMom*nMom ) );
559       fLVh = G4LorentzVector(-nMomDir, sqrt( h    638       fLVh = G4LorentzVector(-nMomDir, sqrt( hM*hM+nMom*nMom ) ); 
560     }                                             639     }
561     // G4cout<<hM<<", ";                          640     // G4cout<<hM<<", ";
562     // bst = fLVh.boostVector(); // 9-3-20     << 641     bst = fLVh.boostVector();
563                                                   642 
564     // lvp1.boost(-bst); // 9-3-20 -> nucleon  << 643     lvp1.boost(-bst); // -> nucleon rest system, where Q2 transfer is ???
565                                                   644 
566     fNuEnergy  = lvp1.e();                        645     fNuEnergy  = lvp1.e();
567     iTer = 0;                                     646     iTer = 0;
568                                                   647 
569     do                                            648     do
570     {                                             649     {
571       fXsample = SampleXkr(fNuEnergy);            650       fXsample = SampleXkr(fNuEnergy);
572       fQtransfer = SampleQkr(fNuEnergy, fXsamp    651       fQtransfer = SampleQkr(fNuEnergy, fXsample);
573       fQ2 = fQtransfer*fQtransfer;                652       fQ2 = fQtransfer*fQtransfer;
574                                                   653 
575       if( fXsample > 0. )                         654       if( fXsample > 0. )
576       {                                           655       {
577         fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; //    656         fW2 = fM1*fM1 - fQ2 + fQ2/fXsample; // sample excited hadron mass
578         fEmu = fNuEnergy - fQ2/2./fM1/fXsample    657         fEmu = fNuEnergy - fQ2/2./fM1/fXsample;
579       }                                           658       }
580       else                                        659       else
581       {                                           660       {
582         fW2 = fM1*fM1;                            661         fW2 = fM1*fM1;
583         fEmu = fNuEnergy;                         662         fEmu = fNuEnergy;
584       }                                           663       }
585                                                   664 
586       // if(fEmu < 0.) G4cout<<"fEmu = "<<fEmu    665       // if(fEmu < 0.) G4cout<<"fEmu = "<<fEmu<<" hM = "<<hM<<G4endl;
587                                                   666 
588       e3 = fNuEnergy + fM1 - fEmu;                667       e3 = fNuEnergy + fM1 - fEmu;
589                                                   668 
590       // if( e3 < sqrt(fW2) )  G4cout<<"energy    669       // if( e3 < sqrt(fW2) )  G4cout<<"energyX = "<<e3/GeV<<", fW = "<<sqrt(fW2)/GeV<<G4endl;
591                                                   670     
592       pMu2 = fEmu*fEmu - fMnumu*fMnumu;           671       pMu2 = fEmu*fEmu - fMnumu*fMnumu;
593       pX2  = e3*e3 - fW2;                         672       pX2  = e3*e3 - fW2;
594                                                   673 
595       fCosTheta  = fNuEnergy*fNuEnergy  + pMu2    674       fCosTheta  = fNuEnergy*fNuEnergy  + pMu2 - pX2;
596       fCosTheta /= 2.*fNuEnergy*sqrt(pMu2);       675       fCosTheta /= 2.*fNuEnergy*sqrt(pMu2);
597       iTer++;                                     676       iTer++;
598     }                                             677     }
599     while( ( abs(fCosTheta) > 1. || fEmu < fMn    678     while( ( abs(fCosTheta) > 1. || fEmu < fMnumu ) && iTer < iTerMax );
600                                                   679 
601     if( iTer >= iTerMax ) { fBreak = true; ret    680     if( iTer >= iTerMax ) { fBreak = true; return; }
602                                                   681 
603     if( abs(fCosTheta) > 1.) // vmg: due to bi    682     if( abs(fCosTheta) > 1.) // vmg: due to big Q2/x values. To be improved ...
604     {                                             683     { 
605       G4cout<<"FM: fCosTheta = "<<fCosTheta<<"    684       G4cout<<"FM: fCosTheta = "<<fCosTheta<<", fEmu = "<<fEmu<<G4endl;
606       // fCosTheta = -1. + 2.*G4UniformRand();    685       // fCosTheta = -1. + 2.*G4UniformRand(); 
607       if(fCosTheta < -1.) fCosTheta = -1.;        686       if(fCosTheta < -1.) fCosTheta = -1.;
608       if(fCosTheta >  1.) fCosTheta =  1.;        687       if(fCosTheta >  1.) fCosTheta =  1.;
609     }                                             688     }
610     // LVs                                        689     // LVs
611     G4LorentzVector lvt1  = G4LorentzVector( 0    690     G4LorentzVector lvt1  = G4LorentzVector( 0., 0., 0., fM1 );
612     G4LorentzVector lvsum = lvp1 + lvt1;          691     G4LorentzVector lvsum = lvp1 + lvt1;
613                                                   692 
614     cost = fCosTheta;                             693     cost = fCosTheta;
615     sint = std::sqrt( (1.0 - cost)*(1.0 + cost    694     sint = std::sqrt( (1.0 - cost)*(1.0 + cost) );
616     phi  = G4UniformRand()*CLHEP::twopi;          695     phi  = G4UniformRand()*CLHEP::twopi;
617     eP   = G4ThreeVector( sint*std::cos(phi),     696     eP   = G4ThreeVector( sint*std::cos(phi), sint*std::sin(phi), cost );
618     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);        697     muMom = sqrt(fEmu*fEmu-fMnumu*fMnumu);
619     eP *= muMom;                                  698     eP *= muMom;
620     fLVl = G4LorentzVector( eP, fEmu );           699     fLVl = G4LorentzVector( eP, fEmu );
621     fLVh = lvsum - fLVl;                          700     fLVh = lvsum - fLVl;
622     // back to lab system                         701     // back to lab system
623     // fLVl.boost(bst); // 9-3-20              << 702     fLVl.boost(bst);
624     // fLVh.boost(bst); // 9-3-20              << 703     fLVh.boost(bst);
625   }                                               704   }
626   //G4cout<<iTer<<", "<<fBreak<<"; ";             705   //G4cout<<iTer<<", "<<fBreak<<"; ";
                                                   >> 706 }
                                                   >> 707 
                                                   >> 708 //////////////////////////////////////
                                                   >> 709 
                                                   >> 710 G4double G4NuMuNucleusNcModel::SampleXkr(G4double energy)
                                                   >> 711 {
                                                   >> 712   G4int i(0), nBin(50);
                                                   >> 713   G4double xx(0.), prob = G4UniformRand();
                                                   >> 714 
                                                   >> 715   for( i = 0; i < nBin; ++i ) 
                                                   >> 716   {
                                                   >> 717     if( energy <= fNuMuEnergyLogVector[i] ) break;
                                                   >> 718   }
                                                   >> 719   if( i <= 0)          // E-edge
                                                   >> 720   {
                                                   >> 721     fEindex = 0;
                                                   >> 722     xx = GetXkr( 0, prob);  
                                                   >> 723   }
                                                   >> 724   else if ( i >= nBin-1) 
                                                   >> 725   {
                                                   >> 726     fEindex = nBin-1;  
                                                   >> 727     xx = GetXkr( nBin-1, prob); 
                                                   >> 728   }
                                                   >> 729   else
                                                   >> 730   {
                                                   >> 731     fEindex = i;
                                                   >> 732     G4double x1 = GetXkr(i-1,prob);
                                                   >> 733     G4double x2 = GetXkr(i,prob);
                                                   >> 734 
                                                   >> 735     G4double e1 = G4Log(fNuMuEnergyLogVector[i-1]);
                                                   >> 736     G4double e2 = G4Log(fNuMuEnergyLogVector[i]);
                                                   >> 737     G4double e  = G4Log(energy);
                                                   >> 738 
                                                   >> 739     if( e2 <= e1) xx = x1 + G4UniformRand()*(x2-x1);
                                                   >> 740     else          xx = x1 + (e-e1)*(x2-x1)/(e2-e1);  // lin in energy log-scale
                                                   >> 741   }
                                                   >> 742   return xx;
                                                   >> 743 }
                                                   >> 744 
                                                   >> 745 //////////////////////////////////////////////
                                                   >> 746 //
                                                   >> 747 // sample X according to prob (xmin,1) at a given energy index iEnergy
                                                   >> 748 
                                                   >> 749 G4double G4NuMuNucleusNcModel::GetXkr(G4int iEnergy, G4double prob)
                                                   >> 750 {
                                                   >> 751   G4int i(0), nBin=50; 
                                                   >> 752   G4double xx(0.);
                                                   >> 753 
                                                   >> 754   for( i = 0; i < nBin; ++i ) 
                                                   >> 755   {
                                                   >> 756     if( prob <= fNuMuXdistrKR[iEnergy][i] ) 
                                                   >> 757       break;
                                                   >> 758   }
                                                   >> 759   if(i <= 0 )  // X-edge
                                                   >> 760   {
                                                   >> 761     fXindex = 0;
                                                   >> 762     xx = fNuMuXarrayKR[iEnergy][0];
                                                   >> 763   }
                                                   >> 764   if ( i >= nBin ) 
                                                   >> 765   {
                                                   >> 766     fXindex = nBin;
                                                   >> 767     xx = fNuMuXarrayKR[iEnergy][nBin];
                                                   >> 768   }  
                                                   >> 769   else
                                                   >> 770   {
                                                   >> 771     fXindex = i;
                                                   >> 772     G4double x1 = fNuMuXarrayKR[iEnergy][i];
                                                   >> 773     G4double x2 = fNuMuXarrayKR[iEnergy][i+1];
                                                   >> 774 
                                                   >> 775     G4double p1 = 0.;
                                                   >> 776 
                                                   >> 777     if( i > 0 ) p1 = fNuMuXdistrKR[iEnergy][i-1];
                                                   >> 778 
                                                   >> 779     G4double p2 = fNuMuXdistrKR[iEnergy][i];  
                                                   >> 780 
                                                   >> 781     if( p2 <= p1 ) xx = x1 + G4UniformRand()*(x2-x1);
                                                   >> 782     else           xx = x1 + (prob-p1)*(x2-x1)/(p2-p1);
                                                   >> 783   }
                                                   >> 784   return xx;
                                                   >> 785 }
                                                   >> 786 
                                                   >> 787 //////////////////////////////////////
                                                   >> 788 //
                                                   >> 789 // Sample fQtransfer at a given Enu and fX
                                                   >> 790 
                                                   >> 791 G4double G4NuMuNucleusNcModel::SampleQkr( G4double energy, G4double xx)
                                                   >> 792 {
                                                   >> 793   G4int nBin(50), iE=fEindex, jX=fXindex;
                                                   >> 794   G4double qq(0.), qq1(0.), qq2(0.);
                                                   >> 795   G4double prob = G4UniformRand();
                                                   >> 796 
                                                   >> 797   // first E
                                                   >> 798 
                                                   >> 799   if( iE <= 0 )          
                                                   >> 800   {
                                                   >> 801     qq1 = GetQkr( 0, jX, prob);  
                                                   >> 802   }
                                                   >> 803   else if ( iE >= nBin-1) 
                                                   >> 804   {
                                                   >> 805     qq1 = GetQkr( nBin-1, jX, prob); 
                                                   >> 806   }
                                                   >> 807   else
                                                   >> 808   {
                                                   >> 809     G4double q1 = GetQkr(iE-1,jX, prob);
                                                   >> 810     G4double q2 = GetQkr(iE,jX, prob);
                                                   >> 811 
                                                   >> 812     G4double e1 = G4Log(fNuMuEnergyLogVector[iE-1]);
                                                   >> 813     G4double e2 = G4Log(fNuMuEnergyLogVector[iE]);
                                                   >> 814     G4double e  = G4Log(energy);
                                                   >> 815 
                                                   >> 816     if( e2 <= e1) qq1 = q1 + G4UniformRand()*(q2-q1);
                                                   >> 817     else          qq1 = q1 + (e-e1)*(q2-q1)/(e2-e1);  // lin in energy log-scale
                                                   >> 818   }
                                                   >> 819 
                                                   >> 820   // then X
                                                   >> 821 
                                                   >> 822   if( jX <= 0 )          
                                                   >> 823   {
                                                   >> 824     qq2 = GetQkr( iE, 0, prob);  
                                                   >> 825   }
                                                   >> 826   else if ( jX >= nBin) 
                                                   >> 827   {
                                                   >> 828     qq2 = GetQkr( iE, nBin, prob); 
                                                   >> 829   }
                                                   >> 830   else
                                                   >> 831   {
                                                   >> 832     G4double q1 = GetQkr(iE,jX-1, prob);
                                                   >> 833     G4double q2 = GetQkr(iE,jX, prob);
                                                   >> 834 
                                                   >> 835     G4double e1 = G4Log(fNuMuXarrayKR[iE][jX-1]);
                                                   >> 836     G4double e2 = G4Log(fNuMuXarrayKR[iE][jX]);
                                                   >> 837     G4double e  = G4Log(xx);
                                                   >> 838 
                                                   >> 839     if( e2 <= e1) qq2 = q1 + G4UniformRand()*(q2-q1);
                                                   >> 840     else          qq2 = q1 + (e-e1)*(q2-q1)/(e2-e1);  // lin in energy log-scale
                                                   >> 841   }
                                                   >> 842   qq = 0.5*(qq1+qq2);
                                                   >> 843 
                                                   >> 844   return qq;
                                                   >> 845 }
                                                   >> 846 
                                                   >> 847 //////////////////////////////////////////////
                                                   >> 848 //
                                                   >> 849 // sample Q according to prob (qmin,qmax) at a given energy index iE and X index jX
                                                   >> 850 
                                                   >> 851 G4double G4NuMuNucleusNcModel::GetQkr( G4int iE, G4int jX, G4double prob )
                                                   >> 852 {
                                                   >> 853   G4int i(0), nBin=50; 
                                                   >> 854   G4double qq(0.);
                                                   >> 855 
                                                   >> 856   for( i = 0; i < nBin; ++i ) 
                                                   >> 857   {
                                                   >> 858     if( prob <= fNuMuQdistrKR[iE][jX][i] ) 
                                                   >> 859       break;
                                                   >> 860   }
                                                   >> 861   if(i <= 0 )  // Q-edge
                                                   >> 862   {
                                                   >> 863     fQindex = 0;
                                                   >> 864     qq = fNuMuQarrayKR[iE][jX][0];
                                                   >> 865   }
                                                   >> 866   if ( i >= nBin ) 
                                                   >> 867   {
                                                   >> 868     fQindex = nBin;
                                                   >> 869     qq = fNuMuQarrayKR[iE][jX][nBin];
                                                   >> 870   }  
                                                   >> 871   else
                                                   >> 872   {
                                                   >> 873     fQindex = i;
                                                   >> 874     G4double q1 = fNuMuQarrayKR[iE][jX][i];
                                                   >> 875     G4double q2 = fNuMuQarrayKR[iE][jX][i+1];
                                                   >> 876 
                                                   >> 877     G4double p1 = 0.;
                                                   >> 878 
                                                   >> 879     if( i > 0 ) p1 = fNuMuQdistrKR[iE][jX][i-1];
                                                   >> 880 
                                                   >> 881     G4double p2 = fNuMuQdistrKR[iE][jX][i];  
                                                   >> 882 
                                                   >> 883     if( p2 <= p1 ) qq = q1 + G4UniformRand()*(q2-q1);
                                                   >> 884     else           qq = q1 + (prob-p1)*(q2-q1)/(p2-p1);
                                                   >> 885   }
                                                   >> 886   return qq;
627 }                                                 887 }
628                                                   888 
629 //                                                889 //
630 //                                                890 //
631 ///////////////////////////                       891 ///////////////////////////
632                                                   892