Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4QFragmentation Class Reference

#include <G4QFragmentation.hh>

Public Member Functions

 G4QFragmentation (const G4QNucleus &aNucleus, const G4QHadron &aPrimary)
 
 ~G4QFragmentation ()
 
G4QHadronVectorFragment ()
 

Static Public Member Functions

static void SetParameters (G4int nC, G4double strTens, G4double tubeDens, G4double SigPt)
 

Protected Member Functions

G4bool ExciteDiffParticipants (G4QHadron *aPartner, G4QHadron *bPartner) const
 
G4bool ExciteSingDiffParticipants (G4QHadron *aPartner, G4QHadron *bPartner) const
 
std::pair< G4int, G4intReducePair (G4int P1, G4int P2) const
 
void Breeder ()
 
G4bool IsSingleDiffractive ()
 
G4int SumPartonPDG (G4int PDG1, G4int PFG2) const
 
G4double ChooseX (G4double Xmin, G4double Xmax) const
 
G4ThreeVector GaussianPt (G4double widthSquare, G4double maxPtSquare) const
 
G4int AnnihilationOrder (G4int LS, G4int MS, G4int uP, G4int mP, G4int sP, G4int nP)
 
void SwapPartons ()
 
void EvaporateResidual (G4QHadron *hadrNuc)
 

Detailed Description

Definition at line 60 of file G4QFragmentation.hh.

Constructor & Destructor Documentation

◆ G4QFragmentation()

G4QFragmentation::G4QFragmentation ( const G4QNucleus aNucleus,
const G4QHadron aPrimary 
)

Definition at line 68 of file G4QFragmentation.cc.

