source: trunk/source/processes/hadronic/models/chiral_inv_phase_space/interface/src/G4QDiffraction.cc @ 1196

Last change on this file since 1196 was 1055, checked in by garnier, 15 years ago

maj sur la beta de geant 4.9.3

File size: 29.0 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26// $Id: G4QDiffraction.cc,v 1.6 2009/02/23 09:49:24 mkossov Exp $
27// GEANT4 tag $Name: geant4-09-03-beta-cand-01 $
28//
29//      ---------------- G4QDiffraction class -----------------
30//                 by Mikhail Kossov, Aug 2007.
31// G4QDiffraction class of the CHIPS Simulation Branch in GEANT4
32// ---------------------------------------------------------------
33// Short description: This is a process, which describes the diffraction
34// excitation of the projectile and the nucleus. On nuclei in addition there
35// can be a coherent diffraction process for the projectile, but it is
36// comparably small. The most important part of the diffraction is the
37// progectile diffraction excitation, as in this interaction proton can lose
38// only a small part of its energy and make the shower longer. This is because
39// only 1-2 (n) pions are produce in the diffraction escitation, and the mean
40// kept energy of the nucleon is (1-n/7)=80%. For kaons the kept energy is much
41// smaller (1-n/3.5)=60%, and for pions it is less important (about 40%).
42// ----------------------------------------------------------------------------
43
44//#define debug
45//#define pdebug
46//#define tdebug
47//#define nandebug
48//#define ppdebug
49
50#include "G4QDiffraction.hh"
51
52// Initialization of static vectors
53G4int    G4QDiffraction::nPartCWorld=152;  // #of particles initialized in CHIPS
54std::vector<G4int> G4QDiffraction::ElementZ; // Z of element(i) in theLastCalc
55std::vector<G4double> G4QDiffraction::ElProbInMat; // SumProbOfElem in Material
56std::vector<std::vector<G4int>*> G4QDiffraction::ElIsoN;// N of isotope(j), E(i)
57std::vector<std::vector<G4double>*>G4QDiffraction::IsoProbInEl;//SumProbIsotE(i)
58
59// Constructor
60G4QDiffraction::G4QDiffraction(const G4String& processName):
61 G4VDiscreteProcess(processName, fHadronic)
62{
63#ifdef debug
64  G4cout<<"G4QDiffraction::Constructor is called processName="<<processName<<G4endl;
65#endif
66  if (verboseLevel>0) G4cout << GetProcessName() << " process is created "<< G4endl;
67  SetProcessSubType(fHadronInelastic);
68  G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part. max)
69}
70
71// Destructor
72G4QDiffraction::~G4QDiffraction() {}
73
74
75G4LorentzVector G4QDiffraction::GetEnegryMomentumConservation(){return EnMomConservation;}
76
77G4int G4QDiffraction::GetNumberOfNeutronsInTarget() {return nOfNeutrons;}
78
79// output of the function must be in units of length! L=1/sig_V,sig_V=SUM(n(j,i)*sig(j,i)),
80// where n(i,j) is a number of nuclei of the isotop j of the element i in V=1(lengtUnit^3)
81// ********** All CHIPS cross sections are calculated in the surface units ************
82G4double G4QDiffraction::GetMeanFreePath(const G4Track&Track,G4double Q,G4ForceCondition*F)
83{
84  *F = NotForced;
85  const G4DynamicParticle* incidentParticle = Track.GetDynamicParticle();
86  G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition();
87  if( !IsApplicable(*incidentParticleDefinition))
88    G4cout<<"-Warning-G4QDiffraction::GetMeanFreePath for notImplemented Particle"<<G4endl;
89  // Calculate the mean Cross Section for the set of Elements(*Isotopes) in the Material
90  G4double Momentum = incidentParticle->GetTotalMomentum(); // 3-momentum of the Particle
91#ifdef debug
92  G4double KinEn = incidentParticle->GetKineticEnergy();
93  G4cout<<"G4QDiffraction::GetMeanFreePath:Prpj, kinE="<<KinEn<<", Mom="<<Momentum<<G4endl;
94#endif
95  const G4Material* material = Track.GetMaterial();        // Get the current material
96  const G4double* NOfNucPerVolume = material->GetVecNbOfAtomsPerVolume();
97  const G4ElementVector* theElementVector = material->GetElementVector();
98  G4int nE=material->GetNumberOfElements();
99#ifdef debug
100  G4cout<<"G4QDiffraction::GetMeanFreePath:"<<nE<<" Elems in Material="<<*material<<G4endl;
101#endif
102  G4int pPDG=0;
103  // @@ At present it is made only for n & p, but can be extended if inXS are available
104  if     (incidentParticleDefinition == G4Proton::Proton()  ) pPDG=2212;
105  else if(incidentParticleDefinition == G4Neutron::Neutron()) pPDG=2112;
106  else G4cout<<"G4QDiffraction::GetMeanFreePath: only nA & pA are implemented"<<G4endl;
107 
108  G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singleton
109  G4double sigma=0.;                        // Sums over elements for the material
110  G4int IPIE=IsoProbInEl.size();            // How many old elements?
111  if(IPIE) for(G4int ip=0; ip<IPIE; ++ip)   // Clean up the SumProb's of Isotopes (SPI)
112  {
113    std::vector<G4double>* SPI=IsoProbInEl[ip]; // Pointer to the SPI vector
114    SPI->clear();
115    delete SPI;
116    std::vector<G4int>* IsN=ElIsoN[ip];     // Pointer to the N vector
117    IsN->clear();
118    delete IsN;
119  }
120  ElProbInMat.clear();                      // Clean up the SumProb's of Elements (SPE)
121  ElementZ.clear();                         // Clear the body vector for Z of Elements
122  IsoProbInEl.clear();                      // Clear the body vector for SPI
123  ElIsoN.clear();                           // Clear the body vector for N of Isotopes
124  for(G4int i=0; i<nE; ++i)
125  {
126    G4Element* pElement=(*theElementVector)[i]; // Pointer to the current element
127    G4int Z = static_cast<G4int>(pElement->GetZ()); // Z of the Element
128    ElementZ.push_back(Z);                  // Remember Z of the Element
129    G4int isoSize=0;                        // The default for the isoVectorLength is 0
130    G4int indEl=0;                          // Index of non-natural element or 0(default)
131    G4IsotopeVector* isoVector=pElement->GetIsotopeVector(); // Get the predefined IsoVect
132    if(isoVector) isoSize=isoVector->size();// Get size of the existing isotopeVector
133#ifdef debug
134    G4cout<<"G4QDiffraction::GetMeanFreePath: isovector Length="<<isoSize<<G4endl;
135#endif
136    if(isoSize)                             // The Element has non-trivial abundance set
137    {
138      indEl=pElement->GetIndex()+1;         // Index of the non-trivial element is an order
139#ifdef debug
140      G4cout<<"G4QDiffr::GetMFP:iE="<<indEl<<",def="<<Isotopes->IsDefined(Z,indEl)<<G4endl;
141#endif
142      if(!Isotopes->IsDefined(Z,indEl))     // This index is not defined for this Z: define
143      {
144        std::vector<std::pair<G4int,G4double>*>* newAbund =
145                                               new std::vector<std::pair<G4int,G4double>*>;
146        G4double* abuVector=pElement->GetRelativeAbundanceVector();
147        for(G4int j=0; j<isoSize; j++)      // Calculation of abundance vector for isotopes
148        {
149          G4int N=pElement->GetIsotope(j)->GetN()-Z; // N means A=N+Z !
150          if(pElement->GetIsotope(j)->GetZ()!=Z)G4cerr<<"G4QDiffract::GetMeanFreePath: Z="
151                                         <<pElement->GetIsotope(j)->GetZ()<<"#"<<Z<<G4endl;
152          G4double abund=abuVector[j];
153          std::pair<G4int,G4double>* pr= new std::pair<G4int,G4double>(N,abund);
154#ifdef debug
155          G4cout<<"G4QDiffract::GetMeanFreePath:pair#"<<j<<",N="<<N<<",ab="<<abund<<G4endl;
156#endif
157          newAbund->push_back(pr);
158        }
159#ifdef debug
160        G4cout<<"G4QDiffract::GetMeanFreePath:pairVectorLength="<<newAbund->size()<<G4endl;
161#endif
162        indEl=G4QIsotope::Get()->InitElement(Z,indEl,newAbund); // definition of the newInd
163        for(G4int k=0; k<isoSize; k++) delete (*newAbund)[k];   // Cleaning temporary
164        delete newAbund; // Was "new" in the beginning of the name space
165      }
166    }
167    std::vector<std::pair<G4int,G4double>*>* cs= Isotopes->GetCSVector(Z,indEl);//CSPointer
168    std::vector<G4double>* SPI = new std::vector<G4double>; // Pointer to the SPI vector
169    IsoProbInEl.push_back(SPI);
170    std::vector<G4int>* IsN = new std::vector<G4int>; // Pointer to the N vector
171    ElIsoN.push_back(IsN);
172    G4int nIs=cs->size();                   // A#Of Isotopes in the Element
173#ifdef debug
174    G4cout<<"G4QDiffract::GetMFP:=***=>,#isot="<<nIs<<", Z="<<Z<<", indEl="<<indEl<<G4endl;
175#endif
176    G4double susi=0.;                       // sum of CS over isotopes
177    if(nIs) for(G4int j=0; j<nIs; j++)      // Calculate CS for eachIsotope of El
178    {
179      std::pair<G4int,G4double>* curIs=(*cs)[j]; // A pointer, which is used twice
180      G4int N=curIs->first;                 // #of Neuterons in the isotope j of El i
181      IsN->push_back(N);                    // Remember Min N for the Element
182#ifdef debug
183      G4cout<<"G4QDiff::GMFP:true,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<pPDG<<G4endl;
184#endif
185      G4bool ccsf=true;
186      if(Q==-27.) ccsf=false;
187#ifdef debug
188      G4cout<<"G4QDiffraction::GMFP: GetCS #1 j="<<j<<G4endl;
189#endif
190      G4double CSI=CalculateXS(Momentum, Z, N, pPDG); // XS(j,i) for theIsotope
191
192#ifdef debug
193      G4cout<<"G4QDiffraction::GetMeanFreePath: jI="<<j<<", Zt="<<Z<<", Nt="<<N<<", Mom="
194            <<Momentu<<", XSec="<<CSI/millibarn<<G4endl;
195#endif
196      curIs->second = CSI;
197      susi+=CSI;                            // Make a sum per isotopes
198      SPI->push_back(susi);                 // Remember summed cross-section
199    } // End of temporary initialization of the cross sections in the G4QIsotope singeltone
200    sigma+=Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i];//SUM(MeanCS*NOfNperV)
201#ifdef debug
202    G4cout<<"G4QDiffraction::GetMeanFreePath:<XS>="<<Isotopes->GetMeanCrossSection(Z,indEl)
203          <<",AddSigm="<<Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i]<<G4endl;
204#endif
205    ElProbInMat.push_back(sigma);
206  } // End of LOOP over Elements
207  // Check that cross section is not zero and return the mean free path
208#ifdef debug
209  G4cout<<"G4QDiffraction::GetMeanFreePath: MeanFreePath="<<1./sigma<<G4endl;
210#endif
211  if(sigma > 0.) return 1./sigma;                 // Mean path [distance]
212  return DBL_MAX;
213}
214
215G4bool G4QDiffraction::IsApplicable(const G4ParticleDefinition& particle) 
216{
217  if      (particle == *(        G4Proton::Proton()        )) return true;
218  else if (particle == *(       G4Neutron::Neutron()       )) return true;
219  //else if (particle == *(     G4MuonMinus::MuonMinus()     )) return true;
220  //else if (particle == *(       G4TauPlus::TauPlus()       )) return true;
221  //else if (particle == *(      G4TauMinus::TauMinus()      )) return true;
222  //else if (particle == *(      G4Electron::Electron()      )) return true;
223  //else if (particle == *(      G4Positron::Positron()      )) return true;
224  //else if (particle == *(         G4Gamma::Gamma()         )) return true;
225  //else if (particle == *(      G4MuonPlus::MuonPlus()      )) return true;
226  //else if (particle == *(G4AntiNeutrinoMu::AntiNeutrinoMu())) return true;
227  //else if (particle == *(    G4NeutrinoMu::NeutrinoMu()    )) return true;
228  //else if (particle == *(     G4PionMinus::PionMinus()     )) return true;
229  //else if (particle == *(      G4PionPlus::PionPlus()      )) return true;
230  //else if (particle == *(      G4KaonPlus::KaonPlus()      )) return true;
231  //else if (particle == *(     G4KaonMinus::KaonMinus()     )) return true;
232  //else if (particle == *(  G4KaonZeroLong::KaonZeroLong()  )) return true;
233  //else if (particle == *( G4KaonZeroShort::KaonZeroShort() )) return true;
234  //else if (particle == *(        G4Lambda::Lambda()        )) return true;
235  //else if (particle == *(     G4SigmaPlus::SigmaPlus()     )) return true;
236  //else if (particle == *(    G4SigmaMinus::SigmaMinus()    )) return true;
237  //else if (particle == *(     G4SigmaZero::SigmaZero()     )) return true;
238  //else if (particle == *(       G4XiMinus::XiMinus()       )) return true;
239  //else if (particle == *(        G4XiZero::XiZero()        )) return true;
240  //else if (particle == *(    G4OmegaMinus::OmegaMinus()    )) return true;
241  //else if (particle == *(   G4AntiNeutron::AntiNeutron()   )) return true;
242  //else if (particle == *(    G4AntiProton::AntiProton()    )) return true;
243#ifdef debug
244  G4cout<<"***>>G4QDiffraction::IsApplicable: projPDG="<<particle.GetPDGEncoding()<<G4endl;
245#endif
246  return false;
247}
248
249G4VParticleChange* G4QDiffraction::PostStepDoIt(const G4Track& track, const G4Step& step)
250{
251  static const G4double mProt= G4QPDGCode(2212).GetMass();     // CHIPS proton Mass in MeV
252  static const G4double mNeut= G4QPDGCode(2112).GetMass();     // CHIPS neutron Mass in MeV
253  static const G4double mPion= G4QPDGCode(111).GetMass();      // CHIPS Pi0 Mass in MeV
254  static G4QDiffractionRatio* diffRatio;
255  //
256  //-------------------------------------------------------------------------------------
257  static G4bool CWinit = true;                       // CHIPS Warld needs to be initted
258  if(CWinit)
259  {
260    CWinit=false;
261    G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part.max)
262    diffRatio=G4QDiffractionRatio::GetPointer();
263  }
264  //-------------------------------------------------------------------------------------
265  const G4DynamicParticle* projHadron = track.GetDynamicParticle();
266  const G4ParticleDefinition* particle=projHadron->GetDefinition();
267#ifdef debug
268  G4cout<<"G4QDiffraction::PostStepDoIt: Before the GetMeanFreePath is called In4M="
269        <<projHadron->Get4Momentum()<<" of PDG="<<particle->GetPDGEncoding()<<", Type="
270        <<particle->GetParticleType()<<",SubType="<<particle->GetParticleSubType()<<G4endl;
271#endif
272  G4ForceCondition cond=NotForced;
273  GetMeanFreePath(track, -27., &cond);                  // @@ ?? jus to update parameters?
274#ifdef debug
275  G4cout<<"G4QDiffraction::PostStepDoIt: After GetMeanFreePath is called"<<G4endl;
276#endif
277  G4LorentzVector proj4M=(projHadron->Get4Momentum())/MeV; // Convert to MeV!
278  G4double momentum = projHadron->GetTotalMomentum()/MeV; // 3-momentum of the Proj in MeV
279  G4double Momentum = proj4M.rho();                   // @@ Just for the test purposes
280  if(std::fabs(Momentum-momentum)>.000001)
281    G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt:P_IU="<<Momentum<<"#"<<momentum<<G4endl;
282#ifdef pdebug
283  G4cout<<"G4QDiffraction::PostStepDoIt: pP(IU)="<<Momentum<<"="<<momentum
284        <<",proj4M="<<proj4M<<", projM="<<proj4M.m()<<G4endl;
285#endif
286  if (!IsApplicable(*particle))  // Check applicability
287  {
288    G4cerr<<"G4QDiffraction::PostStepDoIt: Only NA is implemented."<<G4endl;
289    return 0;
290  }
291  const G4Material* material = track.GetMaterial();      // Get the current material
292  G4int Z=0;
293  const G4ElementVector* theElementVector = material->GetElementVector();
294  G4int nE=material->GetNumberOfElements();
295#ifdef debug
296  G4cout<<"G4QDiffraction::PostStepDoIt: "<<nE<<" elements in the material."<<G4endl;
297#endif
298  G4int projPDG=0;                           // PDG Code prototype for the captured hadron
299  // Not all these particles are implemented yet (see Is Applicable)
300  if      (particle ==          G4Proton::Proton()         ) projPDG= 2212;
301  else if (particle ==         G4Neutron::Neutron()        ) projPDG= 2112;
302  //else if (particle ==       G4PionMinus::PionMinus()      ) projPDG= -211;
303  //else if (particle ==        G4PionPlus::PionPlus()       ) projPDG=  211;
304  //else if (particle ==        G4KaonPlus::KaonPlus()       ) projPDG=  321;
305  //else if (particle ==       G4KaonMinus::KaonMinus()      ) projPDG= -321;
306  //else if (particle ==    G4KaonZeroLong::KaonZeroLong()   ) projPDG=  130;
307  //else if (particle ==   G4KaonZeroShort::KaonZeroShort()  ) projPDG=  310;
308  //else if (particle ==        G4MuonPlus::MuonPlus()       ) projPDG=  -13;
309  //else if (particle ==       G4MuonMinus::MuonMinus()      ) projPDG=   13;
310  //else if (particle ==      G4NeutrinoMu::NeutrinoMu()     ) projPDG=   14;
311  //else if (particle ==  G4AntiNeutrinoMu::AntiNeutrinoMu() ) projPDG=  -14;
312  //else if (particle ==        G4Electron::Electron()       ) projPDG=   11;
313  //else if (particle ==        G4Positron::Positron()       ) projPDG=  -11;
314  //else if (particle ==       G4NeutrinoE::NeutrinoE()      ) projPDG=   12;
315  //else if (particle ==   G4AntiNeutrinoE::AntiNeutrinoE()  ) projPDG=  -12;
316  //else if (particle ==           G4Gamma::Gamma()          ) projPDG=   22;
317  //else if (particle ==         G4TauPlus::TauPlus()        ) projPDG=  -15;
318  //else if (particle ==        G4TauMinus::TauMinus()       ) projPDG=   15;
319  //else if (particle ==     G4NeutrinoTau::NeutrinoTau()    ) projPDG=   16;
320  //else if (particle == G4AntiNeutrinoTau::AntiNeutrinoTau()) projPDG=  -16;
321  //else if (particle ==          G4Lambda::Lambda()         ) projPDG= 3122;
322  //else if (particle ==       G4SigmaPlus::SigmaPlus()      ) projPDG= 3222;
323  //else if (particle ==      G4SigmaMinus::SigmaMinus()     ) projPDG= 3112;
324  //else if (particle ==       G4SigmaZero::SigmaZero()      ) projPDG= 3212;
325  //else if (particle ==         G4XiMinus::XiMinus()        ) projPDG= 3312;
326  //else if (particle ==          G4XiZero::XiZero()         ) projPDG= 3322;
327  //else if (particle ==      G4OmegaMinus::OmegaMinus()     ) projPDG= 3334;
328  //else if (particle ==     G4AntiNeutron::AntiNeutron()    ) projPDG=-2112;
329  //else if (particle ==      G4AntiProton::AntiProton()     ) projPDG=-2212;
330#ifdef debug
331  G4int prPDG=particle->GetPDGEncoding();
332  G4cout<<"G4QDiffraction::PostStepDoIt: projPDG="<<projPDG<<", stPDG="<<prPDG<<G4endl;
333#endif
334  if(!projPDG)
335  {
336    G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt:UndefProjHadron(PDG=0) ->ret 0"<<G4endl;
337    return 0;
338  }
339  //G4double pM2=proj4M.m2();        // in MeV^2
340  //G4double pM=std::sqrt(pM2);      // in MeV
341  G4double pM=mNeut;
342  G4int    fPDG=2112;
343  if(projPDG==2112)
344  {
345    pM=mProt;
346    fPDG=2212;
347  }
348  // Element treatment
349  G4int EPIM=ElProbInMat.size();
350#ifdef debug
351  G4cout<<"G4QDiffra::PostStDoIt: m="<<EPIM<<",n="<<nE<<",T="<<ElProbInMat[EPIM-1]<<G4endl;
352#endif
353  G4int i=0;
354  if(EPIM>1)
355  {
356    G4double rnd = ElProbInMat[EPIM-1]*G4UniformRand();
357    for(i=0; i<nE; ++i)
358    {
359#ifdef debug
360      G4cout<<"G4QDiffra::PostStepDoIt: EPM["<<i<<"]="<<ElProbInMat[i]<<",r="<<rnd<<G4endl;
361#endif
362      if (rnd<ElProbInMat[i]) break;
363    }
364    if(i>=nE) i=nE-1;                        // Top limit for the Element
365  }
366  G4Element* pElement=(*theElementVector)[i];
367  Z=static_cast<G4int>(pElement->GetZ());
368#ifdef debug
369    G4cout<<"G4QDiffraction::PostStepDoIt: i="<<i<<", Z(element)="<<Z<<G4endl;
370#endif
371  if(Z<=0)
372  {
373    G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt: Element with Z="<<Z<<G4endl;
374    if(Z<0) return 0;
375  }
376  std::vector<G4double>* SPI = IsoProbInEl[i];// Vector of summedProbabilities for isotopes
377  std::vector<G4int>* IsN = ElIsoN[i];     // Vector of "#of neutrons" in the isotope El[i]
378  G4int nofIsot=SPI->size();               // #of isotopes in the element i
379#ifdef debug
380  G4cout<<"G4QDiffraction::PostStepDoIt: nI="<<nofIsot<<", T="<<(*SPI)[nofIsot-1]<<G4endl;
381#endif
382  G4int j=0;
383  if(nofIsot>1)
384  {
385    G4double rndI=(*SPI)[nofIsot-1]*G4UniformRand(); // Randomize the isotop of the Element
386    for(j=0; j<nofIsot; ++j)
387    {
388#ifdef debug
389      G4cout<<"G4QDiffraction::PostStepDoIt: SP["<<j<<"]="<<(*SPI)[j]<<",r="<<rndI<<G4endl;
390#endif
391      if(rndI < (*SPI)[j]) break;
392    }
393    if(j>=nofIsot) j=nofIsot-1;            // Top limit for the isotope
394  }
395  G4int N =(*IsN)[j]; ;                    // Randomized number of neutrons
396#ifdef debug
397  G4cout<<"G4QDiffraction::PostStepDoIt: j="<<i<<", N(isotope)="<<N<<", MeV="<<MeV<<G4endl;
398#endif
399  if(N<0)
400  {
401    G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt: Isotope Z="<<Z<<" has 0>N="<<N<<G4endl;
402    return 0;
403  }
404  nOfNeutrons=N;                           // Remember it for the energy-momentum check
405#ifdef debug
406  G4cout<<"G4QDiffraction::PostStepDoIt: N="<<N<<" for element with Z="<<Z<<G4endl;
407#endif
408  if(N<0)
409  {
410    G4cerr<<"*Warning*G4QDiffraction::PostStepDoIt:Element with N="<<N<< G4endl;
411    return 0;
412  }
413  aParticleChange.Initialize(track);
414#ifdef debug
415  G4cout<<"G4QDiffraction::PostStepDoIt: track is initialized"<<G4endl;
416#endif
417  G4double      weight    = track.GetWeight();
418  G4double      localtime = track.GetGlobalTime();
419  G4ThreeVector position  = track.GetPosition();
420#ifdef debug
421  G4cout<<"G4QDiffraction::PostStepDoIt: before Touchable extraction"<<G4endl;
422#endif
423  G4TouchableHandle trTouchable = track.GetTouchableHandle();
424#ifdef debug
425  G4cout<<"G4QDiffraction::PostStepDoIt: Touchable is extracted"<<G4endl;
426#endif
427  G4int targPDG=90000000+Z*1000+N;         // CHIPS PDG Code of the target nucleus
428  G4QPDGCode targQPDG(targPDG);            // @@ use G4Ion and get rid of CHIPS World
429  G4double tM=targQPDG.GetMass();          // CHIPS final nucleus mass in MeV
430  G4double kinEnergy= projHadron->GetKineticEnergy()*MeV; // Kin energy in MeV (Is *MeV n?)
431  G4ParticleMomentum dir = projHadron->GetMomentumDirection();// It is a unit three-vector
432  G4LorentzVector tot4M=proj4M+G4LorentzVector(0.,0.,0.,tM); // Total 4-mom of the reaction
433#ifdef debug
434  G4cout<<"G4QDiffraction::PostStepDoIt: tM="<<tM<<",p4M="<<proj4M<<",t4M="<<tot4M<<G4endl;
435#endif
436  EnMomConservation=tot4M;                 // Total 4-mom of reaction for E/M conservation
437  // @@ Probably this is not necessary any more
438#ifdef debug
439  G4cout<<"G4QDiff::PSDI:false,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<projPDG<<G4endl;
440#endif
441  G4double xSec=CalculateXS(Momentum, Z, N, projPDG); // Recalculate CrossSection
442#ifdef debug
443  G4cout<<"G4QDiffra::PSDI:PDG="<<projPDG<<",P="<<Momentum<<",XS="<<xSec/millibarn<<G4endl;
444#endif
445#ifdef nandebug
446  if(xSec>0. || xSec<0. || xSec==0);
447  else  G4cout<<"-Warning-G4QDiffraction::PostSDI: *NAN* xSec="<<xSec/millibarn<<G4endl;
448#endif
449  // @@ check a possibility to separate p, n, or alpha (!)
450  if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing
451  {
452#ifdef pdebug
453    G4cerr<<"*Warning*G4QDiffraction::PSDoIt:*Zero cross-section* PDG="<<projPDG
454          <<",tPDG="<<targPDG<<",P="<<Momentum<<G4endl;
455#endif
456    //Do Nothing Action insead of the reaction
457    aParticleChange.ProposeEnergy(kinEnergy);
458    aParticleChange.ProposeLocalEnergyDeposit(0.);
459    aParticleChange.ProposeMomentumDirection(dir) ;
460    return G4VDiscreteProcess::PostStepDoIt(track,step);
461  }
462  G4double totCMMass=tot4M.m(); // Total CM mass, pM=projectileMass, tM=targetMass
463  if(totCMMass < mPion+pM+tM) // The diffraction reaction is impossible -> Do Nothing
464  {
465#ifdef pdebug
466    G4cerr<<"*Warning*G4QDiffraction::PSDoIt:*Below Diffraction Threshold* cmM="<<totCMMass
467          <<">pM="<<pM<<"+tM="<<tM<<"+pi0="<<mPion<<"=="<<pM+tM+mPion<<G4endl;
468#endif
469    //Do Nothing Action insead of the reaction
470    aParticleChange.ProposeEnergy(kinEnergy);
471    aParticleChange.ProposeLocalEnergyDeposit(0.);
472    aParticleChange.ProposeMomentumDirection(dir) ;
473    return G4VDiscreteProcess::PostStepDoIt(track,step);
474  }
475  // Kill interacting hadron
476  aParticleChange.ProposeTrackStatus(fStopAndKill);
477  G4QHadronVector* out=diffRatio->TargFragment(projPDG, proj4M, Z, N);
478  G4int nSec=out->size();             // #of secondaries in the diffraction reaction
479  G4DynamicParticle* theSec=0;        // A prototype for secondary for the secondary
480  G4LorentzVector dif4M(0.,0.,0.,0.); // Prototype for the secondary 4-momentum
481  G4int difPDG=0;                     // PDG code of the secondary
482  G4QHadron* difQH=0;                 // Prototype for a Q-secondary
483#ifdef pdebug
484  G4cout<<"G4QDiffraction::PostStepDoIt: =====found===== nSecondaries="<<nSec<<G4endl;
485#endif
486  for(G4int i=0; i<nSec; i++)
487  {
488    difQH = (*out)[i];
489    difPDG= difQH->GetPDGCode();
490    G4ParticleDefinition*  theDefinition=0;
491    if     (difPDG==2212 || difPDG==90001000) theDefinition=G4Proton::Proton();
492    else if(difPDG==2112 || difPDG==90000001) theDefinition=G4Neutron::Neutron();
493    else if(difPDG==  22) theDefinition=G4Gamma::Gamma();
494    else if(difPDG== 111) theDefinition=G4PionZero::PionZero();
495    else if(difPDG==-211 || difPDG==89999001) theDefinition=G4PionMinus::PionMinus();
496    else if(difPDG== 211 || difPDG==90000999) theDefinition=G4PionPlus::PionPlus();
497    else if(difPDG== 321 || difPDG==89001000) theDefinition=G4KaonPlus::KaonPlus();
498    else if(difPDG==-321 || difPDG==90999000) theDefinition=G4KaonMinus::KaonMinus();
499    else if(difPDG== 130 || difPDG==-311 || difPDG==89000001)
500                                              theDefinition=G4KaonZeroLong::KaonZeroLong();
501    else if(difPDG== 310 || difPDG== 311 || difPDG==90999999)
502                                            theDefinition=G4KaonZeroShort::KaonZeroShort();
503    else if(difPDG==3122 || difPDG==91000000) theDefinition=G4Lambda::Lambda();
504    else if(difPDG== 3222) theDefinition=G4SigmaPlus::SigmaPlus();
505    else if(difPDG== 3112) theDefinition=G4SigmaMinus::SigmaMinus();
506    else if(difPDG== 3212) theDefinition=G4SigmaZero::SigmaZero();
507    else if(difPDG== 3312) theDefinition=G4XiMinus::XiMinus();
508    else if(difPDG== 3322) theDefinition=G4XiZero::XiZero();
509    else if(difPDG== 3334) theDefinition=G4OmegaMinus::OmegaMinus();
510    else if(difPDG==-2112) theDefinition=G4AntiNeutron::AntiNeutron();
511    else if(difPDG==-2212) theDefinition=G4AntiProton::AntiProton();
512    else if(difPDG==-3122) theDefinition=G4AntiLambda::AntiLambda();
513    else if(difPDG==-3222) theDefinition=G4AntiSigmaPlus::AntiSigmaPlus();
514    else if(difPDG==-3112) theDefinition=G4AntiSigmaMinus::AntiSigmaMinus();
515    else if(difPDG==-3212) theDefinition=G4AntiSigmaZero::AntiSigmaZero();
516    else if(difPDG==-3312) theDefinition=G4AntiXiMinus::AntiXiMinus();
517    else if(difPDG==-3322) theDefinition=G4AntiXiZero::AntiXiZero();
518    else if(difPDG==-3334) theDefinition=G4AntiOmegaMinus::AntiOmegaMinus();
519    else if(difPDG==  -11) theDefinition=G4Electron::Electron();
520    else if(difPDG==  -13) theDefinition=G4MuonMinus::MuonMinus();
521    else if(difPDG==   11) theDefinition=G4Positron::Positron();
522    else if(difPDG==   13) theDefinition=G4MuonPlus::MuonPlus();
523    else
524    {
525      G4int Z = difQH->GetCharge();
526      G4int B = difQH->GetBaryonNumber();
527      G4int S = difQH->GetStrangeness();
528      if(S||Z>B||Z<0)G4cout<<"-Warning-G4QDif::PoStDoIt:Z="<<Z<<",A="<<B<<",S="<<S<<G4endl;
529      theDefinition = G4ParticleTable::GetParticleTable()->FindIon(Z,B,0,0);
530#ifdef pdebug
531      G4cout<<"G4QDiffraction::PoStDoIt:Ion,Z="<<Z<<",A="<<B<<",D="<<theDefinition<<G4endl;
532#endif
533    }
534    if(theDefinition)
535    {
536      theSec = new G4DynamicParticle;       // A secondary for the recoil hadron
537      theSec->SetDefinition(theDefinition);
538      dif4M  = difQH->Get4Momentum();
539      EnMomConservation-=dif4M;
540      theSec->Set4Momentum(dif4M);
541      G4Track* aNewTrack = new G4Track(theSec, localtime, position );
542      aNewTrack->SetWeight(weight);                                   //    weighted
543      aNewTrack->SetTouchableHandle(trTouchable);
544      aParticleChange.AddSecondary( aNewTrack );
545#ifdef pdebug
546      G4cout<<"G4QDiffraction::PostStepDoIt: Filled 4M="<<dif4M<<", PDG="<<difPDG<<G4endl;
547#endif
548    }
549    else G4cout<<"-Warning-G4QDif::PSDI: Lost PDG="<<difPDG<<", Z="<<difQH->GetCharge()
550               <<", A="<<difQH->GetBaryonNumber()<<",S ="<<difQH->GetStrangeness()<<G4endl;
551    delete difQH; // Clean up the output QHadrons
552  }
553  delete out;     // Delete the output QHadron-vector
554#ifdef debug
555  G4cout<<"G4QDiffraction::PostStepDoIt:*** PostStepDoIt is done ***"<<G4endl;
556#endif
557  return G4VDiscreteProcess::PostStepDoIt(track, step);
558}
559
560G4double G4QDiffraction::CalculateXS(G4double p, G4int Z, G4int N, G4int PDG) 
561{
562  static G4bool first=true;
563  static G4VQCrossSection* CSmanager;
564  static G4QDiffractionRatio* diffRatio;
565  if(first)                              // Connection with a singletone
566  {
567    CSmanager=G4QProtonNuclearCrossSection::GetPointer();
568    diffRatio=G4QDiffractionRatio::GetPointer();
569    first=false;
570  }
571  //G4double x=CSmanager->GetCrossSection(true, p, Z, N, PDG); // inelastic XS
572  //G4double pIU=p*GeV;                                        // IndependentUnistMomentum
573  //G4double r=diffRatio->GetRatio(pIU, PDG, Z, N);            // Proj. Diffraction Part
574  //G4double s=x*r;                                            // XS for proj. diffraction
575  G4double s=diffRatio->GetTargSingDiffXS(p, PDG, Z, N);     // XS for target diffraction
576#ifdef debug
577  G4cout<<"G4QDiff::CXS:p="<<p<<",Z="<<Z<<",N="<<N<<",C="<<PDG<<",XS="<<s<<G4endl;
578#endif
579  return s;
580}
Note: See TracBrowser for help on using the repository browser.