69{
70 static const G4double mProt= G4QPDGCode(2212).GetMass(); // Mass of proton
71 static const G4double mProt2= mProt*mProt; // SquaredMass of proton
72 static const G4double mPi0= G4QPDGCode(111).GetMass(); // Mass of Pi0
73 static const G4double thresh= 1000; // Diffraction threshold (MeV)
74 theWorld= G4QCHIPSWorld::Get(); // Pointer to CHIPS World
75 theQuasiElastic=G4QuasiFreeRatios::GetPointer(); // Pointer to CHIPS quasiElastic
76 theDiffraction=G4QDiffractionRatio::GetPointer(); // Pointer to CHIPS Diffraction
77 theResult = new G4QHadronVector; // Define theResultingHadronVector
78 G4bool stringsInitted=false; // Strings are initiated
79 G4QHadron aProjectile = aPrimary; // As a primary is const
80 G4LorentzRotation toZ; // Lorentz Transformation to the projectileSystem
81 G4LorentzVector proj4M=aProjectile.Get4Momentum(); // Projectile 4-momentum in LS
82#ifdef edebug
83 G4LorentzVector targ4M=aProjectile.Get4Momentum(); // Target 4-momentum in LS
84 G4double tgMass=aNucleus.GetGSMass(); // Ground state mass of the nucleus
85 G4double cM=0.;
86 G4double cs=(proj4M+targ4M).mag2(); // s of the compound
87 if(cs > 0.) cM=std::sqrt(cs);
88 G4cout<<"G4QFragmentation::Construct: *Called*, p4M="<<proj4M<<", A="<<aNucleus<<tgMass
89 <<",M="<<cM<<",s="<<cs<<",t4M="<<targ4M<<G4endl;
90#endif
91 G4int tZ=aNucleus.GetZ();
92 G4int tN=aNucleus.GetN();
93 G4int tPDG=90000000+tZ*1000+tN;
94 toZ.rotateZ(-proj4M.phi());
95 toZ.rotateY(-proj4M.theta());
96 G4LorentzVector zProj4M=toZ*proj4M; // Proj 4-momentum in LS rotated to Z axis
97 aProjectile.Set4Momentum(zProj4M); // Now the projectile moves along Z axis
98#ifdef edebug
99 G4int totChg=aProjectile.GetCharge()+tZ;// Charge of the projectile+target for the CHECK
100 G4int totBaN=aProjectile.GetBaryonNumber()+tZ+tN;// Baryon Number of Proj+Targ for CHECK
101 G4LorentzVector tgLS4M(0.,0.,0.,tgMass);// Target 4-momentum in LS
102 G4LorentzVector totLS4M=proj4M+tgLS4M; // Total 4-momentum in LS
103 G4LorentzVector totZLS4M=zProj4M+tgLS4M;// Total 4-momentum in LS with momentum along Z
104 G4cout<<"-EMC-G4QFragmentation::Construct:tLS4M="<<totLS4M<<",tZLS4M="<<totZLS4M<<G4endl;
105 // === From nere all consideration is made in the rotated LS frame (proj is along Z) ===
106#endif
107 G4LorentzRotation toLab(toZ.inverse()); // Lorentz Transfornation "ZLS"->LS (at the end)
108 G4int pPDG=aProjectile.GetPDGCode(); // The PDG code of the projectile
109 G4double projM=aProjectile.GetMass(); // Mass of the projectile
110 G4QInteractionVector theInteractions; // A vector of interactions (taken from the Body)
111 G4QPartonPairVector thePartonPairs; // The parton pairs (taken from the Body)
112 G4int ModelMode=SOFT; // The current model type (taken from the Body)
113 theNucleus=G4QNucleus(tZ,tN); // Create theNucleus (Body) to Move From LS to CM
114 theNucleus.InitByPDG(tPDG); // Reinit the Nucleus for the new Attempt
115#ifdef debug
116 G4cout<<"G4QFragmentation::Construct: Nucleus4Mom="<<theNucleus.Get4Momentum()<<G4endl;
117#endif
118 theNucleus.Init3D(); // 3D-initialisation(nucleons) of theNucleusClone
119 // Now we can make the Quasi-Elastic (@@ Better to select a nucleon from the perifery)
120 std::pair<G4double,G4double> ratios=std::make_pair(0.,0.);
121 G4int apPDG=std::abs(pPDG);
122 if(apPDG>99) // Diffraction or Quasi-elastic
123 {
124 G4double pMom=proj4M.vect().mag(); // proj.Momentum in MeV (indepUnits)
125 ratios = theQuasiElastic->GetRatios(pMom, pPDG, tZ, tN);
126 G4double qeRat = ratios.first*ratios.second; // quasi-elastic part [qe/in]
127 G4double difRat= theDiffraction->GetRatio(pMom, pPDG, tZ, tN); // diffrPart [d/(in-qe)]
128 //if(qeRat < 1.) difRat /= (1.-qeRat)*.5; // Double for Top/Bottom @@ ?
129 if(qeRat<1. && proj4M.e()>thresh) difRat /= 1.-qeRat; // Both Top & Bottom
130 else difRat=0.; // Close diffraction for low Energy
131 difRat += qeRat; // for the diffraction selection
133 if(rnd < qeRat) // --> Make Quasi-Elastic reaction
134 {
135 theNucleus.StartLoop(); // Prepare Loop ovder nucleons
136 G4QHadron* pNucleon = theNucleus.GetNextNucleon(); // Get the next nucleon to try
137 G4LorentzVector pN4M=pNucleon->Get4Momentum(); // Selected Nucleon 4-momentum
138 G4int pNPDG=pNucleon->GetPDGCode(); // Selected Nucleon PDG code
139#ifdef debug
140 G4cout<<">QE>G4QFragmentation::Construct:TryQE,R="<<ratios.first*ratios.second<<",N4M="
141 <<pN4M<<",NPDG="<<pNPDG<<G4endl;
142#endif
143 std::pair<G4LorentzVector,G4LorentzVector> QEout=theQuasiElastic->Scatter(pNPDG,pN4M,
144 pPDG,proj4M);
145 G4bool CoulB = true; // No Under Coulomb Barrier flag
146 G4double CB=theNucleus.CoulombBarrier(1, 1); // Coulomb barrier for protons
147 if( (pNPDG==2212 && QEout.first.e()-mProt < CB) ||
148 (pPDG==2212 && QEout.second.e()-mProt < CB) ) CoulB = false; // at least one UCB
149 if(QEout.first.e() > 0 && CoulB) // ==> Successful scattering
150 {
151 G4QHadron* qfN = new G4QHadron(pNPDG,QEout.first);
152 theResult->push_back(qfN); // Scattered Quasi-free nucleon
153 G4QHadron* qfP = new G4QHadron(pPDG,QEout.second);
154 theResult->push_back(qfP); // Scattered Projectile
155 theNucleus.SubtractNucleon(pNucleon); // Exclude the used nucleon from Nuc
156 G4LorentzVector r4M=theNucleus.Get4Momentum(); // Nucleus 4-momentum in LS
157 G4int rPDG=theNucleus.GetPDG(); // Nuclear PDG
158 G4QHadron* resNuc = new G4QHadron(rPDG,r4M); // The residual Nucleus
159 theResult->push_back(resNuc); // Fill the residual nucleus
160#ifdef debug
161 G4cout<<"-->QE-->G4QFragmentation::Construct:QEDone, N4M="<<QEout.first<<", p4M="
162 <<QEout.second<<G4endl;
163#endif
164 return; // The Quasielastic is the only act
165 }
166 } // End of quasi-elastic reaction
167 else if(rnd < difRat) // --> Make diffractive reaction
168 {
169#ifdef debug
170 G4cout<<"-->Dif-->G4QFragmentation::Construct: qe="<<qeRat<<", dif="<<difRat-qeRat
171 <<",P="<<proj4M.vect().mag()<<", tZ="<<tZ<<", tN="<<tN<<G4endl;
172#endif
173 G4QHadronVector* out=0;
174 //if(G4UniformRand()>0.5) out=theDiffraction->TargFragment(pPDG, proj4M, tZ, tN);
175 //else out=theDiffraction->ProjFragment(pPDG, proj4M, tZ, tN);
176 //theDiffraction->TargFragment(pPDG, proj4M, tZ, tN); // !! is not debugged !!
177 out=theDiffraction->ProjFragment(pPDG, proj4M, tZ, tN);
178 G4int nSec=out->size(); // #of secondaries in diffReaction
179 if(nSec>1) for(G4int i=0; i<nSec; i++) theResult->push_back((*out)[i]);
180 else if(nSec>0)
181 {
182#ifdef debug
183 G4cout<<"-Warning-G4QFragmentation::Construct: 1 secondary in Diffractionp 4M="
184 <<proj4M<<", s4M="<<(*out)[0]->Get4Momentum()<<G4endl;
185#endif
186 delete (*out)[0];
187 }
188 out->clear(); // Clean up the output QHadronVector
189 delete out; // Delete the output QHadronVector
190 if(nSec>1) return;
191 } // End of diffraction
192 }
193#ifdef edebug
194 G4LorentzVector sum1=theNucleus.GetNucleons4Momentum(); // Sum ofNucleons4M inRotatedLS
195 G4cout<<"-EMC-G4QFragmentation::Construct: Nuc4M="<<sum1<<G4endl;
196#endif
197 G4ThreeVector theCurrentVelocity(0.,0.,0.); // "CM" velosity (temporary)
198 // @@ "target Nucleon" == "Proton at rest" case (M.K. ?)
199 G4double nCons = 1; // 1 or baryonNum of the Projectile
200 G4int projAbsB=std::abs(aProjectile.GetBaryonNumber());// Fragment/Baryon (Meson/AntiB)
201 if(projAbsB>1) nCons = projAbsB; // @@ what if this is a meson ?
202 // Very important! Here the projectile 4M is recalculated in the ZLS (previously in LS)
203 proj4M = aProjectile.Get4Momentum(); // 4-mom of theProjectileHadron inZLS
204 G4double pz_per_projectile = proj4M.pz()/nCons; // Momentum per nucleon (hadron?)
205 // @@ use M_A/A instead of mProt ------------ M.K.
206 G4double e_per_projectile = proj4M.e()/nCons+mProt;// @@ Add MassOfTargetProtonAtRest
207 G4double vz = pz_per_projectile/e_per_projectile; // Speed of the "oneNuclenCM"
208#ifdef debug
209 G4cout<<"G4QFragmentation::Construct: Projectile4M="<<proj4M<<", Vz="<<vz<<", nC="
210 <<nCons<<", pE="<<e_per_projectile<<G4endl;
211#endif
212 theCurrentVelocity.setZ(vz); // CM (w/r to one nucleon) velosity
213 theNucleus.DoLorentzBoost(-theCurrentVelocity); // BoostTgNucleus to"CM"
214#ifdef edebug
215 G4LorentzVector sum2=theNucleus.GetNucleons4Momentum();// Sum of Nucleons 4M in RotatedCM
216 G4cout<<"-EMC-G4QFragmentation::Construct: AfterBoost, v="<<vz<<", Nuc4M="<<sum2<<G4endl;
217#endif
218 G4LorentzVector cmProjMom = proj4M; // Copy the original proj4M in LS
219 cmProjMom.boost(-theCurrentVelocity); // Bring the LS proj4Mom to "CM"
220 G4double kE=cmProjMom.e()-projM;
221#ifdef debug
222 G4cout<<"G4QFragmentation::Construct: kE="<<kE<<G4endl;
223#endif
224 G4int maxCt=1;
225 if(kE > 720.) maxCt=static_cast<int>(std::log(kE/270.)); // 270 MeV !
226 // @@ The maxCuts can improve the performance at low energies
227 //G4int maxCuts = 7;
228 G4int maxCuts=std::min( 7 , std::max(1, maxCt) );
229#ifdef debug
230 G4cout<<"G4QFragmentation::Construct: Proj4MInCM="<<cmProjMom<<", pPDG="<<pPDG<<G4endl;
231#endif
232 //
233 // ---------->> Find collisions meeting collision conditions
234 //
235 G4QHadron* cmProjectile = new G4QHadron(pPDG,cmProjMom); // HipCopy of the CMProjectile
236 // @@ Do not forget to delete the probability!
237 G4QProbability theProbability(pPDG); // thePDG must be a data member
238 G4double outerRadius = theNucleus.GetOuterRadius();// Get the nucleus frontiers
239#ifdef debug
240 G4cout<<"G4QFrag::Constr:OutR="<<outerRadius<<",mC="<<maxCuts<<",A="<<theNucleus<<G4endl;
241#endif
242 G4QHadron* pNucleon=0;
243 // Check the reaction threshold
244 G4int theNA=theNucleus.GetA();
245 G4LorentzVector pNuc4M=theNucleus.Get4Momentum()/theNA;
246 G4double s_value = (cmProjMom + pNuc4M).mag2(); // Squared CM Energy of compound
247 G4double ThresholdMass = projM + theNucleus.GetGSMass()/theNA;
248#ifdef debug
249 G4cout<<"G4QFrag::Construc: p4M="<<cmProjMom<<", tgN4M="<<pNuc4M<<", s="<<s_value<<", ThreshM="
250 <<ThresholdMass<<G4endl;
251#endif
252 ModelMode = SOFT; // NOT-Diffractive hadronization
253 if (s_value < 0.) // At ThP=0 is impossible(virtNucl)
254 {
255 G4cerr<<"***G4QFragmentation::Construct: s="<<s_value<<", pN4M="<<pNuc4M<<G4endl;
256 G4Exception("G4QFragmentation::Construct:","72",FatalException,"LowEnergy(NegativeS)");
257 }
258 else if(s_value < mProt2)
259 {
260 theNucleus.StartLoop(); // To get the same nucleon
261 G4QHadron* aTarget=0; // Prototype of the target
262 G4QHadron* pProjectile=0; // Prototype of the projectile
263 G4QHadron* bNucleon=0; // Prototype of the best nucleon
264 G4double maxS=0.; // Maximum s found
265 while((bNucleon=theNucleus.GetNextNucleon())) // Loop over all nuclei to get theBest
266 {
267 G4LorentzVector cp4M=bNucleon->Get4Momentum(); // 4-mom of the current nucleon
268 G4double cs=(cmProjMom + cp4M).mag2(); // Squared CM Energy of compound
269 if(cs > maxS) // Remember nucleon with the biggest s
270 {
271 maxS=cs;
272 pNucleon=bNucleon;
273 }
274 }
275 aTarget = new G4QHadron(*pNucleon); // Copy selected nucleon for String
276 pProjectile =cmProjectile;
277 theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
278 theNucleus.SubtractNucleon(pNucleon); // Pointer to theUsedNucleon to delete
279 theNucleus.DoLorentzBoost(-theCurrentVelocity); // Boost theResNucleus back to CM
280 G4QContent QQC=aTarget->GetQC()+pProjectile->GetQC(); // QContent of the compound
281 G4LorentzVector Q4M=aTarget->Get4Momentum()+pProjectile->Get4Momentum(); // 4-mom of Q
282 delete aTarget;
283 delete pProjectile;
284 //if(maxNuc>1) // Absorb moreNucleons to theQuasmon
285 //{
286 // for(G4int i=1; i<maxNuc; ++i)
287 // {
288 // pNucleon=theNucleus.GetNextNucleon(); // Get the next nucleon
289 // QQC+=pNucleon->GetQC(); // Add it to the Quasmon
290 // Q4M+=pNucleon->Get4Momentum();
291 // theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
292 // theNucleus.SubtractNucleon(pNucleon); // Exclude the used nucleon from Nuc
293 // theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
294 // }
295 //}
296 // 4-Mom should be converted to LS
297 Q4M.boost(theCurrentVelocity);
298 Q4M=toLab*Q4M;
299 G4Quasmon* stringQuasmon = new G4Quasmon(QQC, Q4M);
300 theQuasmons.push_back(stringQuasmon);
301 theNucleus.DoLorentzBoost(theCurrentVelocity); // BoostTheResidualNucleus toRotatedLS
302 theNucleus.DoLorentzRotation(toLab);// Recove Z-direction in LS ("LS"->LS) for rNucleus
303 return;
304 }
305 if (s_value < sqr(ThresholdMass)) // --> Only diffractive interaction
306 {
307#ifdef debug
308 G4cout<<"G4QFragmentation::Construct:*OnlyDiffraction*ThM="<<ThresholdMass<<">sqrt(s)="
309 <<std::sqrt(s_value)<<" -> only Diffraction is possible"<<G4endl; // @@ Dif toQuasmon
310#endif
311 ModelMode = DIFFRACTIVE;
312 }
313 // Clean up all previous interactions and reset the counters
314#ifdef debug
315 G4cout<<"G4QFragmentation::Construct: theIntSize="<<theInteractions.size()<<G4endl;
316#endif
317 std::for_each(theInteractions.begin(),theInteractions.end(), DeleteQInteraction());
318 theInteractions.clear();
319 G4int totalCuts = 0;
320 G4int attCnt=0;
321 //G4int maxAtt=227;
322 G4int maxAtt=27;
323 G4double prEn=proj4M.e(); // For mesons
324 G4int proB=aProjectile.GetBaryonNumber();
325 if (proB>0) prEn-=aProjectile.GetMass(); // For baryons
326 else if(proB<0) prEn+=mProt; // For anti-baryons
327#ifdef debug
328 G4double impactUsed = 0.;
329 G4cout<<"G4QFragmentation::Construct: estimated energy, prEn="<<prEn<<G4endl;
330#endif
331 while(!theInteractions.size() && ++attCnt < maxAtt) // Till Interaction is created
332 {
333#ifdef debug
334 G4cout<<"G4QFragmentation::Construct: *EnterTheInteractionLOOP*, att#"<<attCnt<<G4endl;
335#endif
336 // choose random impact parameter
337 std::pair<G4double, G4double> theImpactParameter;
338 theImpactParameter = theNucleus.ChooseImpactXandY(outerRadius);
339 G4double impactX = theImpactParameter.first;
340 G4double impactY = theImpactParameter.second;
341#ifdef debug
342 G4cout<<"G4QFragmentation::Construct: Impact Par X="<<impactX<<", Y="<<impactY<<G4endl;
343#endif
344 G4double impar=std::sqrt(impactX*impactX+impactY*impactY);
345 G4int nA=theNucleus.GetA();
346 G4double eflen=theNucleus.GetThickness(impar); // EffectiveLength
347 maxEn=eflen*stringTension; // max absorbed energy in IndUnits=MeV
348 maxNuc=static_cast<int>(eflen*tubeDensity+0.5); // max #0f involved nuclear nucleons
349#ifdef debug
350 G4cout<<"G4QFragment::Construct: pE="<<prEn<<" <? mE="<<maxEn<<", mN="<<maxNuc<<G4endl;
351#endif
352 if(prEn < maxEn) // Create DIN interaction and go out
353 {
354 theNucleus.StartLoop(); // Initialize newSelection forNucleons
355 pNucleon=theNucleus.GetNextNucleon(); // Select a nucleon
356 G4QHadron* aTarget = new G4QHadron(*pNucleon); // Copy selected nucleon for String
357 G4QInteraction* anInteraction = new G4QInteraction(cmProjectile);
358 anInteraction->SetTarget(aTarget);
359 anInteraction->SetNumberOfDINRCollisions(1); // Consider this interaction as DINR
360 theInteractions.push_back(anInteraction); //--> now theInteractions not empty
361 theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
362 theNucleus.SubtractNucleon(pNucleon); // Pointer to the used nucleon
363 theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
364#ifdef debug
365 G4cout<<"G4QFragmentation::Construct: DINR interaction is created"<<G4endl;
366#endif
367 break; // Break the WHILE of interactions
368 }
369 // LOOP over nuclei of the target nucleus to select collisions
370 theNucleus.StartLoop(); // To get the same nucleon
371 G4int nucleonCount = 0;
372#ifdef debug
373 G4cout<<"G4QFragment::Construct:BeforeWhileOveNuc, A="<<nA<<",p4M="<<cmProjMom<<G4endl;
374#endif
375 while( (pNucleon=theNucleus.GetNextNucleon()) && nucleonCount<nA && totalCuts<maxCuts)
376 {
377 ++nucleonCount;
378 // Needs to be moved to Probability class @@@
379 s_value = (cmProjMom + pNucleon->Get4Momentum()).mag2();
380#ifdef debug
381 G4cout<<"G4QFrag::Constr:N# "<<nucleonCount<<", s="<<s_value<<", tgN4M="
382 <<pNucleon->Get4Momentum()<<G4endl;
383#endif
384 if(s_value<=10000.)
385 {
386#ifdef debug
387 G4cout<<"G4QFragmentation::Construct: SKIP, s<.01 GeV^2, p4M="<<cmProjMom
388 <<",t4M="<<pNucleon->Get4Momentum()<<G4endl;
389#endif
390 continue;
391 }
392#ifdef sdebug
393 G4cout<<"G4QFragmentation::Construct:LOOPovNuc,nC="<<nucleonCount<<", s="<<s_value<<G4endl;
394 G4cout<<"G4QFragmentation::Construct:LOOPovNuc, R="<<pNucleon->GetPosition()<<G4endl;
395#endif
396 G4double Distance2 = sqr(impactX - pNucleon->GetPosition().x()) +
397 sqr(impactY - pNucleon->GetPosition().y());
398#ifdef sdebug
399 G4cout<<"G4QFragmentation::Construct: s="<<s_value<<", D2="<<Distance2<<G4endl;
400#endif
401 G4double Probability = theProbability.GetPomInelProbability(s_value, Distance2); // PomINEL
402 // test for inelastic collision
403#ifdef sdebug
404 G4cout<<"G4QFragmentation::Construct: Probubility="<<Probability<<G4endl;
405#endif
406 G4double rndNumber = G4UniformRand(); // For the printing purpose
407 // ModelMode = DIFFRACTIVE;
408#ifdef sdebug
409 G4cout<<"G4QFragmentation::Construct: NLOOP prob="<<Probability<<", rndm="<<rndNumber
410 <<", d="<<std::sqrt(Distance2)<<G4endl;
411#endif
412 if (Probability > rndNumber) // Inelastic (diffractive or soft) interaction (JOB)
413 {
414 G4QHadron* aTarget = new G4QHadron(*pNucleon);// Copy for String (ValgrindComplain)
415#ifdef edebug
416 G4cout<<"--->EMC-->G4QFragmentation::Construct: Target Nucleon is filled, 4M/PDG="
417 <<aTarget->Get4Momentum()<<aTarget->GetPDGCode()<<G4endl;
418#endif
419 // Now the energy of the nucleons must be updated in CMS
420 theNucleus.DoLorentzBoost(theCurrentVelocity);// Boost theResNucleus toRotatedLS
421 theNucleus.SubtractNucleon(pNucleon); // Pointer to the used nucleon
422 theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
423 if((theProbability.GetPomDiffProbability(s_value,Distance2)/Probability >
424 G4UniformRand() && ModelMode==SOFT ) || ModelMode==DIFFRACTIVE)
425 {
426 // --------------->> diffractive interaction @@ IsSingleDiffractive called once
427 if(IsSingleDiffractive()) ExciteSingDiffParticipants(cmProjectile, aTarget);
428 else ExciteDiffParticipants(cmProjectile, aTarget);
429 G4QInteraction* anInteraction = new G4QInteraction(cmProjectile);
430 anInteraction->SetTarget(aTarget);
431 anInteraction->SetNumberOfDiffractiveCollisions(1); // Why not increment? M.K.?
432 theInteractions.push_back(anInteraction); //--> now theInteractions not empty
433 // @@ Why not breake the NLOOP, if only one diffractive can happend?
434 totalCuts++; // UpdateOfNucleons in't necessary
435#ifdef debug
436 G4cout<<"G4QFragmentation::Construct:NLOOP DiffInteract, tC="<<totalCuts<<G4endl;
437#endif
438 }
439 else
440 {
441 // ---------------->> nondiffractive = soft interaction
442 // sample nCut+1 (cut Pomerons) pairs of strings can be produced
443 G4int nCut; // Result in a chosen number of cuts
444 G4double* running = new G4double[nCutMax]; // @@ This limits the max cuts
445 for(nCut = 0; nCut < nCutMax; nCut++) // Calculates multiCut probabilities
446 {
447 running[nCut]= theProbability.GetCutPomProbability(s_value, Distance2, nCut+1);
448 if(nCut) running[nCut] += running[nCut-1];// Sum up with the previous one
449 }
450 G4double random = running[nCutMax-1]*G4UniformRand();
451 for(nCut = 0; nCut < nCutMax; nCut++) if(running[nCut] > random) break;
452 delete [] running;
453#ifdef debug
454 G4cout<<"G4QFragmentation::Construct: NLOOP-Soft Chosen nCut="<<nCut<<G4endl;
455#endif
456 // @@ If nCut>0 interaction with a few nucleons is possible
457 // @@ nCut is found with big efforts and now nCut=0 ?? M.K. ?? !!
458 //nCut = 0; // @@ in original code ?? @@
459 aTarget->IncrementCollisionCount(nCut+1); // @@ What about multyNucleon target?
460 cmProjectile->IncrementCollisionCount(nCut+1);
461 G4QInteraction* anInteraction = new G4QInteraction(cmProjectile);
462 anInteraction->SetTarget(aTarget);
463 anInteraction->SetNumberOfSoftCollisions(nCut+1);
464 theInteractions.push_back(anInteraction);
465 totalCuts += nCut+1;
466#ifdef debug
467 G4cout<<"G4QFragmentation::Construct:NLOOP SoftInteract, tC="<<totalCuts<<G4endl;
468 impactUsed=Distance2;
469#endif
470 }
471 }
472 } // End of While over nucleons
473 // When nucleon count is incremented, the LOOP stops, so nucleonCount==1 always!
474#ifdef debug
475 G4cout<<"G4QFragmentation::Construct: NUCLEONCOUNT="<<nucleonCount<<G4endl;
476#endif
477 }
478 G4int nInt=theInteractions.size();
479#ifdef debug
480 G4cout<<"G4QFrag::Con:CUT="<<totalCuts<<",ImpPar="<<impactUsed<<",#ofInt="<<nInt<<G4endl;
481#endif
482 // --- Use this line ---
483 if(!nInt || (nInt==1 && theInteractions[0]->GetNumberOfDINRCollisions()==1)) // @@ ?? @@
484 {
485 G4QHadron* aTarget=0;
486 G4QHadron* pProjectile=0;
487 if(nInt) // Take Targ/Proj from the Interaction
488 {
489 aTarget=theInteractions[0]->GetTarget();
490 pProjectile=theInteractions[0]->GetProjectile();
491 delete theInteractions[0];
492 theInteractions.clear();
493 }
494 else // Create a new target nucleon
495 {
496 theNucleus.StartLoop(); // To get the same nucleon
497 pNucleon=theNucleus.GetNextNucleon(); // Get the nucleon to create
498 aTarget = new G4QHadron(*pNucleon); // Copy selected nucleon for String
499 pProjectile =cmProjectile;
500 theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
501 theNucleus.SubtractNucleon(pNucleon); // Pointer to theUsedNucleon to delete
502 theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
503 }
504 G4QContent QQC=aTarget->GetQC()+pProjectile->GetQC(); // QContent of the compound
505 G4LorentzVector Q4M=aTarget->Get4Momentum()+pProjectile->Get4Momentum(); // 4-mom of Q
506 delete aTarget;
507 delete pProjectile;
508 //if(maxNuc>1) // Absorb moreNucleons to theQuasmon
509 //{
510 // for(G4int i=1; i<maxNuc; ++i)
511 // {
512 // pNucleon=theNucleus.GetNextNucleon(); // Get the next nucleon
513 // QQC+=pNucleon->GetQC(); // Add it to the Quasmon
514 // Q4M+=pNucleon->Get4Momentum();
515 // theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
516 // theNucleus.SubtractNucleon(pNucleon); // Exclude the used nucleon from Nuc
517 // theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
518 // }
519 //}
520 // 4-Mom should be converted to LS
521 Q4M.boost(theCurrentVelocity);
522 Q4M=toLab*Q4M;
523 G4Quasmon* stringQuasmon = new G4Quasmon(QQC, Q4M);
524 theQuasmons.push_back(stringQuasmon);
525 theNucleus.DoLorentzBoost(theCurrentVelocity); // BoostTheResidualNucleus toRotatedLS
526 theNucleus.DoLorentzRotation(toLab);// Recove Z-direction in LS ("LS"->LS) for rNucleus
527 return;
528 }
529 //
530 // ------------------ now build the parton pairs for the strings ------------------
531 //
532#ifdef debug
533 G4cout<<"G4QFragmentation::Construct: Before PartPairCreation nInt="<<nInt<<G4endl;
534#endif
535 for(G4int i=0; i<nInt; i++)
536 {
537 theInteractions[i]->SplitHadrons();
538#ifdef edebug
539 G4QHadron* projH=theInteractions[i]->GetProjectile(); // Projectile of theInteraction
540 G4QHadron* targH=theInteractions[i]->GetTarget(); // Target of the Interaction
541 G4LorentzVector pSP(0.,0.,0.,0.); // Sum of parton's 4mom's for proj
542 G4LorentzVector tSP(0.,0.,0.,0.); // Sum of parton's 4mom's for proj
543 std::list<G4QParton*> projCP=projH->GetColor(); // Pointers to proj Color-partons
544 std::list<G4QParton*> projAC=projH->GetAntiColor();// PointersTo projAntiColorPartons
545 std::list<G4QParton*> targCP=targH->GetColor(); // Pointers to targ Color-partons
546 std::list<G4QParton*> targAC=targH->GetAntiColor();// PointersTo targAntiColorPartons
547 std::list<G4QParton*>::iterator picp = projCP.begin();
548 std::list<G4QParton*>::iterator pecp = projCP.end();
549 std::list<G4QParton*>::iterator piac = projAC.begin();
550 std::list<G4QParton*>::iterator peac = projAC.end();
551 std::list<G4QParton*>::iterator ticp = targCP.begin();
552 std::list<G4QParton*>::iterator tecp = targCP.end();
553 std::list<G4QParton*>::iterator tiac = targAC.begin();
554 std::list<G4QParton*>::iterator teac = targAC.end();
555 for(; picp!=pecp&& piac!=peac&& ticp!=tecp&& tiac!=teac; ++picp,++piac,++ticp,++tiac)
556 {
557 pSP+=(*picp)->Get4Momentum();
558 pSP+=(*piac)->Get4Momentum();
559 tSP+=(*ticp)->Get4Momentum();
560 tSP+=(*tiac)->Get4Momentum();
561 }
562 G4cout<<"-EMC-G4QFragmentation::Construct: Interaction#"<<i<<",dP4M="
563 <<projH->Get4Momentum()-pSP<<",dT4M="<<targH->Get4Momentum()-tSP<<G4endl;
564#endif
565 }
566 //
567 // ------->> make soft collisions (ordering is vital)
568 //
569 G4QInteractionVector::iterator it;
570#ifdef debug
571 G4cout<<"G4QFragmentation::Construct: Creation ofSoftCollisionPartonPair STARTS"<<G4endl;
572#endif
573 G4bool rep=true;
574 while(rep && theInteractions.size())
575 {
576 for(it = theInteractions.begin(); it != theInteractions.end(); ++it)
577 {
578 G4QInteraction* anIniteraction = *it;
579 G4QPartonPair* aPair=0;
580 G4int nSoftCollisions = anIniteraction->GetNumberOfSoftCollisions();
581#ifdef debug
582 G4cout<<"G4QFragmentation::Construct: #0f SOFT collisions ="<<nSoftCollisions<<G4endl;
583#endif
584 if (nSoftCollisions)
585 {
586 G4QHadron* pProjectile = anIniteraction->GetProjectile();
587 G4QHadron* pTarget = anIniteraction->GetTarget();
588 for (G4int j = 0; j < nSoftCollisions; j++)
589 {
590 aPair = new G4QPartonPair(pTarget->GetNextParton(),
591 pProjectile->GetNextAntiParton(),
593 thePartonPairs.push_back(aPair); // A target pair (Why TAGRET?)
594 aPair = new G4QPartonPair(pProjectile->GetNextParton(),
595 pTarget->GetNextAntiParton(),
597 thePartonPairs.push_back(aPair); // A projectile pair (Why Projectile?)
598#ifdef debug
599 G4cout<<"--->G4QFragmentation::Construct: SOFT, 2 parton pairs are filled"<<G4endl;
600#endif
601 }
602 delete *it;
603 it=theInteractions.erase(it); // Soft interactions are converted & erased
604 if( it != theInteractions.begin() )// To avoid going below begin() (for Windows)
605 {
606 it--;
607 rep=false;
608#ifdef debug
609 G4cout<<"G4QFragmentation::Construct: *** Decremented ***"<<G4endl;
610#endif
611 }
612 else
613 {
614 rep=true;
615#ifdef debug
616 G4cout<<"G4QFragmentation::Construct: *** IT Begin ***"<<G4endl;
617#endif
618 break;
619 }
620 }
621 else rep=false;
622#ifdef debug
623 G4cout<<"G4QFragmentation::Construct: #0fSC="<<nSoftCollisions<<", r="<<rep<<G4endl;
624#endif
625 }
626#ifdef debug
627 G4cout<<"G4QFragmentation::Construct: *** IT While *** , r="<<rep<<G4endl;
628#endif
629 }
630#ifdef debug
631 G4cout<<"G4QFragmentation::Construct: -> Parton pairs for SOFT strings are made"<<G4endl;
632#endif
633 //
634 // ---------->> make the rest as the diffractive interactions
635 //
636 for(unsigned i = 0; i < theInteractions.size(); i++) // Interactions are reduced bySoft
637 {
638 // The double or single diffraction is defined by the presonce of proj/targ partons
639 G4QInteraction* anIniteraction = theInteractions[i];
640 G4QPartonPair* aPartonPair;
641#ifdef debug
642 G4cout<<"G4QFragmentation::Construct: CreationOfDiffractivePartonPairs, i="<<i<<G4endl;
643#endif
644 // the projectile diffraction parton pair is created first
645 G4QHadron* pProjectile = anIniteraction->GetProjectile();
646 G4QParton* aParton = pProjectile->GetNextParton();
647 if (aParton)
648 {
649 aPartonPair = new G4QPartonPair(aParton, pProjectile->GetNextAntiParton(),
652 thePartonPairs.push_back(aPartonPair);
653#ifdef debug
654 G4cout<<"G4QFragmentation::Construct: proj Diffractive PartonPair is filled"<<G4endl;
655#endif
656 }
657 // then the target diffraction parton pair is created
658 G4QHadron* aTarget = anIniteraction->GetTarget();
659 aParton = aTarget->GetNextParton();
660 if (aParton)
661 {
662 aPartonPair = new G4QPartonPair(aParton, aTarget->GetNextAntiParton(),
664 thePartonPairs.push_back(aPartonPair);
665#ifdef debug
666 G4cout<<"G4QFragmentation::Constr: target Diffractive PartonPair is filled"<<G4endl;
667#endif
668 }
669 }
670#ifdef debug
671 G4cout<<"G4QFragmentation::Construct: DiffractivePartonPairs are created"<<G4endl;
672#endif
673 //
674 // ---------->> clean-up Interactions and cmProjectile, if necessary
675 //
676 std::for_each(theInteractions.begin(),theInteractions.end(), DeleteQInteraction());
677 theInteractions.clear();
678 delete cmProjectile;
679#ifdef debug
680 G4cout<<"G4QFragmentation::Construct: Temporary objects are cleaned up"<<G4endl;
681#endif
682 // This function prepares theBoost for transformation of secondaries to LS (-ProjRot!)
683 theNucleus.DoLorentzBoost(theCurrentVelocity);// Boost theResidualNucleus to RotatedLS
684 // @@ Nucleus isn't completely in LS, it needs the toZ (-ProjRot) rotation to consE/M
685#ifdef debug
686 G4cout<<"--------->>G4QFragmentation::Construct: ------->> Strings are created "<<G4endl;
687#endif
688 G4QPartonPair* aPair;
689 G4QString* aString=0;
690 while(thePartonPairs.size()) // @@ At present noDifference in stringBuild (? M.K.)
691 {
692 aPair = thePartonPairs.back(); // Get the parton pair
693 thePartonPairs.pop_back(); // Clean up thePartonPairPointer in the Vector
694#ifdef debug
695 G4cout<<"G4QFragmentation::Construct: StringType="<<aPair->GetCollisionType()<<G4endl;
696#endif
697 aString= new G4QString(aPair);
698#ifdef debug
699 G4cout<<"G4QFragmentation::Construct:NewString4M="<<aString->Get4Momentum()<<G4endl;
700#endif
701 aString->Boost(theCurrentVelocity); // ! Strings are moved to ZLS when pushed !
702 strings.push_back(aString);
703 stringsInitted=true;
704 delete aPair;
705 } // End of the String Creation LOOP
706#ifdef edebug
707 G4LorentzVector sum=theNucleus.Get4Momentum();// Nucleus 4Mom in rotatedLS
708 G4int rChg=totChg-theNucleus.GetZ();
709 G4int rBaN=totBaN-theNucleus.GetA();
710 G4int nStrings=strings.size();
711 G4cout<<"-EMC-G4QFragmentation::Construct:#ofString="<<nStrings<<",tNuc4M="<<sum<<G4endl;
712 for(G4int i=0; i<nStrings; i++)
713 {
714 G4QString* prString=strings[i];
715 G4LorentzVector strI4M=prString->Get4Momentum();
716 sum+=strI4M;
717 G4int sChg=prString->GetCharge();
718 G4int sBaN=prString->GetBaryonNumber();
719 G4int LPDG=prString->GetLeftParton()->GetPDGCode();
720 G4int RPDG=prString->GetRightParton()->GetPDGCode();
721 G4QContent LQC =prString->GetLeftParton()->GetQC();
722 G4QContent RQC =prString->GetRightParton()->GetQC();
723 rChg-=sChg;
724 rBaN-=sBaN;
725 G4cout<<"-EMC-G4QFragmentation::Construct: String#"<<i<<", 4M="<<strI4M<<",LPDG="<<LPDG
726 <<LQC<<",RPDG="<<RPDG<<RQC<<", Ch="<<sChg<<", BN="<<sBaN<<G4endl;
727 }
728 G4cout<<"-EMC-G4QFragm::Constr: r4M="<<sum-totZLS4M<<",rC="<<rChg<<",rB="<<rBaN<<G4endl;
729#endif
730 if(!stringsInitted)
731 {
732 G4cerr<<"******G4QFragmentation::Construct:***** No strings are created *****"<<G4endl;
733 G4Exception("G4QFragmentation::Construct:","72",FatalException,"NoStrings're created");
734 }
735#ifdef debug
736 G4cout<<"G4QFragmentation::Constr: BeforeRotation, #0fStrings="<<strings.size()<<G4endl;
737#endif
738 //
739 // ---------------- At this point the strings must be already created in "LS" -----------
740 //
741 for(unsigned astring=0; astring < strings.size(); astring++)
742 strings[astring]->LorentzRotate(toLab); // Recove Z-direction in LS ("LS"->LS)
743 theNucleus.DoLorentzRotation(toLab); // Recove Z-direction in LS ("LS"->LS) for rNucleus
744 // Now everything is in LS system
745#ifdef edebug
746 G4LorentzVector sm=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
747 G4int rCg=totChg-theNucleus.GetZ();
748 G4int rBC=totBaN-theNucleus.GetA();
749 G4int nStrs=strings.size();
750 G4cout<<"-EMCLS-G4QFragmentation::Constr: #ofS="<<nStrings<<",tNuc4M(E=M)="<<sum<<G4endl;
751 for(G4int i=0; i<nStrs; i++)
752 {
753 G4LorentzVector strI4M=strings[i]->Get4Momentum();
754 sm+=strI4M;
755 G4int sChg=strings[i]->GetCharge();
756 rCg-=sChg;
757 G4int sBaN=strings[i]->GetBaryonNumber();
758 rBC-=sBaN;
759 G4cout<<"-EMCLS-G4QFragm::Construct:String#"<<i<<",4M="<<strI4M<<strI4M.m()<<",Charge="
760 <<sChg<<",BaryN="<<sBaN<<G4endl;
761 }
762 G4cout<<"-EMCLS-...G4QFragm::Constr:r4M="<<sm-totLS4M<<",rC="<<rCg<<",rB="<<rBC<<G4endl;
763#endif
764 //
765 // --- Strings are created, but we should try to get rid of negative mass strings -----
766 //
767 SwapPartons();
768#ifdef edebug
769 sm=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
770 rCg=totChg-theNucleus.GetZ();
771 rBC=totBaN-theNucleus.GetA();
772 nStrs=strings.size();
773 G4cout<<"-EMCLS-G4QFrag::Constr:AfterSwap #ofS="<<nStrings<<",tNuc4M(E=M)="<<sum<<G4endl;
774 for(G4int i=0; i<nStrs; i++)
775 {
776 G4LorentzVector strI4M=strings[i]->Get4Momentum();
777 sm+=strI4M;
778 G4int sChg=strings[i]->GetCharge();
779 rCg-=sChg;
780 G4int sBaN=strings[i]->GetBaryonNumber();
781 rBC-=sBaN;
782 G4cout<<"-EMCLS-G4QFragm::Construct:String#"<<i<<",4M="<<strI4M<<strI4M.m()<<",Charge="
783 <<sChg<<",BaryN="<<sBaN<<G4endl;
784 }
785 G4cout<<"-EMCLS-...G4QFragm::Constr:r4M="<<sm-totLS4M<<",rC="<<rCg<<",rB="<<rBC<<G4endl;
786#endif
787 //
788 // --- Strings are created, but we should get rid of too light strings (Mmin+MPi0) -----
789 //
790 G4int problem=0; // 0="no problem", incremented by ASIS
791 G4QStringVector::iterator ist;
792 G4bool con=true;
793 while(con && strings.size())
794 {
795 for(ist = strings.begin(); ist < strings.end(); ++ist)
796 {
797 G4bool bad=true;
798 G4LorentzVector cS4M=(*ist)->Get4Momentum();
799 G4double cSM2=cS4M.m2(); // Squared mass of the String
800 G4QParton* cLeft=(*ist)->GetLeftParton();
801 G4QParton* cRight=(*ist)->GetRightParton();
802 G4int cLT=cLeft->GetType();
803 G4int cRT=cRight->GetType();
804 G4int cLPDG=cLeft->GetPDGCode();
805 G4int cRPDG=cRight->GetPDGCode();
806 G4int aLPDG=0;
807 G4int aRPDG=0;
808 if (cLPDG > 7) aLPDG= cLPDG/100;
809 else if(cLPDG <-7) aLPDG=(-cLPDG)/100;
810 if (cRPDG > 7) aRPDG= cRPDG/100;
811 else if(cRPDG <-7) aRPDG=(-cRPDG)/100;
812 G4int L1=0;
813 G4int L2=0;
814 if(aLPDG)
815 {
816 L1=aLPDG/10;
817 L2=aLPDG%10;
818 }
819 G4int R1=0;
820 G4int R2=0;
821 if(aRPDG)
822 {
823 R1=aRPDG/10;
824 R2=aRPDG%10;
825 }
826 G4double cSM=cSM2;
827 if(cSM2>0.) cSM=std::sqrt(cSM2);
828#ifdef debug
829 G4cout<<"G4QFrag::Constr:NeedsFusion? cLPDG="<<cLPDG<<",cRPDG="<<cRPDG<<",cM(cM2If<0)="
830 <<cSM<<",c4M"<<cS4M<<G4endl;
831#endif
832 if(cSM>0.) // Mass can be calculated
833 {
834 G4bool single=true;
835 G4double miM=0.; // Proto of the Min HadronString Mass
836 if(cLT==2 && cRT==2)
837 {
838 if(L1!=R1 && L1!=R2 && L2!=R1 && L2!=R2) // Unreducable DiQ-aDiQ
839 {
840 single=false;
841 G4QPDGCode tmp;
842 std::pair<G4int,G4int> paB=tmp.MakeTwoBaryons(L1, L2, R1, R2);
843 miM=G4QPDGCode(paB.first).GetMass()+G4QPDGCode(paB.second).GetMass();
844 }
845 }
846 if(single) miM=G4QPDGCode((*ist)->GetQC().GetSPDGCode()).GetMass() + mPi0;//MinHSMass
847 //if(single) miM=G4QPDGCode((*ist)->GetQC().GetSPDGCode()).GetMass();//MinHSMass
848#ifdef debug
849 G4cout<<"G4QFrag::Const:*IsItGood? realM="<<std::sqrt(cSM2)<<" > GSM="<<miM<<G4endl;
850#endif
851 if(std::sqrt(cSM2) > miM) bad=false; // String is OK
852 }
853 if(bad) // String should be merged with others
854 {
855#ifdef debug
856 G4cout<<"G4QFrag::Const:TryFuse,L1="<<L1<<",L2="<<L2<<",R1="<<R1<<",R2="<<R2<<G4endl;
857#endif
858 G4int cST=cLT+cRT;
859 G4double excess=-DBL_MAX; // The value to be maximized excess M
860 G4double maxiM2=-DBL_MAX; // The value to be maximized M2
861 G4QStringVector::iterator sst; // Selected partner string
862 G4QStringVector::iterator pst;
863 G4int sLPDG=0; // selectedLeft (like inStringPartner)
864 G4int sRPDG=0; // selectedRight(like inStringPartner)
865 G4int sOrd=0; // selected Order of PartonFusion
866 G4bool minC=true; // for the case when M2<0
867 if(cSM2>0.) minC=false; // If M2>0 already don'tSearchFor M2>0
868 for(pst = strings.begin(); pst < strings.end(); pst++) if(pst != ist)
869 {
870 G4LorentzVector sS4M=(*pst)->Get4Momentum(); // Partner's 4-momentum
871 G4LorentzVector pS4M=sS4M+cS4M; // Summed 4-momentum
872 G4int nLPDG=0; // new Left (like in theStringPartner)
873 G4int nRPDG=0; // new Right(like in theStringPartner)
874 G4double pExcess=-DBL_MAX; // Prototype of the excess
875 G4double pSM2=pS4M.m2(); // Squared mass of the Fused Strings
876#ifdef debug
877 G4cout<<"->G4QFragm::Construct: sum4M="<<pS4M<<",M2="<<pSM2<<",p4M="<<sS4M<<G4endl;
878#endif
879 //if(pSM2>0.) // The partner can be a candidate
880 //{
881 G4QParton* pLeft=(*pst)->GetLeftParton();
882 G4QParton* pRight=(*pst)->GetRightParton();
883 G4int pLT=pLeft->GetType();
884 G4int pRT=pRight->GetType();
885 G4int pLPDG=pLeft->GetPDGCode();
886 G4int pRPDG=pRight->GetPDGCode();
887 G4int LPDG=0;
888 G4int RPDG=0;
889 if (pLPDG > 7) LPDG= pLPDG/100;
890 else if(pLPDG <-7) LPDG=(-pLPDG)/100;
891 if (pRPDG > 7) RPDG= pRPDG/100;
892 else if(pRPDG <-7) RPDG=(-pRPDG)/100;
893 G4int pL1=0;
894 G4int pL2=0;
895 if(LPDG)
896 {
897 pL1=LPDG/10;
898 pL2=LPDG%10;
899 }
900 G4int pR1=0;
901 G4int pR2=0;
902 if(RPDG)
903 {
904 pR1=RPDG/10;
905 pR2=RPDG%10;
906 }
907 G4int pST=pLT+pRT;
908#ifdef debug
909 G4cout<<"G4QFragm::Construct: Partner/w pLPDG="<<pLPDG<<", pRPDG="<<pRPDG<<", pM2="
910 <<pSM2<<G4endl;
911#endif
912 // Different fromCompactAlrorithm ofStringFusionAfterDecay (no DiQaDiQ reduction)
913 G4int tf=0; // Type combination flag
914 G4int af=0; // Annihilatio combination flag
915 if (cST==2 && pST==2) // QaQ + QaQ = DiQaDiQ (always)
916 {
917 tf=1;
918 af=1;
919 }
920 else if(cST==2 && pST==3) // QaQ + QDiQ/aQaDiQ = QDiQ/aQaDiQ (s)
921 {
922 tf=2;
923 if (pLPDG > 7 &&
924 ( (cLPDG<0 && (-cLPDG==pL1 || -cLPDG==pL2 || -cLPDG==pRPDG) ) ||
925 (cRPDG<0 && (-cRPDG==pL1 || -cRPDG==pL2 || -cRPDG==pRPDG) )
926 )
927 ) af=1;
928 else if(pRPDG > 7 &&
929 ( (cLPDG<0 && (-cLPDG==pR1 || -cLPDG==pR2 || -cLPDG==pLPDG) ) ||
930 (cRPDG<0 && (-cRPDG==pR1 || -cRPDG==pR2 || -cRPDG==pLPDG) )
931 )
932 ) af=2;
933 else if(pLPDG <-7 &&
934 ( (cLPDG>0 && ( cLPDG==pL1 || cLPDG==pL2 || cLPDG==-pRPDG) ) ||
935 (cRPDG>0 && ( cRPDG==pL1 || cRPDG==pL2 || cRPDG==-pRPDG) )
936 )
937 ) af=3;
938 else if(pRPDG <-7 &&
939 ( (cLPDG>0 && ( cLPDG==pR1 || cLPDG==pR2 || cLPDG==-pLPDG) ) ||
940 (cRPDG>0 && ( cRPDG==pR1 || cRPDG==pR2 || cRPDG==-pLPDG) )
941 )
942 ) af=4;
943#ifdef debug
944 else G4cout<<"G4QFragmentation::Construct:2(QaQ+QDiQ/aQaDiQ) Can't fuse"<<G4endl;
945#endif
946 }
947 else if(cST==3 && pST==2) // QDiQ/aQaDiQ + QaQ = QDiQ/aQaDiQ (s)
948 {
949 tf=3;
950 if (cLPDG > 7 &&
951 ( (pLPDG<0 && (-pLPDG==L1 || -pLPDG==L2 || -pLPDG==cRPDG) ) ||
952 (pRPDG<0 && (-pRPDG==L1 || -pRPDG==L2 || -pRPDG==cRPDG) )
953 )
954 ) af=1;
955 else if(cRPDG > 7 &&
956 ( (pLPDG<0 && (-pLPDG==R1 || -pLPDG==R2 || -pLPDG==cLPDG) ) ||
957 (pRPDG<0 && (-pRPDG==R1 || -pRPDG==R2 || -pRPDG==cLPDG) )
958 )
959 ) af=2;
960 else if(cLPDG <-7 &&
961 ( (pLPDG>0 && ( pLPDG==L1 || pLPDG==L2 || pLPDG==-cRPDG) ) ||
962 (pRPDG>0 && ( pRPDG==L1 || pRPDG==L2 || pRPDG==-cRPDG) )
963 )
964 ) af=3;
965 else if(cRPDG <-7 &&
966 ( (pLPDG>0 && ( pLPDG==R1 || pLPDG==R2 || pLPDG==-cLPDG) ) ||
967 (pRPDG>0 && ( pRPDG==R1 || pRPDG==R2 || pRPDG==-cLPDG) )
968 )
969 ) af=4;
970#ifdef debug
971 else G4cout<<"G4QFragmentation::Construct:3(QDiQ/aQaDiQ+QaQ) Can't fuse"<<G4endl;
972#endif
973 }
974 else if(cST==2 && pST==4) // QaQ + aDiQDiQ = QaQ (double)
975 {
976 tf=4;
977 if (pLPDG > 7) // pRPDG <-7
978 {
979 if ( (-cLPDG==pL1 || -cLPDG==pL2) && (cRPDG==pR1 || cRPDG==pR2) ) af=1;
980 else if( (-cRPDG==pL1 || -cRPDG==pL2) && (cLPDG==pR1 || cLPDG==pR2) ) af=2;
981 }
982 else if(pRPDG > 7) // pLPDG <-7
983 {
984 if ( (-cRPDG==pR1 || -cRPDG==pR2) && (cLPDG==pL1 || cLPDG==pL2) ) af=3;
985 else if( (-cLPDG==pR1 || -cLPDG==pR2) && (cRPDG==pL1 || cRPDG==pL2) ) af=4;
986 }
987#ifdef debug
988 else G4cout<<"-G4QFragmentation::Construct: 4 (QaQ+aQDiQDiQ) Can't fuse"<<G4endl;
989#endif
990 }
991 else if(cST==4 && pST==2) // aDiQDiQ + QaQ = QaQ (double)
992 {
993 tf=5;
994 if (cLPDG > 7) // cRPDG<-7
995 {
996 if ( (-pLPDG==L1 || -pLPDG==L2) && (pRPDG==R1 || pRPDG==R2) ) af=1;
997 else if( (-pRPDG==L1 || -pRPDG==L2) && (pLPDG==R1 || pLPDG==R2) ) af=2;
998 }
999 else if(cRPDG > 7) // cLPDG<-7
1000 {
1001 if ( (-pRPDG==R1 || -pRPDG==R2) && (pLPDG==L1 || pLPDG==L2) ) af=3;
1002 else if( (-pLPDG==R1 || -pLPDG==R2) && (pRPDG==L1 || pRPDG==L2) ) af=4;
1003 }
1004#ifdef debug
1005 else G4cout<<"-G4QFragmentation::Construct: 5 (aQDiQDiQ+QaQ) Can't fuse"<<G4endl;
1006#endif
1007 }
1008 else if(cST==3 && pST==3) // QDiQ + aQaDiQ = QaQ (double)
1009 {
1010 tf=6;
1011 if(pLPDG > 7)
1012 {
1013 if (cLPDG<-7 && (-cRPDG==pL1 || -cRPDG==pL2) && (pRPDG==L1 || pRPDG==L2))
1014 af=1;
1015 else if(cRPDG<-7 && (-cLPDG==pL1 || -cLPDG==pL2) && (pRPDG==R1 || pRPDG==R2))
1016 af=2;
1017 }
1018 else if(pRPDG > 7)
1019 {
1020 if (cLPDG<-7 && (-cRPDG==pR1 || -cRPDG==pR2) && (pLPDG==L1 || pLPDG==L2))
1021 af=3;
1022 else if(cRPDG<-7 && (-cLPDG==pR1 || -cLPDG==pR2) && (pLPDG==R1 || pLPDG==R2))
1023 af=4;
1024 }
1025 else if(cLPDG > 7)
1026 {
1027 if (pLPDG<-7 && (-pRPDG==L1 || -pRPDG==L2) && (cRPDG==pL1 || cRPDG==pL2))
1028 af=5;
1029 else if(pRPDG<-7 && (-pLPDG==L1 || -pLPDG==L2) && (cRPDG==pR1 || cRPDG==pR2))
1030 af=6;
1031 }
1032 else if(cRPDG > 7)
1033 {
1034 if (pLPDG<-7 && (-pRPDG==R1 || -pRPDG==R2) && (cLPDG==pL1 || cLPDG==pL2))
1035 af=7;
1036 else if(pRPDG<-7 && (-pLPDG==R1 || -pLPDG==R2) && (cLPDG==pR1 || cLPDG==pR2))
1037 af=8;
1038 }
1039#ifdef debug
1040 else G4cout<<"-G4QFragmentation::Construct: 6 (QDiQ+aQaDiQ) Can't fuse"<<G4endl;
1041#endif
1042 }
1043#ifdef debug
1044 G4cout<<"G4QFragmentation::Const: ***Possibility***, tf="<<tf<<", af="<<af<<G4endl;
1045#endif
1046 if(tf && af)
1047 {
1048 // Strings can be fused, update the max excess and remember usefull switches
1049 G4int order=0; // LL/RR (1) or LR/RL (2) PartonFusion
1050 switch (tf)
1051 {
1052 case 1: // ------------------------------------> QaQ + QaQ = DiQaDiQ (always)
1053 if (cLPDG > 0 && pLPDG > 0)
1054 {
1055 order= 1;
1056 if (cLPDG > pLPDG) nLPDG=cLPDG*1000+pLPDG*100+1;
1057 else if(cLPDG < pLPDG) nLPDG=pLPDG*1000+cLPDG*100+1;
1058 else nLPDG=pLPDG*1000+cLPDG*100+3;
1059 if (cRPDG < pRPDG) nRPDG=cRPDG*1000+pRPDG*100-1;
1060 else if(cRPDG > pRPDG) nRPDG=pRPDG*1000+cRPDG*100-1;
1061 else nRPDG=pRPDG*1000+cRPDG*100-3;
1062 }
1063 else if(cLPDG < 0 && pLPDG < 0)
1064 {
1065 order= 1;
1066 if (cRPDG > pRPDG) nRPDG=cRPDG*1000+pRPDG*100+1;
1067 else if(cRPDG < pRPDG) nRPDG=pRPDG*1000+cRPDG*100+1;
1068 else nRPDG=pRPDG*1000+cRPDG*100+3;
1069 if (cLPDG < pLPDG) nLPDG=cLPDG*1000+pLPDG*100-1;
1070 else if(cLPDG > pLPDG) nLPDG=pLPDG*1000+cLPDG*100-1;
1071 else nLPDG=pLPDG*1000+cLPDG*100-3;
1072 }
1073 else if(cRPDG > 0 && pLPDG > 0)
1074 {
1075 order=-1;
1076 if (cRPDG > pLPDG) nLPDG=cRPDG*1000+pLPDG*100+1;
1077 else if(cRPDG < pLPDG) nLPDG=pLPDG*1000+cRPDG*100+1;
1078 else nLPDG=pLPDG*1000+cRPDG*100+3;
1079 if (cLPDG < pRPDG) nRPDG=cLPDG*1000+pRPDG*100-1;
1080 else if(cLPDG > pRPDG) nRPDG=pRPDG*1000+cLPDG*100-1;
1081 else nRPDG=pRPDG*1000+cLPDG*100-3;
1082 }
1083 else if(cRPDG < 0 && pLPDG < 0)
1084 {
1085 order=-1;
1086 if (cLPDG > pRPDG) nRPDG=cLPDG*1000+pRPDG*100+1;
1087 else if(cLPDG < pRPDG) nRPDG=pRPDG*1000+cLPDG*100+1;
1088 else nRPDG=pRPDG*1000+cLPDG*100+3;
1089 if (cRPDG < pLPDG) nLPDG=cRPDG*1000+pLPDG*100-1;
1090 else if(cRPDG > pLPDG) nLPDG=pLPDG*1000+cRPDG*100-1;
1091 else nLPDG=pLPDG*1000+cRPDG*100-3;
1092 }
1093 break;
1094 case 2: // ------------------------> QaQ + QDiQ/aQaDiQ = QDiQ/aQaDiQ (single)
1095 switch (af)
1096 {
1097 case 1: // ....................... pLPDG > 7
1098 if(cLPDG < 0)
1099 {
1100 order= 1;
1101 if(-cLPDG==pRPDG)
1102 {
1103 nLPDG=pLPDG;
1104 nRPDG=cRPDG;
1105 }
1106 else
1107 {
1108 if (cRPDG > pRPDG) nRPDG=cRPDG*1000+pRPDG*100+1;
1109 else if(cRPDG < pRPDG) nRPDG=pRPDG*1000+cRPDG*100+1;
1110 else nRPDG=pRPDG*1000+cRPDG*100+3;
1111 if (-cLPDG == pL1) nLPDG=pL2;
1112 else nLPDG=pL1; // -cLPDG == pL2
1113 }
1114 }
1115 else // cRPDG < 0
1116 {
1117 order=-1;
1118 if(-cRPDG==pRPDG)
1119 {
1120 nLPDG=pLPDG;
1121 nRPDG=cLPDG;
1122 }
1123 else
1124 {
1125 if (cLPDG > pRPDG) nRPDG=cLPDG*1000+pRPDG*100+1;
1126 else if(cLPDG < pRPDG) nRPDG=pRPDG*1000+cLPDG*100+1;
1127 else nRPDG=pRPDG*1000+cLPDG*100+3;
1128 if (-cRPDG == pL1) nLPDG=pL2;
1129 else nLPDG=pL1; // -cRPDG == pL2
1130 }
1131 }
1132 break;
1133 case 2: // ....................... pRPDG > 7
1134 if(cLPDG < 0)
1135 {
1136 order=-1;
1137 if(-cLPDG==pLPDG)
1138 {
1139 nLPDG=cRPDG;
1140 nRPDG=pRPDG;
1141 }
1142 else
1143 {
1144 if (cRPDG > pLPDG) nLPDG=cRPDG*1000+pLPDG*100+1;
1145 else if(cRPDG < pLPDG) nLPDG=pLPDG*1000+cRPDG*100+1;
1146 else nLPDG=pLPDG*1000+cRPDG*100+3;
1147 if (-cLPDG == pR1) nRPDG=pR2;
1148 else nRPDG=pR1; // -cLPDG == pR2
1149 }
1150 }
1151 else // cRPDG < 0
1152 {
1153 order= 1;
1154 if(-cRPDG==pLPDG)
1155 {
1156 nLPDG=cLPDG;
1157 nRPDG=pRPDG;
1158 }
1159 else
1160 {
1161 if (cLPDG > pLPDG) nLPDG=cLPDG*1000+pLPDG*100+1;
1162 else if(cLPDG < pLPDG) nLPDG=pLPDG*1000+cLPDG*100+1;
1163 else nLPDG=pLPDG*1000+cLPDG*100+3;
1164 if (-cRPDG == pR1) nRPDG=pR2;
1165 else nRPDG=pR1; // -cRPDG == pR2
1166 }
1167 }
1168 break;
1169 case 3: // ....................... pLPDG <-7
1170 if(cLPDG > 0)
1171 {
1172 order= 1;
1173 if(cLPDG==-pRPDG)
1174 {
1175 nLPDG=pLPDG;
1176 nRPDG=cRPDG;
1177 }
1178 else
1179 {
1180 if (cRPDG < pRPDG) nRPDG=cRPDG*1000+pRPDG*100-1;
1181 else if(cRPDG > pRPDG) nRPDG=pRPDG*1000+cRPDG*100-1;
1182 else nRPDG=pRPDG*1000+cRPDG*100-3;
1183 if ( cLPDG == pL1) nLPDG=-pL2;
1184 else nLPDG=-pL1; // cLPDG == pL2
1185 }
1186 }
1187 else // cRPDG > 0
1188 {
1189 order=-1;
1190 if(cRPDG==-pRPDG)
1191 {
1192 nLPDG=pLPDG;
1193 nRPDG=cLPDG;
1194 }
1195 else
1196 {
1197 if (cLPDG < pRPDG) nRPDG=cLPDG*1000+pRPDG*100-1;
1198 else if(cLPDG > pRPDG) nRPDG=pRPDG*1000+cLPDG*100-1;
1199 else nRPDG=pRPDG*1000+cLPDG*100-3;
1200 if ( cRPDG == pL1) nLPDG=-pL2;
1201 else nLPDG=-pL1; // cRPDG == pL2
1202 }
1203 }
1204 break;
1205 case 4: // ....................... pRPDG <-7
1206 if(cLPDG > 0)
1207 {
1208 order=-1;
1209 if(cLPDG==-pLPDG)
1210 {
1211 nLPDG=cRPDG;
1212 nRPDG=pRPDG;
1213 }
1214 else
1215 {
1216 if (cRPDG < pLPDG) nLPDG=cRPDG*1000+pLPDG*100-1;
1217 else if(cRPDG > pLPDG) nLPDG=pLPDG*1000+cRPDG*100-1;
1218 else nLPDG=pLPDG*1000+cRPDG*100-3;
1219 if ( cLPDG == pR1) nRPDG=-pR2;
1220 else nRPDG=-pR1; // cLPDG == pR2
1221 }
1222 }
1223 else // cRPDG > 0
1224 {
1225 order= 1;
1226 if(cRPDG==-pLPDG)
1227 {
1228 nLPDG=cLPDG;
1229 nRPDG=pRPDG;
1230 }
1231 else
1232 {
1233 if (cLPDG < pLPDG) nLPDG=cLPDG*1000+pLPDG*100-1;
1234 else if(cLPDG > pLPDG) nLPDG=pLPDG*1000+cLPDG*100-1;
1235 else nLPDG=pLPDG*1000+cLPDG*100-3;
1236 if ( cRPDG == pR1) nRPDG=-pR2;
1237 else nRPDG=-pR1; // cRPDG == pR2
1238 }
1239 }
1240 break;
1241 }
1242 break;
1243 case 3: // ------------------------> QDiQ/aQaDiQ + QaQ = QDiQ/aQaDiQ (single)
1244 switch (af)
1245 {
1246 case 1: // ....................... cLPDG > 7
1247 if(pLPDG < 0)
1248 {
1249 order= 1;
1250 if(-pLPDG==cRPDG)
1251 {
1252 nLPDG=cLPDG;
1253 nRPDG=pRPDG;
1254 }
1255 else
1256 {
1257 if (pRPDG > cRPDG) nRPDG=pRPDG*1000+cRPDG*100+1;
1258 else if(pRPDG < cRPDG) nRPDG=cRPDG*1000+pRPDG*100+1;
1259 else nRPDG=cRPDG*1000+pRPDG*100+3;
1260 if (-pLPDG == L1) nLPDG=L2;
1261 else nLPDG=L1; // -pLPDG == L2
1262 }
1263 }
1264 else // pRPDG < 0
1265 {
1266 order=-1;
1267 if(-pRPDG==cRPDG)
1268 {
1269 nLPDG=cLPDG;
1270 nRPDG=pLPDG;
1271 }
1272 else
1273 {
1274 if (pLPDG > cRPDG) nLPDG=pLPDG*1000+cRPDG*100+1;
1275 else if(pLPDG < cRPDG) nLPDG=cRPDG*1000+pLPDG*100+1;
1276 else nLPDG=cRPDG*1000+pLPDG*100+3;
1277 if (-pRPDG == L1) nRPDG=L2;
1278 else nRPDG=L1; // -pRPDG == L2
1279 }
1280 }
1281 break;
1282 case 2: // ....................... cRPDG > 7
1283 if(pLPDG < 0)
1284 {
1285 order=-1;
1286 if(-pLPDG==cLPDG)
1287 {
1288 nLPDG=pRPDG;
1289 nRPDG=cRPDG;
1290 }
1291 else
1292 {
1293 if (pRPDG > cLPDG) nRPDG=pRPDG*1000+cLPDG*100+1;
1294 else if(pRPDG < cLPDG) nRPDG=cLPDG*1000+pRPDG*100+1;
1295 else nRPDG=cLPDG*1000+pRPDG*100+3;
1296 if (-pLPDG == R1) nLPDG=R2;
1297 else nLPDG=R1; // -pLPDG == R2
1298 }
1299 }
1300 else // pRPDG < 0
1301 {
1302 order= 1;
1303 if(-pRPDG==cLPDG)
1304 {
1305 nLPDG=pLPDG;
1306 nRPDG=cRPDG;
1307 }
1308 else
1309 {
1310 if (pLPDG > cLPDG) nLPDG=pLPDG*1000+cLPDG*100+1;
1311 else if(pLPDG < cLPDG) nLPDG=cLPDG*1000+pLPDG*100+1;
1312 else nLPDG=cLPDG*1000+pLPDG*100+3;
1313 if (-pRPDG == R1) nRPDG=R2;
1314 else nRPDG=R1; // -pRPDG == R2
1315 }
1316 }
1317 break;
1318 case 3: // ....................... cLPDG <-7 (cRPDG <0)
1319 if(pLPDG > 0)
1320 {
1321 order= 1;
1322 if(pLPDG==-cRPDG)
1323 {
1324 nLPDG=cLPDG;
1325 nRPDG=pRPDG;
1326 }
1327 else
1328 {
1329 if (pRPDG < cRPDG) nRPDG=pRPDG*1000+cRPDG*100-1;
1330 else if(pRPDG > cRPDG) nRPDG=cRPDG*1000+pRPDG*100-1;
1331 else nRPDG=cRPDG*1000+pRPDG*100-3;
1332 if ( pLPDG == L1) nLPDG=-L2;
1333 else nLPDG=-L1; // pLPDG == L2
1334 }
1335 }
1336 else // pRPDG > 0
1337 {
1338 order=-1;
1339 if(pRPDG==-cRPDG)
1340 {
1341 nLPDG=cLPDG;
1342 nRPDG=pLPDG;
1343 }
1344 else
1345 {
1346 if (pLPDG < cRPDG) nLPDG=pLPDG*1000+cRPDG*100-1;
1347 else if(pLPDG > cRPDG) nLPDG=cRPDG*1000+pLPDG*100-1;
1348 else nLPDG=cRPDG*1000+pLPDG*100-3;
1349 if ( pRPDG == L1) nRPDG=-L2;
1350 else nRPDG=-L1; // pRPDG == L2
1351 }
1352 }
1353 break;
1354 case 4: // ....................... cRPDG <-7 (cLPDG <0)
1355 if(pLPDG > 0) // pRPDG & cLPDG are anti-quarks
1356 {
1357 order=-1;
1358 if(pLPDG==-cLPDG)
1359 {
1360 nLPDG=pRPDG;
1361 nRPDG=cRPDG;
1362 }
1363 else
1364 {
1365 if (pRPDG < cLPDG) nRPDG=pRPDG*1000+cLPDG*100-1;
1366 else if(pRPDG > cLPDG) nRPDG=cLPDG*1000+pRPDG*100-1;
1367 else nRPDG=cLPDG*1000+pRPDG*100-3;
1368 if ( pLPDG == R1) nLPDG=-R2;
1369 else nLPDG=-R1; // pLPDG == R2
1370 }
1371 }
1372 else // pRPDG > 0
1373 {
1374 order= 1;
1375 if(pRPDG==-cLPDG)
1376 {
1377 nLPDG=pLPDG;
1378 nRPDG=cRPDG;
1379 }
1380 else
1381 {
1382 if (pLPDG < cLPDG) nLPDG=pLPDG*1000+cLPDG*100-1;
1383 else if(pLPDG > cLPDG) nLPDG=cLPDG*1000+pLPDG*100-1;
1384 else nLPDG=cLPDG*1000+pLPDG*100-3;
1385 if ( pRPDG == R1) nRPDG=-R2;
1386 else nRPDG=-R1; // pRPDG == R2
1387 }
1388 }
1389 break;
1390 }
1391 break;
1392 case 4: // ------------------------------------> QaQ + aDiQDiQ = QaQ (double)
1393 switch (af)
1394 {
1395 case 1: // ....................... pLPDG > 7 && pRPDG <-7 === LL/RR
1396 order= 1;
1397 if(-cLPDG == pL1) nLPDG= pL2;
1398 else nLPDG= pL1;
1399 if( cRPDG == pR1) nRPDG=-pR2;
1400 else nRPDG=-pR1;
1401 break;
1402 case 2: // ...................... pLPDG > 7 && pRPDG <-7 === LR/RL
1403 order=-1;
1404 if(-cRPDG == pL1) nLPDG= pL2;
1405 else nLPDG= pL1;
1406 if( cLPDG == pR1) nRPDG=-pR2;
1407 else nRPDG=-pR1;
1408 break;
1409 case 3: // ...................... pRPDG > 7 && pLPDG <-7 === LL/RR
1410 order= 1;
1411 if( cLPDG == pL1) nLPDG=-pL2;
1412 else nLPDG=-pL1;
1413 if(-cRPDG == pR1) nRPDG= pR2;
1414 else nRPDG= pR1;
1415 break;
1416 case 4: // ...................... pRPDG > 7 && pLPDG <-7 === LR/RL
1417 order=-1;
1418 if( cRPDG == pL1) nLPDG=-pL2;
1419 else nLPDG=-pL1;
1420 if(-cLPDG == pR1) nRPDG= pR2;
1421 else nRPDG= pR1;
1422 break;
1423 }
1424 break;
1425 case 5: // ------------------------------------> aDiQDiQ + QaQ = QaQ (double)
1426 switch (af)
1427 {
1428 case 1: // ...................... cLPDG > 7 && cRPDG <-7 === LL/RR
1429 order= 1;
1430 if(-pLPDG == L1) nLPDG= L2;
1431 else nLPDG= L1;
1432 if( pRPDG == R1) nRPDG=-R2;
1433 else nRPDG=-R1;
1434 break;
1435 case 2: // ...................... cLPDG > 7 && cRPDG <-7 === LR/RL
1436 order=-1;
1437 if(-pRPDG == L1) nRPDG= L2;
1438 else nRPDG= L1;
1439 if( pLPDG == R1) nLPDG=-R2;
1440 else nLPDG=-R1;
1441 break;
1442 case 3: // ...................... cRPDG > 7 && cLPDG <-7 === LL/RR
1443 order= 1;
1444 if( pLPDG == L1) nLPDG=-L2;
1445 else nLPDG=-L1;
1446 if(-pRPDG == R1) nRPDG= R2;
1447 else nRPDG= R1;
1448 break;
1449 case 4: // ...................... cRPDG > 7 && cLPDG <-7 === LR/RL
1450 order=-1;
1451 if( pRPDG == L1) nRPDG=-L2;
1452 else nRPDG=-L1;
1453 if(-pLPDG == R1) nLPDG= R2;
1454 else nLPDG= R1;
1455 break;
1456 }
1457 break;
1458 case 6: // ------------------------------------> QDiQ + aQaDiQ = QaQ (double)
1459 switch (af)
1460 {
1461 case 1:
1462 order=-1;
1463 if(-cRPDG == pL1) nLPDG= pL2;
1464 else nLPDG= pL1;
1465 if( pRPDG == L1) nRPDG= -L2;
1466 else nRPDG= -L1;
1467 break;
1468 case 2:
1469 order= 1;
1470 if(-cLPDG == pL1) nLPDG= pL2;
1471 else nLPDG= pL1;
1472 if( pRPDG == R1) nRPDG= -R2;
1473 else nRPDG= -R1;
1474 break;
1475 case 3:
1476 order= 1;
1477 if(-cRPDG == pR1) nRPDG= pR2;
1478 else nRPDG= pR1;
1479 if( pLPDG == L1) nLPDG= -L2;
1480 else nLPDG= -L1;
1481 break;
1482 case 4:
1483 order=-1;
1484 if(-cLPDG == pR1) nRPDG= pR2;
1485 else nRPDG= pR1;
1486 if( pLPDG == R1) nLPDG= -R2;
1487 else nLPDG= -R1;
1488 break;
1489 case 5:
1490 order=-1;
1491 if(-pRPDG == L1) nRPDG= L2;
1492 else nRPDG= L1;
1493 if( cRPDG == pL1) nLPDG=-pL2;
1494 else nLPDG=-pL1;
1495 break;
1496 case 6:
1497 order= 1;
1498 if(-pLPDG == L1) nLPDG= L2;
1499 else nLPDG= L1;
1500 if( cRPDG == pR1) nRPDG=-pR2;
1501 else nRPDG=-pR1;
1502 break;
1503 case 7:
1504 order= 1;
1505 if(-pRPDG == R1) nRPDG= R2;
1506 else nRPDG= R1;
1507 if( cLPDG == pL1) nLPDG=-pL2;
1508 else nLPDG=-pL1;
1509 break;
1510 case 8:
1511 order=-1;
1512 if(-pLPDG == R1) nLPDG= R2;
1513 else nLPDG= R1;
1514 if( cLPDG == pR1) nRPDG=-pR2;
1515 else nRPDG=-pR1;
1516 break;
1517 }
1518 break;
1519 }
1520 if(!order) G4cerr<<"-Warning-G4QFrag::Constr: t="<<tf<<", a="<<af<<", cL="<<cLPDG
1521 <<", cR="<<cRPDG<<", pL="<<pLPDG<<", pR="<<pRPDG<<G4endl;
1522 else
1523 {
1524 // With theNewHypotheticalPartons the min mass must be calculated & compared
1525 G4int LT=1;
1526 if(std::abs(nLPDG) > 7) ++LT;
1527 G4int RT=1;
1528 if(std::abs(nRPDG) > 7) ++RT;
1529 G4double minM=0.;
1530 G4bool sing=true;
1531 if(cLT==2 && cRT==2)
1532 {
1533 aLPDG=0;
1534 aRPDG=0;
1535 if(cLPDG>0)
1536 {
1537 aLPDG=nLPDG/100;
1538 aRPDG=(-nRPDG)/100;
1539 }
1540 else //cRPDG>0
1541 {
1542 aRPDG=nRPDG/100;
1543 aLPDG=(-nLPDG)/100;
1544 }
1545 G4int nL1=aLPDG/10;
1546 G4int nL2=aLPDG%10;
1547 G4int nR1=aRPDG/10;
1548 G4int nR2=aRPDG%10;
1549 if(nL1!=nR1 && nL1!=nR2 && nL2!=nR1 && nL2!=nR2) // Unreducable DiQ-aDiQ
1550 {
1551#ifdef debug
1552 G4cout<<"G4QFragmentation::Const:aLPDG="<<aLPDG<<", aRPDG="<<aRPDG<<G4endl;
1553#endif
1554 sing=false;
1555 G4QPDGCode tmp;
1556 std::pair<G4int,G4int> pB=tmp.MakeTwoBaryons(nL1, nL2, nR1, nR2);
1557 minM=G4QPDGCode(pB.first).GetMass()+G4QPDGCode(pB.second).GetMass();
1558 }
1559 }
1560 if(sing)
1561 {
1562 std::pair<G4int,G4int> newPair = std::make_pair(nLPDG,nRPDG);
1563 G4QContent newStQC(newPair); // NewString QuarkContent
1564#ifdef debug
1565 G4cout<<"G4QFr::Con: LPDG="<<nLPDG<<",RPDG="<<nRPDG<<",QC="<<newStQC<<G4endl;
1566#endif
1567 G4int minPDG=newStQC.GetSPDGCode(); // PDG of the Lightest Hadron=String
1568 minM=G4QPDGCode(minPDG).GetMass() + mPi0; // Min SingleHadron=String Mass
1569 }
1570 // Compare this mass
1571 G4bool win=false;
1572 G4double pSM=0.;
1573 if(pSM2>0.) pSM=std::sqrt(pSM2);
1574 if(minC && pSM2 > maxiM2) // Up to now any positive mass is good
1575 {
1576 maxiM2=pSM2;
1577 win=true;
1578 }
1579 else if(!minC || pSM > minM)
1580 {
1581 pExcess=pSM-minM;
1582 if(minC || pExcess > excess)
1583 {
1584 minC=false;
1585 excess=pExcess;
1586 win=true;
1587 }
1588 }
1589 if(win)
1590 {
1591 sst=pst;
1592 sLPDG=nLPDG;
1593 sRPDG=nRPDG;
1594 sOrd=order;
1595 }
1596 } // End of IF(new partons are created)
1597 } // End of IF(compatible partons)
1598 //} // End of positive squared mass of the fused string
1599 } // End of the LOOP over the possible partners (with the exclusive if for itself)
1600 if(sOrd) // The best pStringCandidate was found
1601 {
1602 G4LorentzVector cL4M=cLeft->Get4Momentum();
1603 G4LorentzVector cR4M=cRight->Get4Momentum();
1604 G4QParton* pLeft=(*sst)->GetLeftParton();
1605 G4QParton* pRight=(*sst)->GetRightParton();
1606 G4LorentzVector pL4M=pLeft->Get4Momentum();
1607 G4LorentzVector pR4M=pRight->Get4Momentum();
1608#ifdef debug
1609 G4cout<<"G4QFragmentation::Const:cS4M="<<cS4M<<" fused/w pS4M="<<pL4M+pR4M<<G4endl;
1610#endif
1611 if(sOrd>0)
1612 {
1613 pL4M+=cL4M;
1614 pR4M+=cR4M;
1615 }
1616 else
1617 {
1618 pL4M+=cR4M;
1619 pR4M+=cL4M;
1620 }
1621 pLeft->SetPDGCode(sLPDG);
1622 pLeft->Set4Momentum(pL4M);
1623 pRight->SetPDGCode(sRPDG);
1624 pRight->Set4Momentum(pR4M);
1625 delete (*ist);
1626 strings.erase(ist);
1627#ifdef debug
1628 G4LorentzVector ss4M=pL4M+pR4M;
1629 G4cout<<"G4QFragmentation::Construct:Created,4M="<<ss4M<<",m2="<<ss4M.m2()<<G4endl;
1630#endif
1631 if( ist != strings.begin() ) // To avoid going below begin() (for Windows)
1632 {
1633 ist--;
1634 con=false;
1635#ifdef debug
1636 G4cout<<"G4QFragmentation::Construct: *** IST Decremented ***"<<G4endl;
1637#endif
1638 }
1639 else
1640 {
1641 con=true;
1642#ifdef debug
1643 G4cout<<"G4QFragmentation::Construct: *** IST Begin ***"<<G4endl;
1644#endif
1645 break;
1646 }
1647 } // End of the IF(the best partnerString candidate was found)
1648 else
1649 {
1650#ifdef debug
1651 G4cout<<"-Warning-G4QFragm::Const:S4M="<<cS4M<<",M2="<<cSM2<<" Leave ASIS"<<G4endl;
1652#endif
1653 ++problem;
1654 con=false;
1655 }
1656 } // End of IF
1657 else con=false;
1658 } // End of loop over ist iterator
1659#ifdef debug
1660 G4cout<<"G4QFragmentation::Construct: *** IST While *** , con="<<con<<G4endl;
1661#endif
1662 } // End of "con" while
1663#ifdef edebug
1664 // This print has meaning only if something appear between it and the StringFragmLOOP
1665 G4LorentzVector t4M=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
1666 G4int rC=totChg-theNucleus.GetZ();
1667 G4int rB=totBaN-theNucleus.GetA();
1668 G4int nStr=strings.size();
1669 G4cout<<"-EMCLS-G4QFr::Const: AfterSUPPRESION #ofS="<<nStr<<",tNuc4M(E=M)="<<sum<<G4endl;
1670 for(G4int i=0; i<nStr; i++)
1671 {
1672 G4LorentzVector strI4M=strings[i]->Get4Momentum();
1673 t4M+=strI4M;
1674 G4int sChg=strings[i]->GetCharge();
1675 rC-=sChg;
1676 G4int sBaN=strings[i]->GetBaryonNumber();
1677 rB-=sBaN;
1678 G4cout<<"-EMCLS-G4QFragm::Construct: St#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
1679 <<", C="<<sChg<<", B="<<sBaN<<G4endl;
1680 }
1681 G4cout<<"-EMCLS-G4QFragm::Construct:r4M="<<t4M-totLS4M<<",rC="<<rC<<",rB="<<rB<<G4endl;
1682#endif
1683 //
1684 // --- If a problem is foreseen then the DiQaDiQ strings should be reduced if possible --
1685 //
1686#ifdef debug
1687 G4cout<<"G4QFragmentation::Construct: problem="<<problem<<G4endl;
1688#endif
1689 if(problem)
1690 {
1691 G4int nOfStr=strings.size();
1692#ifdef debug
1693 G4cout<<"G4QFragmentation::Construct:SecurityDiQaDiQReduction,#OfStr="<<nOfStr<<G4endl;
1694#endif
1695 for (G4int astring=0; astring < nOfStr; astring++)
1696 {
1697 G4QString* curString=strings[astring];
1698 G4QParton* cLeft=curString->GetLeftParton();
1699 G4QParton* cRight=curString->GetRightParton();
1700 G4int LT=cLeft->GetType();
1701 G4int RT=cRight->GetType();
1702 G4int sPDG=cLeft->GetPDGCode();
1703 G4int nPDG=cRight->GetPDGCode();
1704 if(LT==2 && RT==2)
1705 {
1706#ifdef debug
1707 G4cout<<"G4QFragmentation::Constr:TrySelfReduString,L="<<sPDG<<",R="<<nPDG<<G4endl;
1708#endif
1709 if( cLeft->ReduceDiQADiQ(cLeft, cRight) ) // DiQ-aDiQ pair was successfully reduced
1710 {
1711 sPDG=cLeft->GetPDGCode();
1712 nPDG=cRight->GetPDGCode();
1713#ifdef debug
1714 G4cout<<"+G4QFragm::Const:#"<<astring<<" Reduced, L="<<sPDG<<",R="<<nPDG<<G4endl;
1715#endif
1716 }
1717#ifdef debug
1718 else G4cout<<"--*--G4QFragm::Const:#"<<astring<<" DQ-aDQ reduction Failed"<<G4endl;
1719#endif
1720 } // End of the found DiQ/aDiQ pair
1721 else if(sPDG==3 && nPDG==-3)
1722 {
1723 sPDG= 1;
1724 nPDG=-1;
1725 cLeft->SetPDGCode(sPDG);
1726 cRight->SetPDGCode(nPDG);
1727 }
1728 else if(sPDG==-3 && nPDG==3)
1729 {
1730 sPDG=-1;
1731 nPDG= 1;
1732 cLeft->SetPDGCode(sPDG);
1733 cRight->SetPDGCode(nPDG);
1734 }
1735 }
1736 SwapPartons();
1737 } // End of IF(problem)
1738#ifdef edebug
1739 G4LorentzVector u4M=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
1740 G4int rCh=totChg-theNucleus.GetZ();
1741 G4int rBa=totBaN-theNucleus.GetA();
1742 G4int nStri=strings.size();
1743 G4cout<<"-EMCLS-G4QFr::Const: FinalConstruct, #ofSt="<<nStri<<",tN4M(E=M)="<<t4M<<G4endl;
1744 for(G4int i=0; i<nStri; i++)
1745 {
1746 G4LorentzVector strI4M=strings[i]->Get4Momentum();
1747 u4M+=strI4M;
1748 G4int sChg=strings[i]->GetCharge();
1749 rCh-=sChg;
1750 G4int sBaN=strings[i]->GetBaryonNumber();
1751 rBa-=sBaN;
1752 G4cout<<"-EMCLS-G4QFragm::Construct: St#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
1753 <<", C="<<sChg<<", B="<<sBaN<<G4endl;
1754 }
1755 G4cout<<"-EMCLS-G4QFragm::Construct:r4M="<<u4M-totLS4M<<",rC="<<rCh<<",rB="<<rBa<<G4endl;
1756#endif
1757} // End of the Constructer
@ LT
Definition: Evaluator.cc:66
@ FatalException
std::vector< G4QHadron * > G4QHadronVector
std::vector< G4QInteraction * > G4QInteractionVector
std::vector< G4QPartonPair * > G4QPartonPairVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
double x() const
double y() const
HepLorentzRotation & rotateY(double delta)
HepLorentzRotation & rotateZ(double delta)
HepLorentzRotation inverse() const
double theta() const
HepLorentzVector & boost(double, double, double)
static G4QCHIPSWorld * Get()
G4QHadronVector * ProjFragment(G4int pPDG, G4LorentzVector p4M, G4int tgZ, G4int tgN)
static G4QDiffractionRatio * GetPointer()
G4double GetRatio(G4double pIU, G4int prPDG, G4int tgZ, G4int tgN)
G4bool IsSingleDiffractive()
G4bool ExciteDiffParticipants(G4QHadron *aPartner, G4QHadron *bPartner) const
G4bool ExciteSingDiffParticipants(G4QHadron *aPartner, G4QHadron *bPartner) const
G4LorentzVector Get4Momentum() const
Definition: G4QHadron.hh:79
G4double GetMass() const
Definition: G4QHadron.hh:176
G4int GetBaryonNumber() const
Definition: G4QHadron.hh:181
void IncrementCollisionCount(G4int aCount)
Definition: G4QHadron.hh:104
G4int GetCharge() const
Definition: G4QHadron.hh:179
G4QParton * GetNextParton()
Definition: G4QHadron.cc:1614
G4int GetPDGCode() const
Definition: G4QHadron.hh:170
const G4ThreeVector & GetPosition() const
Definition: G4QHadron.hh:182
std::list< G4QParton * > GetColor()
Definition: G4QHadron.hh:93
std::list< G4QParton * > GetAntiColor()
Definition: G4QHadron.hh:94
G4QParton * GetNextAntiParton()
Definition: G4QHadron.cc:1622
G4QContent GetQC() const
Definition: G4QHadron.hh:173
void Set4Momentum(const G4LorentzVector &aMom)
Definition: G4QHadron.hh:187
G4int GetNumberOfSoftCollisions()
void SetNumberOfSoftCollisions(G4int nofSoft)
G4QHadron * GetProjectile() const
G4QHadron * GetTarget() const
void SetTarget(G4QHadron *aTarget)
void SetNumberOfDINRCollisions(G4int nofDINR)
void SetNumberOfDiffractiveCollisions(G4int nofDiff)
void InitByPDG(G4int newPDG)
Definition: G4QNucleus.cc:371
G4int GetN() const
Definition: G4QNucleus.hh:71
G4int GetZ() const
Definition: G4QNucleus.hh:70
std::pair< G4double, G4double > ChooseImpactXandY(G4double maxImpact)
Definition: G4QNucleus.cc:3551
G4int GetPDG() const
Definition: G4QNucleus.hh:69
G4double GetOuterRadius()
Definition: G4QNucleus.cc:3947
G4bool StartLoop()
Definition: G4QNucleus.cc:3982
void SubtractNucleon(G4QHadron *pNucleon)
Definition: G4QNucleus.cc:612
void DoLorentzBoost(const G4LorentzVector &theBoost)
Definition: G4QNucleus.hh:155
G4int GetA() const
Definition: G4QNucleus.hh:73
void DoLorentzRotation(const G4LorentzRotation &theLoRot)
Definition: G4QNucleus.hh:160
G4double GetThickness(G4double b)
Definition: G4QNucleus.cc:4048
G4LorentzVector GetNucleons4Momentum()
Definition: G4QNucleus.hh:107
void Init3D()
Definition: G4QNucleus.cc:3910
G4QHadron * GetNextNucleon()
Definition: G4QNucleus.hh:100
G4double CoulombBarrier(const G4double &cZ=1, const G4double &cA=1, G4double dZ=0., G4double dA=0.)
Definition: G4QNucleus.cc:3386
G4double GetGSMass() const
Definition: G4QNucleus.hh:82
G4double GetMass()
Definition: G4QPDGCode.cc:693
std::pair< G4int, G4int > MakeTwoBaryons(G4int L1, G4int L2, G4int R1, G4int R2)
Definition: G4QPDGCode.cc:2413
G4int GetCollisionType()
void SetPDGCode(G4int aPDG)
Definition: G4QParton.cc:130
G4QContent GetQC() const
Definition: G4QParton.hh:82
const G4int & GetType() const
Definition: G4QParton.hh:88
G4int GetPDGCode() const
Definition: G4QParton.hh:81
const G4LorentzVector & Get4Momentum() const
Definition: G4QParton.hh:84
void Set4Momentum(const G4LorentzVector &aMomentum)
Definition: G4QParton.hh:75
G4bool ReduceDiQADiQ(G4QParton *d1, G4QParton *d2)
Definition: G4QParton.cc:246
G4QParton * GetLeftParton() const
Definition: G4QString.hh:87
G4int GetCharge() const
Definition: G4QString.hh:92
G4LorentzVector Get4Momentum() const
Definition: G4QString.cc:124
G4int GetBaryonNumber() const
Definition: G4QString.hh:93
G4QParton * GetRightParton() const
Definition: G4QString.hh:88
void Boost(G4ThreeVector &Velocity)
Definition: G4QString.cc:152
std::pair< G4LorentzVector, G4LorentzVector > Scatter(G4int NPDG, G4LorentzVector N4M, G4int pPDG, G4LorentzVector p4M)
static G4QuasiFreeRatios * GetPointer()
std::pair< G4double, G4double > GetRatios(G4double pIU, G4int prPDG, G4int tgZ, G4int tgN)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
T sqr(const T &x)
Definition: templates.hh:145
#define DBL_MAX
Definition: templates.hh:83

◆ ~G4QFragmentation()

G4QFragmentation::~G4QFragmentation ( )

Definition at line 1759 of file G4QFragmentation.cc.

1760{
1761 std::for_each(strings.begin(), strings.end(), DeleteQString() );
1762}

Member Function Documentation

◆ AnnihilationOrder()

G4int G4QFragmentation::AnnihilationOrder ( G4int  LS,
G4int  MS,
G4int  uP,
G4int  mP,
G4int  sP,
G4int  nP 
)
protected

Definition at line 4432 of file G4QFragmentation.cc.

4434{// ^L^^ Curent ^^R^
4435 G4int Ord=0;
4436 // Curent Partner
4437 if (LS==2 && MPS==2 ) // Fuse 2 Q-aQ strings to DiQ-aDiQ
4438 {
4439#ifdef debug
4440 G4cout<<"G4QFragmentation::AnnihilationOrder: QaQ/QaQ->DiQ-aDiQ, uPDG="<<uPDG<<G4endl;
4441#endif
4442 if ( (uPDG>0 && sPDG>0 && mPDG<0 && nPDG<0) ||
4443 (uPDG<0 && sPDG<0 && mPDG>0 && nPDG>0) ) Ord= 1; // LL/RR
4444 else if( (uPDG>0 && nPDG>0 && mPDG<0 && sPDG<0) ||
4445 (uPDG<0 && nPDG<0 && mPDG>0 && sPDG>0) ) Ord=-1; // LR/RL
4446 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 22 fusion, L="<<uPDG
4447 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4448 }
4449 else if ( LS==2 && MPS==3 )
4450 {
4451 if (uPDG > 7) // Fuse pLDiQ
4452 {
4453#ifdef debug
4454 G4cout<<"G4QFragmentation::AnnihOrder: pLDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
4455#endif
4456 if ( sPDG<0 && (-sPDG==uPDG/1000 || -sPDG==(uPDG/100)%10) ) Ord= 1; // LL/RR
4457 else if( nPDG<0 && (-nPDG==uPDG/1000 || -nPDG==(uPDG/100)%10) ) Ord=-1; // LR/RL
4458 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pLDiQ, L="<<uPDG
4459 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4460 }
4461 else if (mPDG > 7) // Fuse pRDiQ
4462 {
4463#ifdef debug
4464 G4cout<<"G4QFragmentation::AnnihOrder: pRDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
4465#endif
4466 if ( sPDG<0 && (-sPDG==mPDG/1000 || -sPDG==(mPDG/100)%10) ) Ord=-1; // LR/RL
4467 else if( nPDG<0 && (-nPDG==mPDG/1000 || -nPDG==(mPDG/100)%10) ) Ord= 1; // LL/RR
4468 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pRDiQ, L="<<uPDG
4469 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4470 }
4471 else if (uPDG <-7) // Fuse pLaDiQ
4472 {
4473#ifdef debug
4474 G4cout<<"G4QFragmentation::AnnihOrder: pLaDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
4475#endif
4476 if ( sPDG>0 && (sPDG==(-uPDG)/1000 || sPDG==((-uPDG)/100)%10) ) Ord= 1; // LL/RR
4477 else if( nPDG>0 && (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord=-1; // LR/RL
4478 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pLaDiQ, L="<<uPDG
4479 <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
4480 }
4481 else if (mPDG <-7) // Fuse pRaDiQ
4482 {
4483#ifdef debug
4484 G4cout<<"G4QFragmentation::AnnihOrder: pRaDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
4485#endif
4486 if ( sPDG>0 && (sPDG==(-mPDG)/1000 || sPDG==((-mPDG)/100)%10) ) Ord=-1; // LR/RL
4487 else if( nPDG>0 && (nPDG==(-mPDG)/1000 || nPDG==((-mPDG)/100)%10) ) Ord= 1; // LL/RR
4488 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pRaDiQ, L="<<uPDG
4489 <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
4490 }
4491 else if( (sPDG<0 && (-sPDG==mPDG || -sPDG==uPDG) ) ||
4492 (nPDG<0 && (-nPDG==mPDG || -nPDG==uPDG) ) ) Ord= 2; // @@ Annihilation fusion
4493#ifdef debug
4494 else G4cout<<"-Warning-G4QFragmentation::AnnihilatOrder: Wrong 23StringFusion"<<G4endl;
4495 G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
4496 <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4497#endif
4498 }
4499 else if ( LS==3 && MPS==2 )
4500 {
4501 if (sPDG > 7) // Fuse cLDiQ
4502 {
4503#ifdef debug
4504 G4cout<<"G4QFragmentation::AnnihOrder: cLDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
4505#endif
4506 if ( uPDG<0 && (-uPDG==sPDG/1000 || -uPDG==(sPDG/100)%10) ) Ord= 1; // LL/RR
4507 else if( mPDG<0 && (-mPDG==sPDG/1000 || -mPDG==(sPDG/100)%10) ) Ord=-1; // LR/RL
4508 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cLDiQ, L="<<uPDG
4509 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4510 }
4511 else if (nPDG > 7) // Fuse cRDiQ
4512 {
4513#ifdef debug
4514 G4cout<<"G4QFragmentation::AnnihOrder: cRDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
4515#endif
4516 if ( uPDG<0 && (-uPDG==nPDG/1000 || -uPDG==(nPDG/100)%10) ) Ord=-1; // LR/RL
4517 else if( mPDG<0 && (-mPDG==nPDG/1000 || -mPDG==(nPDG/100)%10) ) Ord= 1; // LL/RR
4518 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cRDiQ, L="<<uPDG
4519 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4520 }
4521 else if (sPDG <-7) // Fuse cLaDiQ
4522 {
4523#ifdef debug
4524 G4cout<<"G4QFragmentation::AnnihOrder: cLaDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
4525#endif
4526 if ( uPDG>0 && (uPDG==(-sPDG)/1000 || uPDG==((-sPDG)/100)%10) ) Ord= 1; // LL/RR
4527 else if( mPDG>0 && (mPDG==(-sPDG)/1000 || mPDG==((-sPDG)/100)%10) ) Ord=-1; // LR/RL
4528 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cLaDiQ, L="<<uPDG
4529 <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
4530 }
4531 else if (nPDG <-7) // Fuse cRaDiQ
4532 {
4533#ifdef debug
4534 G4cout<<"G4QFragmentation::AnnihOrder: cRaDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
4535#endif
4536 if ( uPDG>0 && (uPDG==(-nPDG)/1000 || uPDG==((-nPDG)/100)%10) ) Ord=-1; // LR/RL
4537 else if( mPDG>0 && (mPDG==(-nPDG)/1000 || mPDG==((-nPDG)/100)%10) ) Ord= 1; // LL/RR
4538 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cRaDiQ, L="<<uPDG
4539 <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
4540 }
4541 else if( (uPDG<0 && (-uPDG==sPDG || -uPDG==nPDG) ) ||
4542 (mPDG<0 && (-mPDG==sPDG || -mPDG==nPDG) ) ) Ord=2; // @@ Annihilation fusion
4543#ifdef debug
4544 else G4cout<<"-Warning-G4QFragmentation::AnnihilatOrder: Wrong 32StringFusion"<<G4endl;
4545 G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
4546 <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4547#endif
4548 }
4549 else if ( (LS==2 && MPS==4) || (LS==4 && MPS==2) )
4550 {
4551 if (uPDG > 7) // Annihilate pLDiQ
4552 {
4553#ifdef debug
4554 G4cout<<"G4QFragmentation::AnnihilOrder:pLDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
4555#endif
4556 if ( sPDG<0 && (-sPDG==uPDG/1000 || -sPDG==(uPDG/100)%10) &&
4557 (nPDG==(-mPDG)/1000 || nPDG==((-mPDG)/100)%10) ) Ord= 1; // LL/RR
4558 else if( nPDG<0 && (-nPDG==uPDG/1000 || -nPDG==(uPDG/100)%10) &&
4559 (sPDG==(-mPDG)/1000 || sPDG==((-mPDG)/100)%10) ) Ord=-1; // LR/RL
4560 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 pLDiQ, L="<<uPDG
4561 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4562 }
4563 else if (mPDG >7) // Annihilate pRDiQ
4564 {
4565#ifdef debug
4566 G4cout<<"G4QFragmentation::AnnihilOrder:PRDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
4567#endif
4568 if ( sPDG<0 && (-sPDG==mPDG/1000 || -sPDG==(mPDG/100)%10) &&
4569 (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord=-1; // LR/RL
4570 else if( nPDG<0 && (-nPDG==mPDG/1000 || -nPDG==(mPDG/100)%10) &&
4571 (sPDG==(-uPDG)/1000 || sPDG==((-uPDG)/100)%10) ) Ord= 1; // LL/RR
4572 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 pLDiQ, L="<<uPDG
4573 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4574 }
4575 else if (sPDG > 7) // Annihilate cLDiQ
4576 {
4577#ifdef debug
4578 G4cout<<"G4QFragmentation::AnnihilOrder:cLDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4579#endif
4580 if ( uPDG<0 && (-uPDG==sPDG/1000 || -uPDG==(sPDG/100)%10) &&
4581 (mPDG==(-nPDG)/1000 || mPDG==((-nPDG)/100)%10) ) Ord= 1; // LL/RR
4582 else if( mPDG<0 && (-mPDG==sPDG/1000 || -mPDG==(sPDG/100)%10) &&
4583 (uPDG==(-nPDG)/1000 || uPDG==((-nPDG)/100)%10) ) Ord=-1; // LR/RL
4584 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 cLDiQ, L="<<uPDG
4585 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4586 }
4587 else if (nPDG > 7) // Annihilate cRDiQ
4588 {
4589#ifdef debug
4590 G4cout<<"G4QFragmentation::AnnihilOrder:cRDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4591#endif
4592 if ( uPDG<0 && (-uPDG==nPDG/1000 || -uPDG==(nPDG/100)%10) &&
4593 (mPDG==(-sPDG)/1000 || mPDG==((-sPDG)/100)%10) ) Ord=-1; // LR/RL
4594 else if( mPDG<0 && (-mPDG==nPDG/1000 || -mPDG==(nPDG/100)%10) &&
4595 (uPDG==(-sPDG)/1000 || uPDG==((-sPDG)/100)%10) ) Ord= 1; // LL/RR
4596 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 cRDiQ, L="<<uPDG
4597 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4598 }
4599#ifdef debug
4600 else G4cout<<"-Warning-G4QFragmentation::AnnihilOrder: Wrong 24 StringFusion"<<G4endl;
4601 G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
4602 <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4603#endif
4604 }
4605 else if ( LS==3 && MPS==3 )
4606 {
4607 if (uPDG > 7) // Annihilate pLDiQ
4608 {
4609#ifdef debug
4610 G4cout<<"G4QFragmentation::AnnihilOrder: pLDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
4611#endif
4612 if ( sPDG<-7 && (-nPDG==uPDG/1000 || -nPDG==(uPDG/100)%10) &&
4613 (mPDG==(-sPDG)/1000 || mPDG==((-sPDG)/100)%10) ) Ord=-1; // LR/RL
4614 else if( nPDG<-7 && (-sPDG==uPDG/1000 || -sPDG==(uPDG/100)%10) &&
4615 (mPDG==(-nPDG)/1000 || mPDG==((-nPDG)/100)%10) ) Ord= 1; // LL/RR
4616 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 pLDiQ, L="<<uPDG
4617 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4618 }
4619 else if(mPDG > 7) // Annihilate pRDiQ
4620 {
4621#ifdef debug
4622 G4cout<<"G4QFragmentation::AnnihilOrder: pRDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
4623#endif
4624 if ( sPDG<-7 && (-nPDG==mPDG/1000 || -nPDG==(mPDG/100)%10) &&
4625 (uPDG==(-sPDG)/1000 || uPDG==((-sPDG)/100)%10) ) Ord= 1; // LL/RR
4626 else if( nPDG<-7 && (-sPDG==mPDG/1000 || -sPDG==(mPDG/100)%10) &&
4627 (uPDG==(-nPDG)/1000 || uPDG==((-nPDG)/100)%10) ) Ord=-1; // LR/RL
4628 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 pRDiQ, L="<<uPDG
4629 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4630 }
4631 else if(sPDG > 7) // Annihilate cLDiQ
4632 {
4633#ifdef debug
4634 G4cout<<"G4QFragmentation::AnnihilOrder: cLDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4635#endif
4636 if ( uPDG<-7 && (-mPDG==sPDG/1000 || -mPDG==(sPDG/100)%10) &&
4637 (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord=-1; // LR/RL
4638 else if( mPDG<-7 && (-uPDG==sPDG/1000 || -uPDG==(sPDG/100)%10) &&
4639 (nPDG==(-mPDG)/1000 || nPDG==((-mPDG)/100)%10) ) Ord= 1; // LL/RR
4640 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 cLDiQ, L="<<uPDG
4641 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4642 }
4643 else if(nPDG > 7) // Annihilate cRDiQ
4644 {
4645#ifdef debug
4646 G4cout<<"G4QFragmentation::AnnihilOrder: cRDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4647#endif
4648 if ( uPDG<-7 && (-mPDG==nPDG/1000 || -mPDG==(nPDG/100)%10) &&
4649 (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord= 1; // LL/RR
4650 else if( mPDG<-7 && (-uPDG==nPDG/1000 || -sPDG==(nPDG/100)%10) &&
4651 (sPDG==(-mPDG)/1000 || sPDG==((-mPDG)/100)%10) ) Ord=-1; // LR/RL
4652 else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 cRDiQ, L="<<uPDG
4653 <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
4654 }
4655#ifdef debug
4656 else G4cout<<"-Warning-G4QFragmentation::AnnihilOrder: Wrong 33 StringFusion"<<G4endl;
4657 G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
4658 <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
4659#endif
4660 }
4661 return Ord;
4662}

Referenced by Breeder().

◆ Breeder()

void G4QFragmentation::Breeder ( )
protected

! Try to fragment the new String !!

Try to fragment the new String !

Definition at line 2449 of file G4QFragmentation.cc.

2450{ // This is the member function, which returns the resulting vector of Hadrons & Quasmons
2451 static const G4double eps = 0.001; // Tolerance in MeV
2452 //static const G4QContent vacQC(0,0,0,0,0,0);
2453 static const G4LorentzVector vac4M(0.,0.,0.,0.);
2454 //
2455 // ------------ At this point the strings are fragmenting to hadrons in LS -------------
2456 //
2457#ifdef edebug
2458 G4LorentzVector totLS4M=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
2459 G4int totChg=theNucleus.GetZ();
2460 G4int totBaN=theNucleus.GetA();
2461 G4int nStri=strings.size();
2462 G4cout<<"-EMCLS-G4QFr::Breed: CHECKRecovery #ofS="<<nStri<<",N4M(E=M)="<<totLS4M<<G4endl;
2463 for(G4int i=0; i<nStri; i++)
2464 {
2465 G4LorentzVector strI4M=strings[i]->Get4Momentum();
2466 totLS4M+=strI4M;
2467 G4int sChg=strings[i]->GetCharge();
2468 totChg+=sChg;
2469 G4int sBaN=strings[i]->GetBaryonNumber();
2470 totBaN+=sBaN;
2471 G4cout<<"-EMCLS-G4QFragm::Breeder: St#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
2472 <<", C="<<sChg<<", B="<<sBaN<<G4endl;
2473 }
2474#endif
2475 G4int nOfStr=strings.size();
2476#ifdef debug
2477 G4cout<<"G4QFragmentation::Breeder: BeforeFragmentation, #OfStr="<<nOfStr<<G4endl;
2478#endif
2479 G4LorentzVector ft4M(0.,0.,0.,0.);
2480 G4QContent ftQC(0,0,0,0,0,0);
2481 G4bool ftBad=false;
2482 for(G4int i=0; i < nOfStr; ++i)
2483 {
2484 G4QString* crStr=strings[i];
2485 G4LorentzVector pS4M=crStr->Get4Momentum(); // String 4-momentum
2486 ft4M+=pS4M;
2487 G4QContent pSQC=crStr->GetQC(); // String Quark Content
2488 ftQC+=pSQC;
2489 if(pS4M.m2() < 0.) ftBad=true;
2490#ifdef debug
2491 G4cout<<">G4QFrag::Br:1stTest,S#"<<i<<",P="<<crStr<<",4M="<<pS4M<<",QC="<<pSQC<<G4endl;
2492#endif
2493 }
2494 if(ftBad)
2495 {
2496 G4Quasmon* stringQuasmon = new G4Quasmon(ftQC, ft4M);
2497#ifdef debug
2498 G4cout<<"->G4QFragmentation::Breeder:*TotQ*,QC="<<ftQC<<",4M="<<ft4M<<ft4M.m()<<G4endl;
2499#endif
2500 theQuasmons.push_back(stringQuasmon);
2501 G4LorentzVector r4M=theNucleus.Get4Momentum(); // Nucleus 4-momentum in LS
2502 G4int rPDG=theNucleus.GetPDG();
2503 G4QHadron* resNuc = new G4QHadron(rPDG,r4M);
2504 theResult->push_back(resNuc); // Fill the residual nucleus
2505 return;
2506 }
2507 for (G4int astring=0; astring < nOfStr; astring++)
2508 {
2509#ifdef edebug
2510 G4LorentzVector sum=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
2511 G4int rChg=totChg-theNucleus.GetZ();
2512 G4int rBaN=totBaN-theNucleus.GetA();
2513 G4int nOfHadr=theResult->size();
2514 G4cout<<"-EMCLS-G4QFragmentation::Breeder:#ofSt="<<nOfStr<<",#ofHad="<<nOfHadr<<G4endl;
2515 for(G4int i=astring; i<nOfStr; i++)
2516 {
2517 G4LorentzVector strI4M=strings[i]->Get4Momentum();
2518 sum+=strI4M;
2519 G4int sChg=strings[i]->GetCharge();
2520 rChg-=sChg;
2521 G4int sBaN=strings[i]->GetBaryonNumber();
2522 rBaN-=sBaN;
2523 G4cout<<"-EMCLS-G4QF::Breed:S#"<<i<<",4M="<<strI4M<<",C="<<sChg<<",B="<<sBaN<<G4endl;
2524 }
2525 for(G4int i=0; i<nOfHadr; i++)
2526 {
2527 G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
2528 sum+=hI4M;
2529 G4int hChg=(*theResult)[i]->GetCharge();
2530 rChg-=hChg;
2531 G4int hBaN=(*theResult)[i]->GetBaryonNumber();
2532 rBaN-=hBaN;
2533 G4cout<<"-EMCLS-G4QFr::Breed: H#"<<i<<",4M="<<hI4M<<",C="<<hChg<<",B="<<hBaN<<G4endl;
2534 }
2535 G4cout<<"....-EMCLS-G4QFrag::Br:r4M="<<sum-totLS4M<<",rC="<<rChg<<",rB="<<rBaN<<G4endl;
2536#endif
2537 G4QString* curString=strings[astring];
2538 if(!curString->GetDirection()) continue; // Historic for the dead strings: DoesNotWork
2539 G4int curStrChg = curString->GetCharge();
2540 G4int curStrBaN = curString->GetBaryonNumber();
2541 G4LorentzVector curString4M = curString->Get4Momentum();
2542#ifdef debug
2543 G4cout<<"=--=>G4QFragmentation::Breeder: String#"<<astring<<",s4M/m="<<curString4M
2544 <<curString4M.m()<<", LPart="<<curString->GetLeftParton()->GetPDGCode()
2545 <<", RPart="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
2546#endif
2547 G4QHadronVector* theHadrons = 0; // Prototype of theStringFragmentationOUTPUT
2548 theHadrons=curString->FragmentString(true);// !! Fragmenting the String !!
2549 if (!theHadrons) // The string can not be fragmented
2550 {
2551 // First try to correct the diQ-antiDiQ strings, converting them to Q-antiQ
2552 G4QParton* cLeft=curString->GetLeftParton();
2553 G4QParton* cRight=curString->GetRightParton();
2554 G4int sPDG=cLeft->GetPDGCode();
2555 G4int nPDG=cRight->GetPDGCode();
2556 G4int LT=cLeft->GetType();
2557 G4int RT=cRight->GetType();
2558 G4int LS=LT+RT;
2559 if(LT==2 && RT==2)
2560 {
2561#ifdef debug
2562 G4cout<<"G4QFragmentation::Breeder:TryReduceString, L="<<sPDG<<",R="<<nPDG<<G4endl;
2563#endif
2564 if( cLeft->ReduceDiQADiQ(cLeft, cRight) ) // DiQ-aDiQ pair was successfully reduced
2565 {
2566 LT=1;
2567 RT=1;
2568 LS=2;
2569 sPDG=cLeft->GetPDGCode();
2570 nPDG=cRight->GetPDGCode();
2571#ifdef debug
2572 G4cout<<"G4QFragmentation::Breeder:AfterReduction,L="<<sPDG<<",R="<<nPDG<<G4endl;
2573#endif
2574 theHadrons=curString->FragmentString(true);//!! Try to fragment the new String !!
2575 cLeft=curString->GetLeftParton();
2576 cRight=curString->GetRightParton();
2577#ifdef debug
2578 G4cout<<"G4QFrag::Breed:L="<<cLeft->Get4Momentum()<<",R="<<cRight->Get4Momentum()
2579 <<G4endl;
2580#endif
2581 }
2582#ifdef debug
2583 else G4cout<<"^G4QFragmentation::Breeder: DQ-aDQ reduction to Q-aQ Failed"<<G4endl;
2584#endif
2585 } // End of the SelfReduction
2586#ifdef debug
2587 G4cout<<"G4QFrag::Breed:AfterRedAttempt, theH="<<theHadrons<<", L4M="
2588 <<cLeft->Get4Momentum()<<", R4M="<<cRight->Get4Momentum()<<G4endl;
2589#endif
2590 unsigned next=astring+1; // The next string position
2591 if (!theHadrons) // The string can not be fragmented
2592 {
2593 G4int fusionDONE=0; // StringFusion didn't happen (1=Fuse L+L/R+R, -1=Fuse L+R/R+L)
2594 if(next < strings.size()) // TheString isn't theLastString can fuse
2595 {
2596 G4int fustr=0; // The found partner index (never can be 0)
2597 G4int swap=0; // working interger for swapping parton PDG
2598 G4double Vmin=DBL_MAX; // Prototype of the found Velocity Distance
2599 G4int dPDG=nPDG;
2600 G4int qPDG=sPDG;
2601 if(dPDG<-99 || (dPDG>0&&dPDG<7) || qPDG>99 || (qPDG<0 && qPDG>-7))
2602 {
2603 swap=qPDG;
2604 qPDG=dPDG;
2605 dPDG=swap;
2606 }
2607 if(dPDG>99) dPDG/=100;
2608 if(qPDG<-99) qPDG=-(-qPDG)/100;
2609#ifdef debug
2610 G4cout<<"G4QFrag::Breed:TryFuseStringS, q="<<qPDG<<", a="<<dPDG<<", n="<<next
2611 <<G4endl;
2612#endif
2613 G4ThreeVector curV=curString4M.vect()/curString4M.e();
2614 G4int reduce=0; // a#of reduced Q-aQ pairs
2615 G4int restr=0; // To use beyon the LOOP for printing
2616 G4int MPS=0; // PLS for the selected string
2617 for (restr=next; restr < nOfStr; restr++)
2618 {
2619 reduce=0;
2620 G4QString* reString=strings[restr];
2621 G4QParton* Left=reString->GetLeftParton();
2622 G4QParton* Right=reString->GetRightParton();
2623 G4int uPDG=Left->GetPDGCode();
2624 G4int mPDG=Right->GetPDGCode();
2625 G4int PLT =Left->GetType();
2626 G4int PRT =Right->GetType();
2627 G4int aPDG=mPDG;
2628 G4int rPDG=uPDG;
2629 if(aPDG<-99 || (aPDG>0 && aPDG<7) || rPDG>99 || (rPDG<0 && rPDG>-7))
2630 {
2631 swap=rPDG;
2632 rPDG=aPDG;
2633 aPDG=swap;
2634 }
2635 if(aPDG > 99) aPDG/=100;
2636 if(rPDG <-99) rPDG=-(-rPDG)/100;
2637 // Try to reduce two DQ-aDQ strings
2638#ifdef debug
2639 G4cout<<"G4QFragm::Breed: TryReduce #"<<restr<<",q="<<rPDG<<",a="<<aPDG<<G4endl;
2640#endif
2641 if(LT==2 && RT==2 && PLT==2 && PRT==2) // Have a chance for the reduction
2642 {
2643 G4int cQ1=(-qPDG)/10;
2644 G4int cQ2=(-qPDG)%10;
2645 G4int cA1=dPDG/10;
2646 G4int cA2=dPDG%10;
2647 G4int pQ1=(-rPDG)/10;
2648 G4int pQ2=(-rPDG)%10;
2649 G4int pA1=aPDG/10;
2650 G4int pA2=aPDG%10;
2651#ifdef debug
2652 G4cout<<"G4QFragment::Breeder: cQ="<<cQ1<<","<<cQ2<<", cA="<<cA1<<","<<cA2
2653 <<", pQ="<<pQ1<<","<<pQ2<<", pA="<<pA1<<","<<pA2<<G4endl;
2654#endif
2655 G4bool iQA = (cA1==pQ1 || cA1==pQ2 || cA2==pQ1 || cA2==pQ2);
2656 G4bool iAQ = (cQ1==pA1 || cQ1==pA2 || cQ2==pA1 || cQ2==pA2);
2657 if(iQA) reduce++;
2658 if(iAQ) reduce++;
2659 if (reduce==2) // Two quark pairs can be reduced
2660 {
2661 if(sPDG>0 && uPDG<0) // LL/RR Reduction
2662 {
2663 std::pair<G4int,G4int> resLL=ReducePair(sPDG/100, (-uPDG)/100);
2664 G4int newCL=resLL.first;
2665 G4int newPL=resLL.second;
2666 if(!newCL || !newPL)
2667 {
2668 G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PL="<<newPL<<G4endl;
2669 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LL-");
2670 }
2671 std::pair<G4int,G4int> resRR=ReducePair((-nPDG)/100, mPDG/100);
2672 G4int newCR=resRR.first;
2673 G4int newPR=resRR.second;
2674 if(!newCR || !newPR)
2675 {
2676 G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PR="<<newPR<<G4endl;
2677 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RR-");
2678 }
2679 cLeft->SetPDGCode(newCL); // Reset the left quark of curString
2680 cRight->SetPDGCode(-newCR); // Reset the right quark of curString
2681 Left->SetPDGCode(-newPL); // Reset the left quark of reString
2682 Right->SetPDGCode(newPR); // Reset the right quark of reString
2683 break; // Break out of the reString internal LOOP
2684 }
2685 else if(sPDG<0 && uPDG>0) // LL/RR Reduction
2686 {
2687 std::pair<G4int,G4int> resLL=ReducePair((-sPDG)/100, uPDG/100);
2688 G4int newCL=resLL.first;
2689 G4int newPL=resLL.second;
2690 if(!newCL || !newPL)
2691 {
2692 G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PL="<<newPL<<G4endl;
2693 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LL+");
2694 }
2695 std::pair<G4int,G4int> resRR=ReducePair(nPDG/100, (-mPDG)/100);
2696 G4int newCR=resRR.first;
2697 G4int newPR=resRR.second;
2698 if(!newCR || !newPR)
2699 {
2700 G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PR="<<newPR<<G4endl;
2701 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RR+");
2702 }
2703 cLeft->SetPDGCode(-newCL); // Reset the left quark of curString
2704 cRight->SetPDGCode(newCR); // Reset the right quark of curString
2705 Left->SetPDGCode(newPL); // Reset the left quark of reString
2706 Right->SetPDGCode(-newPR); // Reset the right quark of reString
2707 break; // Break out of the reString internal LOOP
2708 }
2709 else if(sPDG>0 && mPDG<0) // LR Reduction
2710 {
2711 std::pair<G4int,G4int> resLL=ReducePair(sPDG/100, (-mPDG)/100);
2712 G4int newCL=resLL.first;
2713 G4int newPR=resLL.second;
2714 if(!newCL || !newPR)
2715 {
2716 G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PR="<<newPR<<G4endl;
2717 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LR");
2718 }
2719 std::pair<G4int,G4int> resRR=ReducePair((-nPDG)/100, uPDG/100);
2720 G4int newCR=resRR.first;
2721 G4int newPL=resRR.second;
2722 if(!newCR || !newPR)
2723 {
2724 G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PL="<<newPL<<G4endl;
2725 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LR");
2726 }
2727 cLeft->SetPDGCode(newCL); // Reset the left quark of curString
2728 cRight->SetPDGCode(-newCR); // Reset the right quark of curString
2729 Left->SetPDGCode(newPL); // Reset the left quark of reString
2730 Right->SetPDGCode(-newPR); // Reset the right quark of reString
2731 break; // Break out of the reString internal LOOP
2732 }
2733 else // RL Reduction
2734 {
2735 std::pair<G4int,G4int> resLL=ReducePair((-sPDG)/100, mPDG/100);
2736 G4int newCL=resLL.first;
2737 G4int newPR=resLL.second;
2738 if(!newCL || !newPR)
2739 {
2740 G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PR="<<newPR<<G4endl;
2741 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RL");
2742 }
2743 std::pair<G4int,G4int> resRR=ReducePair(nPDG/100, (-uPDG)/100);
2744 G4int newCR=resRR.first;
2745 G4int newPL=resRR.second;
2746 if(!newCR || !newPR)
2747 {
2748 G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PL="<<newPL<<G4endl;
2749 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RL");
2750 }
2751 cLeft->SetPDGCode(-newCL); // Reset the left quark of curString
2752 cRight->SetPDGCode(newCR); // Reset the right quark of curString
2753 Left->SetPDGCode(-newPL); // Reset the left quark of reString
2754 Right->SetPDGCode(newPR); // Reset the right quark of reString
2755 break; // Break out of the reString internal LOOP
2756 }
2757 } // End of IF(possible reduction)
2758 }
2759 // Check StringsCanBeFused: all QaQ+QaQ(22), single QaQ+QDiQ/aQaDtQ(23/32),
2760 // double QaQ+DiQaDiQ(24/42), QDiQ+aDiQaQ(34/43)
2761#ifdef debug
2762 G4cout<<"G4QFragm::Breed:TryFuse/w #"<<restr<<",q="<<rPDG<<",a="<<aPDG<<G4endl;
2763#endif
2764 G4int PLS=PLT+PRT;
2765 if( (LS==2 && PLS==2) || // QaQ+QaQ always to DiQaDiQ
2766 ( ( (LS==2 && PLS==3) || (LS==3 && PLS==2) ) &&// QaQ w QDiQ/aQaDiQ(single)
2767 ( (aPDG> 7 && (-dPDG==aPDG/10 || -dPDG==aPDG%10) ) || // cAQ w DQ
2768 (dPDG> 7 && (-aPDG==dPDG/10 || -aPDG==dPDG%10) ) || // AQ w cDQ
2769 (rPDG<-7 && (qPDG==(-rPDG)/10 || qPDG==(-rPDG)%10) ) || // cQ w ADQ
2770 (qPDG<-7 && (rPDG==(-qPDG)/10 || rPDG==(-qPDG)%10) ) // Q w cADQ
2771 //|| (aPDG< 0 && -aPDG==qPDG) || (dPDG< 0 && -dPDG==rPDG) // aQ w Q
2772 )
2773 ) || // -----------------------
2774 ( ( LS==2 && PLS==4 &&// QaQ w DiQaDiQ (double)
2775 (aPDG> 7 && (-dPDG == aPDG/10 || -dPDG == aPDG%10) ) &&
2776 (rPDG<-7 && (qPDG==(-rPDG)/10 || qPDG==(-rPDG)%10) )
2777 ) ||
2778 ( LS==4 && PLS==2 &&// DiQaDiQ w QaQ (double)
2779 (dPDG> 7 && (-aPDG == dPDG/10 || -aPDG == dPDG%10) ) &&
2780 (qPDG<-7 && (rPDG==(-qPDG)/10 || rPDG==(-qPDG)%10) )
2781 )
2782 ) || // -----------------------
2783 ( LS==3 && PLS==3 &&// QDiQ w aDiQaQ (double)
2784 ( (aPDG> 7 && (-dPDG == aPDG/10 || -dPDG == aPDG%10) &&
2785 qPDG<-7 && (rPDG==(-qPDG)/10 || rPDG==(-qPDG)%10)
2786 ) ||
2787 (dPDG> 7 && (-aPDG == dPDG/10 || -aPDG == dPDG%10) &&
2788 rPDG<-7 && (dPDG==(-rPDG)/10 || dPDG==(-rPDG)%10)
2789 )
2790 )
2791 )
2792 )
2793 {
2794 G4LorentzVector reString4M = reString->Get4Momentum();
2795 G4ThreeVector reV = reString4M.vect()/reString4M.e();
2796 G4double dV=(curV-reV).mag2(); // Squared difference between relVelocities
2797#ifdef debug
2798 G4cout<<"G4QFragmentation::Breeder: StringCand#"<<restr<<", q="<<rPDG<<", a="
2799 <<aPDG<<", L="<<uPDG<<", R="<<mPDG<<",dV="<<dV<<G4endl;
2800#endif
2801 if(dV < Vmin)
2802 {
2803 Vmin=dV;
2804 fustr=restr;
2805 MPS=PLS;
2806 }
2807 }
2808 }
2809 if(reduce==2) // String mutual reduction happened
2810 {
2811#ifdef debug
2812 G4cout<<"-G4QFragmentation::Breeder:Reduced #"<<astring<<" & #"<<restr<<G4endl;
2813#endif
2814 astring--; // String was QCreduced using another String
2815 continue; // Repeat fragmentation of the same string
2816 }
2817 if(fustr) // The partner was found -> fuse strings
2818 {
2819#ifdef debug
2820 G4cout<<"G4QFragm::Breeder: StPartner#"<<fustr<<",LT="<<LT<<",RT="<<RT<<G4endl;
2821#endif
2822 G4QString* fuString=strings[fustr];
2823 G4QParton* Left=fuString->GetLeftParton();
2824 G4QParton* Right=fuString->GetRightParton();
2825 G4int uPDG=Left->GetPDGCode();
2826 G4int mPDG=Right->GetPDGCode();
2827 G4int rPDG=uPDG;
2828 G4int aPDG=mPDG;
2829 if(aPDG<-99 || (aPDG>0 && aPDG<7) || rPDG>99 || (rPDG<0 && rPDG>-7))
2830 {
2831 swap=rPDG;
2832 rPDG=aPDG;
2833 aPDG=swap;
2834 }
2835 if(aPDG > 99) aPDG/=100;
2836 if(rPDG <-99) rPDG=-(-rPDG)/100;
2837 // Check that the strings can fuse (no anti-diquarks assumed)
2838 G4LorentzVector resL4M(0.,0.,0.,0.);
2839 G4LorentzVector resR4M(0.,0.,0.,0.);
2840 G4LorentzVector L4M=cLeft->Get4Momentum();
2841 G4LorentzVector R4M=cRight->Get4Momentum();
2842#ifdef debug
2843 G4cout<<"G4QFragmentation::Breeder:BeforeFuDir,sL="<<sPDG<<",nR="<<nPDG<<",uL="
2844 <<uPDG<<",mR="<<mPDG<<",L4M="<<L4M<<",R4M="<<R4M<<G4endl;
2845#endif
2846 G4LorentzVector PL4M=Left->Get4Momentum();
2847 G4LorentzVector PR4M=Right->Get4Momentum();
2848 fusionDONE=AnnihilationOrder(LS, MPS, uPDG, mPDG, sPDG, nPDG);
2849 if (fusionDONE>0)
2850 {
2851 if(fusionDONE>1) // Anihilation algorithm
2852 {
2853 if ( (uPDG<0 || nPDG<0) && -uPDG==nPDG ) Left->SetPDGCode(sPDG);
2854 else if( (mPDG<0 || sPDG<0) && -mPDG==sPDG ) Right->SetPDGCode(nPDG);
2855 else if( (uPDG<0 || sPDG<0) && -uPDG==sPDG ) Left->SetPDGCode(nPDG);
2856 else if( (mPDG<0 || nPDG<0) && -mPDG==nPDG ) Right->SetPDGCode(sPDG);
2857 }
2858 {
2859 Left->SetPDGCode(SumPartonPDG(uPDG, sPDG));
2860 Right->SetPDGCode(SumPartonPDG(mPDG, nPDG));
2861 }
2862 Left->Set4Momentum(L4M+PL4M);
2863 Right->Set4Momentum(R4M+PR4M);
2864#ifdef debug
2865 G4cout<<"G4QFragmentation::Breeder:LL/RR s4M="<<fuString->Get4Momentum()
2866 <<",S="<<L4M+PL4M+R4M+PR4M<<", L="<<Left->Get4Momentum()<<", R="
2867 <<Right->Get4Momentum()<<G4endl;
2868#endif
2869 }
2870 else if(fusionDONE<0)
2871 {
2872 Left->SetPDGCode(SumPartonPDG(uPDG, nPDG));
2873 Left->Set4Momentum(L4M+PR4M);
2874 Right->SetPDGCode(SumPartonPDG(mPDG, sPDG));
2875 Right->Set4Momentum(R4M+PL4M);
2876#ifdef debug
2877 G4cout<<"G4QFragmentation::Breeder:LR/RL s4M="<<fuString->Get4Momentum()
2878 <<",S="<<L4M+PL4M+R4M+PR4M<<", L="<<Left->Get4Momentum()<<", R="
2879 <<Right->Get4Momentum()<<G4endl;
2880#endif
2881 }
2882#ifdef debug
2883 else G4cout<<"-Warning-G4QFragmentation::Breeder: WrongStringFusion"<<G4endl;
2884#endif
2885#ifdef edebug
2886 G4cout<<"#EMC#G4QFragmentation::Breeder:StringFused,F="<<fusionDONE<<",L="<<L4M
2887 <<",R="<<R4M<<",pL="<<PL4M<<",pR="<<PR4M<<",nL="<<Left->Get4Momentum()
2888 <<",nR="<<Right->Get4Momentum()<<",S="<<fuString->Get4Momentum()<<G4endl;
2889#endif
2890 if(fusionDONE)
2891 {
2892#ifdef debug
2893 G4cout<<"###G4QFragmentation::Breeder: Str#"<<astring<<" fused/w Str#"<<fustr
2894 <<"->"<<fuString->Get4Momentum()<<fuString->Get4Momentum().m()<<G4endl;
2895#endif
2896 continue; // @@ killing of the curString is excluded
2897 }
2898 }
2899#ifdef debug
2900 else
2901 {
2902
2903 G4cout<<"**G4QFragmentation::Breeder:*NoPart*M="<<curString->Get4Momentum().m()
2904 <<", F="<<fusionDONE<<", LPDG="<<curString->GetLeftParton()->GetPDGCode()
2905 <<", RPDG="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
2906 }
2907#endif
2908 }
2909 if(!fusionDONE) // Fusion of theString failed, try hadrons
2910 {
2911 G4int nHadr=theResult->size(); // #of collected resulting hadrons upToNow
2912#ifdef debug
2913 G4cout<<"+++4QFragmentation::Breeder:*TryHadr* M="<<curString->Get4Momentum().m()
2914 <<", nH="<<nHadr<<", LPDG="<<curString->GetLeftParton()->GetPDGCode()
2915 <<", RPDG="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
2916#endif
2917 // The only solution now is to try fusion with the secondary hadron
2918 while( (nHadr=theResult->size()) && !theHadrons)
2919 {
2920#ifdef edebug
2921 for(G4int i=0; i<nHadr; i++)
2922 {
2923 G4LorentzVector h4M=(*theResult)[i]->Get4Momentum();
2924 G4int hPDG=(*theResult)[i]->GetPDGCode();
2925 G4QContent hQC=(*theResult)[i]->GetQC();
2926 G4cout<<"-EMC-G4QFrag::Breed:H#"<<i<<",4M="<<h4M<<hQC<<",PDG="<<hPDG<<G4endl;
2927 }
2928#endif
2929 G4int fusDONE=0; // String+Hadron fusion didn't happen
2930 G4int fuhad=-1; // The found hadron index
2931 G4int newPDG=0; // PDG ofTheParton afterMerging with Hadr
2932 G4int secPDG=0; // Second PDG oParton afterMerging w/Hadr
2933 G4double maM2=-DBL_MAX; // Prototype of the max ResultingStringM2
2934 G4LorentzVector selH4M(0.,0.,0.,0.); // 4-mom of the selected hadron
2935 G4QHadron* selHP=0; // Pointer to the used hadron for erasing
2936 G4QString* cString=strings[astring]; // Must be the last string by definition
2937 G4LorentzVector cString4M = cString->Get4Momentum();
2938 cLeft=cString->GetLeftParton();
2939 cRight=cString->GetRightParton();
2940 G4int sumT=cLeft->GetType()+cRight->GetType();
2941 sPDG=cLeft->GetPDGCode();
2942 nPDG=cRight->GetPDGCode();
2943 G4int cMax=0; // Both or only one cuark can merge
2944 for (G4int reh=0; reh < nHadr; reh++)
2945 {
2946 G4QHadron* curHadr=(*theResult)[reh];
2947 G4int curPDG=curHadr->GetPDGCode(); // PDGCode of the hadron
2948 G4QContent curQC=curHadr->GetQC(); // Quark content of the hadron
2949 if(curPDG==331 && sPDG!=3 && nPDG!=3 && sPDG!=-3 && nPDG!=-3) // eta' red
2950 {
2951 if(sPDG==2 || sPDG==-2 || nPDG==2 || nPDG==-2)
2952 curQC=G4QContent(0,1,0,0,1,0);
2953 else curQC=G4QContent(1,0,0,1,0,0);
2954 }
2955 else if(curPDG==221 && sPDG!=2 && nPDG!=2 && sPDG!=-2 && nPDG!=-2) // eta
2956 curQC=G4QContent(1,0,0,1,0,0);
2957 else if(curPDG==111 && sPDG!=1 && nPDG!=1 && sPDG!=-1 && nPDG!=-1) // eta
2958 curQC=G4QContent(0,1,0,0,1,0);
2959 G4int partPDG1=curQC.AddParton(sPDG);
2960 G4int partPDG2=curQC.AddParton(nPDG);
2961#ifdef debug
2962 G4cout<<"G4QFragmentation::Breeder: Hadron # "<<reh<<", QC="<<curQC
2963 <<", P1="<<partPDG1<<", P2="<<partPDG2<<G4endl;
2964#endif
2965 if(partPDG1 || partPDG2) // Hadron can merge at least w/one parton
2966 {
2967 G4int cCur=1;
2968 if(sumT>3 && partPDG1 && partPDG2) cCur=2;
2969 G4LorentzVector curHadr4M = curHadr->Get4Momentum();
2970 G4double M2=(cString4M+curHadr4M).m2();// SquaredMass of theResultingString
2971#ifdef debug
2972 G4cout<<"G4QFragmentation::Breeder:*IN*Hadron#"<<reh<<",M2="<<M2<<G4endl;
2973#endif
2974 if( (sumT<4 || cCur>=cMax) && M2 > maM2) // DeepAnnihilation for DiQ-aDiQ
2975 {
2976 maM2=M2;
2977 fuhad=reh;
2978 if(partPDG1)
2979 {
2980 fusDONE= 1;
2981 newPDG=partPDG1;
2982 if(partPDG2)
2983 {
2984 secPDG=partPDG2;
2985 cMax=cCur;
2986 }
2987 }
2988 else
2989 {
2990 fusDONE=-1;
2991 newPDG=partPDG2;
2992 }
2993#ifdef debug
2994 G4cout<<"G4QFrag::Br:*Selected*,P1="<<partPDG1<<",P2="<<partPDG2<<G4endl;
2995#endif
2996 selH4M=curHadr4M;
2997 selHP=curHadr;
2998 } // End of IF(update selection)
2999 } // End of IF(HadronCanMergeWithTheString)
3000 } // End of the LOOP over Hadrons
3001#ifdef debug
3002 G4cout<<"G4QFragmentation::Breeder: fuh="<<fuhad<<",fus="<<fusDONE<<G4endl;
3003#endif
3004 if(fuhad>-1) // The partner was found -> fuse H&S
3005 {
3006 if (fusDONE>0) // Fuse hadron with the left parton
3007 {
3008 cLeft->SetPDGCode(newPDG);
3009 G4LorentzVector newLeft=cLeft->Get4Momentum()+selH4M;
3010 cLeft->Set4Momentum(newLeft);
3011 if(secPDG && cMax>1)
3012 {
3013#ifdef debug
3014 G4cout<<"G4QFragm::Br:TryReduce,nPDG="<<newPDG<<",sPDG="<<secPDG<<G4endl;
3015#endif
3016 cLeft->ReduceDiQADiQ(cLeft, cRight);
3017 }
3018#ifdef debug
3019 G4cout<<"G4QFragmentation::Breeder: Left, s4M="<<curString->Get4Momentum()
3020 <<", L4M="<<newLeft<<", R4M="<<cRight->Get4Momentum()<<", h4M="
3021 <<selH4M<<", newL="<<newPDG<<", oldR="<<cRight->GetPDGCode()<<G4endl;
3022#endif
3023 }
3024 else if(fusDONE<0) // Fuse hadron with the right parton
3025 {
3026 cRight->SetPDGCode(newPDG);
3027 G4LorentzVector newRight=cRight->Get4Momentum()+selH4M;
3028 cRight->Set4Momentum(newRight);
3029#ifdef debug
3030 G4cout<<"G4QFragmentation::Breeder: Right, s4M="<<curString->Get4Momentum()
3031 <<", L4M="<<cLeft->Get4Momentum()<<", R4M="<<newRight<<", h4M="
3032 <<selH4M<<", newR="<<newPDG<<", oldL="<<cLeft->GetPDGCode()<<G4endl;
3033#endif
3034 }
3035#ifdef debug
3036 else G4cout<<"-G4QFragmentation::Breeder: Wrong String+HadronFusion"<<G4endl;
3037#endif
3038#ifdef debug
3039 if(fusDONE) G4cout<<"####G4QFragmentation::Breeder: String #"<<astring
3040 <<" is fused with Hadron #"<<fuhad
3041 <<", new4Mom="<<curString->Get4Momentum()
3042 <<", M2="<<curString->Get4Momentum().m2()
3043 <<", QC="<<curString->GetQC()<<G4endl;
3044#endif
3045 }
3046 else
3047 {
3048#ifdef debug
3049 G4cout<<"**G4QFragmentation::Breeder:*NoH*,M="<<curString->Get4Momentum().m()
3050 <<", LPDG="<<curString->GetLeftParton()->GetPDGCode()
3051 <<", RPDG="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
3052 // @@ Temporary exception for the future solution
3053 //G4Exception("G4QFragmentation::Breeder:","72",FatalException,"SHNotFused");
3054#endif
3055 break; // Breake the While LOOP
3056 } // End of the namespace where both Fusion and reduction have failed
3057 // The fused hadron must be excluded from theResult
3058#ifdef debug
3059 G4cout<<"G4QFragmentation::Breeder: before HR, nH="<<theResult->size()<<G4endl;
3060 G4int icon=0; // Loop counter
3061#endif
3062 G4QHadronVector::iterator ih;
3063#ifdef debug
3064 G4bool found=false;
3065#endif
3066 for(ih = theResult->begin(); ih != theResult->end(); ih++)
3067 {
3068#ifdef debug
3069 G4cout<<"G4QFrag::Breeder:#"<<icon<<", i="<<(*ih)<<", sH="<<selHP<<G4endl;
3070 icon++;
3071#endif
3072 if((*ih)==selHP)
3073 {
3074#ifdef debug
3075 G4cout<<"G4QFragm::Breed: *HadronFound*,PDG="<<selHP->GetPDGCode()<<G4endl;
3076#endif
3077 G4LorentzVector p4M=selHP->Get4Momentum();
3078 //
3079 curString4M+=p4M;
3080 G4int Chg=selHP->GetCharge();
3081 G4int BaN=selHP->GetBaryonNumber();
3082 curStrChg+=Chg;
3083 curStrBaN+=BaN;
3084#ifdef edebug
3085 G4cout<<"-EMC->>G4QFragmentation::Breeder: S+=H, 4M="<<curString4M<<", M="
3086 <<curString4M.m()<<", Charge="<<curStrChg<<", B="<<curStrBaN<<G4endl;
3087#endif
3088 delete selHP; // delete the Hadron
3089 theResult->erase(ih); // erase the Hadron from theResult
3090#ifdef debug
3091 found=true;
3092#endif
3093 break; // beak the LOOP over hadrons
3094 }
3095 } // End of the LOOP over hadrons
3096#ifdef debug
3097 if(!found) G4cout<<"*G4QFragmentation::Breeder:nH="<<theResult->size()<<G4endl;
3098#endif
3099 // New attempt of the string decay
3100 theHadrons=curString->FragmentString(true);//! Try to fragment the new String !
3101#ifdef debug
3102 G4cout<<"G4QFrag::Breeder: tH="<<theHadrons<<",nH="<<theResult->size()<<G4endl;
3103#endif
3104 } // End of the while LOOP over the fusion with hadrons
3105#ifdef debug
3106 G4cout<<"*G4QFragmentation::Breeder: *CanTryToDecay?* nH="<<theHadrons<<", next="
3107 <<next<<" =? nS="<<strings.size()<<", nR="<<theResult->size()<<G4endl;
3108#endif
3109 if(!theHadrons && next == strings.size() && !(theResult->size()))// TryToDecay
3110 {
3111 G4QContent miQC=curString->GetQC(); // QContent of the Lightest Hadron
3112 G4int miPDG=miQC.GetSPDGCode(); // PDG of the Lightest Hadron
3113 if(miPDG == 10) // ==> Decay Hadron-Chipolino
3114 {
3115 G4QChipolino QCh(miQC); // define theTotalResidual as aChipolino
3116 G4QPDGCode h1QPDG=QCh.GetQPDG1(); // QPDG of the first hadron
3117 G4double h1M =h1QPDG.GetMass();// Mass of the first hadron
3118 G4QPDGCode h2QPDG=QCh.GetQPDG2(); // QPDG of the second hadron
3119 G4double h2M =h2QPDG.GetMass();// Mass of the second hadron
3120 G4double ttM =curString4M.m(); // Real Mass of the Chipolino
3121 if(h1M+h2M<ttM+eps) // Two particles decay of Chipolino
3122 {
3123 G4LorentzVector h14M(0.,0.,0.,h1M);
3124 G4LorentzVector h24M(0.,0.,0.,h2M);
3125 if(std::fabs(ttM-h1M-h2M)<=eps)
3126 {
3127 G4double part1=h1M/(h1M+h2M);
3128 h14M=part1*curString4M;
3129 h24M=curString4M-h14M;
3130 }
3131 else
3132 {
3133 if(!G4QHadron(curString4M).DecayIn2(h14M,h24M))
3134 {
3135 G4cerr<<"***G4QFragmentation::Breeder: tM="<<ttM<<"->h1="<<h1QPDG<<"("
3136 <<h1M<<")+h2="<<h1QPDG<<"("<<h2M<<")="<<h1M+h2M<<G4endl;
3137 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChiDec");
3138 }
3139 }
3140 G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
3141 theResult->push_back(h1H); // (delete equivalent)
3142#ifdef debug
3143 G4LorentzVector f4M=h1H->Get4Momentum();
3144 G4int fPD=h1H->GetPDGCode();
3145 G4int fCg=h1H->GetCharge();
3146 G4int fBN=h1H->GetBaryonNumber();
3147 G4cout<<"-EMC->>G4QFragment::Breeder: String=Hadr ChiPro1 is filled, f4M="
3148 <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
3149#endif
3150 G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
3151 theResult->push_back(h2H); // (delete equivalent)
3152#ifdef debug
3153 G4LorentzVector s4M=h2H->Get4Momentum();
3154 G4int sPD=h2H->GetPDGCode();
3155 G4int sCg=h2H->GetCharge();
3156 G4int sBN=h2H->GetBaryonNumber();
3157 G4cout<<"-EMC->>G4QFragmentation::Breeder: String=Hadr ChiPro2 is filled, s4M="
3158 <<s4M<<", sPDG="<<sPD<<", sCg="<<sCg<<", sBN="<<sBN<<G4endl;
3159#endif
3160#ifdef edebug
3161 G4cout<<"-EMC-..Chi..G4QFragmentation::Breeder: DecayCHECK, Ch4M="
3162 <<curString4M<<", d4M="<<curString4M-h14M-h24M<<G4endl;
3163#endif
3164 break; // Go out of the main StringDecay LOOP
3165 }
3166 else
3167 {
3168 G4Quasmon* stringQuasmon = new G4Quasmon(miQC, curString4M);// String->Quas
3169 theQuasmons.push_back(stringQuasmon);
3170 break; // Go out of the main StringDecay LOOP
3171 }
3172 }
3173 else if(miPDG) // Decay Hadron as a Resonans
3174 {
3175 if (miPDG>0 && miPDG%10 < 3) miPDG+=2; // Convert to Resonans
3176 else if(miPDG<0 && (-miPDG)%10< 3) miPDG-=2; // Convert to antiResonans
3177 G4Quasmon Quasm;
3178 G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
3179 G4QHadronVector* tmpQHadVec=Quasm.DecayQHadron(sHad); // It deletes sHad
3180 G4int tmpN=tmpQHadVec->size();
3181#ifdef debug
3182 G4cout<<"G4QFragmentation::Breeder: Decay the Last, Res#H="<<tmpN<<G4endl;
3183#endif
3184 if(tmpN>1)
3185 {
3186 for(G4int aH=0; aH < tmpN; aH++)
3187 {
3188 theResult->push_back((*tmpQHadVec)[aH]);//TheDecayProdOfHadronDecIsFilled
3189#ifdef debug
3190 G4QHadron* prodH =(*tmpQHadVec)[aH];
3191 G4LorentzVector p4M=prodH->Get4Momentum();
3192 G4int PDG=prodH->GetPDGCode();
3193 G4int Chg=prodH->GetCharge();
3194 G4int BaN=prodH->GetBaryonNumber();
3195 G4cout<<"-EMC->>G4QFragment::Breeder:String=Hadr,H#"<<aH<<" filled, 4M="
3196 <<p4M<<", PDG="<<PDG<<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
3197#endif
3198 }
3199 }
3200 else
3201 {
3202 G4Quasmon* stringQuasmon = new G4Quasmon(miQC, curString4M);// String->Quas
3203#ifdef debug
3204 G4cout<<"G4QFragmentat::Breeder:==> to Quasm="<<miQC<<curString4M<<", Nuc="
3205 <<theNucleus<<theNucleus.Get4Momentum()<<", NString="<<strings.size()
3206 <<", nR="<<theResult->size()<<", nQ="<<theQuasmons.size()<<G4endl;
3207#endif
3208 theQuasmons.push_back(stringQuasmon);
3209 delete sHad;
3210 tmpQHadVec->clear();
3211 delete tmpQHadVec; // WhoCallsDecayQHadron is responsible for clear&delete
3212 break; // Go out of the main StringDecay LOOP
3213 }
3214 tmpQHadVec->clear();
3215 delete tmpQHadVec; // Who calls DecayQHadron is responsible for clear&delete
3216 break; // Go out of the main String Decay LOOP
3217 }
3218 } // End of the DecayOfTheLast
3219 } // End of IF(String-Hadron fusion)
3220 } // End of IF(NO_Hadrons) for String-String and String-Hadron fusion
3221 // The last hope is to CORREC the string, using other strings (ForwardInLOOP)
3222#ifdef debug
3223 G4cout<<"G4QFragmentation::Breeder: theH="<<theHadrons<<"?=0, next="<<next<<G4endl;
3224#endif
3225 if(!theHadrons && next < strings.size()) // ForwardInLOOP strings exist
3226 {
3227 // @@ string can be not convertable to one hadron (2,0.0,0,2,0) - To be improved
3228 G4QContent miQC=curString->GetQC(); // QContent of the Lightest Hadron
3229 G4int miPDG=miQC.GetSPDGCode();// PDG of the Lightest Hadron
3230#ifdef debug
3231 G4cout<<"---->>G4QFragmentation::Breeder: SQC="<<miQC<<", miSPDG="<<miPDG<<G4endl;
3232#endif
3233 G4double miM=0.; // Prototype of the Mass of the Cur LightestHadron
3234 if(miPDG!=10) miM=G4QPDGCode(miPDG).GetMass(); // Mass of theCurLightestOneHadron
3235 else
3236 {
3237 G4QChipolino QCh(miQC); // define the TotalString as a Chipolino
3238 miM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass();//MinMass of theStringChipo
3239 }
3240 G4double cM2=curString4M.m2(); // Actual squared mass of the Cur String
3241#ifdef debug
3242 G4cout<<"---->>G4QFragmentation::Breeder: minMass="<<miM<<", realM2="<<cM2<<G4endl;
3243#endif
3244 G4double cM=0.;
3245 if(cM2>0.)
3246 {
3247 cM=std::sqrt(cM2);
3248 if(std::fabs(cM-miM) < eps) // Convert to hadron(2 hadrons) w/o calculations
3249 {
3250 if(miPDG!=10)
3251 {
3252 G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
3253 theResult->push_back(sHad);// Fill the curString as a hadron
3254#ifdef debug
3255 G4cout<<"----->>G4QFragmentation::Breeder:S->H="<<miPDG<<curString4M<<G4endl;
3256#endif
3257 }
3258 else
3259 {
3260 G4QChipolino QCh(miQC); // define TotalResidual as a Chipolino
3261 G4QPDGCode h1QPDG=QCh.GetQPDG1(); // QPDG of the first hadron
3262 G4double h1M =h1QPDG.GetMass(); // Mass of the first hadron
3263 G4QPDGCode h2QPDG=QCh.GetQPDG2(); // QPDG of the second hadron
3264 G4double h2M =h2QPDG.GetMass(); // Mass of the second hadron
3265 G4double pt1 =h1M/(h1M+h2M); // 4-mom part of the first hadron
3266 G4LorentzVector h14M=pt1*curString4M; // 4-mom of the first hadron
3267 G4LorentzVector h24M=curString4M-h14M;// 4-mom of the second hadron
3268 G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
3269 theResult->push_back(h1H); // (delete equivalent)
3270#ifdef debug
3271 G4LorentzVector f4M=h1H->Get4Momentum();
3272 G4int fPD=h1H->GetPDGCode();
3273 G4int fCg=h1H->GetCharge();
3274 G4int fBN=h1H->GetBaryonNumber();
3275 G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=2HadrAR Prod-F is filled, f4M="
3276 <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
3277#endif
3278 G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
3279 theResult->push_back(h2H); // (delete equivalent)
3280#ifdef debug
3281 G4LorentzVector s4M=h2H->Get4Momentum();
3282 G4int sPD=h2H->GetPDGCode();
3283 G4int sCg=h2H->GetCharge();
3284 G4int sBN=h2H->GetBaryonNumber();
3285 G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=2HadrAR Prod-S is filled, s4M="
3286 <<s4M<<", sPDG="<<sPD<<", sCg="<<sCg<<", sBN="<<sBN<<G4endl;
3287#endif
3288 }
3289 continue; // Continue the LOOP over the curStrings
3290 }
3291 else // Try to recover (+/-) to min Mass
3292 {
3293 G4ThreeVector cP=curString4M.vect(); // Momentum of the curString
3294 G4double cE=curString4M.e(); // Energy of the curString
3295 G4ThreeVector curV=cP/cE; // curRelativeVelocity
3296 G4double miM2=miM*miM;
3297 G4int restr=0; // To use beyon the LOOP for printing
3298 G4int fustr=0; // Selected String-partner (0 = NotFound)
3299 G4double selX=0.; // Selected value of x
3300 G4double maD=-DBL_MAX; // Maximum Free Mass
3301 G4double Vmin=DBL_MAX; // min Velocity Distance
3302 G4LorentzVector s4M(0.,0.,0.,0.); // Selected 4-mom of the hadron
3303#ifdef debug
3304 G4cout<<"G4QFr::Breed:TryRecover,V="<<curV<<",cM2="<<cM2<<",miM="<<miM<<G4endl;
3305#endif
3306 nOfStr=strings.size();
3307 for(restr=next; restr < nOfStr; ++restr) if(restr != astring)
3308 {
3309#ifdef debug
3310 G4cout<<"G4QFragmentation::Breeder: rS="<<restr<<", nS="<<nOfStr<<G4endl;
3311#endif
3312 G4QString* pString=strings[restr];
3313#ifdef debug
3314 G4cout<<"G4QFragmentation::Breeder: pString="<<pString<<G4endl;
3315#endif
3316 G4LorentzVector p4M=pString->Get4Momentum();
3317#ifdef debug
3318 G4cout<<"G4QFragmentation::Breeder: p4M="<<p4M<<G4endl;
3319#endif
3320 G4ThreeVector pP=p4M.vect(); // Momentum of the partnerString
3321 G4double pE=p4M.e(); // Energy of the partnerString
3322 G4double D2=cE*pE-cP.dot(pP);
3323 G4double pM2=p4M.m2();
3324#ifdef debug
3325 G4cout<<"G4QFrag::Breeder: pM2="<<pM2<<",miM2="<<miM2<<",cM2="<<cM2<<G4endl;
3326#endif
3327 G4double dM4=pM2*(miM2-cM2);
3328 G4double D=D2*D2+dM4;
3329#ifdef debug
3330 G4cout<<"G4QFragmentation::Breeder: D="<<D<<",dM4="<<dM4<<",D2="<<D2<<G4endl;
3331#endif
3332 G4double x=-1.; // Bad preexpectation
3333 if(D > 0. && pM2>.01) x=(std::sqrt(D)-D2)/pM2; // what we should get from p
3334#ifdef debug
3335 else G4cout<<"G4QFragment::Breeder: D="<<D<<",D2="<<D2<<",pM4="<<dM4<<G4endl;
3336 G4cout<<"G4QFragmentation::Breeder: pM2="<<pM2<<",D2="<<D2<<",x="<<x<<G4endl;
3337#endif
3338 if(x > 0. && x < 1.) // We are getting x part of p4M
3339 {
3340 G4QContent pQC=pString->GetQC(); // Quark Content of The Partner
3341 G4int pPDG=pQC.GetSPDGCode();// PDG of The Lightest Hadron for the Partner
3342 G4double pM=0.; // Mass of the LightestHadron
3343 if(pPDG==10)
3344 {
3345 G4QChipolino QCh(pQC); // define the TotalString as a Chipolino
3346 pM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass();// Mass of Chipolino
3347 }
3348 else pM=G4QPDGCode(pPDG).GetMass();// Mass of theLightestHadron for Partner
3349 G4double rM=std::sqrt(pM2); // Real mass of the string-partner
3350 G4double delta=(1.-x)*rM-pM;// @@ Minimum CM disterbance measure
3351 if(delta > 0. && delta > maD)
3352 {
3353 maD=delta;
3354#ifdef debug
3355 G4cout<<"G4QFragmentation::Breeder: Subtr,S#"<<restr<<",d="<<maD<<G4endl;
3356#endif
3357 fustr=restr;
3358 selX=x;
3359 s4M=p4M;
3360 }
3361 }
3362 else if(x <= 0.) // We are adding to p4M, so use RelVelocity
3363 {
3364 G4ThreeVector pV=pP/pE; // curRelativeVelocity
3365 G4double dV=(curV-pV).mag2();// SquaredDifferenceBetweenRelVelocities
3366 if(dV < Vmin)
3367 {
3368#ifdef debug
3369 G4cout<<"G4QFragmentation::Breeder: FreeAdd,S#"<<restr<<",x="<<x<<G4endl;
3370#endif
3371 Vmin=dV;
3372 fustr=restr;
3373 selX=x;
3374 s4M=p4M;
3375 }
3376 }
3377#ifdef debug
3378 G4cout<<"G4QFragmentation::Breeder:EndOfLOOP r="<<restr<<"<"<<nOfStr<<G4endl;
3379#endif
3380 } // End of the LOOP over string-partners for Correction
3381#ifdef debug
3382 G4cout<<"G4QFragmentation::Breeder: AfterLOOP fustr="<<fustr<<G4endl;
3383#endif
3384 if(fustr)
3385 {
3386#ifdef edebug
3387 G4LorentzVector sum4M=s4M+curString4M;
3388 G4cout<<"G4QFragmentation::Breeder: Found Sum4M="<<sum4M<<G4endl;
3389#endif
3390 G4QString* pString=strings[fustr];
3391 curString4M+=selX*s4M;
3392 if(std::abs(miPDG)%10 > 2) // Decay String-Hadron-Resonance
3393 {
3394 G4Quasmon Quasm;
3395 G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
3396 G4QHadronVector* tmpQHadVec=Quasm.DecayQHadron(sHad); // It deletes sHad
3397#ifdef debug
3398 G4cout<<"G4QFragmentation::Breeder:DecStH,nH="<<tmpQHadVec->size()<<G4endl;
3399#endif
3400 for(unsigned aH=0; aH < tmpQHadVec->size(); aH++)
3401 {
3402 theResult->push_back((*tmpQHadVec)[aH]);//TheDecayProdOfHadron is filled
3403#ifdef debug
3404 G4QHadron* prodH =(*tmpQHadVec)[aH];
3405 G4LorentzVector p4M=prodH->Get4Momentum();
3406 G4int PDG=prodH->GetPDGCode();
3407 G4int Chg=prodH->GetCharge();
3408 G4int BaN=prodH->GetBaryonNumber();
3409 G4cout<<"-EMC->>G4QFragmentation::Breeder:St=Had,pH#"<<aH<<" filled, 4M="
3410 <<p4M<<", PDG="<<PDG<<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
3411#endif
3412 }
3413 tmpQHadVec->clear();
3414 delete tmpQHadVec; // Who calls DecayQHadron is responsibleRorClear&Delete
3415 }
3416 else if(miPDG == 10) // ==> Decay Hadron-Chipolino
3417 {
3418 G4QChipolino QCh(miQC); // define theTotalResid as aChipolino
3419 G4QPDGCode h1QPDG=QCh.GetQPDG1(); // QPDG of the first hadron
3420 G4double h1M =h1QPDG.GetMass();// Mass of the first hadron
3421 G4QPDGCode h2QPDG=QCh.GetQPDG2(); // QPDG of the second hadron
3422 G4double h2M =h2QPDG.GetMass();// Mass of the second hadron
3423 G4double ttM =curString4M.m(); // Real Mass of the Chipolino
3424 if(h1M+h2M<ttM+eps) // Two particles decay of Chipolino
3425 {
3426 G4LorentzVector h14M(0.,0.,0.,h1M);
3427 G4LorentzVector h24M(0.,0.,0.,h2M);
3428 if(std::fabs(ttM-h1M-h2M)<=eps)
3429 {
3430 G4double part1=h1M/(h1M+h2M);
3431 h14M=part1*curString4M;
3432 h24M=curString4M-h14M;
3433 }
3434 else
3435 {
3436 if(!G4QHadron(curString4M).DecayIn2(h14M,h24M))
3437 {
3438 G4cerr<<"***G4QFragmentation::Breeder: tM="<<ttM<<"->h1="<<h1QPDG
3439 <<"("<<h1M<<")+h2="<<h1QPDG<<"("<<h2M<<")="<<h1M+h2M<<G4endl;
3440 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChDe");
3441 }
3442 }
3443 G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
3444 theResult->push_back(h1H); // (delete equivalent)
3445#ifdef debug
3446 G4LorentzVector f4M=h1H->Get4Momentum();
3447 G4int fPD=h1H->GetPDGCode();
3448 G4int fCg=h1H->GetCharge();
3449 G4int fBN=h1H->GetBaryonNumber();
3450 G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=Hadr Prod-F's filled, f4M="
3451 <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
3452#endif
3453 G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
3454 theResult->push_back(h2H); // (delete equivalent)
3455#ifdef debug
3456 G4LorentzVector s4M=h2H->Get4Momentum();
3457 G4int sPD=h2H->GetPDGCode();
3458 G4int sCg=h2H->GetCharge();
3459 G4int sBN=h2H->GetBaryonNumber();
3460 G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=Hadr Prod-S's filled, s4M="
3461 <<s4M<<", sPDG="<<sPD<<", sCg="<<sCg<<", sBN="<<sBN<<G4endl;
3462#endif
3463#ifdef edebug
3464 G4cout<<"-EMC-Chipo.G4QFragmentation::Breeder:DecCHECK,c4M="<<curString4M
3465 <<", ChQC="<<miQC<<", d4M="<<curString4M-h14M-h24M<<G4endl;
3466#endif
3467 }
3468 else
3469 {
3470 G4cerr<<"***G4QFragm::Breeder:tM="<<ttM<<miQC<<"->h1="<<h1QPDG<<"(" <<h1M
3471 <<")+h2="<<h1QPDG<<"("<<h2M<<") = "<<h1M+h2M<<G4endl;
3472 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChiDecMa");
3473 }
3474 }
3475 else
3476 {
3477 G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
3478 theResult->push_back(sHad); // The original string-hadron is filled
3479#ifdef debug
3480 G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=Hadr Filled, 4M="
3481 <<curString4M<<", PDG="<<miPDG<<G4endl;
3482#endif
3483 }
3484 G4double corF=1-selX;
3485 G4QParton* Left=pString->GetLeftParton();
3486 G4QParton* Right=pString->GetRightParton();
3487 Left->Set4Momentum(corF*Left->Get4Momentum());
3488 Right->Set4Momentum(corF*Right->Get4Momentum());
3489#ifdef edebug
3490 G4cout<<"-EMC-...Cor...G4QFragmentation::Breeder:CorCHECK Sum="<<sum4M
3491 <<" =? "<<curString4M+pString->Get4Momentum()<<", M="<<miM<<" ?= "
3492 <<curString4M.m()<<G4endl;
3493#endif
3494#ifdef debug
3495 G4cout<<"---->>G4QFragmentation::Breeder:*Corrected* String->Hadr="<<miPDG
3496 <<curString4M<<" by String #"<<fustr<<G4endl;
3497#endif
3498 continue; // Continue the LOOP over the curStrings
3499 } // End of Found combination for the String on string correction
3500 } // End of the Try-to-recover String+String correction algorithm
3501 } // End of IF(CM2>0.)
3502 } // End of IF(Can try to correct by String-String)
3503#ifdef debug
3504 else G4cout<<"***G4QFragmentation::Breeder: **No SSCorrection**,next="<<next<<G4endl;
3505#endif
3506 // ------------ At this point we can reduce the 3/-3 meson to 1/-1 meson ------------
3507 G4QParton* lpcS=curString->GetLeftParton();
3508 G4QParton* rpcS=curString->GetRightParton();
3509 G4int lPDGcS=lpcS->GetPDGCode();
3510 G4int rPDGcS=rpcS->GetPDGCode();
3511 if (lPDGcS==3 && rPDGcS==-3)
3512 {
3513 lpcS->SetPDGCode( 1);
3514 rpcS->SetPDGCode(-1);
3515 }
3516 else if(lPDGcS==-3 && rPDGcS==3)
3517 {
3518 lpcS->SetPDGCode(-1);
3519 rpcS->SetPDGCode( 1);
3520 }
3521 // -------- Now the only hope is Correction, using the already prodused Hadrons -----
3522 G4int nofRH=theResult->size(); // #of resulting Hadrons
3523#ifdef debug
3524 G4cout<<"G4QFragmentation::Breeder: theH="<<theHadrons<<", #OfH="<<nofRH<<G4endl;
3525#endif
3526 if(!theHadrons && nofRH) // Hadrons are existing for SH Correction
3527 {
3528#ifdef debug
3529 G4cout<<"!G4QFragmentation::Breeder:Can try SHCor, nH="<<theResult->size()<<G4endl;
3530#endif
3531 // @@ string can be not convertable to one hadron (2,0.0,0,2,0) - To be improved
3532 G4QContent miQC=curString->GetQC(); // QContent of the Lightest Hadron
3533 G4int miPDG=miQC.GetSPDGCode(); // PDG of the Lightest Hadron
3534 G4double miM=0.; // Prototype ofMass of theCurLightestHadron
3535 if(miPDG==10) // Mass of the Cur Lightest ChipolinoHadron
3536 {
3537 G4QChipolino QCh(miQC); // define the TotalString as a Chipolino
3538 miM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass();//MinMass of theStringChipo
3539 }
3540 else miM=G4QPDGCode(miPDG).GetMass(); // Mass of the Cur Lightest Hadron
3541 G4double spM=0.; // Mass of the selected Hadron-Partner
3542 G4ThreeVector cP=curString4M.vect(); // Momentum of the curString
3543 G4double cE=curString4M.e(); // Energy of the curString
3544 G4ThreeVector curV=cP/cE; // curRelativeVelocity
3545 G4int reha=0; // Hadron # to use beyon the LOOP
3546 G4int fuha=-1; // Selected Hadron-partner (0 = NotFound)
3547 G4double dMmin=DBL_MAX; // min Excess of the mass
3548 G4LorentzVector s4M(0.,0.,0.,0.); // Selected 4-mom of the Hadron+String
3549 G4double sM=0.; // Selected Mass of the Hadron+String
3550 for (reha=0; reha < nofRH; reha++) // LOOP over already collected hadrons
3551 {
3552 G4QHadron* pHadron=(*theResult)[reha];// Pointer to the current Partner-Hadron
3553 G4LorentzVector p4M=pHadron->Get4Momentum();
3554 G4double pM=p4M.m(); // Mass of the Partner-Hadron
3555 G4LorentzVector t4M=p4M+curString4M; // Total momentum of the compound
3556 G4double tM2=t4M.m2(); // Squared total mass of the compound
3557 if(tM2 >= sqr(pM+miM+eps)) // Condition of possible correction
3558 {
3559 G4double tM=std::sqrt(tM2); // Mass of the Hadron+String compound
3560 G4double dM=tM-pM-miM; // Excess of the compound mass
3561 if(dM < dMmin)
3562 {
3563 dMmin=dM;
3564 fuha=reha;
3565 spM=pM;
3566 s4M=t4M;
3567 sM=tM;
3568 }
3569 }
3570#ifdef debug
3571 else G4cout<<"G4QFragmentation::Breeder:H# "<<reha<<",tM="<<std::sqrt(tM2)<<" < "
3572 <<" mS="<<miM<<" + mH="<<pM<<" = "<<pM+miM<<G4endl;
3573#endif
3574 } // End of the LOOP over string-partners for Correction
3575#ifdef debug
3576 G4cout<<"G4QFragment::Breeder: fuha="<<fuha<<", dMmin="<<dMmin<<G4endl;
3577#endif
3578 if(fuha>-1) // The hadron-partner was found
3579 {
3580 G4QHadron* pHadron=(*theResult)[fuha];// Necessary for update
3581 G4LorentzVector mi4M(0.,0.,0.,miM); // Prototype of the new String=Hadron
3582 if(miM+spM<sM+eps) // Decay into CorrectedString+theSameHadron
3583 {
3584 G4LorentzVector sp4M(0.,0.,0.,spM);
3585 if(std::fabs(sM-miM-spM)<=eps)
3586 {
3587 G4double part1=miM/(miM+spM);
3588 mi4M=part1*s4M;
3589 sp4M=s4M-mi4M;
3590 }
3591 else
3592 {
3593 if(!G4QHadron(s4M).DecayIn2(mi4M,sp4M))
3594 {
3595 G4cerr<<"***G4QFragmentation::Breeder: *SH*, tM="<<sM<<"->h1=("<<miPDG<<")"
3596 <<miM<<" + h2="<<spM<<" = "<<miM+spM<<G4endl;
3597 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"SHChipoDec");
3598 }
3599 }
3600 pHadron->Set4Momentum(sp4M);
3601#ifdef debug
3602 G4cout<<"-EMC->...>G4QFragmentation::Breeder: H# "<<fuha<<" is updated, new4M="
3603 <<sp4M<<G4endl;
3604#endif
3605 }
3606 else
3607 {
3608 G4cerr<<"***G4QFragm::Breeder: HS Failed, tM="<<sM<<"->h1M=("<<miPDG<<")"<<miM
3609 <<"+h2M="<<spM<<" = "<<miM+spM<<G4endl;
3610 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"HSChipoDecMass");
3611 }
3612 if(std::abs(miPDG)%10 > 2) // Decay Hadron-Resonans
3613 {
3614 G4Quasmon Quasm;
3615 G4QHadron* sHad = new G4QHadron(miPDG,mi4M);
3616 G4QHadronVector* tmpQHadVec=Quasm.DecayQHadron(sHad); // It deletes sHad
3617#ifdef debug
3618 G4cout<<"G4QFragment::Breeder:*HS* DecStrHad, nH="<<tmpQHadVec->size()<<G4endl;
3619#endif
3620 for(unsigned aH=0; aH < tmpQHadVec->size(); aH++)
3621 {
3622 theResult->push_back((*tmpQHadVec)[aH]);// TheDecayProductOfTheHadronIsFilled
3623#ifdef debug
3624 G4QHadron* prodH =(*tmpQHadVec)[aH];
3625 G4LorentzVector p4M=prodH->Get4Momentum();
3626 G4int PDG=prodH->GetPDGCode();
3627 G4int Chg=prodH->GetCharge();
3628 G4int BaN=prodH->GetBaryonNumber();
3629 G4cout<<"-EMC->>G4QFragmentation::Breeder: Str+Hadr PrH#"<<aH<<" filled, 4M="
3630 <<p4M<<", PDG="<<PDG<<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
3631#endif
3632 }
3633 tmpQHadVec->clear();
3634 delete tmpQHadVec; // Who calls DecayQHadron is responsible for clear & delete
3635 }
3636 else if(miPDG == 10) // ==> Decay Hadron-Chipolino
3637 {
3638 G4QChipolino QCh(miQC); // define the TotalResidual as a Chipolino
3639 G4QPDGCode h1QPDG=QCh.GetQPDG1(); // QPDG of the first hadron
3640 G4double h1M =h1QPDG.GetMass();// Mass of the first hadron
3641 G4QPDGCode h2QPDG=QCh.GetQPDG2(); // QPDG of the second hadron
3642 G4double h2M =h2QPDG.GetMass();// Mass of the second hadron
3643 G4double ttM =curString4M.m(); // Real Mass of the Chipolino
3644 if(h1M+h2M<miM+eps) // Two particles decay of Chipolino
3645 {
3646 G4LorentzVector h14M(0.,0.,0.,h1M);
3647 G4LorentzVector h24M(0.,0.,0.,h2M);
3648 if(std::fabs(ttM-h1M-h2M)<=eps)
3649 {
3650 G4double part1=h1M/(h1M+h2M);
3651 h14M=part1*mi4M;
3652 h24M=mi4M-h14M;
3653 }
3654 else
3655 {
3656 if(!G4QHadron(mi4M).DecayIn2(h14M,h24M))
3657 {
3658 G4cerr<<"***G4QFragmentation::Breeder: HS tM="<<ttM<<"->h1="<<h1QPDG<<"("
3659 <<h1M<<")+h2="<<h1QPDG<<"("<<h2M<<")="<<h1M+h2M<<G4endl;
3660 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChipoDec");
3661 }
3662 }
3663 G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
3664 theResult->push_back(h1H); // (delete equivalent)
3665#ifdef debug
3666 G4LorentzVector f4M=h1H->Get4Momentum();
3667 G4int fPD=h1H->GetPDGCode();
3668 G4int fCg=h1H->GetCharge();
3669 G4int fBN=h1H->GetBaryonNumber();
3670 G4cout<<"-EMC->>G4QFragmentation::Breeder: CorStrHadr Prod-1 is filled, f4M="
3671 <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
3672#endif
3673 G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
3674 theResult->push_back(h2H); // (delete equivalent)
3675#ifdef debug
3676 G4LorentzVector n4M=h2H->Get4Momentum();
3677 G4int nPD=h2H->GetPDGCode();
3678 G4int nCg=h2H->GetCharge();
3679 G4int nBN=h2H->GetBaryonNumber();
3680 G4cout<<"-EMC->>G4QFragmentation::Breeder: CorStrHadr Prod-2 is filled, n4M="
3681 <<n4M<<", nPDG="<<nPD<<", nCg="<<nCg<<", nBN="<<nBN<<G4endl;
3682#endif
3683#ifdef edebug
3684 G4cout<<"-EMC-...HS-Chipo...G4QFragmentation::Breeder:DecCHECK, Ch4M="<<mi4M
3685 <<", ChQC="<<miQC<<", d4M="<<mi4M-h14M-h24M<<G4endl;
3686#endif
3687 }
3688 }
3689 else
3690 {
3691 G4QHadron* sHad = new G4QHadron(miPDG, mi4M);
3692 theResult->push_back(sHad); // The original string=hadron is filled
3693#ifdef debug
3694 G4cout<<"----->>G4QFragmentation::Breeder: CorStr=Hadr is Filled, 4M="
3695 <<curString4M<<", StPDG="<<miPDG<<G4endl;
3696#endif
3697 }
3698#ifdef edebug
3699 G4cout<<"-EMC-...Cor...G4QFragmentation::Breeder:StHadCor CHECK Sum="<<s4M
3700 <<" =? "<<mi4M+pHadron->Get4Momentum()<<G4endl;
3701#endif
3702#ifdef debug
3703 G4cout<<"------->>G4QFragmentation::Breeder: *Corrected* String+Hadr="<<miPDG
3704 <<mi4M<<" by Hadron #"<<reha<<G4endl;
3705#endif
3706 continue; // Continue the LOOP over the curStrings
3707 }
3708 else
3709 {
3710#ifdef debug
3711 G4cout<<"G4QFragmentation::Breeder: Str+Hadr Failed, 4M="<<curString4M
3712 <<", PDG="<<miPDG<<" -> Now try to recover the string as a hadron"<<G4endl;
3713#endif
3714 //for (reha=0; reha < nofRH; reha++) // LOOP over already collected hadrons
3715 //{
3716 // G4QHadron* pHadron=(*theResult)[reha];// Pointer to the CurrentPartnerHadron
3717 // G4LorentzVector p4M=pHadron->Get4Momentum();
3718 // G4double pM=p4M.m(); // Mass of the Partner-Hadron
3719 // G4LorentzVector t4M=p4M+curString4M; // Total momentum of the compound
3720 // G4double tM2=t4M.m2(); // Squared total mass of the compound
3721 // if(tM2 >= sqr(pM+miM+eps)) // Condition of possible correction
3722 // {
3723 // G4double tM=std::sqrt(tM2); // Mass of the Hadron+String compound
3724 // G4double dM=tM-pM-miM; // Excess of the compound mass
3725 // if(dM < dMmin)
3726 // {
3727 // dMmin=dM;
3728 // fuha=reha;
3729 // spM=pM;
3730 // s4M=t4M;
3731 // sM=tM;
3732 // }
3733 // }
3734 //} // End of the LOOP over string-partners for Correction
3735 }
3736 // @@@ convert string to Quasmon with curString4M
3737 G4QContent curStringQC=curString->GetQC();
3738 G4Quasmon* stringQuasmon = new G4Quasmon(curStringQC, curString4M);
3739 theQuasmons.push_back(stringQuasmon);
3740 continue; // Continue the LOOP over the curStrings
3741 } // End of IF(Can try the String-Hadron correction
3742 } // End of IF(NO_Hadrons) = Problem solution namespace
3743 G4Quasmon tmpQ; // @@ an issue of Q to decay resonances
3744 G4int nHfin=0;
3745 if(theHadrons) nHfin=theHadrons->size();
3746 else // !! Sum Up all strings and convert them in a Quasmon (Exception for development)
3747 {
3748 G4LorentzVector ss4M(0.,0.,0.,0.);
3749 G4QContent ssQC(0,0,0,0,0,0);
3750 G4int tnSt=strings.size();
3751 for(G4int i=astring; i < tnSt; ++i)
3752 {
3753 G4LorentzVector pS4M=strings[i]->Get4Momentum(); // String 4-momentum
3754 ss4M+=pS4M;
3755 G4QContent pSQC=strings[i]->GetQC(); // String Quark Content
3756 ssQC+=pSQC;
3757#ifdef debug
3758 G4cout<<"=--=>G4QFragmentation::Breeder:S#"<<i<<",4M="<<pS4M<<",QC="<<pSQC<<G4endl;
3759#endif
3760 }
3761#ifdef debug
3762 G4cout<<"==>G4QFragmentation::Breeder:AllStrings are summed up in a Quasmon"<<G4endl;
3763#endif
3764 G4Quasmon* stringQuasmon = new G4Quasmon(ssQC, ss4M);
3765 theQuasmons.push_back(stringQuasmon);
3766 break; // break the LOOP over Strings
3767 }
3768#ifdef debug
3769 G4cout<<"G4QFragmentation::Breeder: Trying to decay hadrons #ofHRes="<<nHfin<<G4endl;
3770#endif
3771 for(G4int aTrack=0; aTrack<nHfin; aTrack++)
3772 {
3773 G4QHadron* curHadron=(*theHadrons)[aTrack];
3774 G4int hPDG=curHadron->GetPDGCode();
3775 G4LorentzVector curH4M=curHadron->Get4Momentum();
3776 G4int curHCh=curHadron->GetCharge();
3777 G4int curHBN=curHadron->GetBaryonNumber();
3778#ifdef debug
3779 G4cout<<"----->>G4QFragmentation::Breeder:S#"<<astring<<",H#"<<aTrack<<",PDG="<<hPDG
3780 <<",4M="<<curHadron->Get4Momentum()<<G4endl;
3781#endif
3782 if(std::abs(hPDG)%10 > 2)
3783 {
3784 G4QHadronVector* tmpQHadVec=tmpQ.DecayQHadron(curHadron); // It deletes curHadron
3785#ifdef debug
3786 G4cout<<"G4QFragmentation::Breeder:-DECAY'S DONE-,nH="<<tmpQHadVec->size()<<G4endl;
3787#endif
3788 for(unsigned aH=0; aH < tmpQHadVec->size(); aH++)
3789 {
3790 theResult->push_back((*tmpQHadVec)[aH]);// TheDecayProduct of TheHadron is filled
3791 //
3792 G4QHadron* prodH =(*tmpQHadVec)[aH];
3793 G4LorentzVector p4M=prodH->Get4Momentum();
3794 G4int Chg=prodH->GetCharge();
3795 G4int BaN=prodH->GetBaryonNumber();
3796 curString4M-=p4M;
3797 curStrChg-=Chg;
3798 curStrBaN-=BaN;
3799 curH4M-=p4M;
3800 curHCh-=Chg;
3801 curHBN-=BaN;
3802#ifdef edebug
3803 G4int PDG=prodH->GetPDGCode();
3804 G4cout<<"-EMC->>G4QFragmentation::Breeder:String*Filled, 4M="<<p4M<<", PDG="<<PDG
3805 <<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
3806#endif
3807 }
3808#ifdef edebug
3809 G4cout<<"-EMC-.G4QFr::Br:Dec,r4M="<<curH4M<<",rC="<<curHCh<<",rB="<<curHBN<<G4endl;
3810#endif
3811 tmpQHadVec->clear();
3812 delete tmpQHadVec; // Who calls DecayQHadron is responsible for clear & delete
3813 }
3814 else // Chipolino is not checked here
3815 {
3816 theResult->push_back(curHadron); // The original hadron is filled
3817 //
3818 curString4M-=curH4M;
3819 G4int curCh=curHadron->GetCharge();
3820 G4int curBN=curHadron->GetBaryonNumber();
3821 curStrChg-=curCh;
3822 curStrBaN-=curBN;
3823#ifdef edebug
3824 G4cout<<"-EMC->>-->>G4QFragmentation::Breeder: curH filled 4M="<<curH4M<<",PDG="
3825 <<curHadron->GetPDGCode()<<", Chg="<<curCh<<", BaN="<<curBN<<G4endl;
3826#endif
3827 }
3828 }
3829 // clean up (the issues are filled to theResult)
3830 if(theHadrons) delete theHadrons;
3831#ifdef edebug
3832 G4cout<<"-EMC-.........G4QFragmentation::Breeder: StringDecay CHECK, r4M="<<curString4M
3833 <<", rChg="<<curStrChg<<", rBaN="<<curStrBaN<<G4endl;
3834#endif
3835 // Trap with the debugging warning --- Starts ---
3836 if(curStrChg || curStrBaN || curString4M.t() > eps || std::fabs(curString4M.x()) > eps
3837 || std::fabs(curString4M.y()) > eps || std::fabs(curString4M.z()) > eps )
3838 {
3839 G4double dEn=curString4M.t();
3840 G4double dPx=curString4M.x();
3841 G4double dPy=curString4M.y();
3842 G4double dPz=curString4M.z();
3843 G4int nHadr=theResult->size();
3844 G4double hEn=0.;
3845 G4double hPx=0.;
3846 G4double hPy=0.;
3847 G4double hPz=0.;
3848 G4int hCh=0;
3849 G4int hBN=0;
3850 G4double mEn=0.;
3851 G4double mPx=0.;
3852 G4double mPy=0.;
3853 G4double mPz=0.;
3854 G4int mCh=0;
3855 G4int mBN=0;
3856 for(G4int i=0; i<nHadr; i++)
3857 {
3858 mEn=hEn; // Previous hadron
3859 mPx=hPx;
3860 mPy=hPy;
3861 mPz=hPz;
3862 mCh=hCh;
3863 mBN=hBN;
3864 G4QHadron* curHadr = (*theResult)[i];
3865 G4LorentzVector hI4M = curHadr->Get4Momentum();
3866 hEn=hI4M.t();
3867 hPx=hI4M.x();
3868 hPy=hI4M.y();
3869 hPz=hI4M.z();
3870 hCh=curHadr->GetCharge();
3871 hBN=curHadr->GetBaryonNumber();
3872 G4cout<<"G4QFragmentation::Breeder: H#"<<i<<", d4M="<<curString4M+hI4M
3873 <<",dCh="<<hCh+curStrChg<<",dBN="<<hBN+curStrBaN<<G4endl;
3874 if( !(hCh+curStrChg) && !(hBN+curStrBaN) && std::fabs(dEn+hEn)<eps &&
3875 std::fabs(dPx+hPx)<eps && std::fabs(dPy+hPy)<eps && std::fabs(dPz+hPz)<eps )
3876 {
3877 G4cout<<"G4QFragmentation::Breeder: ***Cured*** Redundent Hadron # "<<i<<G4endl;
3878 G4QHadron* theLast = (*theResult)[nHadr-1];
3879 curHadr->Set4Momentum(theLast->Get4Momentum()); //4-Mom of CurHadr
3880 G4QPDGCode lQP=theLast->GetQPDG();
3881 if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP);
3882 else curHadr->SetQC(theLast->GetQC());
3883 theResult->pop_back(); // theLastQHadron is excluded from OUTPUT
3884 delete theLast; //*!!When kill, delete theLastQHadr as an Instance!*
3885 break;
3886 }
3887 if( !(hCh+mCh+curStrChg) && !(hBN+mBN+curStrBaN) && std::fabs(dEn+hEn+mEn)<eps &&
3888 std::fabs(dPx+hPx+mPx)<eps && std::fabs(dPy+hPy+mPy)<eps &&
3889 std::fabs(dPz+hPz+mPz)<eps && i>0)
3890 {
3891 G4cout<<"G4QFragmentation::Breeder:***Cured*** Redundent 2Hadrons i="<<i<<G4endl;
3892 G4QHadron* preHadr = (*theResult)[i-1];
3893 G4QHadron* theLast = (*theResult)[nHadr-1];
3894 if(i < nHadr-1) // Only cur can overlap with the two last hadrons
3895 { // Put the last to the previous
3896 preHadr->Set4Momentum(theLast->Get4Momentum()); // must be 4-Mom of preHadr
3897 G4QPDGCode lQP=theLast->GetQPDG();
3898 if(lQP.GetPDGCode()!=10) preHadr->SetQPDG(lQP);
3899 else preHadr->SetQC(theLast->GetQC());
3900 }
3901 theResult->pop_back(); // theLastQHadron's excluded from OUTPUT(even if Cur=Last)
3902 delete theLast; //*!!When kill, delete theLastQHadr as an Instance!*
3903 theLast = (*theResult)[nHadr-2]; // nHadr is not changed -> so it's LastButOne
3904 if(i < nHadr-2) // The two current and the two Last are not overlaped
3905 { // Put the last but one to the current
3906 curHadr->Set4Momentum(theLast->Get4Momentum()); // must be 4-Mom of curHadr
3907 G4QPDGCode lQP=theLast->GetQPDG();
3908 if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP);
3909 else curHadr->SetQC(theLast->GetQC());
3910 }
3911 theResult->pop_back(); // theLastQHadron's excluded from OUTPUT(even for overlap)
3912 delete theLast; //*!!When kill, delete theLastQHadr as an Instance!*
3913 nHadr=theResult->size(); // Just a precaution... should be nHadr-2
3914 break;
3915 }
3916 // If the redundent particle decay in 3 FS hadrons -> the corresponding Improvement
3917 G4cout<<"*Warning*G4QFragmentation::Breeder: Nonconservation isn't cured!"<<G4endl;
3918 }
3919 }
3920 // Trap with the debugging warning ^^^ Ends ^^^
3921 } // End of the main LOOP over decaying strings
3922 G4LorentzVector r4M=theNucleus.Get4Momentum(); // Nucleus 4-momentum in LS
3923 G4int rPDG=theNucleus.GetPDG();
3924 G4QHadron* resNuc = new G4QHadron(rPDG,r4M);
3925 theResult->push_back(resNuc); // Fill the residual nucleus
3926#ifdef edebug
3927 G4LorentzVector s4M(0.,0.,0.,0.); // Sum of the Result in LS
3928 G4int rCh=totChg;
3929 G4int rBN=totBaN;
3930 G4int nHadr=theResult->size();
3931 G4int nQuasm=theQuasmons.size();
3932 G4cout<<"-EMCLS-G4QFragmentation::Breeder:#ofHadr="<<nHadr<<", #OfQuasm="<<nQuasm<<",rN="
3933 <<r4M.m()<<"="<<G4QNucleus(rPDG).GetGSMass()<<G4endl;
3934 for(G4int i=0; i<nHadr; i++)
3935 {
3936 G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
3937 s4M+=hI4M;
3938 G4int hChg=(*theResult)[i]->GetCharge();
3939 rCh-=hChg;
3940 G4int hBaN=(*theResult)[i]->GetBaryonNumber();
3941 rBN-=hBaN;
3942 G4cout<<"-EMCLS-G4QFragmentation::Breeder:(1) Hadron#"<<i<<", 4M="<<hI4M<<", PDG="
3943 <<(*theResult)[i]->GetPDGCode()<<", C="<<hChg<<", B="<<hBaN<<G4endl;
3944 }
3945 for(G4int i=0; i<nQuasm; i++)
3946 {
3947 G4LorentzVector hI4M=theQuasmons[i]->Get4Momentum();
3948 s4M+=hI4M;
3949 G4int hChg=theQuasmons[i]->GetCharge();
3950 rCh-=hChg;
3951 G4int hBaN=theQuasmons[i]->GetBaryonNumber();
3952 rBN-=hBaN;
3953 G4cout<<"-EMCLS-G4QFragmentation::Breeder:(1) Quasmon#"<<i<<", 4M="<<hI4M<<", C="<<hChg
3954 <<", B="<<hBaN<<G4endl;
3955 }
3956 G4cout<<"-EMCLS-G4QFragm::Breed: LS r4M="<<s4M-totLS4M<<",rC="<<rCh<<",rB="<<rBN<<G4endl;
3957#endif
3958 // Now we need to coolect particles for creation of a Quasmon @@ improve !!
3959 G4int nRes=theResult->size();
3960#ifdef ppdebug
3961 G4cout<<"G4QFragmentation::Breeder: Strings4M="<<ft4M<<", nRes="<<nRes<<G4endl;
3962#endif
3963 G4ThreeVector LS3Mom=ft4M.v();
3964 G4ThreeVector LSDir=LS3Mom.unit();
3965 if(nRes > 2 && maxEn > 0.)
3966 {
3967 std::list<std::pair<G4double, G4QHadron*> > theSorted; // Output
3968 std::list<std::pair<G4double, G4QHadron*> >::iterator current; // Input
3969 for(G4int secondary = 0; secondary<nRes-1; ++secondary)
3970 {
3971 G4QHadron* ih =theResult->operator[](secondary);
3972 G4LorentzVector h4M =ih->Get4Momentum();
3973 G4double hM2 =ih->GetMass2();
3974 G4ThreeVector h3M =h4M.v();
3975 G4double toSort=DBL_MAX;
3976 if(hM2>0.00001) toSort=h4M.e()+h3M.dot(LSDir)/std::sqrt(hM2);// monotonic as rapidity
3977#ifdef ppdebug
3978 G4cout<<"G4QFragmentation::Breeder:#"<<secondary<<",M2="<<hM2<<",s="<<toSort<<G4endl;
3979#endif
3980 std::pair<G4double, G4QHadron*> it;
3981 it.first = toSort;
3982 it.second = ih;
3983 G4bool inserted = false;
3984 for(current = theSorted.begin(); current!=theSorted.end(); ++current)
3985 {
3986 if((*current).first > toSort) // The current is smaller then existing
3987 {
3988 theSorted.insert(current, it); // It shifts the others up
3989 inserted = true;
3990 break;
3991 }
3992 }
3993 if(!inserted) theSorted.push_back(it); // It is bigger than any previous
3994 }
3995 theResult->clear(); // Clear and refill theResult by StriHardPart
3996 G4LorentzVector q4M(0.,0.,0.,0.);
3997 G4QContent qQC(0,0,0,0,0,0);
3998 for(current = theSorted.begin(); current!=theSorted.end(); ++current)
3999 {
4000 G4QHadron* ih= (*current).second;
4001 G4LorentzVector h4M= ih->Get4Momentum();
4002 G4int hPDG= ih->GetPDGCode();
4003 G4double dE= 0.;
4004 G4bool tested=true;
4005 if (hPDG> 1111 && hPDG< 3335) dE=h4M.e()-ih->GetMass(); // Baryons
4006 else if(hPDG>-1111 && hPDG<1111 && hPDG!=22) dE=h4M.e(); // Mesons (Photons Hard)
4007 //else if(hPDG<-1111 && hPDG>-3335) dE=h4M.e()+ih->GetMass(); // Antiaryons Don'tUse
4008 else tested=false; // Skip other
4009#ifdef ppdebug
4010 G4cout<<"G4QFragmentation::Breeder:dE="<<dE<<",mE="<<maxEn<<",t="<<tested<<G4endl;
4011#endif
4012 if(tested && dE < maxEn)
4013 {
4014 maxEn-=dE;
4015 q4M+=h4M;
4016 qQC+=ih->GetQC();
4017#ifdef debug
4018 G4cout<<"%->G4QFragmentation::Breeder:Exclude,4M="<<h4M<<",dE="<<maxEn<<G4endl;
4019#endif
4020 delete ih;
4021 }
4022 else theResult->push_back(ih); // Delete equivalent
4023 } // End of Loop over sorted pairs
4024 G4Quasmon* softQuasmon = new G4Quasmon(qQC, q4M); // SoftPart -> Quasmon
4025#ifdef debug
4026 G4cout<<"%->G4QFragmentation::Breeder:QuasmonIsFilled,4M="<<q4M<<",QC="<<qQC<<G4endl;
4027#endif
4028 if(q4M != vac4M) theQuasmons.push_back(softQuasmon);
4029 else delete softQuasmon;
4030 theResult->push_back(resNuc);
4031#ifdef edebug
4032 G4LorentzVector f4M(0.,0.,0.,0.); // Sum of the Result in LS
4033 G4int fCh=totChg;
4034 G4int fBN=totBaN;
4035 G4int nHd=theResult->size();
4036 G4int nQm=theQuasmons.size();
4037 G4cout<<"-EMCLS-G4QFragmentation::Breeder:#ofHadr="<<nHd<<", #OfQuasm="<<nQm<<",rN="
4038 <<r4M.m()<<"="<<G4QNucleus(rPDG).GetGSMass()<<G4endl;
4039 for(G4int i=0; i<nHd; i++)
4040 {
4041 G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
4042 f4M+=hI4M;
4043 G4int hChg=(*theResult)[i]->GetCharge();
4044 fCh-=hChg;
4045 G4int hBaN=(*theResult)[i]->GetBaryonNumber();
4046 fBN-=hBaN;
4047 G4cout<<"-EMCLS-G4QFragmentation::Breeder:(2) Hadron#"<<i<<", 4M="<<hI4M<<", PDG="
4048 <<(*theResult)[i]->GetPDGCode()<<", C="<<hChg<<", B="<<hBaN<<G4endl;
4049 }
4050 for(G4int i=0; i<nQm; i++)
4051 {
4052 G4LorentzVector hI4M=theQuasmons[i]->Get4Momentum();
4053 f4M+=hI4M;
4054 G4int hChg=theQuasmons[i]->GetCharge();
4055 fCh-=hChg;
4056 G4int hBaN=theQuasmons[i]->GetBaryonNumber();
4057 fBN-=hBaN;
4058 G4cout<<"-EMCLS-G4QFragmentation::Breeder:(2) Quasmon#"<<i<<", 4M="<<hI4M<<", C="
4059 <<hChg<<", B="<<hBaN<<G4endl;
4060 }
4061 G4cout<<"-EMCLS-G4QFragm::Breed:, r4M="<<f4M-totLS4M<<",rC="<<fCh<<",rB="<<fBN<<G4endl;
4062#endif
4063 } // End of the soft Quasmon Creation
4064 return;
4065} // End of Breeder
Hep3Vector unit() const
double dot(const Hep3Vector &) const
Hep3Vector vect() const
Hep3Vector v() const
G4int GetSPDGCode() const
Definition: G4QContent.cc:1204
G4int AddParton(G4int pPDG) const
Definition: G4QContent.cc:1655
G4int SumPartonPDG(G4int PDG1, G4int PFG2) const
std::pair< G4int, G4int > ReducePair(G4int P1, G4int P2) const
G4int AnnihilationOrder(G4int LS, G4int MS, G4int uP, G4int mP, G4int sP, G4int nP)
G4bool DecayIn2(G4LorentzVector &f4Mom, G4LorentzVector &s4Mom)
Definition: G4QHadron.cc:544
void SetQC(const G4QContent &newQC)
Definition: G4QHadron.hh:186
void SetQPDG(const G4QPDGCode &QPDG)
Definition: G4QHadron.cc:275
G4double GetMass2() const
Definition: G4QHadron.hh:177
G4QPDGCode GetQPDG() const
Definition: G4QHadron.hh:172
G4int GetPDGCode() const
Definition: G4QPDGCode.hh:326
G4QHadronVector * FragmentString(G4bool QL)
Definition: G4QString.cc:348
G4int GetDirection() const
Definition: G4QString.hh:89
G4QContent GetQC() const
Definition: G4QString.hh:91
G4QHadronVector * DecayQHadron(G4QHadron *hadron)
Definition: G4Quasmon.cc:5779
void swap(shared_ptr< P > &, shared_ptr< P > &)
Definition: memory.h:1247

Referenced by Fragment().

◆ ChooseX()

G4double G4QFragmentation::ChooseX ( G4double  Xmin,
G4double  Xmax 
) const
protected

Definition at line 4312 of file G4QFragmentation.cc.

4313{
4314 // choose an x between Xmin and Xmax with P(x) ~ 1/x @@ M.K. -> 1/sqrt(x)
4315 //G4double range=Xmax-Xmin;
4316 if(Xmax == Xmin) return Xmin;
4317 if( Xmin < 0. || Xmax < Xmin)
4318 {
4319 G4cerr<<"***G4QFragmentation::ChooseX: Xmin="<<Xmin<<", Xmax="<<Xmax<< G4endl;
4320 G4Exception("G4QFragmentation::ChooseX:","72",FatalException,"Bad X or X-Range");
4321 }
4322 //G4double x;
4323 //do {x=Xmin+G4UniformRand()*range;} while ( Xmin/x < G4UniformRand() );
4324 G4double sxi=std::sqrt(Xmin);
4325 G4double x=sqr(sxi+G4UniformRand()*(std::sqrt(Xmax)-sxi));
4326#ifdef debug
4327 G4cout<<"G4QFragmentation::ChooseX: DiffractiveX="<<x<<G4endl;
4328#endif
4329 return x;
4330} // End of ChooseX

Referenced by ExciteDiffParticipants(), and ExciteSingDiffParticipants().

◆ EvaporateResidual()

void G4QFragmentation::EvaporateResidual ( G4QHadron hadrNuc)
protected

Definition at line 4790 of file G4QFragmentation.cc.

4791{
4792 static const G4double mAlph = G4QPDGCode(2112).GetNuclMass(2,2,0);
4793 static const G4double mDeut = G4QPDGCode(2112).GetNuclMass(1,1,0);
4794 static const G4double mNeut = G4QPDGCode(2112).GetMass();
4795 static const G4double mProt = G4QPDGCode(2212).GetMass();
4796 static const G4double mAlPr = mAlph+mProt;
4797 static const G4double mAlNt = mAlph+mNeut;
4798 static const G4double dProt = mProt+mProt;
4799 static const G4double dNeut = mNeut+mNeut;
4800 static const G4double dAlph = mAlph+mAlph;
4801 static const G4double eps=.003;
4802 G4QEnvironment envir(theNucleus);
4803 G4int thePDG = qH->GetPDGCode(); // Get PDG code of the Residual Nucleus
4804 G4int theBN = qH->GetBaryonNumber(); // A (Baryon number of the nucleus)
4805 G4QContent theQC = qH->GetQC(); // Quark Content of the hadron
4806 G4int theS=theQC.GetStrangeness(); // S (Strangeness of the nucleus)
4807#ifdef debug
4808 G4cout<<"G4QFragment::EvaRes:-Called- PDG="<<thePDG<<",4M="<<qH->Get4Momentum()
4809 <<",QC="<<theQC<<", BN="<<theBN<<G4endl;
4810#endif
4811 if(thePDG==10)
4812 {
4813#ifdef debug
4814 G4cout<<"G4QFragment::EvaRes: Cgipolino QC="<<theQC<<qH->Get4Momentum()<<G4endl;
4815#endif
4816 G4QContent chQC=qH->GetQC(); // Quark content of the Hadron-Chipolino
4817 G4QChipolino QCh(chQC); // Define a Chipolino instance for the Hadron
4818 G4LorentzVector ch4M=qH->Get4Momentum(); // 4Mom of the Hadron-Chipolino
4819 G4QPDGCode h1QPDG=QCh.GetQPDG1(); // QPDG of the first hadron
4820 G4double h1M =h1QPDG.GetMass(); // Mass of the first hadron
4821 G4QPDGCode h2QPDG=QCh.GetQPDG2(); // QPDG of the second hadron
4822 G4double h2M =h2QPDG.GetMass(); // Mass of the second hadron
4823 G4double chM2 =ch4M.m2(); // Squared Mass of the Chipolino
4824 if( sqr(h1M+h2M) < chM2 ) // Decay is possible
4825 {
4826 G4LorentzVector h14M(0.,0.,0.,h1M);
4827 G4LorentzVector h24M(0.,0.,0.,h2M);
4828 if(!G4QHadron(ch4M).DecayIn2(h14M,h24M))
4829 {
4830 G4cerr<<"***G4QFrag::EvaporateResid: CM="<<std::sqrt(chM2)<<" -> h1="<<h1QPDG<<"("
4831 <<h1M<<") + h2="<<h1QPDG<<"("<<h2M<<") = "<<h1M+h2M<<" **Failed**"<<G4endl;
4832 // throw G4QException("*G4QFragmentation::EvaporateResidual:QChipolino DecIn2 error");
4833 G4Exception("G4QFragmentation::EvaporateResidual()", "HAD_CHPS_0000",
4834 FatalException, "QChipolino DecIn2 error");
4835 }
4836 delete qH; // Kill the primary Chipolino
4837 G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
4838 theResult->push_back(h1H); // (delete equivalent)
4839#ifdef debug
4840 G4cout<<"G4QFragm::EvaporateResidual: Chipolino -> H1="<<h1QPDG<<h14M<<G4endl;
4841#endif
4842 qH = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
4843 theResult->push_back(qH); // (delete equivalent)
4844#ifdef debug
4845 G4cout<<"G4QE::EvaporateResidual: Chipolino -> H2="<<h2QPDG<<h24M<<G4endl;
4846#endif
4847 }
4848 else
4849 {
4850 G4cerr<<"***G4QFragment::EvaporateResid: Chipolino="<<qH->GetQC()<<qH->Get4Momentum()
4851 <<", chipoM="<<std::sqrt(chM2)<<" < m1="<<h1M<<"("<<h1QPDG<<") + m2="<<h2M
4852 <<"("<<h2QPDG<<") = "<<h1M+h2M<<G4endl;
4853 // throw G4QException("G4QFragmentation::EvaporateResidual: LowMassChipolino in Input");
4854 G4Exception("G4QFragmentation::EvaporateResidual()", "HAD_CHPS_0001",
4855 FatalException, "LowMassChipolino in Input");
4856 }
4857 return;
4858 }
4859 else if(theS<0) // Antistrange nucleus
4860 {
4861#ifdef debug
4862 G4cout<<"G4QFragment::EvaRes: AntistrangeNucleus="<<thePDG<<qH->Get4Momentum()<<G4endl;
4863#endif
4864 envir.DecayAntistrange(qH, theResult); // (delete equivalent)
4865 return;
4866 }
4867 else if(theBN==1)
4868 {
4869#ifdef debug
4870 G4cout<<"G4QFragmentation::EvaporateResid:Baryon="<<thePDG<<qH->Get4Momentum()<<G4endl;
4871#endif
4872 envir.DecayBaryon(qH, theResult); // (delete equivalent)
4873 return;
4874 }
4875 else if(!theBN) // @@ In future it is usefull to add the MesonExcitationDecay (?!)
4876 {
4877#ifdef debug
4878 G4LorentzVector mesLV=qH->Get4Momentum();
4879 G4cout<<"G4QFragmentation::EvaRes:(!)Meson(!) PDG="<<thePDG<<",4M="<<mesLV<<mesLV.m()
4880 <<",QC="<<qH->GetQC()<<",MPDG="<<G4QPDGCode(thePDG).GetMass()<<G4endl;
4881#endif
4882 envir.DecayMeson(qH, theResult); // @@ To be written
4883 return;
4884 }
4885 G4int theC=theQC.GetCharge(); // P
4886#ifdef debug
4887 G4cout<<"G4QFragment::EvaRes: qH.Charge = "<<theC<<G4endl;
4888#endif
4889 if(!thePDG) thePDG = theQC.GetSPDGCode(); // If there is no PDG code, get it from QC
4890 if( thePDG == 10 && theBN > 0 ) thePDG=theQC.GetZNSPDGCode();
4891 if(theS>0) thePDG-=theS*999999; // @@ May hide hypernuclear problems (G4) ! @@
4892#ifdef debug
4893 G4cout<<"G4QFragment::EvaRes: S="<<theS<<", newPDG="<<thePDG<<G4endl;
4894#endif
4895 G4double totGSM = G4QNucleus(thePDG).GetGSMass();// TheGroundStMass of theTotalResNucleus
4896#ifdef debug
4897 G4cout<<"G4QFragment::EvaRes: totGSM="<<totGSM<<G4endl;
4898#endif
4899 if(theBN==2)
4900 {
4901 if(!theC) totGSM=dNeut; // nn, nL, LL
4902 else if(theC==2) totGSM=dProt; // pp
4903 else totGSM=mDeut; // np, Lp
4904 }
4905 else if(theBN==5)
4906 {
4907 if (theC==3) totGSM=mAlPr; // effective "Alph+p"
4908 else if(theC==2) totGSM=mAlNt; // effective "Alph+n"
4909 }
4910 else if(theBN==8) totGSM=dAlph; // effective "Be8"
4911 // @@ Should be more (else if) for bigger A=theBN
4912 G4LorentzVector q4M = qH->Get4Momentum(); // Get 4-momentum of theTotalResidNucleus
4913 G4double totMass = q4M.m(); // Get theRealMass of theTotalResidNucleus
4914#ifdef debug
4915 G4cout<<"G4QFragment::EvaRes: Excitation = "<<totMass-totGSM<<G4endl;
4916#endif
4917 if(std::fabs(totMass-totGSM) < eps)
4918 {
4919 theResult->push_back(qH); // fill As It Is
4920 }
4921 else if(totMass > totGSM)
4922 {
4923#ifdef debug
4924 G4cout<<"G4QFragment::EvaRes: try Evaporate Nucleus PDG="<<thePDG<<G4endl;
4925#endif
4926 theNucleus.EvaporateNucleus(qH, theResult);
4927#ifdef debug
4928 G4cout<<"G4QFragment::EvaRes: ** Evaporation is done **"<<G4endl;
4929#endif
4930 //delete qH;
4931 qH=0;
4932 }
4933 else // Correction must be done
4934 {
4935#ifdef debug
4936 G4cout<<"-War-G4QFr::EvaRes:*Must correct* "<<theQC<<q4M<<totMass<<"<"<<totGSM<<G4endl;
4937#endif
4938 }
4939#ifdef qdebug
4940 if (qH)
4941 {
4942 G4cout<<"-W-G4QFragmentation::EvaporateResid:*Deleted*,PDG="<<qH->GetPDGCode()<<G4endl;
4943 delete qH;
4944 }
4945#endif
4946 return;
4947} // End of EvaporateResidual
G4int GetCharge() const
Definition: G4QContent.cc:1159
G4int GetStrangeness() const
Definition: G4QContent.hh:184
G4int GetZNSPDGCode() const
Definition: G4QContent.hh:217
void EvaporateNucleus(G4QHadron *hA, G4QHadronVector *oHV)
Definition: G4QNucleus.cc:4171
G4double GetNuclMass(G4int Z, G4int N, G4int S)
Definition: G4QPDGCode.cc:766

Referenced by Fragment().

◆ ExciteDiffParticipants()

G4bool G4QFragmentation::ExciteDiffParticipants ( G4QHadron aPartner,
G4QHadron bPartner 
) const
protected

Definition at line 4068 of file G4QFragmentation.cc.

4070{
4071 G4LorentzVector Pprojectile=projectile->Get4Momentum();
4072 G4double Mprojectile=projectile->GetMass();
4073 G4double Mprojectile2=Mprojectile*Mprojectile;
4074 G4LorentzVector Ptarget=target->Get4Momentum();
4075 G4double Mtarget=target->GetMass();
4076 G4double Mtarget2=Mtarget*Mtarget;
4077#ifdef debug
4078 G4cout<<"G4QFragm::ExciteDiffPartici:Ep="<<Pprojectile.e()<<",Et="<<Ptarget.e()<<G4endl;
4079#endif
4080 // Transform momenta to cms and then rotate parallel to z axis;
4081 G4LorentzVector Psum=Pprojectile+Ptarget;
4082 G4LorentzRotation toCms(-Psum.boostVector()); // Boost Rotation to CMS
4083 G4LorentzVector Ptmp=toCms*Pprojectile;
4084 if(Ptmp.pz()<=0.) // "String" moving backwards in CMS, abort collision !! ? M.K.
4085 {
4086#ifdef debug
4087 G4cout<<"G4QFragmentation::ExciteDiffParticipants: *1* abort Collision!! *1*"<<G4endl;
4088#endif
4089 return false;
4090 }
4091 toCms.rotateZ(-Ptmp.phi());
4092 toCms.rotateY(-Ptmp.theta());
4093#ifdef debug
4094 G4cout<<"G4QFragment::ExciteDiffParticipantts:BeforBoost Pproj="<<Pprojectile<<", Ptarg="
4095 <<Ptarget<<G4endl;
4096#endif
4097 G4LorentzRotation toLab(toCms.inverse()); // Boost Rotation to LabSys (LS)
4098 Pprojectile.transform(toCms);
4099 Ptarget.transform(toCms);
4100#ifdef debug
4101 G4cout<< "G4QFragment::ExciteDiffParticipantts: AfterBoost Pproj="<<Pprojectile<<"Ptarg="
4102 <<Ptarget<<", cms4M="<<Pprojectile+Ptarget<<G4endl;
4103 G4cout<<"G4QFragment::ExciteDiffParticipants: ProjX+="<<Pprojectile.plus()<<", ProjX-="
4104 <<Pprojectile.minus()<<", TargX+="<< Ptarget.plus()<<", TargX-="<<Ptarget.minus()
4105 <<G4endl;
4106#endif
4107 G4LorentzVector Qmomentum(0.,0.,0.,0.);
4108 G4int whilecount=0;
4109#ifdef debug
4110 G4cout<<"G4QFragmentation::ExciteDiffParticipants: Before DO"<<G4endl;
4111#endif
4112 do
4113 {
4114 // Generate pt
4115 G4double maxPtSquare=sqr(Ptarget.pz());
4116#ifdef debug
4117 G4cout<<"G4QFragmentation::ExciteDiffParticipants: maxPtSq="<<maxPtSquare<<G4endl;
4118 if(whilecount++>=500 && whilecount%100==0) // @@ M.K. Hardwired limits
4119 G4cout<<"G4QFragmentation::ExciteDiffParticipantts: can loop, loopCount="<<whilecount
4120 <<", maxPtSquare="<<maxPtSquare<<G4endl;
4121#endif
4122 if(whilecount>1000) // @@ M.K. Hardwired limits
4123 {
4124#ifdef debug
4125 G4cout<<"G4QFragmentation::ExciteDiffParticipants: *2* abort Loop!! *2*"<<G4endl;
4126#endif
4127 return false; // Ignore this interaction
4128 }
4129 Qmomentum=G4LorentzVector(GaussianPt(widthOfPtSquare,maxPtSquare),0);
4130#ifdef debug
4131 G4cout<<"G4QFragment::ExciteDiffParticipants: generated Pt="<<Qmomentum<<", ProjPt="
4132 <<Pprojectile+Qmomentum<<", TargPt="<<Ptarget-Qmomentum<<G4endl;
4133#endif
4134 // Momentum transfer
4135 G4double Xmin=0.;
4136 G4double Xmax=1.;
4137 G4double Xplus =ChooseX(Xmin,Xmax);
4138 G4double Xminus=ChooseX(Xmin,Xmax);
4139#ifdef debug
4140 G4cout<<"G4QFragment::ExciteDiffParticip: X-plus="<<Xplus<<",X-minus="<<Xminus<<G4endl;
4141#endif
4142 G4double pt2=Qmomentum.vect().mag2();
4143 G4double Qplus =-pt2/Xminus/Ptarget.minus();
4144 G4double Qminus= pt2/Xplus /Pprojectile.plus();
4145 Qmomentum.setPz((Qplus-Qminus)/2);
4146 Qmomentum.setE( (Qplus+Qminus)/2);
4147#ifdef debug
4148 G4cout<<"G4QFragment::ExciteDiffParticip: Qplus="<<Qplus<<", Qminus="<<Qminus<<", pt2="
4149 <<pt2<<", Qmomentum="<<Qmomentum<<", ProjM="<<(Pprojectile+Qmomentum).mag()
4150 <<", TargM="<<(Ptarget-Qmomentum).mag()<<G4endl;
4151#endif
4152 } while((Pprojectile+Qmomentum).mag2()<=Mprojectile2 ||
4153 (Ptarget-Qmomentum).mag2()<=Mtarget2);
4154 Pprojectile += Qmomentum;
4155 Ptarget -= Qmomentum;
4156#ifdef debug
4157 G4cout<<"G4QFragment::ExciteDiffParticipan: Proj(Q)="<<Pprojectile<<", Targ(Q)="<<Ptarget
4158 <<", Proj(back)="<<toLab*Pprojectile<<", Targ(bac)="<< toLab*Ptarget << G4endl;
4159#endif
4160 // Transform back and update SplitableHadron Participant.
4161 Pprojectile.transform(toLab);
4162 Ptarget.transform(toLab);
4163#ifdef debug
4164 G4cout<< "G4QFragmentation::ExciteDiffParticipants: TargetMass="<<Ptarget.mag()<<G4endl;
4165#endif
4166 target->Set4Momentum(Ptarget);
4167#ifdef debug
4168 G4cout<<"G4QFragment::ExciteDiffParticipants:ProjectileMass="<<Pprojectile.mag()<<G4endl;
4169#endif
4170 projectile->Set4Momentum(Pprojectile);
4171 return true;
4172} // End of ExciteDiffParticipants
CLHEP::HepLorentzVector G4LorentzVector
Hep3Vector boostVector() const
G4double ChooseX(G4double Xmin, G4double Xmax) const
G4ThreeVector GaussianPt(G4double widthSquare, G4double maxPtSquare) const

Referenced by G4QFragmentation().

◆ ExciteSingDiffParticipants()

G4bool G4QFragmentation::ExciteSingDiffParticipants ( G4QHadron aPartner,
G4QHadron bPartner 
) const
protected

Definition at line 4176 of file G4QFragmentation.cc.

4178{
4179 G4LorentzVector Pprojectile=projectile->Get4Momentum();
4180 G4double Mprojectile=projectile->GetMass();
4181 G4double Mprojectile2=Mprojectile*Mprojectile;
4182 G4LorentzVector Ptarget=target->Get4Momentum();
4183 G4double Mtarget=target->GetMass();
4184 G4double Mtarget2=Mtarget*Mtarget;
4185#ifdef debug
4186 G4cout<<"G4QFragm::ExSingDiffPartici:Ep="<<Pprojectile.e()<<",Et="<<Ptarget.e()<<G4endl;
4187#endif
4188 G4bool KeepProjectile= G4UniformRand() > 0.5;
4189 // Reset minMass of the non diffractive particle to its value, (minus for rounding...)
4190 if(KeepProjectile )
4191 {
4192#ifdef debug
4193 G4cout<<"--1/2--G4QFragmentation::ExSingDiffParticipants: Projectile is fixed"<<G4endl;
4194#endif
4195 Mprojectile2 = projectile->GetMass2()*(1.-perCent); // Isn't it too big reduction? M.K.
4196 }
4197 else
4198 {
4199#ifdef debug
4200 G4cout<<"---1/2---G4QFragmentation::ExSingDiffParticipants: Target is fixed"<<G4endl;
4201#endif
4202 Mtarget2 = target->GetMass2()*(1.-perCent); // @@ Isn't it too big reduction? M.K.
4203 }
4204 // @@ From this point it repeats the Diffractional excitation (? Use flag ?)
4205 // Transform momenta to cms and then rotate parallel to z axis;
4206 G4LorentzVector Psum=Pprojectile+Ptarget;
4207 G4LorentzRotation toCms(-Psum.boostVector()); // Boost Rotation to CMS
4208 G4LorentzVector Ptmp=toCms*Pprojectile;
4209 if(Ptmp.pz()<=0.) // "String" moving backwards in CMS, abort collision !! ? M.K.
4210 {
4211#ifdef debug
4212 G4cout<<"G4QFragment::ExciteSingDiffParticipants: *1* abort Collision!! *1*"<<G4endl;
4213#endif
4214 return false;
4215 }
4216 toCms.rotateZ(-Ptmp.phi());
4217 toCms.rotateY(-Ptmp.theta());
4218#ifdef debug
4219 G4cout<<"G4QFragm::ExciteSingDiffParticipantts: Be4Boost Pproj="<<Pprojectile<<",Ptarg="
4220 <<Ptarget<<G4endl;
4221#endif
4222 G4LorentzRotation toLab(toCms.inverse()); // Boost Rotation to LabSys (LS)
4223 Pprojectile.transform(toCms);
4224 Ptarget.transform(toCms);
4225#ifdef debug
4226 G4cout<< "G4QFragment::ExciteDiffParticipantts: AfterBoost Pproj="<<Pprojectile<<"Ptarg="
4227 <<Ptarget<<", cms4M="<<Pprojectile+Ptarget<<G4endl;
4228
4229 G4cout<<"G4QFragment::ExciteDiffParticipantts: ProjX+="<<Pprojectile.plus()<<", ProjX-="
4230 <<Pprojectile.minus()<<", TargX+="<< Ptarget.plus()<<", TargX-="<<Ptarget.minus()
4231 <<G4endl;
4232#endif
4233 G4LorentzVector Qmomentum(0.,0.,0.,0.);
4234 G4int whilecount=0;
4235 do
4236 {
4237 // Generate pt
4238 G4double maxPtSquare=sqr(Ptarget.pz());
4239 if(whilecount++>=500 && whilecount%100==0) // @@ M.K. Hardwired limits
4240#ifdef debug
4241 G4cout<<"G4QFragment::ExciteSingDiffParticipantts: can loop, loopCount="<<whilecount
4242 <<", maxPtSquare="<<maxPtSquare<<G4endl;
4243#endif
4244 if(whilecount>1000) // @@ M.K. Hardwired limits
4245 {
4246#ifdef debug
4247 G4cout<<"G4QFragmentation::ExciteSingDiffParticipants: *2* abort Loop!! *2*"<<G4endl;
4248#endif
4249 return false; // Ignore this interaction
4250 }
4251 Qmomentum=G4LorentzVector(GaussianPt(widthOfPtSquare,maxPtSquare),0);
4252#ifdef debug
4253 G4cout<<"G4QFragm::ExciteSingDiffParticipants: generated Pt="<<Qmomentum<<", ProjPt="
4254 <<Pprojectile+Qmomentum<<", TargPt="<<Ptarget-Qmomentum<<G4endl;
4255#endif
4256 // Momentum transfer
4257 G4double Xmin=0.;
4258 G4double Xmax=1.;
4259 G4double Xplus =ChooseX(Xmin,Xmax);
4260 G4double Xminus=ChooseX(Xmin,Xmax);
4261#ifdef debug
4262 G4cout<<"G4QFragm::ExciteSingDiffPartici:X-plus="<<Xplus<<",X-minus="<<Xminus<<G4endl;
4263#endif
4264 G4double pt2=G4ThreeVector(Qmomentum.vect()).mag2();
4265 G4double Qplus =-pt2/Xminus/Ptarget.minus();
4266 G4double Qminus= pt2/Xplus /Pprojectile.plus();
4267 if (KeepProjectile)
4268 Qminus=(projectile->GetMass2()+pt2)/(Pprojectile.plus()+Qplus) - Pprojectile.minus();
4269 else Qplus=Ptarget.plus() - (target->GetMass2()+pt2)/(Ptarget.minus()-Qminus);
4270 Qmomentum.setPz((Qplus-Qminus)/2);
4271 Qmomentum.setE( (Qplus+Qminus)/2);
4272#ifdef debug
4273 G4cout<<"G4QFragm::ExciteDiffParticip: Qplus="<<Qplus<<", Qminus="<<Qminus<<", pt2="
4274 <<pt2<<", Qmomentum="<<Qmomentum<<", ProjM="<<(Pprojectile+Qmomentum).mag()
4275 <<", TargM="<<(Ptarget-Qmomentum).mag()<<G4endl;
4276#endif
4277 // while is different from the Double Diffractive Excitation (@@ !)
4278 //} while((Pprojectile+Qmomentum).mag2()<= Mprojectile2 ||
4279 // (Ptarget-Qmomentum).mag2()<=Mtarget2);
4280 } while((Ptarget-Qmomentum).mag2()<=Mtarget2 ||
4281 (Pprojectile+Qmomentum).mag2()<=Mprojectile2 ||
4282 (Ptarget-Qmomentum).e() < 0. || (Pprojectile+Qmomentum).e() < 0.);
4283 Pprojectile += Qmomentum;
4284 Ptarget -= Qmomentum;
4285#ifdef debug
4286 G4cout<<"G4QFragmentation::ExciteSingDiffParticipan: Proj(Q)="<<Pprojectile<<"(E="
4287 <<Pprojectile.e()<<"), Targ(Q)="<<Ptarget<<"(E="<<Ptarget.e()
4288 <<"), Proj(back)="<<toLab*Pprojectile<<", Targ(bac)="<< toLab*Ptarget << G4endl;
4289#endif
4290 // Transform back and update SplitableHadron Participant.
4291 Pprojectile.transform(toLab);
4292 Ptarget.transform(toLab);
4293#ifdef debug
4294 G4cout<< "G4QFragm::ExciteSingleDiffParticipants: TargetMass="<<Ptarget.mag()<<G4endl;
4295#endif
4296 target->Set4Momentum(Ptarget);
4297#ifdef debug
4298 G4cout<<"G4QFragm::ExciteSingleParticipants:ProjectileMass="<<Pprojectile.mag()<<G4endl;
4299#endif
4300 projectile->Set4Momentum(Pprojectile);
4301 return true;
4302} // End of ExciteSingleDiffParticipants
CLHEP::Hep3Vector G4ThreeVector
double mag2() const

Referenced by G4QFragmentation().

◆ Fragment()

G4QHadronVector * G4QFragmentation::Fragment ( )

!When kill,DON'T forget to delete theLastQHadron as an instance!!

Definition at line 1764 of file G4QFragmentation.cc.

1765{ // This is the member function fragmenting Strings & Quasmons (in nuclear matter)
1766 static const G4QPDGCode nQPDG(2112);
1767 static const G4double mProt = G4QPDGCode(2212).GetMass(); // Mass of proton
1768 static const G4double mNeut = G4QPDGCode(2112).GetMass(); // Mass of neutron
1769 static const G4double mPiCh = G4QPDGCode(211).GetMass(); // Mass of chgdPion
1770 static const G4double mPiZr = G4QPDGCode(111).GetMass(); // Mass of neutrPion
1771 //static const G4double mHe3 = G4QPDGCode(2112).GetNuclMass(2,1,0);
1772 static const G4LorentzVector nul4M(0.,0.,0.,0.); // Zero (vacuum) 4M
1773 //static const G4double eps=0.003;
1774#ifdef debug
1775 G4cout<<"*******>G4QFragmentation::Fragment: ***Called***, Res="<<theResult<<G4endl;
1776#endif
1777 G4int striNum=strings.size(); // Find out if there're strings
1778 G4int hadrNum=theResult->size(); // Find out if there're hadrons
1779#ifdef edebug
1780 G4int nQm=theQuasmons.size();
1781 G4LorentzVector totLS4M=theNucleus.Get4Momentum(); // Nucleus 4Mom in LS
1782 G4int totChg=theNucleus.GetZ();
1783 G4int totBaN=theNucleus.GetA();
1784 G4cout<<"-EMCLS-G4QF::Fragment: CHECKRecovery, #ofS="<<striNum<<", #Nuc4M(E=M)="<<totLS4M
1785 <<",#Q="<<nQm<<",#H="<<hadrNum<<G4endl;
1786 for(G4int i=0; i < striNum; i++)
1787 {
1788 G4LorentzVector strI4M=strings[i]->Get4Momentum();
1789 totLS4M+=strI4M;
1790 G4int sChg=strings[i]->GetCharge();
1791 totChg+=sChg;
1792 G4int sBaN=strings[i]->GetBaryonNumber();
1793 totBaN+=sBaN;
1794 G4cout<<"-EMCLS-G4QFragm::Fragment: String#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
1795 <<", C="<<sChg<<", B="<<sBaN<<G4endl;
1796 }
1797 for(G4int i=0; i < nQm; i++)
1798 {
1799 G4LorentzVector hI4M=theQuasmons[i]->Get4Momentum();
1800 totLS4M+=hI4M;
1801 G4int hChg=theQuasmons[i]->GetCharge();
1802 totChg+=hChg;
1803 G4int hBaN=theQuasmons[i]->GetBaryonNumber();
1804 totBaN+=hBaN;
1805 G4cout<<"-EMCLS-G4QFragmentation::Fragment: Quasmon#"<<i<<", 4M="<<hI4M<<", C="<<hChg
1806 <<", B="<<hBaN<<G4endl;
1807 }
1808 for(G4int i=0; i < hadrNum; i++)
1809 {
1810 G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
1811 totLS4M+=hI4M;
1812 G4int hChg=(*theResult)[i]->GetCharge();
1813 totChg+=hChg;
1814 G4int hBaN=(*theResult)[i]->GetBaryonNumber();
1815 totBaN+=hBaN;
1816 G4cout<<"-EMCLS-G4QFr::Fragment:H#"<<i<<",4M="<<hI4M<<",C="<<hChg<<",B="<<hBaN<<G4endl;
1817 }
1818#endif
1819#ifdef debug
1820 G4cout<<"***>G4QFragmentation::Fragment: #OfStr="<<striNum<<", #OfRes="<<hadrNum<<G4endl;
1821#endif
1822 if(!striNum && hadrNum) // Quasi-elastic or decoupled p
1823 {
1824#ifdef debug
1825 G4cout<<"***>G4QFragmentation::Fragment:**Quasi-Elastic**,#OfResult="<<hadrNum<<G4endl;
1826#endif
1827 return theResult;
1828 }
1829 else if(striNum) Breeder(); // Strings fragmentation
1830 else // No strings, make HadrNucleus
1831 {
1832 if(hadrNum)
1833 {
1834 for(G4int ih=0; ih<hadrNum; ih++) delete (*theResult)[ih];
1835 theResult->clear();
1836 }
1837 G4LorentzVector r4M=theNucleus.Get4Momentum(); // Nucleus 4-momentum in LS
1838 G4int rPDG=theNucleus.GetPDG(); // Nuclear PDG
1839 G4QHadron* resNuc = new G4QHadron(rPDG,r4M); // Nucleus -> Hadron
1840 theResult->push_back(resNuc); // Fill the residual nucleus
1841 }
1842 G4int nQuas=theQuasmons.size(); // Size of the Quasmon OUTPUT
1843 G4int theRS=theResult->size(); // Size of Hadron Output by now
1844#ifdef debug
1845 G4cout<<"***>G4QFragmentation::Fragment:beforeEnv,#OfQ="<<nQuas<<",#OfR="<<theRS<<G4endl;
1846#endif
1847 if(nQuas && theRS)
1848 {
1849 G4QHadron* resNuc = (*theResult)[theRS-1]; // Pointer to Residual Nucleus
1850 G4LorentzVector resNuc4M = resNuc->Get4Momentum(); // 4-Momentum of the Nucleuz
1851 G4int resNucPDG= resNuc->GetPDGCode(); // PDG Code of the Nucleus
1852 if(resNucPDG==90000000 || resNuc4M.m2()<800000.) // m_N^2 = 880000 MeV^2
1853 {
1854 resNuc4M=G4LorentzVector(0.,0.,0.,0.);
1855 if(resNucPDG == 90000000) resNuc->Set4Momentum(resNuc4M);
1856 }
1857#ifdef edebug
1858 G4int rnChg=resNuc->GetCharge();
1859 G4int rnBaN=resNuc->GetBaryonNumber();
1860#endif
1861 G4QNucleus theEnv(resNucPDG); // NucleusHadron->NucleusAtRest
1862 delete resNuc; // Delete resNucleus as aHadron
1863 theResult->pop_back(); // Exclude the nucleus from HV
1864 --theRS; // Reduce the OUTPUT by theNucl
1865#ifdef debug
1866 G4cout<<"G4QFragmentation::Fragment:#OfRemainingHadron="<<theRS<<",A="<<theEnv<<G4endl;
1867#endif
1868 // Now we need to be sure that the compound nucleus is heavier than the Ground State
1869 for(G4int j=theRS-1; j>-2; --j) // try to reach M_compound>M_GS
1870 {
1871 G4LorentzVector qsum4M=resNuc4M; // Proto compound 4-momentum
1872 G4QContent qsumQC=theEnv.GetQCZNS(); // Proto compound Quark Content
1873#ifdef debug
1874 G4cout<<"G4QFragmentation::Fragm:rN4M"<<qsum4M<<qsum4M.m()<<",rNQC="<<qsumQC<<G4endl;
1875#endif
1876 G4Quasmon* firstQ=0; // Prototype of theFirstQuasmon
1877 G4LorentzVector first4M; // Proto of the FirstQuasmon 4M
1878 G4QContent firstQC; // Proto of the FirstQuasmon QC
1879 for(G4int i=0; i<nQuas; ++i) // LOOP over Quasmons
1880 {
1881 G4Quasmon* curQuasm=theQuasmons[i]; // current Quasmon
1882 G4LorentzVector cur4M=curQuasm->Get4Momentum(); // 4-Mom of the Quasmon
1883 G4QContent curQC=curQuasm->GetQC(); // Quark Content of the Quasmon
1884 qsum4M+=cur4M; // Add quasmon's 4-momentum
1885 qsumQC+=curQC; // Add quasmon's Quark Content
1886#ifdef debug
1887 G4cout<<"G4QFr::Fr:Q#"<<i<<",Q4M="<<cur4M<<",QQC="<<curQC<<",sQC="<<qsumQC<<G4endl;
1888#endif
1889 if(!i) // Remember 1-st for correction
1890 {
1891 firstQ =curQuasm;
1892 first4M=cur4M;
1893 firstQC=curQC;
1894 }
1895 }
1896 G4int miPDG=qsumQC.GetSPDGCode(); // PDG of minM of hadron/fragm.
1897 G4double gsM=0.; // Proto minM of had/frag forQC
1898#ifdef debug
1899 G4cout<<"G4QFragmentation::Fragment: QC="<<qsumQC<<",PDG="<<miPDG<<G4endl;
1900#endif
1901 if(miPDG == 10)
1902 {
1903 G4QChipolino QCh(qsumQC); // define TotNuc as a Chipolino
1904 gsM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass(); // Sum of Hadron Masses
1905 //gsM=theWorld->GetQParticle(QCh.GetQPDG1())->MinMassOfFragm() +
1906 // theWorld->GetQParticle(QCh.GetQPDG2())->MinMassOfFragm();
1907 }
1908 // @@ it is not clear, why it does not work ?!
1909 //else if(miPDG>80000000) // Compound Nucleus
1910 //{
1911 // G4QNucleus rtN(qsumQC); // CreatePseudoNucl for totComp
1912 // gsM=rtN.GetGSMass(); // MinMass of residQ+(Env-ParC)
1913 //}
1914 else if(miPDG < 80000000 && std::abs(miPDG)%10 > 2)
1915 gsM=theWorld->GetQParticle(G4QPDGCode(miPDG))->MinMassOfFragm();
1916 else gsM=G4QPDGCode(miPDG).GetMass(); // minM of hadron/fragm. for QC
1917 G4double reM=qsum4M.m(); // real mass of the compound
1918#ifdef debug
1919 G4cout<<"G4QFragmentation::Fragment: PDG="<<miPDG<<",rM="<<reM<<",GSM="<<gsM<<G4endl;
1920#endif
1921 if(reM > gsM) break; // CHIPS can be called
1922 if(j > -1) // Can try to add hadrons to Q0
1923 {
1924 G4QHadron* cH = (*theResult)[j]; // Pointer to the last Hadron
1925 G4LorentzVector h4M = cH->Get4Momentum(); // 4-Momentum of the Hadron
1926 G4QContent hQC = cH->GetQC(); // QC of the Hadron
1927 firstQ->Set4Momentum(first4M+h4M); // Update the Quasmon's 4-Mom
1928 firstQ->SetQC(firstQC+hQC); // Update the Quasmon's QCont
1929 delete cH; // Delete the Hadron
1930 theResult->pop_back(); // Exclude the hadron from HV
1931#ifdef debug
1932 G4cout<<"G4QFragm::Fragm: H#"<<j<<",hQC="<<hQC<<",hPDG="<<cH->GetPDGCode()<<G4endl;
1933#endif
1934 }
1935 else
1936 {
1937 G4cerr<<"*G4QFr::Fr:PDG="<<miPDG<<",M="<<reM<<",GSM="<<gsM<<",QC="<<qsumQC<<G4endl;
1938 G4Exception("G4QFragmentation::Fragment:","27",FatalException,"Can't recover GSM");
1939 }
1940 }
1941 G4double nucE=resNuc4M.e(); // Total energy of the nuclEnv
1942 if(nucE < 1.E-12) nucE=0.; // Computer accuracy safety
1943 else if(resNucPDG==22 && nQuas==1) // NuclEnv for nQ=1 is a photon
1944 {
1945 G4Quasmon* aQuasm=theQuasmons[0]; // the only Quasmon
1946 aQuasm->Set4Momentum(aQuasm->Get4Momentum()+resNuc4M);// add the gammaEnv to the Q
1947 nucE=0.;
1948 }
1949 G4ThreeVector nucVel(0.,0.,0.); // Proto of the NucleusVelocity
1950 G4QHadronVector* output=0; // NucleusFragmentation Hadrons
1951 G4QEnvironment* pan= new G4QEnvironment(theEnv); // ---> DELETED --->----------+
1952#ifdef debug
1953 G4cout<<"G4QFragm::Fragm: nucE="<<nucE<<",nQ="<<nQuas<<G4endl; // |
1954#endif
1955 if(nucE) nucVel=resNuc4M.vect()/nucE; // The NucleusVelocity |
1956#ifdef edebug
1957 G4LorentzVector sq4M=resNuc4M-totLS4M; // 4-mom deficit |
1958 G4int sqCg=rnChg-totChg; // Charge deficit |
1959 G4int sqBN=rnBaN-totBaN; // Baryon number deficit |
1960#endif
1961 for(G4int i=0; i<nQuas; ++i) // LOOP over Quasmons |
1962 { // |
1963 G4Quasmon* curQuasm=theQuasmons[i]; // current Quasmon |
1964#ifdef debug
1965 if(nucE) G4cout<<"G4QFr::Fr:V="<<nucVel<<",Q="<<curQuasm->Get4Momentum()<<",R=" // |
1966 <<resNuc4M<<resNucPDG<<G4endl; // |
1967#endif
1968 if(nucE) curQuasm->Boost(-nucVel); // Boost it to CMS of Nucleus |
1969 pan->AddQuasmon(curQuasm); // Fill the predefined Quasmon|
1970#ifdef edebug
1971 G4LorentzVector cQ4M=curQuasm->Get4Momentum(); // Just for printing |
1972 G4cout<<"G4QFragmentation::Fragment: Quasmon# "<<i<<" added, 4M="<<cQ4M<<G4endl; // |
1973 sq4M+=cQ4M; // Sum up total 4Mom |
1974 sqCg+=curQuasm->GetCharge(); // Sum up the Charge |
1975 sqBN+=curQuasm->GetBaryonNumber(); // Sum up the baryon number |
1976#endif
1977 } // |
1978#ifdef edebug
1979 G4cout<<"-EMCLS-G4QFrag::Fragm: r4M="<<sq4M<<", rC="<<sqCg<<", rB="<<sqBN<<G4endl; // |
1980#endif
1981 try // |
1982 { // |
1983#ifdef debug
1984 G4cout<<"G4QFrag::Fragm: *** Before Del Output ***"<<G4endl; // |
1985#endif
1986 delete output; // |
1987#ifdef debug
1988 G4cout<<"G4QFrag::Fragm: *** After Del Output ***"<<G4endl; // |
1989#endif
1990 output = pan->Fragment();// DESTROYED after theHadrons are transferred to theResult |
1991 } // | |
1992 catch (G4QException& error) // | |
1993 { // | |
1994 G4cerr<<"***G4QFragmentation::Fragment: G4QE Exception is catched"<<G4endl; // | |
1995 // G4Exception("G4QFragmentation::Fragment:","27",FatalException,"CHIPSCrash");// | |
1996 G4Exception("G4QFragmentation::Fragment()", "HAD_CHPS_0027",
1997 FatalException, "CHIPSCrash");
1998 } // | |
1999#ifdef debug
2000 G4cout<<"G4QFrag::Fragm: *** Before Del Pan ***"<<G4endl; // | |
2001#endif
2002 delete pan; // Delete the Nuclear Environment <-----<--+-*
2003#ifdef debug
2004 G4cout<<"G4QFrag::Fragm: *** After Del Pan ***"<<G4endl; // |
2005#endif
2006 if(output) // Output exists |
2007 { // |
2008 G4int nOut=output->size(); // #ofHadrons in the Nuclear Fragmentation |
2009 for(G4int j=0; j<nOut; j++) // LOOP over Hadrons transferring to LS |
2010 { // |
2011 G4QHadron* curHadr=(*output)[j]; // Hadron from the nucleus fragmentation |
2012 if(nucE) curHadr->Boost(nucVel); // Boost it back to Laboratory System |
2013 G4int hPDG=curHadr->GetPDGCode(); // PDGC of the hadron |
2014 G4LorentzVector h4M=curHadr->Get4Momentum(); // 4-mom of the hadron |
2015 if((hPDG!=90000000 && hPDG!=22) || h4M!=nul4M) theResult->push_back(curHadr); //|
2016 else delete curHadr; // delete zero-photons |
2017 } // |
2018 delete output; // Delete the OUTPUT <-----<-----<-----<---+
2019 }
2020 }
2021 else if(!striNum) G4cout<<"-Warning-G4QFragmentation::Fragment:Nothing was done"<<G4endl;
2022#ifdef debug
2023 G4cout<<"=--=>G4QFragmentation::Fragment: Final #OfResult="<<theResult->size()<<G4endl;
2024#endif
2025 G4int nQ =theQuasmons.size();
2026 if(nQ) theQuasmons.clear(); // @@ Not necesary ?
2027 G4int nHd=theResult->size();
2028#ifdef edebug
2029 G4LorentzVector f4M(0.,0.,0.,0.); // Sum of the Result in LS
2030 G4int fCh=totChg;
2031 G4int fBN=totBaN;
2032 G4cout<<"-EMCLS-G4QFragmentation::Fragment: #ofHadr="<<nHd<<", #OfQuasm="<<nQ<<G4endl;
2033 for(G4int i=0; i<nHd; i++)
2034 {
2035 G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
2036 f4M+=hI4M;
2037 G4int hChg=(*theResult)[i]->GetCharge();
2038 fCh-=hChg;
2039 G4int hBaN=(*theResult)[i]->GetBaryonNumber();
2040 fBN-=hBaN;
2041 G4cout<<"-EMCLS-G4QFragmentation::Fragment: Hadron#"<<i<<", 4M="<<hI4M<<", PDG="
2042 <<(*theResult)[i]->GetPDGCode()<<", C="<<hChg<<", B="<<hBaN<<G4endl;
2043 }
2044 G4cout<<"-EMCLS-G4QFrag::Fragm: r4M="<<f4M-totLS4M<<", rC="<<fCh<<", rB="<<fBN<<G4endl;
2045#endif
2046 //G4QHadron* resNuc = theResult->back(); // Pointer to the Residual Nucleus
2047 G4QHadron* resNuc = (*theResult)[nHd-1]; // Pointer to the Residual Nucleus
2048 G4int rnBn = resNuc->GetBaryonNumber();
2049 G4int rnCg = resNuc->GetCharge();
2050 if(rnBn==1 && (rnCg==-2 || rnCg==3 || rnCg==-1 || rnCg==2)) // E/Delta decay
2051 {
2052 G4LorentzVector tot4M=resNuc->Get4Momentum(); // 4-mom to be split
2053 G4int nPDG=2212; // Proton as a default
2054 G4int mPDG=211; // PiPlus as a default
2055 G4double nM=mProt; // Proton mass as a default
2056 if(rnCg<0)
2057 {
2058 nPDG=2112;
2059 mPDG=-211;
2060 nM=mNeut;
2061 }
2062 G4LorentzVector m14M(0.,0.,0.,mPiCh);
2063 G4LorentzVector n4M(0.,0.,0.,nM);
2064 if(rnCg==-2 || rnCg==3) // Decay In 3
2065 {
2066 G4LorentzVector m24M(0.,0.,0.,mPiCh);
2067 if(!G4QHadron(tot4M).DecayIn3(m14M,m24M,n4M))
2068 {
2069 G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> m1="<<mPiCh<<" + m2="<<mPiCh
2070 <<" + nM="<<nM<<" = "<<2*mPiCh+nM<<G4endl;
2071 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecayIn3");
2072 }
2073 theResult->pop_back();
2074 delete resNuc;
2075 G4QHadron* m1H = new G4QHadron(mPDG,m14M);
2076 theResult->push_back(m1H);
2077#ifdef debug
2078 G4cout<<"G4QFragment::Fragment:DecayIn3, M1="<<mPDG<<m14M<<G4endl;
2079#endif
2080 G4QHadron* m2H = new G4QHadron(mPDG,m24M);
2081 theResult->push_back(m2H);
2082#ifdef debug
2083 G4cout<<"G4QFragment::Fragment:DecayIn3, M2="<<mPDG<<m24M<<G4endl;
2084#endif
2085 G4QHadron* nH = new G4QHadron(nPDG,n4M);
2086 theResult->push_back(nH);
2087#ifdef debug
2088 G4cout<<"G4QFragment::Fragment:DecayIn3, Nucleon="<<nPDG<<n4M<<G4endl;
2089#endif
2090 }
2091 else // Decay in 2
2092 {
2093 if(!G4QHadron(tot4M).DecayIn2(m14M,n4M))
2094 {
2095 G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> m1="<<mPiCh
2096 <<" + nM="<<nM<<" = "<<mPiCh+nM<<G4endl;
2097 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecayIn2");
2098 }
2099 theResult->pop_back();
2100 delete resNuc;
2101 G4QHadron* m1H = new G4QHadron(mPDG,m14M);
2102 theResult->push_back(m1H);
2103#ifdef debug
2104 G4cout<<"G4QFragment::Fragment:DecayIn2, M1="<<mPDG<<m14M<<G4endl;
2105#endif
2106 G4QHadron* nH = new G4QHadron(nPDG,n4M);
2107 theResult->push_back(nH);
2108#ifdef debug
2109 G4cout<<"G4QFragment::Fragment:DecayIn2, Nucleon="<<nPDG<<n4M<<G4endl;
2110#endif
2111 }
2112 }
2113 if(rnBn==2) // Di-baryon
2114 {
2115 if(!rnCg) // Di-neutron pair
2116 {
2117 G4LorentzVector tot4M=resNuc->Get4Momentum(); // 4-mom to be split
2118 G4LorentzVector n14M(0.,0.,0.,mNeut);
2119 G4LorentzVector n24M(0.,0.,0.,mNeut);
2120 if(!G4QHadron(tot4M).DecayIn2(n14M,n24M))
2121 {
2122 G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> n*2="<<2*mNeut<<G4endl;
2123 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecay-2n");
2124 }
2125 theResult->pop_back();
2126 delete resNuc;
2127 G4QHadron* n1H = new G4QHadron(2112,n14M);
2128 theResult->push_back(n1H);
2129#ifdef debug
2130 G4cout<<"G4QFragment::Fragment:DecayIn2, Neutron1="<<n14M<<G4endl;
2131#endif
2132 G4QHadron* n2H = new G4QHadron(2112,n24M);
2133 theResult->push_back(n2H);
2134#ifdef debug
2135 G4cout<<"G4QFragment::Fragment:DecayIn2, Neutron2="<<n24M<<G4endl;
2136#endif
2137 }
2138 else if(rnCg==2) // Di-proton pair
2139 {
2140 G4LorentzVector tot4M=resNuc->Get4Momentum(); // 4-mom to be split
2141 G4LorentzVector n14M(0.,0.,0.,mProt);
2142 G4LorentzVector n24M(0.,0.,0.,mProt);
2143 if(!G4QHadron(tot4M).DecayIn2(n14M,n24M))
2144 {
2145 G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> n*2="<<2*mProt<<G4endl;
2146 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecay-2p");
2147 }
2148 theResult->pop_back();
2149 delete resNuc;
2150 G4QHadron* n1H = new G4QHadron(2212,n14M);
2151 theResult->push_back(n1H);
2152#ifdef debug
2153 G4cout<<"G4QFragment::Fragment:DecayIn2, Proton1="<<n14M<<G4endl;
2154#endif
2155 G4QHadron* n2H = new G4QHadron(2212,n24M);
2156 theResult->push_back(n2H);
2157#ifdef debug
2158 G4cout<<"G4QFragment::Fragment:DecayIn2, Proton2="<<n24M<<G4endl;
2159#endif
2160 }
2161 } // End of the residual dibaryon decay
2162 // Now we should check and correct the final state dibaryons (NN-pairs) and 90000000->22
2163 nHd=theResult->size();
2164 G4int maxChg=0; // max Charge of the hadron found
2165#ifdef debug
2166 G4int maxBN=0; // max Baryon Number of the hadron found
2167#endif
2168 G4QContent maxQC(0,0,0,0,0,0); // QC for maxChgH for particle UndCoulBar QC
2169 for(G4int i=0; i<nHd; ++i)
2170 {
2171 G4int found=0;
2172 G4QHadron* cHadr = (*theResult)[i];
2173 G4int hPDG= cHadr->GetPDGCode();
2174 if(hPDG==90000000 || hPDG==22)
2175 {
2176 G4QHadron* curHadr=(*theResult)[i];
2177 G4LorentzVector curh4M=curHadr->Get4Momentum();
2178 if ( curh4M.e() > 0.) curHadr->SetPDGCode(22);
2179 else if( curh4M == nul4M) // Kill such a creature
2180 {
2181 G4QHadron* theLast = (*theResult)[nHd-1];
2182 if(theLast != curHadr) // Copy the Last to the current hadron
2183 {
2184 curHadr->Set4Momentum(theLast->Get4Momentum()); //4-Mom of CurHadr
2185 G4QPDGCode lQP=theLast->GetQPDG();
2186 if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP);
2187 else curHadr->SetQC(theLast->GetQC());
2188 }
2189 theResult->pop_back(); // theLastQHadron is excluded from OUTPUT
2190 --nHd;
2191 delete theLast; //*!!When kill, delete theLastQHadr as an Instance!*
2192 if(i == nHd-1) break; // @@ Why it was anyway break ??
2193 }
2194 }
2195 //else if(hPDG==2212 || hPDG==2112) // @@ Why this isotopic correction is necessary ??
2196 else if(2 > 3) // @@ The isotopic exchange (correction) is closed for acceleration
2197 {
2198 for(G4int j=i+1; j<nHd; ++j)
2199 {
2200 G4int pPDG=(*theResult)[j]->GetPDGCode();
2201 if(hPDG==pPDG) // The pp or nn pair is found
2202 {
2203 G4LorentzVector h4M=(*theResult)[i]->Get4Momentum();
2204 G4LorentzVector p4M=(*theResult)[j]->Get4Momentum();
2205 G4LorentzVector d4M=h4M+p4M;
2206 G4double E=d4M.m(); // Proto of tot CM energy (@@ was .mag() ??)
2207 if(hPDG==2212) E -= mProt+mProt; // Reduction to tot kin energy in CM
2208 else E -= mNeut+mNeut;
2209 if(E < 140. && G4UniformRand() < .6)// A close pair was found @@ Par 140. @@
2210 {
2211 G4int piPDG= 211; // Pi+ default for nn pairs
2212 if(hPDG==2212) piPDG=-211; // Pi- for pp pairs
2213 for(G4int k=0; k<nHd; ++k)
2214 {
2215 G4int mPDG=(*theResult)[k]->GetPDGCode();
2216 // @@ if the isotopic exchange is made to increase Pi0, then only piPDG
2217 // @@ if the isotopic exchange is made to reduce Pi0, then only pi0
2218 if(mPDG==111 || mPDG==piPDG) // Appropriate for correction pion is found
2219 {
2220 G4LorentzVector m4M=(*theResult)[k]->Get4Momentum();// Must meson be close?
2221 G4double mN=mProt; // Final nucleon after charge exchange (nn)
2222 G4int nPDG=2212; // Default for (nn)
2223 G4int tPDG=-211; // Proto Pion after charge exchange from Pi0
2224 if(hPDG==2212) // (pp)
2225 {
2226 mN=mNeut;
2227 nPDG=2112;
2228 tPDG= 211;
2229 }
2230 G4double mPi=mPiZr; // Pion after the charge exchange from Pi+/-
2231 G4int sPDG=111;
2232 if(mPDG==111)
2233 {
2234 mPi=mPiCh; // Pion after the charge exchange from Pi0
2235 sPDG=tPDG;
2236 }
2237 //G4cout<<"G4QFrag::Frag: H="<<hPDG<<", P="<<pPDG<<", M="<<mPDG<<", N="
2238 // <<nPDG<<", S="<<sPDG<<G4endl;
2239 G4double D=mPi+mN; // The same for both identical nucleons
2240 G4LorentzVector t4M=m4M+h4M; // meson+ 1st nicleon
2241 G4LorentzVector n4M=h4M;
2242 G4double D2=D*D;
2243 G4double S=t4M.m2(); // (@@ was .mag2() ??)
2244 if(S > D2) found= 1; // 1st nucleon correction can be done
2245 else // Try the 2nd nucleon
2246 {
2247 t4M=m4M+p4M; // meson+ 1st nicleon
2248 n4M=p4M;
2249 S=t4M.m2(); // (@@ was .mag2() ??)
2250 if(S > D2) found=-1; // 2nd nucleon correction can be done
2251 }
2252 if(found) // Isotopic Correction
2253 {
2254 G4ThreeVector tV=t4M.vect()/t4M.e();
2255 //G4cout<<"G4QFragment::Fragment: Before 4M/M2="<<m4M<<m4M.m2()<<G4endl;
2256 m4M.boost(-tV); // boost the meson to piN CM
2257 //G4cout<<"G4QFragment::Fragment: After 4M/M2="<<m4M<<m4M.m2()<<G4endl;
2258 n4M.boost(-tV); // boost the nucleon to piN CM
2259 G4double mPi2=mPi*mPi;
2260 G4double mN2=mN*mN;
2261 G4double C=S-mPi2-mN2;
2262 G4double p2=(C*C/4.-mPi2*mN2)/S;
2263 if(p2 < 0.) G4cout<<"-Warning-G4QFragment::Fragment: P2="<<p2<<G4endl;
2264 G4double pc2=m4M.vect().mag2();
2265 //G4double nc2=n4M.vect().mag2();
2266 G4double r=1.;
2267 if(pc2 < .00000000000001)
2268 G4cout<<"-Warning-G4QFragment::Fragment: PC2="<<pc2<<m4M<<G4endl;
2269 else r=std::sqrt(p2/pc2);
2270 m4M.setV(r*m4M.vect()); // conservs the pion direction (not close!)
2271 m4M.setE(std::sqrt(mPi2+p2));
2272 //G4cout<<"G4QFragment::Fragment: Changed 4M/M2="<<m4M<<m4M.m2()<<", pc2="
2273 // <<pc2<<", nc2="<<nc2<<G4endl;
2274 n4M.setV(r*n4M.vect());
2275 n4M.setE(std::sqrt(mN2+p2));
2276 m4M.boost(tV); // Boost the meson back to the Lab system
2277 n4M.boost(tV); // Boost the nucleon back to the Lab system
2278 (*theResult)[k]->SetPDGCode(sPDG);
2279 (*theResult)[k]->Set4Momentum(m4M);
2280 if(found > 0) // Nucleon correction
2281 {
2282 (*theResult)[i]->SetPDGCode(nPDG);
2283 (*theResult)[i]->Set4Momentum(n4M);
2284 }
2285 else
2286 {
2287 (*theResult)[j]->SetPDGCode(nPDG);
2288 (*theResult)[j]->Set4Momentum(n4M);
2289 }
2290 break; // Break the pion LOOP
2291 }
2292 }
2293 } // End of the pion LOOP
2294 if(found) break; // Break the nucleon partner LOOP
2295 } // End of Par 140. IF
2296 } // End of the identical nucleon IF
2297 } // End of the nucleon partner LOOP
2298 } // End of cur=nucleon IF (now closed)
2299 // Here we can find a hadron with the maximum charge = the residual nuclear environment
2300 G4int hChg=cHadr->GetCharge();
2301 if(hChg > maxChg)
2302 {
2303 maxChg = hChg;
2304 maxQC = cHadr->GetQC();
2305#ifdef debug
2306 maxBN = cHadr->GetBaryonNumber();
2307#endif
2308 }
2309 } // End of the primary hadron LOOP
2310 G4QNucleus ResNucEnv(maxQC); // vacuum if not found (check maxChg & maxBN when used)
2311#ifdef debug
2312 G4cout<<"G4QFragmentation::Fra: ResNucEnv with A="<<maxBN<<", Z="<<maxChg<<G4endl;
2313#endif
2314 // --- The photon && UCB suppressor ---
2315 G4LorentzVector sum(0.,0.,0.,0.); // total 4-mom of the found gammas
2316 G4QContent sumQC(0,0,0,0,0,0); // aquired positive particle UndCuBar QC
2317 G4int sumCount=0; // Counter of the found gammas
2318 G4int nHadr=theResult->size(); // #of hadrons in the output so far
2319 G4bool frag=false; // presence of fragments (A>1)
2320 if(nHadr>2) for(unsigned f=0; f<theResult->size(); f++) //Check that there's a fragment
2321 {
2322 G4int fBN=(*theResult)[f]->GetBaryonNumber(); // Baryon number of the fragment
2323#ifdef debug
2324 G4int fPDG=(*theResult)[f]->GetPDGCode(); // PDG code of the possible fragment
2325 G4LorentzVector fLV=(*theResult)[f]->Get4Momentum(); // 4Mom of the possible fragment
2326 G4cout<<"G4QFragmentation::Fra:"<<f<<",PDG="<<fPDG<<",fBN="<<fBN<<",f4M="<<fLV<<G4endl;
2327#endif
2328 if(fBN>1) // At least one fragment (A>1) is found
2329 {
2330 frag=true;
2331 break;
2332 }
2333 }
2334#ifdef debug
2335 G4cout<<"G4QFrag::Frag:=>Before Gamma Suppression<=, nH="<<nHadr<<",frag="<<frag<<G4endl;
2336#endif
2337 if(nHadr>2 && frag) for(G4int h=nHadr-1; h>=0; h--)//Collect gammas & kill DecayedHadrons
2338 {
2339 G4QHadron* curHadr = (*theResult)[h]; // Get a pointer to the current Hadron
2340 G4int hF = curHadr->GetNFragments(); // This is historic ... (was decayed flag)
2341 G4int hPDG = curHadr->GetPDGCode(); // PDG of the hadron
2342 G4LorentzVector h4M=curHadr->Get4Momentum();// 4Mom of the hadron
2343 if(hPDG==89999003||hPDG==90002999)G4cout<<"-Warning-G4QFr::Fr:nD-/pD++="<<hPDG<<G4endl;
2344#ifdef debug
2345 G4cout<<"G4QFragmentation::Fragm: h#"<<h<<", hPDG="<<hPDG<<", hNFrag="<<hF<<G4endl;
2346#endif
2347 G4int hChg = curHadr->GetCharge(); // Charge of the hadron
2348 G4bool UCB = false; // Not UCB yet
2349 if(hChg > 0 && hPDG!=321) // All positive but not K+
2350 {
2351 G4int hBN = curHadr->GetBaryonNumber(); // Baryon Number of the hadron
2352 G4double hCB=ResNucEnv.CoulombBarrier(hChg,hBN); // Coulomb barrier
2353 if(h4M.e()-h4M.m() < hCB) UCB = true; // The hadron should be absorbed
2354 }
2355 if(hF || hPDG==22 || UCB) // Must be absorbed (decayed, photon, UCB)
2356 {
2357 G4int last=theResult->size()-1;
2358 G4QHadron* theLast = (*theResult)[last]; //Get Ptr to the Last Hadron
2359 if(hPDG==22 || UCB) // Absorb if this is gamma
2360 {
2361 sum+=h4M; // Add 4Mom of hadron to the "sum"
2362 sumCount++;
2363 if(UCB) sumQC+=curHadr->GetQC(); // Collect the absorbed QC
2364#ifdef debug
2365 G4cout<<"G4QFragmentation::Frag: gam4M="<<h4M<<" is added to s4M="<<sum<<G4endl;
2366#endif
2367 }
2368 nHadr = static_cast<G4int>(theResult->size())-1;
2369 if(h < last) // Need swap theCurHadron with the Last
2370 {
2371 curHadr->SetNFragments(0);
2372 curHadr->Set4Momentum(theLast->Get4Momentum());
2373 G4QPDGCode lQP=theLast->GetQPDG(); // The QPDG of the last
2374 if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
2375 else curHadr->SetQC(theLast->GetQC()); // CurHadrPDG instead of LastHadrPDG
2376#ifdef debug
2377 G4cout<<"G4QFragmentation::Fragment: Exchange with the last is done"<<G4endl;
2378#endif
2379 }
2380 theResult->pop_back(); // theLastQHadron is excluded from theResult
2381 delete theLast;//!!When kill,DON'T forget to delete theLastQHadron as an instance!!
2382#ifdef debug
2383 G4cout<<"G4QFragmentation::Fragment: The last is compessed"<<G4endl;
2384#endif
2385 }
2386 }
2387#ifdef debug
2388 G4cout<<"G4QFragment::Frag: nH="<<nHadr<<"="<<theResult->size()<<", sum="<<sum<<G4endl;
2389#endif
2390 if(nHadr > 1) for(unsigned hdr=0; hdr<theResult->size()-1; hdr++)//Ord:theBigestIsTheLast
2391 {
2392 G4QHadron* curHadr = (*theResult)[hdr]; // Get a pointer to the current Hadron
2393#ifdef debug
2394 G4cout<<"G4QFrag::Frag: h#"<<hdr<<"<"<<nHadr<<", hPDG="<<curHadr->GetPDGCode()<<G4endl;
2395#endif
2396 G4QHadron* theLast = (*theResult)[theResult->size()-1]; //Get Ptr to the Last Hadron
2397 G4int hB = curHadr->GetBaryonNumber();
2398 G4int lB = theLast->GetBaryonNumber();
2399#ifdef debug
2400 G4cout<<"G4QFra::Fra:hBN="<<hB<<"<lBN="<<lB<<",lstPDG="<<theLast->GetPDGCode()<<G4endl;
2401#endif
2402 if(lB < hB) // Must be swapped
2403 {
2404 G4QPDGCode hQPDG = curHadr->GetQPDG();
2405 G4LorentzVector h4m= curHadr->Get4Momentum();
2406 curHadr->Set4Momentum(theLast->Get4Momentum());
2407 G4QPDGCode lQP=theLast->GetQPDG(); // The QPDG of the last
2408 if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
2409 else curHadr->SetQC(theLast->GetQC()); // CurHadrPDG instead of LastHadrPDG
2410 theLast->Set4Momentum(h4m);
2411 theLast->SetQPDG(hQPDG);
2412 }
2413 }
2414 nHadr=theResult->size(); // --> At this point the last hadron is the biggest nucleus
2415 if(sumCount)
2416 {
2417 G4QHadron* theLast = (*theResult)[nHadr-1];// Get a pointer to the Last Hadron
2418 G4int nucEnvBN=theLast->GetBaryonNumber(); // Initial A of residualNuclearEnvironment
2419 if ( nucEnvBN > 0 ) // "Absorb phot/UCB & evaporate/decay" case
2420 {
2421 G4QHadron* theNew = new G4QHadron(theLast); // Make New Hadron of the Last Hadron
2422#ifdef debug
2423 G4cout<<"G4QFra::Fra:BeforeLastSub,n="<<nHadr<<",PDG="<<theNew->GetPDGCode()<<G4endl;
2424#endif
2425 theResult->pop_back(); // the last QHadron is excluded from OUTPUT
2426 delete theLast;//*!When kill,DON'T forget to delete theLastQHadron as an instance!*
2427 nHadr--; // TheLastHadron only virtually exists now
2428 G4QContent newQC=theNew->GetQC(); // QContent of the fragment=ResNuclEnv
2429 G4LorentzVector new4M=theNew->Get4Momentum(); // 4-mom of the fragment=ResNuclEnv
2430#ifdef debug
2431 G4cout<<"G4QFra::Fra:gSum4M="<<sum<<" is added to "<<new4M<<", QC="<<newQC<<G4endl;
2432#endif
2433 G4LorentzVector exRes4M = new4M + sum; //Icrease 4Mom of theLast by sum 4Mon
2434 G4QContent exResQC = newQC + sumQC; //Icrease QCont of theLast by sumQC
2435 theNew->Set4Momentum(exRes4M);
2436 theNew->SetQC(exResQC);
2437#ifdef debug
2438 G4cout<<"G4QFra::Fra:BeforeEvap, n="<<nHadr<<", nPDG="<<theNew->GetPDGCode()<<G4endl;
2439#endif
2440 EvaporateResidual(theNew); // Try to evaporate theNucl. (del. equiv.)
2441 nHadr=theResult->size();
2442 } // End of "the last is the nucleus" case
2443 else G4cout<<"-Warning-G4QFragmentation::Fragment:RA="<<nucEnvBN<<",E/M cons?"<<G4endl;
2444 } // End of "There are gammas to suppress"
2445 // End of the Gamma Suppression
2446 return theResult;
2447} // End of fragmentation
void setV(const Hep3Vector &)
G4QParticle * GetQParticle(G4int PDG) const
void AddQuasmon(G4Quasmon *Q)
G4QHadronVector * Fragment()
void EvaporateResidual(G4QHadron *hadrNuc)
void SetNFragments(const G4int &nf)
Definition: G4QHadron.hh:188
void SetPDGCode(const G4QPDGCode &PDG)
Definition: G4QHadron.hh:97
void Boost(const G4LorentzVector &theBoost)
Definition: G4QHadron.cc:1293
G4int GetNFragments() const
Definition: G4QHadron.hh:174
G4double MinMassOfFragm()
Definition: G4QParticle.hh:113
G4QContent GetQC() const
Definition: G4Quasmon.hh:162
void Set4Momentum(G4LorentzVector Q4M)
Definition: G4Quasmon.hh:96
void Boost(const G4LorentzVector &theBoost)
Definition: G4Quasmon.cc:6202
G4int GetCharge() const
Definition: G4Quasmon.hh:163
G4LorentzVector Get4Momentum() const
Definition: G4Quasmon.hh:161
void SetQC(G4QContent QQC)
Definition: G4Quasmon.hh:97
G4int GetBaryonNumber() const
Definition: G4Quasmon.hh:164

Referenced by G4QInelastic::PostStepDoIt().

◆ GaussianPt()

G4ThreeVector G4QFragmentation::GaussianPt ( G4double  widthSquare,
G4double  maxPtSquare 
) const
protected

Definition at line 4333 of file G4QFragmentation.cc.

4334{
4335#ifdef debug
4336 G4cout<<"G4QFragmentation::GaussianPt:width2="<<widthSq<<",maxPt2="<<maxPtSquare<<G4endl;
4337#endif
4338 G4double pt2=0.;
4339 G4double rm=maxPtSquare/widthSq; // Negative
4340 if(rm>-.01) pt2=widthSq*(std::sqrt(1.-G4UniformRand()*(1.-sqr(1.+rm)))-1.);
4341 else pt2=widthSq*std::log(1.-G4UniformRand()*(1.-std::exp(rm)));
4342 pt2=std::sqrt(pt2); // It is not pt2, but pt now
4343 G4double phi=G4UniformRand()*twopi;
4344 return G4ThreeVector(pt2*std::cos(phi),pt2*std::sin(phi),0.);
4345} // End of GaussianPt

Referenced by ExciteDiffParticipants(), and ExciteSingDiffParticipants().

◆ IsSingleDiffractive()

G4bool G4QFragmentation::IsSingleDiffractive ( )
inlineprotected

Definition at line 77 of file G4QFragmentation.hh.

77{G4bool r=false; if(G4UniformRand()<1.) r=true; return r;}

Referenced by G4QFragmentation().

◆ ReducePair()

std::pair< G4int, G4int > G4QFragmentation::ReducePair ( G4int  P1,
G4int  P2 
) const
protected

Definition at line 4412 of file G4QFragmentation.cc.

4413{
4414#ifdef debug
4415 G4cout<<"G4QFragmentation::ReducePair: **Called** P1="<<P1<<", P2="<<P2<<G4endl;
4416#endif
4417 G4int P11=P1/10;
4418 G4int P12=P1%10;
4419 G4int P21=P2/10;
4420 G4int P22=P2%10;
4421 if (P11==P21) return std::make_pair(P12,P22);
4422 else if(P11==P22) return std::make_pair(P12,P21);
4423 else if(P12==P21) return std::make_pair(P11,P22);
4424 else if(P12==P22) return std::make_pair(P11,P21);
4425 //#ifdef debug
4426 G4cout<<"-Warning-G4QFragmentation::ReducePair:**Failed**, P1="<<P1<<", P2="<<P2<<G4endl;
4427 //#endif
4428 return std::make_pair(0,0); // Reduction failed
4429}

Referenced by Breeder().

◆ SetParameters()

void G4QFragmentation::SetParameters ( G4int  nC,
G4double  strTens,
G4double  tubeDens,
G4double  SigPt 
)
static

Definition at line 4304 of file G4QFragmentation.cc.

4305{
4306 nCutMax = nC; // max number of pomeron cuts
4307 stringTension = stT; // string tension for absorbed energy
4308 tubeDensity = tbD; // Flux Tube Density of nuclear nucleons
4309 widthOfPtSquare = -2*SigPt*SigPt; // width^2 of pt for string excitation
4310}

◆ SumPartonPDG()

G4int G4QFragmentation::SumPartonPDG ( G4int  PDG1,
G4int  PFG2 
) const
protected

Definition at line 4347 of file G4QFragmentation.cc.

4348{
4349 if (PDG1 < 7 && PDG1 > 0 && PDG2 < 7 && PDG2 > 0) // Sum up two Q in DiQ (S=0)
4350 {
4351 if(PDG1 > PDG2) return PDG1*1000+PDG2*100+1;
4352 else return PDG2*1000+PDG1*100+1;
4353 }
4354 else if (PDG1 >-7 && PDG1 < 0 && PDG2 >-7 && PDG2 < 0) // Sum up two AQ in ADiQ (S=0)
4355 {
4356 if(-PDG1 > -PDG2) return PDG1*1000+PDG2*100-1;
4357 else return PDG2*1000+PDG1*100-1;
4358 }
4359 else if (PDG1 <-99 && PDG2 < 7 && PDG2 > 0) // Sum up Q and ADiQ in AQ
4360 {
4361 G4int PDG=-PDG1/100;
4362 if(PDG2==PDG/10) return -PDG%10;
4363 if(PDG2==PDG%10) return -PDG/10;
4364 else
4365 {
4366 G4cerr<<"***4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
4367 G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"Q&ADiQ notMatch");
4368 }
4369 }
4370 else if (PDG2 <-99 && PDG1 < 7 && PDG1 > 0) // Sum up ADiQ and Q in AQ
4371 {
4372 G4int PDG=-PDG2/100;
4373 if(PDG1==PDG/10) return -PDG%10;
4374 if(PDG1==PDG%10) return -PDG/10;
4375 else
4376 {
4377 G4cerr<<"***4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
4378 G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"ADiQ&Q notMatch");
4379 }
4380 }
4381 else if (PDG1 > 99 && PDG2 >-7 && PDG2 < 0) // Sum up DiQ and AQ in Q
4382 {
4383 G4int PDG=PDG1/100;
4384 if(PDG2==-PDG/10) return PDG%10;
4385 if(PDG2==-PDG%10) return PDG/10;
4386 else
4387 {
4388 G4cerr<<"***4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
4389 G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"DiQ&AQ notMatch");
4390 }
4391 }
4392 else if (PDG2 > 99 && PDG1 >-7 && PDG1 < 0) // Sum up AQ and DiQ in Q
4393 {
4394 G4int PDG=PDG2/100;
4395 if(PDG1==-PDG/10) return PDG%10;
4396 if(PDG1==-PDG%10) return PDG/10;
4397 else
4398 {
4399 G4cerr<<"***G4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
4400 G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"AQ&DiQ notMatch");
4401 }
4402 }
4403 else
4404 {
4405 G4cerr<<"***G4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
4406 G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"Can'tSumUpPartons");
4407 }
4408 return 0;
4409} // End of SumPartonPDG

Referenced by Breeder().

◆ SwapPartons()

void G4QFragmentation::SwapPartons ( )
protected

Definition at line 4664 of file G4QFragmentation.cc.

4665{
4666 static const G4double baryM=800.; // Mass excess for baryons
4667 G4QStringVector::iterator ist;
4668 for(ist = strings.begin(); ist < strings.end(); ist++)
4669 {
4670 G4QParton* cLeft=(*ist)->GetLeftParton(); // Current String Left Parton
4671 G4QParton* cRight=(*ist)->GetRightParton(); // Current String Right Parton
4672 G4LorentzVector cL4M=cLeft->Get4Momentum();
4673 G4LorentzVector cR4M=cRight->Get4Momentum();
4674 G4LorentzVector cS4M=cL4M+cR4M;
4675 G4double cSM2=cS4M.m2(); // Squared mass of the String
4676 if(std::fabs(cSM2)<.01) // Small correction
4677 {
4678 G4double dM2=.001-cSM2;
4679 G4double E=cS4M.e();
4680 G4double dE=std::sqrt(E*E+dM2)-E;
4681 G4double LE=cL4M.e();
4682 G4double RE=cR4M.e();
4683 if(LE<RE) cLeft->Set4Momentum( G4LorentzVector(LE+dE) );
4684 else cRight->Set4Momentum( G4LorentzVector(RE+dE) );
4685 cSM2=.001; // Correction
4686 }
4687 if(cSM2<0.011) // Parton Swapping is needed
4688 {
4689 G4int cLPDG=cLeft->GetPDGCode();
4690 G4int cRPDG=cRight->GetPDGCode();
4691 G4int cLT=cLeft->GetType();
4692 G4int cRT=cRight->GetType();
4693 G4QStringVector::iterator sst; // Selected partner string
4694 G4QStringVector::iterator pst; // LOOP iterator
4695 G4double maxM=-DBL_MAX; // Swapping providing the max mass
4696 G4int sDir=0; // Selected direction of swapping
4697#ifdef debug
4698 G4cout<<"G4QFragmentation::SwapPartons: M2=="<<cSM2<<", 4M="<<cS4M<<",LPDG="<<cLPDG
4699 <<",RPDG="<<cRPDG<<G4endl;
4700#endif
4701 for(pst = strings.begin(); pst < strings.end(); pst++) if(pst != ist)
4702 {
4703 G4QParton* pLeft=(*pst)->GetLeftParton(); // Partner String Left Parton
4704 G4QParton* pRight=(*pst)->GetRightParton(); // Partner String Right Parton
4705 G4int pLPDG=pLeft->GetPDGCode();
4706 G4int pRPDG=pRight->GetPDGCode();
4707 G4LorentzVector pL4M=pLeft->Get4Momentum();
4708 G4LorentzVector pR4M=pRight->Get4Momentum();
4709 G4int pLT=pLeft->GetType();
4710 G4int pRT=pRight->GetType();
4711#ifdef debug
4712 G4cout<<"G4QFragmentation::SwapPartons: p4M="<<cS4M<<",pM2="<<cS4M.m2()<<",LPDG="
4713 <<pLPDG<<",RPDG="<<pRPDG<<G4endl;
4714#endif
4715 G4double LM=0.;
4716 G4double RM=0.;
4717 if(((cLPDG<-7 || (cLPDG>0 && cLPDG< 7) ) && (pLPDG<-7 || (pLPDG>0 && pLPDG< 7) ))||
4718 ((cLPDG> 7 || (cLPDG<0 && cLPDG>-7) ) && (pLPDG> 7 || (pLPDG<0 && cLPDG>-7) )))
4719 {
4720 G4double pLM2=(cL4M+pR4M).m2(); // new partner M2
4721 G4double cLM2=(cR4M+pL4M).m2(); // new partner M2
4722 if(pLM2>0. && cLM2>0.)
4723 {
4724 G4double pLM=std::sqrt(pLM2);
4725 if(cLT+pRT==3) pLM-=baryM;
4726 G4double cLM=std::sqrt(cLM2);
4727 if(cRT+pLT==3) cLM-=baryM;
4728 LM=std::min(pLM2,cLM2);
4729 }
4730 }
4731 if(((cRPDG<-7 || (cRPDG>0 && cRPDG< 7) ) && (pRPDG<-7 || (pRPDG>0 && pRPDG< 7) ))||
4732 ((cRPDG> 7 || (cRPDG<0 && cRPDG>-7) ) && (pRPDG> 7 || (pRPDG<0 && cRPDG>-7) )) )
4733 {
4734 G4double pRM2=(cR4M+pL4M).m2(); // new partner M2
4735 G4double cRM2=(cL4M+pR4M).m2(); // new partner M2
4736 if(pRM2>0. && cRM2>0.)
4737 {
4738 G4double pRM=std::sqrt(pRM2);
4739 if(cRT+pLT==3) pRM-=baryM;
4740 G4double cRM=std::sqrt(cRM2);
4741 if(cLT+pRT==3) cRM-=baryM;
4742 RM=std::min(pRM,cRM);
4743 }
4744 }
4745 G4int dir=0;
4746 G4double sM=0.;
4747 if( LM && LM > RM )
4748 {
4749 dir= 1;
4750 sM=LM;
4751 }
4752 else if(RM)
4753 {
4754 dir=-1;
4755 sM=RM;
4756 }
4757 if(sM > maxM)
4758 {
4759 sst=pst;
4760 maxM=sM;
4761 sDir=dir;
4762 }
4763 }
4764 if(sDir)
4765 {
4766 G4QParton* pLeft=(*sst)->GetLeftParton(); // Partner String Left Parton
4767 G4QParton* pRight=(*sst)->GetRightParton(); // Partner String Right Parton
4768 G4QParton* swap=pLeft; // Prototype remember the partner Left
4769 if(sDir>0) // swap left partons
4770 {
4771 (*sst)->SetLeftParton(cLeft);
4772 (*ist)->SetLeftParton(swap);
4773 }
4774 else
4775 {
4776 swap=pRight;
4777 (*sst)->SetRightParton(cRight);
4778 (*ist)->SetRightParton(swap);
4779 }
4780 }
4781#ifdef debug
4782 else G4cout<<"***G4QFragmentation::SwapPartons:**Failed**,cLPDG="<<cLPDG<<",cRPDG="
4783 <<cRPDG<<",-->cM2="<<cSM2<<G4endl;
4784#endif
4785 }
4786 }
4787}
@ LE
Definition: Evaluator.cc:66

Referenced by G4QFragmentation().


The documentation for this class was generated from the following files: