Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4FTFAnnihilation.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28
29// ------------------------------------------------------------
30// GEANT 4 class implemetation file
31//
32// ---------------- G4FTFAnnihilation --------------
33// by V. Uzhinsky, Spring 2011.
34// Take a projectile and a target
35// make annihilation or re-orangement of quarks and anti-quarks.
36// Ideas of Quark-Gluon-String model my A. Capella and A.B. Kaidalov
37// are implemented.
38// ---------------------------------------------------------------------
39
40#include "globals.hh"
41#include "Randomize.hh"
43#include "G4SystemOfUnits.hh"
44
47#include "G4FTFParameters.hh"
49#include "G4FTFAnnihilation.hh"
50
51#include "G4LorentzRotation.hh"
52#include "G4RotationMatrix.hh"
53#include "G4ThreeVector.hh"
55#include "G4VSplitableHadron.hh"
56#include "G4ExcitedString.hh"
57#include "G4ParticleTable.hh"
58#include "G4Neutron.hh"
60
61#include "G4Exp.hh"
62#include "G4Log.hh"
63#include "G4Pow.hh"
64
65//#include "UZHI_diffraction.hh"
66
67#include "G4ParticleTable.hh"
68
69//============================================================================
70
71//#define debugFTFannih
72
73
74//============================================================================
75
77
78
79//============================================================================
80
82
83
84//============================================================================
85
87 G4VSplitableHadron* target,
88 G4VSplitableHadron*& AdditionalString,
89 G4FTFParameters* theParameters ) const {
90
91 #ifdef debugFTFannih
92 G4cout << "---------------------------- Annihilation----------------" << G4endl;
93 #endif
94
95 CommonVariables common;
96
97 // Projectile parameters
98 common.Pprojectile = projectile->Get4Momentum();
99 G4int ProjectilePDGcode = projectile->GetDefinition()->GetPDGEncoding();
100 if ( ProjectilePDGcode > 0 ) {
101 target->SetStatus( 3 );
102 return false;
103 }
104 G4double M0projectile2 = common.Pprojectile.mag2();
105
106 // Target parameters
107 G4int TargetPDGcode = target->GetDefinition()->GetPDGEncoding();
108 common.Ptarget = target->Get4Momentum();
109 G4double M0target2 = common.Ptarget.mag2();
110
111 #ifdef debugFTFannih
112 G4cout << "PDG codes " << ProjectilePDGcode << " " << TargetPDGcode << G4endl
113 << "Pprojec " << common.Pprojectile << " " << common.Pprojectile.mag() << G4endl
114 << "Ptarget " << common.Ptarget << " " << common.Ptarget.mag() << G4endl
115 << "M0 proj target " << std::sqrt( M0projectile2 )
116 << " " << std::sqrt( M0target2 ) << G4endl;
117 #endif
118
119 // Kinematical properties of the interactions
120 G4LorentzVector Psum = common.Pprojectile + common.Ptarget; // 4-momentum in CMS
121 common.S = Psum.mag2();
122 common.SqrtS = std::sqrt( common.S );
123 #ifdef debugFTFannih
124 G4cout << "Psum SqrtS S " << Psum << " " << common.SqrtS << " " << common.S << G4endl;
125 #endif
126
127 // Transform momenta to cms and then rotate parallel to z axis
128 G4LorentzRotation toCms( -1*Psum.boostVector() );
129 G4LorentzVector Ptmp( toCms*common.Pprojectile );
130 toCms.rotateZ( -1*Ptmp.phi() );
131 toCms.rotateY( -1*Ptmp.theta() );
132 common.toLab = toCms.inverse();
133
134 if ( G4UniformRand() <= G4Pow::GetInstance()->powA( 1880.0/common.SqrtS, 4.0 ) ) {
135 common.RotateStrings = true;
136 common.RandomRotation.rotateZ( 2.0*pi*G4UniformRand() );
137 common.RandomRotation.rotateY( std::acos( 2.0*G4UniformRand() - 1.0 ) );
138 common.RandomRotation.rotateZ( 2.0*pi*G4UniformRand() );
139 }
140
141 G4double MesonProdThreshold = projectile->GetDefinition()->GetPDGMass() +
142 target->GetDefinition()->GetPDGMass() +
143 ( 2.0*140.0 + 16.0 )*MeV; // 2 Mpi + DeltaE
144 G4double Prel2 = sqr(common.S) + sqr(M0projectile2) + sqr(M0target2)
145 - 2.0*( common.S*(M0projectile2 + M0target2) + M0projectile2*M0target2 );
146 Prel2 /= common.S;
147 G4double X_a = 0.0, X_b = 0.0, X_c = 0.0, X_d = 0.0;
148 if ( Prel2 <= 0.0 ) {
149 // Annihilation at rest! Values are copied from Parameters
150 X_a = 625.1; // mb // 3-shirt diagram
151 X_b = 0.0; // mb // anti-quark-quark annihilation
152 X_c = 49.989; // mb // 2 Q-Qbar string creation
153 X_d = 6.614; // mb // One Q-Qbar string
154 #ifdef debugFTFannih
155 G4cout << "Annih at Rest X a b c d " << X_a << " " << X_b << " " << X_c << " " << X_d
156 << G4endl;
157 #endif
158 } else { // Annihilation in flight!
159 G4double FlowF = 1.0 / std::sqrt( Prel2 )*GeV;
160 // Process cross sections
161 X_a = 25.0*FlowF; // mb 3-shirt diagram
162 if ( common.SqrtS < MesonProdThreshold ) {
163 X_b = 3.13 + 140.0*G4Pow::GetInstance()->powA( ( MesonProdThreshold - common.SqrtS )/GeV, 2.5 );
164 } else {
165 X_b = 6.8*GeV / common.SqrtS; // mb anti-quark-quark annihilation
166 }
167 if ( projectile->GetDefinition()->GetPDGMass() + target->GetDefinition()->GetPDGMass()
168 > common.SqrtS ) {
169 X_b = 0.0;
170 }
171 // This can be in an interaction of low energy anti-baryon with off-shell nuclear nucleon
172 X_c = 2.0 * FlowF * sqr( projectile->GetDefinition()->GetPDGMass() +
173 target->GetDefinition()->GetPDGMass() ) / common.S; // mb re-arrangement of
174 // 2 quarks and 2 anti-quarks
175 X_d = 23.3*GeV*GeV / common.S; // mb anti-quark-quark string creation
176 #ifdef debugFTFannih
177 G4cout << "Annih in Flight X a b c d " << X_a << " " << X_b << " " << X_c << " " << X_d
178 << G4endl << "SqrtS MesonProdThreshold " << common.SqrtS << " " << MesonProdThreshold
179 << G4endl;
180 #endif
181 }
182
183 G4bool isUnknown = false;
184 if ( TargetPDGcode == 2212 || TargetPDGcode == 2214 ) { // Target proton or Delta+
185 if ( ProjectilePDGcode == -2212 || ProjectilePDGcode == -2214 ) { // anti_proton or anti_Delta+
186 X_b *= 5.0; X_c *= 5.0; X_d *= 6.0; // Pbar P
187 } else if ( ProjectilePDGcode == -2112 || ProjectilePDGcode == -2114 ) { // anti_neutron or anti_Delta0
188 X_b *= 4.0; X_c *= 4.0; X_d *= 4.0; // NeutrBar P
189 } else if ( ProjectilePDGcode == -3122 ) { // anti_Lambda (no anti_Lambda* in PDG)
190 X_b *= 3.0; X_c *= 3.0; X_d *= 2.0; // LambdaBar P
191 } else if ( ProjectilePDGcode == -3112 ) { // anti_Sigma- (no anti_Sigma*- in G4)
192 X_b *= 2.0; X_c *= 2.0; X_d *= 0.0; // Sigma-Bar P
193 } else if ( ProjectilePDGcode == -3212 ) { // anti_Sigma0 (no anti_Sigma*0 in G4)
194 X_b *= 3.0; X_c *= 3.0; X_d *= 2.0; // Sigma0Bar P
195 } else if ( ProjectilePDGcode == -3222 ) { // anti_Sigma+ (no anti_Sigma*+ in G4)
196 X_b *= 4.0; X_c *= 4.0; X_d *= 2.0; // Sigma+Bar P
197 } else if ( ProjectilePDGcode == -3312 ) { // anti_Xi- (no anti_Xi*- in G4)
198 X_b *= 1.0; X_c *= 1.0; X_d *= 0.0; // Xi-Bar P
199 } else if ( ProjectilePDGcode == -3322 ) { // anti_Xi0 (no anti_Xi*0 in G4)
200 X_b *= 2.0; X_c *= 2.0; X_d *= 0.0; // Xi0Bar P
201 } else if ( ProjectilePDGcode == -3334 ) { // anti_Omega- (no anti_Omega*- in PDG)
202 X_b *= 0.0; X_c *= 0.0; X_d *= 0.0; // Omega-Bar P
203 } else {
204 isUnknown = true;
205 }
206 } else if ( TargetPDGcode == 2112 || TargetPDGcode == 2114 ) { // Target neutron or Delta0
207 if ( ProjectilePDGcode == -2212 || ProjectilePDGcode == -2214 ) { // anti_proton or anti_Delta+
208 X_b *= 4.0; X_c *= 4.0; X_d *= 4.0; // Pbar N
209 } else if ( ProjectilePDGcode == -2112 || ProjectilePDGcode == -2114 ) { // anti_neutron or anti_Delta0
210 X_b *= 5.0; X_c *= 5.0; X_d *= 6.0; // NeutrBar N
211 } else if ( ProjectilePDGcode == -3122 ) { // anti_Lambda (no anti_Lambda* in PDG)
212 X_b *= 3.0; X_c *= 3.0; X_d *= 2.0; // LambdaBar N
213 } else if ( ProjectilePDGcode == -3112 ) { // anti_Sigma- (no anti_Sigma*- in G4)
214 X_b *= 4.0; X_c *= 4.0; X_d *= 2.0; // Sigma-Bar N
215 } else if ( ProjectilePDGcode == -3212 ) { // anti_Sigma0 (no anti_Sigma*0 in G4)
216 X_b *= 3.0; X_c *= 3.0; X_d *= 2.0; // Sigma0Bar N
217 } else if ( ProjectilePDGcode == -3222 ) { // anti_Sigma+ (no anti_Sigma*+ in G4)
218 X_b *= 2.0; X_c *= 2.0; X_d *= 0.0; // Sigma+Bar N
219 } else if ( ProjectilePDGcode == -3312 ) { // anti_Xi- (no anti_Xi*- in G4)
220 X_b *= 2.0; X_c *= 2.0; X_d *= 0.0; // Xi-Bar N
221 } else if ( ProjectilePDGcode == -3322 ) { // anti_Xi0 (no anti_Xi*0 in G4)
222 X_b *= 1.0; X_c *= 1.0; X_d *= 0.0; // Xi0Bar N
223 } else if ( ProjectilePDGcode == -3334 ) { // anti_Omega- (no anti_Omega*- in PDG)
224 X_b *= 0.0; X_c *= 0.0; X_d *= 0.0; // Omega-Bar N
225 } else {
226 isUnknown = true;
227 }
228 } else {
229 isUnknown = true;
230 }
231 if ( isUnknown ) {
232 G4cout << "Unknown anti-baryon for FTF annihilation: PDGcodes - "
233 << ProjectilePDGcode << " " << TargetPDGcode << G4endl;
234 }
235
236 #ifdef debugFTFannih
237 G4cout << "Annih Actual X a b c d " << X_a << " " << X_b << " " << X_c << " " << X_d << G4endl;
238 #endif
239
240 G4double Xannihilation = X_a + X_b + X_c + X_d;
241
242 // Projectile unpacking
243 UnpackBaryon( ProjectilePDGcode, common.AQ[0], common.AQ[1], common.AQ[2] );
244
245 // Target unpacking
246 UnpackBaryon( TargetPDGcode, common.Q[0], common.Q[1], common.Q[2] );
247
248 G4double Ksi = G4UniformRand();
249
250 if ( Ksi < X_a / Xannihilation ) {
251 return Create3QuarkAntiQuarkStrings( projectile, target, AdditionalString, theParameters, common );
252 }
253
254 G4int resultCode = 99;
255 if ( Ksi < (X_a + X_b) / Xannihilation ) {
256 resultCode = Create1DiquarkAntiDiquarkString( projectile, target, common );
257 if ( resultCode == 0 ) {
258 return true;
259 } else if ( resultCode == 99 ) {
260 return false;
261 }
262 }
263
264 if ( Ksi < ( X_a + X_b + X_c ) / Xannihilation ) {
265 resultCode = Create2QuarkAntiQuarkStrings( projectile, target, theParameters, common );
266 if ( resultCode == 0 ) {
267 return true;
268 } else if ( resultCode == 99 ) {
269 return false;
270 }
271 }
272
273 if ( Ksi < ( X_a + X_b + X_c + X_d ) / Xannihilation ) {
274 return Create1QuarkAntiQuarkString( projectile, target, theParameters, common );
275 }
276
277 return true;
278}
279
280
281//-----------------------------------------------------------------------
282
283G4bool G4FTFAnnihilation::
284Create3QuarkAntiQuarkStrings( G4VSplitableHadron* projectile,
285 G4VSplitableHadron* target,
286 G4VSplitableHadron*& AdditionalString,
287 G4FTFParameters* theParameters,
288 G4FTFAnnihilation::CommonVariables& common ) const {
289 // Simulation of 3 anti-quark - quark strings creation
290
291 #ifdef debugFTFannih
292 G4cout << "Process a, 3 shirt diagram" << G4endl;
293 #endif
294
295 // Sampling kinematical properties of quark. It can be done before string's creation
296
297 const G4int maxNumberOfLoops = 1000;
298 G4double MassQ2 = 0.0; // Simplest case is considered with Mass_Q = 0.0
299 // In principle, this must work with Mass_Q != 0.0
300 G4double Quark_Xs[6];
301 G4ThreeVector Quark_Mom[6];
302
303 G4double Alfa_R = 0.5;
304 G4double AveragePt2 = 200.0*200.0, maxPtSquare = common.S;
305 G4double ScaleFactor = 1.0;
306 G4double Alfa = 0.0, Beta = 0.0;
307
308 G4int NumberOfTries = 0, loopCounter = 0;
309
310 do {
311 // Sampling X's of anti-baryon and baryon
312 G4double x1 = 0.0, x2 = 0.0, x3 = 0.0;
313 G4double Product = 1.0;
314 for ( G4int iCase = 0; iCase < 2; ++iCase ) { // anti-baryon (1st case), baryon (2nd case)
315
316 G4double r1 = G4UniformRand(), r2 = G4UniformRand();
317 if ( Alfa_R == 1.0 ) {
318 x1 = 1.0 - std::sqrt( r1 );
319 x2 = (1.0 - x1) * r2;
320 } else {
321 x1 = sqr( r1 );
322 x2 = (1.0 - x1) * sqr( std::sin( pi/2.0*r2 ) );
323 }
324 x3 = 1.0 - x1 - x2;
325
326 G4int index = iCase*3; // 0 for anti-baryon, 3 for baryon
327 Quark_Xs[index] = x1; Quark_Xs[index+1] = x2; Quark_Xs[index+2] = x3;
328 Product *= (x1*x2*x3);
329 }
330
331 if ( Product == 0.0 ) continue;
332
333 ++NumberOfTries;
334 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
335 // After a large number of tries, it is better to reduce the values of <Pt^2>
336 ScaleFactor /= 2.0;
337 AveragePt2 *= ScaleFactor;
338 }
339
340 G4ThreeVector PtSum( 0.0, 0.0, 0.0 );
341 for ( G4int i = 0; i < 6; ++i ) {
342 Quark_Mom [i] = GaussianPt( AveragePt2, maxPtSquare );
343 PtSum += Quark_Mom[i];
344 }
345
346 PtSum /= 6.0;
347 Alfa = 0.0; Beta = 0.0;
348
349 for ( G4int i = 0; i < 6; ++i ) { // Loop over the quarks and (anti-)quarks
350 Quark_Mom[i] -= PtSum;
351
352 G4double val = ( Quark_Mom[i].mag2() + MassQ2 ) / Quark_Xs[i];
353 if ( i < 3 ) { // anti-baryon
354 Alfa += val;
355 } else { // baryon (iCase == 1)
356 Beta += val;
357 }
358 }
359
360 } while ( ( std::sqrt( Alfa ) + std::sqrt( Beta ) > common.SqrtS ) &&
361 ++loopCounter < maxNumberOfLoops ); /* Loop checking, 10.08.2015, A.Ribon */
362
363 if ( loopCounter >= maxNumberOfLoops ) {
364 return false;
365 }
366
367 G4double DecayMomentum2 = sqr(common.S) + sqr(Alfa) + sqr(Beta)
368 - 2.0*( common.S*(Alfa + Beta) + Alfa*Beta );
369
370 G4double WminusTarget = 0.0, WplusProjectile = 0.0;
371 WminusTarget = ( common.S - Alfa + Beta + std::sqrt( DecayMomentum2 ) ) / 2.0 / common.SqrtS;
372 WplusProjectile = common.SqrtS - Beta/WminusTarget;
373
374 for ( G4int iCase = 0; iCase < 2; ++iCase ) { // anti-baryon (1st case), baryon (2nd case)
375 G4int index = iCase*3; // 0 for anti-baryon, 3 for baryon
376 G4double w = WplusProjectile; // for anti-baryon
377 if ( iCase == 1 ) w = - WminusTarget; // for baryon
378 for ( G4int i = 0; i < 3; ++i ) {
379 G4double Pz = w * Quark_Xs[index+i] / 2.0 -
380 ( Quark_Mom[index+i].mag2() + MassQ2 ) /
381 ( 2.0 * w * Quark_Xs[index+i] );
382 Quark_Mom[index+i].setZ( Pz );
383 }
384 }
385
386 // Sampling of anti-quark order in projectile
387 G4int SampledCase = (G4int)G4RandFlat::shootInt( 6 );
388 G4int Tmp1 = 0, Tmp2 = 0;
389 switch ( SampledCase ) {
390 case 1 : Tmp1 = common.AQ[1]; common.AQ[1] = common.AQ[2]; common.AQ[2] = Tmp1; break;
391 case 2 : Tmp1 = common.AQ[0]; common.AQ[0] = common.AQ[1]; common.AQ[1] = Tmp1; break;
392 case 3 : Tmp1 = common.AQ[0]; Tmp2 = common.AQ[1]; common.AQ[0] = common.AQ[2];
393 common.AQ[1] = Tmp1; common.AQ[2] = Tmp2; break;
394 case 4 : Tmp1 = common.AQ[0]; Tmp2 = common.AQ[1]; common.AQ[0] = Tmp2;
395 common.AQ[1] = common.AQ[2]; common.AQ[2] = Tmp1; break;
396 case 5 : Tmp1 = common.AQ[0]; Tmp2 = common.AQ[1]; common.AQ[0] = common.AQ[2];
397 common.AQ[1] = Tmp2; common.AQ[2] = Tmp1; break;
398 }
399
400 // Set the string properties
401 // An anti quark - quark pair can have the quantum number of either a scalar meson
402 // or a vector meson: the last digit of the PDG code is, respectively, 1 and 3.
403 // For simplicity only scalar is considered here.
404 G4int NewCode = 0, antiQuark = 0, quark = 0;
405 G4ParticleDefinition* TestParticle = nullptr;
406 for ( G4int iString = 0; iString < 3; ++iString ) { // Loop over the 3 string cases
407 if ( iString == 0 ) {
408 antiQuark = common.AQ[0]; quark = common.Q[0];
409 projectile->SetFirstParton( antiQuark );
410 projectile->SetSecondParton( quark );
411 projectile->SetStatus( 0 );
412 } else if ( iString == 1 ) {
413 quark = common.Q[1]; antiQuark = common.AQ[1];
414 target->SetFirstParton( quark );
415 target->SetSecondParton( antiQuark );
416 target->SetStatus( 0 );
417 } else { // iString == 2
418 antiQuark = common.AQ[2]; quark = common.Q[2];
419 }
420 G4int absAntiQuark = std::abs( antiQuark ), absQuark = std::abs( quark );
421 G4double aKsi = G4UniformRand();
422 if ( absAntiQuark == absQuark ) {
423 if ( absAntiQuark != 3 ) { // Not yet considered the case absAntiQuark 4 (charm) and 5 (bottom)
424 NewCode = 111; // Pi0-meson
425 if ( aKsi < 0.5 ) {
426 NewCode = 221; // Eta -meson
427 if ( aKsi < 0.25 ) {
428 NewCode = 331; // Eta'-meson
429 }
430 }
431 } else {
432 NewCode = 221; // Eta -meson
433 if ( aKsi < 0.5 ) {
434 NewCode = 331; // Eta'-meson
435 }
436 }
437 } else { // Vector mesons - rho, omega, phi (not yet considered the analogous cases for charm and bottom)
438 if ( absAntiQuark > absQuark ) {
439 NewCode = absAntiQuark*100 + absQuark*10 + 1; NewCode *= absAntiQuark/antiQuark;
440 } else {
441 NewCode = absQuark*100 + absAntiQuark*10 + 1; NewCode *= absQuark/quark;
442 }
443 }
444 if ( iString == 2 ) AdditionalString = new G4DiffractiveSplitableHadron();
445 TestParticle = G4ParticleTable::GetParticleTable()->FindParticle( NewCode );
446 if ( ! TestParticle ) return false;
447 if ( iString == 0 ) {
448 projectile->SetDefinition( TestParticle );
449 theParameters->SetProjMinDiffMass( 0.5 ); // 0.5 GeV : Min diffractive mass of pi-meson
450 theParameters->SetProjMinNonDiffMass( 0.5 ); // It must be self-consistent with Parameters
451 } else if ( iString == 1 ) {
452 target->SetDefinition( TestParticle );
453 theParameters->SetTarMinDiffMass( 0.5 );
454 theParameters->SetTarMinNonDiffMass( 0.5 );
455 } else { // iString == 2
456 AdditionalString->SetDefinition( TestParticle );
457 AdditionalString->SetFirstParton( common.AQ[2] );
458 AdditionalString->SetSecondParton( common.Q[2] );
459 AdditionalString->SetStatus( 0 );
460 }
461 } // End of the for loop over the 3 string cases
462
463 // 1st string AQ[0]-Q[0], 2nd string AQ[1]-Q[1], 3rd string AQ[2]-Q[2]
464
465 G4LorentzVector Pstring1, Pstring2, Pstring3;
466 G4int QuarkOrder[3] = { 0 };
467 G4double YstringMax = 0.0, YstringMin = 0.0;
468 for ( G4int i = 0; i < 3; ++i ) {
469 G4ThreeVector tmp = Quark_Mom[i] + Quark_Mom[i+3];
470 G4LorentzVector Pstring( tmp, std::sqrt( Quark_Mom[i].mag2() + MassQ2 ) +
471 std::sqrt( Quark_Mom[i+3].mag2() + MassQ2 ) );
472 // Add protection for rapidity = 0.5*ln( (E+Pz)/(E-Pz) )
473 G4double Ystring = 0.0;
474 if ( Pstring.e() > 1.0e-30 ) {
475 if ( Pstring.e() + Pstring.pz() < 1.0e-30 ) { // Very small numerator in the logarithm
476 Ystring = -1.0e30; // A very large negative value (E ~= -Pz)
477 if ( Pstring.e() - Pstring.pz() < 1.0e-30 ) { // Very small denominator in the logarithm
478 Ystring = 1.0e30; // A very large positive value (E ~= Pz)
479 } else { // Normal case
480 Ystring = Pstring.rapidity();
481 }
482 }
483 }
484 // Keep ordering in rapidity: "1" highest, "2" middle, "3" smallest
485 if ( i == 0 ) {
486 Pstring1 = Pstring; YstringMax = Ystring;
487 QuarkOrder[0] = 0;
488 } else if ( i == 1 ) {
489 if ( Ystring > YstringMax ) {
490 Pstring2 = Pstring1; YstringMin = YstringMax;
491 Pstring1 = Pstring; YstringMax = Ystring;
492 QuarkOrder[0] = 1; QuarkOrder[1] = 0;
493 } else {
494 Pstring2 = Pstring; YstringMin = Ystring;
495 QuarkOrder[1] = 1;
496 }
497 } else { // i == 2
498 if ( Ystring > YstringMax ) {
499 Pstring3 = Pstring2;
500 Pstring2 = Pstring1;
501 Pstring1 = Pstring;
502 QuarkOrder[1] = QuarkOrder[0];
503 QuarkOrder[2] = QuarkOrder[1];
504 QuarkOrder[0] = 2;
505 } else if ( Ystring > YstringMin ) {
506 Pstring3 = Pstring2;
507 Pstring2 = Pstring;
508 } else {
509 Pstring3 = Pstring;
510 QuarkOrder[2] = 2;
511 }
512 }
513 }
514
515 G4LorentzVector Quark_4Mom[6];
516 for ( G4int i = 0; i < 6; ++i ) {
517 Quark_4Mom[i] = G4LorentzVector( Quark_Mom[i], std::sqrt( Quark_Mom[i].mag2() + MassQ2 ) );
518 if ( common.RotateStrings ) Quark_4Mom[i] *= common.RandomRotation;
519 Quark_4Mom[i].transform( common.toLab );
520 }
521
522 projectile->Splitting();
523 projectile->GetNextAntiParton()->Set4Momentum( Quark_4Mom[QuarkOrder[0]] );
524 projectile->GetNextParton()->Set4Momentum( Quark_4Mom[QuarkOrder[0]+3] );
525
526 target->Splitting();
527 target->GetNextParton()->Set4Momentum( Quark_4Mom[QuarkOrder[2]] );
528 target->GetNextAntiParton()->Set4Momentum( Quark_4Mom[QuarkOrder[2]+3] );
529
530 AdditionalString->Splitting();
531 AdditionalString->GetNextAntiParton()->Set4Momentum( Quark_4Mom[QuarkOrder[1]] );
532 AdditionalString->GetNextParton()->Set4Momentum( Quark_4Mom[QuarkOrder[1]+3] );
533
534 common.Pprojectile = Pstring1; // Highest rapidity
535 common.Ptarget = Pstring3; // Lowest rapidity
536 G4LorentzVector LeftString( Pstring2 ); // Middle rapidity
537
538 if ( common.RotateStrings ) {
539 common.Pprojectile *= common.RandomRotation;
540 common.Ptarget *= common.RandomRotation;
541 LeftString *= common.RandomRotation;
542 }
543
544 common.Pprojectile.transform( common.toLab );
545 common.Ptarget.transform( common.toLab );
546 LeftString.transform( common.toLab );
547
548 // Calculation of the creation time
549 // Creation time and position of target nucleon were determined in ReggeonCascade() of G4FTFModel
550 projectile->SetTimeOfCreation( target->GetTimeOfCreation() );
551 projectile->SetPosition( target->GetPosition() );
552 AdditionalString->SetTimeOfCreation( target->GetTimeOfCreation() );
553 AdditionalString->SetPosition( target->GetPosition() );
554
555 projectile->Set4Momentum( common.Pprojectile );
556 AdditionalString->Set4Momentum( LeftString );
557 target->Set4Momentum( common.Ptarget );
558
559 projectile->IncrementCollisionCount( 1 );
560 AdditionalString->IncrementCollisionCount( 1 );
561 target->IncrementCollisionCount( 1 );
562
563 return true;
564}
565
566
567//-----------------------------------------------------------------------
568
569G4int G4FTFAnnihilation::
570Create1DiquarkAntiDiquarkString( G4VSplitableHadron* projectile,
571 G4VSplitableHadron* target,
572 G4FTFAnnihilation::CommonVariables& common ) const {
573 // Simulation of anti-diquark-diquark string creation.
574 // This method returns an integer code - instead of a boolean, with the following meaning:
575 // "0" : successfully ended and nothing else needs to be done;
576 // "1" : successfully completed, but the work needs to be continued;
577 // "99" : unsuccessfully ended, nothing else can be done.
578
579 #ifdef debugFTFannih
580 G4cout << "Process b, quark - anti-quark annihilation, di-q - anti-di-q string" << G4endl;
581 #endif
582
583 G4int CandidatsN = 0, CandAQ[9][2] = {}, CandQ[9][2] = {};
584 for ( G4int iAQ = 0; iAQ < 3; ++iAQ ) { // index of the 3 constituent anti-quarks of the antibaryon projectile
585 for ( G4int iQ = 0; iQ < 3; ++iQ ) { // index of the 3 constituent quarks of the target nucleon
586 if ( -common.AQ[iAQ] == common.Q[iQ] ) { // antiquark - quark that can annihilate
587 // Here "0", "1", "2" means, respectively, "first", "second" and "third" constituent
588 // of the (anti-baryon) projectile or (nucleon) target.
589 if ( iAQ == 0 ) { CandAQ[CandidatsN][0] = 1; CandAQ[CandidatsN][1] = 2; }
590 if ( iAQ == 1 ) { CandAQ[CandidatsN][0] = 0; CandAQ[CandidatsN][1] = 2; }
591 if ( iAQ == 2 ) { CandAQ[CandidatsN][0] = 0; CandAQ[CandidatsN][1] = 1; }
592 if ( iQ == 0 ) { CandQ[CandidatsN][0] = 1; CandQ[CandidatsN][1] = 2; }
593 if ( iQ == 1 ) { CandQ[CandidatsN][0] = 0; CandQ[CandidatsN][1] = 2; }
594 if ( iQ == 2 ) { CandQ[CandidatsN][0] = 0; CandQ[CandidatsN][1] = 1; }
595 ++CandidatsN;
596 }
597 }
598 }
599
600 // Remaining two (anti-)quarks that form the (anti-)diquark
601 G4int LeftAQ1 = 0, LeftAQ2 = 0, LeftQ1 = 0, LeftQ2 = 0;
602 if ( CandidatsN != 0 ) {
603 G4int SampledCase = (G4int)G4RandFlat::shootInt( CandidatsN );
604 LeftAQ1 = common.AQ[ CandAQ[SampledCase][0] ];
605 LeftAQ2 = common.AQ[ CandAQ[SampledCase][1] ];
606 LeftQ1 = common.Q[ CandQ[SampledCase][0] ];
607 LeftQ2 = common.Q[ CandQ[SampledCase][1] ];
608
609 // Build anti-diquark and diquark : the last digit can be either 3 - for all combinations
610 // of anti-quark - anti-quark and quark - quark - or 1 - only when the two anti-quarks
611 // or quarks are different. For simplicity, only 3 is considered.
612 G4int Anti_DQ = 0, DQ = 0;
613 if ( std::abs( LeftAQ1 ) > std::abs( LeftAQ2 ) ) {
614 Anti_DQ = 1000*LeftAQ1 + 100*LeftAQ2 - 3;
615 } else {
616 Anti_DQ = 1000*LeftAQ2 + 100*LeftAQ1 - 3;
617 }
618 if ( std::abs( LeftQ1 ) > std::abs( LeftQ2 ) ) {
619 DQ = 1000*LeftQ1 + 100*LeftQ2 + 3;
620 } else {
621 DQ = 1000*LeftQ2 + 100*LeftQ1 + 3;
622 }
623
624 // Set the string properties
625 projectile->SetFirstParton( DQ );
626 projectile->SetSecondParton( Anti_DQ );
627
628 // It is assumed that quark and di-quark masses are 0.
629 G4LorentzVector Pquark = G4LorentzVector( 0.0, 0.0, -common.SqrtS/2.0, common.SqrtS/2.0 );
630 G4LorentzVector Paquark = G4LorentzVector( 0.0, 0.0, common.SqrtS/2.0, common.SqrtS/2.0 );
631
632 if ( common.RotateStrings ) {
633 Pquark *= common.RandomRotation;
634 Paquark *= common.RandomRotation;
635 }
636
637 Pquark.transform( common.toLab );
638 Paquark.transform( common.toLab );
639
640 projectile->GetNextParton()->Set4Momentum( Pquark );
641 projectile->GetNextAntiParton()->Set4Momentum( Paquark );
642
643 projectile->Splitting();
644
645 projectile->SetStatus( 0 );
646 target->SetStatus( 4 ); // The target nucleon has annihilated 3->4
647 common.Pprojectile.setPx( 0.0 );
648 common.Pprojectile.setPy( 0.0 );
649 common.Pprojectile.setPz( 0.0 );
650 common.Pprojectile.setE( common.SqrtS );
651 common.Pprojectile.transform( common.toLab );
652
653 // Calculation of the creation time
654 // Creation time and position of target nucleon were determined in ReggeonCascade() of G4FTFModel
655 projectile->SetTimeOfCreation( target->GetTimeOfCreation() );
656 projectile->SetPosition( target->GetPosition() );
657 projectile->Set4Momentum( common.Pprojectile );
658
659 projectile->IncrementCollisionCount( 1 );
660 target->IncrementCollisionCount( 1 );
661
662 return 0; // Completed successfully: nothing else to be done
663 } // End of if ( CandidatsN != 0 )
664
665 // If we allow the string to interact with other nuclear nucleons, we have to
666 // set up MinDiffrMass in Parameters, and ascribe a PDGEncoding. To be done yet!
667
668 return 1; // Successfully ended, but the work is not over
669}
670
671
672//-----------------------------------------------------------------------
673
674G4int G4FTFAnnihilation::
675Create2QuarkAntiQuarkStrings( G4VSplitableHadron* projectile,
676 G4VSplitableHadron* target,
677 G4FTFParameters* theParameters,
678 G4FTFAnnihilation::CommonVariables& common ) const {
679 // Simulation of 2 anti-quark-quark strings creation.
680 // This method returns an integer code - instead of a boolean, with the following meaning:
681 // "0" : successfully ended and nothing else needs to be done;
682 // "1" : successfully completed, but the work needs to be continued;
683 // "99" : unsuccessfully ended, nothing else can be done.
684
685 #ifdef debugFTFannih
686 G4cout << "Process c, quark - anti-quark and string junctions annihilation, 2 strings left."
687 << G4endl;
688 #endif
689
690 // Sampling kinematical properties: 1st string LeftAQ1-LeftQ1, 2nd string LeftAQ2-LeftQ2
691 G4ThreeVector Quark_Mom[4];
692 G4double Quark_Xs[4];
693 G4double AveragePt2 = 200.0*200.0, maxPtSquare = common.S, MassQ2 = 0.0, ScaleFactor = 1.0;
694 G4int NumberOfTries = 0, loopCounter = 0;
695 const G4int maxNumberOfLoops = 1000;
696 G4double Alfa = 0.0, Beta = 0.0;
697 G4double WminusTarget = 0.0, WplusProjectile = 0.0, Alfa_R = 0.5;
698 do {
699 // Sampling X's of the 2 quarks and 2 anti-quarks
700
701 G4double Product = 1.0;
702 for ( G4int iCase = 0; iCase < 2; ++iCase ) { // Loop over the two strings
703 G4double x = 0.0, r = G4UniformRand();
704 if ( Alfa_R == 1.0 ) {
705 if ( iCase == 0 ) { // first string
706 x = std::sqrt( r );
707 } else { // second string
708 x = 1.0 - std::sqrt( r );
709 }
710 } else {
711 x = sqr( std::sin( pi/2.0*r ) );
712 }
713 G4int index = iCase*2; // 0 for the first string, 2 for the second string
714 Quark_Xs[index] = x ; Quark_Xs[index+1] = 1.0 - x ;
715 Product *= x*(1.0-x);
716 }
717
718 if ( Product == 0.0 ) continue;
719
720 ++NumberOfTries;
721 if ( NumberOfTries == 100*(NumberOfTries/100) ) {
722 // After a large number of tries, it is better to reduce the values of <Pt^2>
723 ScaleFactor /= 2.0;
724 AveragePt2 *= ScaleFactor;
725 }
726
727 G4ThreeVector PtSum( 0.0, 0.0, 0.0 );
728 for( G4int i = 0; i < 4; ++i ) {
729 Quark_Mom[i] = GaussianPt( AveragePt2, maxPtSquare );
730 PtSum += Quark_Mom[i];
731 }
732
733 PtSum /= 4.0;
734 for ( G4int i = 0; i < 4; ++i ) {
735 Quark_Mom[i] -= PtSum;
736 }
737
738 Alfa = 0.0; Beta = 0.0;
739 for ( G4int iCase = 0; iCase < 2; ++iCase ) {
740 G4int index = iCase * 2;
741 for ( G4int i = 0; i < 2; ++i ) {
742 G4double val = ( Quark_Mom[index+i].mag2() + MassQ2 ) / Quark_Xs[index+i];
743 if ( iCase == 0 ) { // first string
744 Alfa += val;
745 } else { // second string
746 Beta += val;
747 }
748 }
749 }
750
751 } while ( ( std::sqrt( Alfa ) + std::sqrt( Beta ) > common.SqrtS ) &&
752 ++loopCounter < maxNumberOfLoops ); /* Loop checking, 10.08.2015, A.Ribon */
753
754 if ( loopCounter >= maxNumberOfLoops ) {
755 return 99; // unsuccessfully ended, nothing else can be done
756 }
757
758 G4double DecayMomentum2 = sqr(common.S) + sqr(Alfa) + sqr(Beta)
759 - 2.0*( common.S*(Alfa + Beta) + Alfa*Beta );
760 WminusTarget = ( common.S - Alfa + Beta + std::sqrt( DecayMomentum2 ) ) / 2.0 / common.SqrtS;
761 WplusProjectile = common.SqrtS - Beta/WminusTarget;
762
763 for ( G4int iCase = 0; iCase < 2; ++iCase ) { // Loop over the two strings
764 G4int index = iCase*2; // 0 for the first string, 2 for the second string
765 for ( G4int i = 0; i < 2; ++i ) {
766 G4double w = WplusProjectile; // For the first string
767 if ( iCase == 1 ) w = - WminusTarget; // For the second string
768 G4double Pz = w * Quark_Xs[index+i] / 2.0
769 - ( Quark_Mom[index+i].mag2() + MassQ2 ) /
770 ( 2.0 * w * Quark_Xs[index+i] );
771 Quark_Mom[index+i].setZ( Pz );
772 }
773 }
774
775 G4int CandidatsN = 0, CandAQ[9][2] = {}, CandQ[9][2] = {};
776 G4int LeftAQ1 = 0, LeftAQ2 = 0, LeftQ1 = 0, LeftQ2 = 0;
777 for ( G4int iAQ = 0; iAQ < 3; ++iAQ ) { // index of the 3 constituent anti-quarks of the antibaryon projectile
778 for ( G4int iQ = 0; iQ < 3; ++iQ ) { // index of the 3 constituent quarks of the nucleon target
779 if ( -common.AQ[iAQ] == common.Q[iQ] ) { // antiquark - quark that can annihilate
780 // Here "0", "1", "2" means, respectively, "first", "second" and "third" constituent
781 // of the (anti-baryon) projectile or (nucleon) target.
782 if ( iAQ == 0 ) { CandAQ[CandidatsN][0] = 1; CandAQ[CandidatsN][1] = 2; }
783 if ( iAQ == 1 ) { CandAQ[CandidatsN][0] = 0; CandAQ[CandidatsN][1] = 2; }
784 if ( iAQ == 2 ) { CandAQ[CandidatsN][0] = 0; CandAQ[CandidatsN][1] = 1; }
785 if ( iQ == 0 ) { CandQ[CandidatsN][0] = 1; CandQ[CandidatsN][1] = 2; }
786 if ( iQ == 1 ) { CandQ[CandidatsN][0] = 0; CandQ[CandidatsN][1] = 2; }
787 if ( iQ == 2 ) { CandQ[CandidatsN][0] = 0; CandQ[CandidatsN][1] = 1; }
788 ++CandidatsN;
789 }
790 }
791 }
792
793 if ( CandidatsN != 0 ) {
794 G4int SampledCase = (G4int)G4RandFlat::shootInt( CandidatsN );
795 LeftAQ1 = common.AQ[ CandAQ[SampledCase][0] ];
796 LeftAQ2 = common.AQ[ CandAQ[SampledCase][1] ];
797 if ( G4UniformRand() < 0.5 ) {
798 LeftQ1 = common.Q[ CandQ[SampledCase][0] ];
799 LeftQ2 = common.Q[ CandQ[SampledCase][1] ];
800 } else {
801 LeftQ2 = common.Q[ CandQ[SampledCase][0] ];
802 LeftQ1 = common.Q[ CandQ[SampledCase][1] ];
803 }
804
805 // Set the string properties
806 // An anti quark - quark pair can have the quantum number of either a scalar meson
807 // or a vector meson: the last digit of the PDG code is, respectively, 1 and 3.
808 // For simplicity only scalar is considered here.
809 G4int NewCode = 0, antiQuark = 0, quark = 0;
810 G4ParticleDefinition* TestParticle = nullptr;
811 for ( G4int iString = 0; iString < 2; ++iString ) { // Loop over the 2 string cases
812 if ( iString == 0 ) {
813 antiQuark = LeftAQ1; quark = LeftQ1;
814 projectile->SetFirstParton( antiQuark );
815 projectile->SetSecondParton( quark );
816 projectile->SetStatus( 0 );
817 } else { // iString == 1
818 quark = LeftQ2; antiQuark = LeftAQ2;
819 target->SetFirstParton( quark );
820 target->SetSecondParton( antiQuark );
821 target->SetStatus( 0 );
822 }
823 G4int absAntiQuark = std::abs( antiQuark ), absQuark = std::abs( quark );
824 G4double aKsi = G4UniformRand();
825 if ( absAntiQuark == absQuark ) {
826 if ( absAntiQuark != 3 ) {
827 NewCode = 111; // Pi0-meson
828 if ( aKsi < 0.5 ) {
829 NewCode = 221; // Eta -meson
830 if ( aKsi < 0.25 ) {
831 NewCode = 331; // Eta'-meson
832 }
833 }
834 } else {
835 NewCode = 221; // Eta -meson
836 if ( aKsi < 0.5 ) {
837 NewCode = 331; // Eta'-meson
838 }
839 }
840 } else {
841 if ( absAntiQuark > absQuark ) {
842 NewCode = absAntiQuark*100 + absQuark*10 + 1; NewCode *= absAntiQuark/antiQuark;
843 } else {
844 NewCode = absQuark*100 + absAntiQuark*10 + 1; NewCode *= absQuark/quark;
845 }
846 }
847 TestParticle = G4ParticleTable::GetParticleTable()->FindParticle( NewCode );
848 if ( ! TestParticle ) return 99; // unsuccessfully ended, nothing else can be done
849 if ( iString == 0 ) {
850 projectile->SetDefinition( TestParticle );
851 theParameters->SetProjMinDiffMass( 0.5 );
852 theParameters->SetProjMinNonDiffMass( 0.5 );
853 } else { // iString == 1
854 target->SetDefinition( TestParticle );
855 theParameters->SetTarMinDiffMass( 0.5 );
856 theParameters->SetTarMinNonDiffMass( 0.5 );
857 }
858 } // End of loop over the 2 string cases
859
860 G4int QuarkOrder[2];
861 G4LorentzVector Pstring1, Pstring2;
862 G4double Ystring1 = 0.0, Ystring2 = 0.0;
863
864 for ( G4int iCase = 0; iCase < 2; ++iCase ) { // Loop over the two strings
865 G4ThreeVector tmp = Quark_Mom[iCase] + Quark_Mom[iCase+2];
866 G4LorentzVector Pstring( tmp, std::sqrt( Quark_Mom[iCase].mag2() + MassQ2 ) +
867 std::sqrt( Quark_Mom[iCase+2].mag2() + MassQ2 ) );
868 // Add protection for rapidity = 0.5*ln( (E+Pz)/(E-Pz) )
869 G4double Ystring = 0.0;
870 if ( Pstring.e() > 1.0e-30 ) {
871 if ( Pstring.e() + Pstring.pz() < 1.0e-30 ) { // Very small numerator in the logarithm
872 Ystring = -1.0e30; // A very large negative value (E ~= -Pz)
873 if ( Pstring.e() - Pstring.pz() < 1.0e-30 ) { // Very small denominator in the logarithm
874 Ystring = 1.0e30; // A very large positive value (E ~= Pz)
875 } else { // Normal case
876 Ystring = Pstring.rapidity();
877 }
878 }
879 }
880 if ( iCase == 0 ) { // For the first string
881 Pstring1 = Pstring; Ystring1 = Ystring;
882 } else { // For the second string
883 Pstring2 = Pstring; Ystring2 = Ystring;
884 }
885 }
886 if ( Ystring1 > Ystring2 ) {
887 common.Pprojectile = Pstring1; common.Ptarget = Pstring2;
888 QuarkOrder[0] = 0; QuarkOrder[1] = 1;
889 } else {
890 common.Pprojectile = Pstring2; common.Ptarget = Pstring1;
891 QuarkOrder[0] = 1; QuarkOrder[1] = 0;
892 }
893
894 if ( common.RotateStrings ) {
895 common.Pprojectile *= common.RandomRotation;
896 common.Ptarget *= common.RandomRotation;
897 }
898
899 common.Pprojectile.transform( common.toLab );
900 common.Ptarget.transform( common.toLab );
901
902 G4LorentzVector Quark_4Mom[4];
903 for ( G4int i = 0; i < 4; ++i ) {
904 Quark_4Mom[i] = G4LorentzVector( Quark_Mom[i], std::sqrt( Quark_Mom[i].mag2() + MassQ2 ) );
905 if ( common.RotateStrings ) Quark_4Mom[i] *= common.RandomRotation;
906 Quark_4Mom[i].transform( common.toLab );
907 }
908
909 projectile->Splitting();
910 projectile->GetNextAntiParton()->Set4Momentum( Quark_4Mom[QuarkOrder[0]] );
911 projectile->GetNextParton()->Set4Momentum( Quark_4Mom[QuarkOrder[0]+2] );
912
913 target->Splitting();
914 target->GetNextParton()->Set4Momentum( Quark_4Mom[QuarkOrder[1]] );
915 target->GetNextAntiParton()->Set4Momentum( Quark_4Mom[QuarkOrder[1]+2] );
916
917 // Calculation of the creation time
918 // Creation time and position of target nucleon were determined in ReggeonCascade() of G4FTFModel
919 projectile->SetTimeOfCreation( target->GetTimeOfCreation() );
920 projectile->SetPosition( target->GetPosition() );
921 projectile->Set4Momentum( common.Pprojectile );
922 target->Set4Momentum( common.Ptarget );
923
924 projectile->IncrementCollisionCount( 1 );
925 target->IncrementCollisionCount( 1 );
926
927 return 0; // Completed successfully: nothing else to be done
928 } // End of if ( CandidatsN != 0 )
929
930 return 1; // Successfully ended, but the work is not over
931}
932
933
934//-----------------------------------------------------------------------
935
936G4bool G4FTFAnnihilation::
937Create1QuarkAntiQuarkString( G4VSplitableHadron* projectile,
938 G4VSplitableHadron* target,
939 G4FTFParameters* theParameters,
940 G4FTFAnnihilation::CommonVariables& common ) const {
941 // Simulation of anti-quark - quark string creation
942
943 #ifdef debugFTFannih
944 G4cout << "Process d, only 1 quark - anti-quark string" << G4endl;
945 #endif
946
947 // Determine the set of candidates anti-quark - quark pairs that do not annihilate.
948 // Here "0", "1", "2" means, respectively, "first", "second" and "third" constituent
949 // of the (anti-baryon) projectile or (nucleon) target.
950 G4int CandidatsN = 0, CandAQ[36], CandQ[36];
951 G4int LeftAQ = 0, LeftQ = 0;
952 for ( G4int iAQ1 = 0; iAQ1 < 3; ++iAQ1 ) {
953 for ( G4int iAQ2 = 0; iAQ2 < 3; ++iAQ2 ) {
954 if ( iAQ1 != iAQ2 ) {
955 for ( G4int iQ1 = 0; iQ1 < 3; ++iQ1 ) {
956 for ( G4int iQ2 = 0; iQ2 < 3; ++iQ2 ) {
957 if ( iQ1 != iQ2 ) {
958 if ( -common.AQ[iAQ1] == common.Q[iQ1] && -common.AQ[iAQ2] == common.Q[iQ2] ) {
959 if ( ( iAQ1 == 0 && iAQ2 == 1 ) || ( iAQ1 == 1 && iAQ2 == 0 ) ) {
960 CandAQ[CandidatsN] = 2;
961 } else if ( ( iAQ1 == 0 && iAQ2 == 2 ) || ( iAQ1 == 2 && iAQ2 == 0 ) ) {
962 CandAQ[CandidatsN] = 1;
963 } else if ( ( iAQ1 == 1 && iAQ2 == 2 ) || ( iAQ1 == 2 && iAQ2 == 1 ) ) {
964 CandAQ[CandidatsN] = 0;
965 }
966 if ( ( iQ1 == 0 && iQ2 == 1 ) || ( iQ1 == 1 && iQ2 == 0 ) ) {
967 CandQ[CandidatsN] = 2;
968 } else if ( ( iQ1 == 0 && iQ2 == 2 ) || ( iQ1 == 2 && iQ2 == 0 ) ) {
969 CandQ[CandidatsN] = 1;
970 } else if ( ( iQ1 == 1 && iQ2 == 2 ) || ( iQ1 == 2 && iQ2 == 1 ) ) {
971 CandQ[CandidatsN] = 0;
972 }
973 ++CandidatsN;
974 }
975 }
976 }
977 }
978 }
979 }
980 }
981
982 if ( CandidatsN != 0 ) {
983 G4int SampledCase = (G4int)G4RandFlat::shootInt( CandidatsN );
984 LeftAQ = common.AQ[ CandAQ[SampledCase] ];
985 LeftQ = common.Q[ CandQ[SampledCase] ];
986
987 // Set the string properties
988 projectile->SetFirstParton( LeftQ );
989 projectile->SetSecondParton( LeftAQ );
990 projectile->SetStatus( 0 );
991 G4int aAQ = std::abs( LeftAQ ), aQ = std::abs( LeftQ );
992 G4int NewCode = 0;
993 G4double aKsi = G4UniformRand();
994 // The string can have the quantum number of either a scalar or a vector (whose last digit
995 // of the PDG code is, respectively, 1 and 3). For simplicity only scalar is considered here.
996 if ( aAQ == aQ ) {
997 if ( aAQ != 3 ) {
998 NewCode = 111; // Pi0-meson
999 if ( aKsi < 0.5 ) {
1000 NewCode = 221; // Eta -meson
1001 if ( aKsi < 0.25 ) {
1002 NewCode = 331; // Eta'-meson
1003 }
1004 }
1005 } else {
1006 NewCode = 221; // Eta -meson
1007 if ( aKsi < 0.5 ) {
1008 NewCode = 331; // Eta'-meson
1009 }
1010 }
1011 } else {
1012 if ( aAQ > aQ ) {
1013 NewCode = aAQ*100 + aQ*10 + 1; NewCode *= aAQ/LeftAQ;
1014 } else {
1015 NewCode = aQ*100 + aAQ*10 + 1; NewCode *= aQ/LeftQ;
1016 }
1017 }
1018
1020 if ( ! TestParticle ) return false;
1021 projectile->SetDefinition( TestParticle );
1022 theParameters->SetProjMinDiffMass( 0.5 );
1023 theParameters->SetProjMinNonDiffMass( 0.5 );
1024
1025 target->SetStatus( 4 ); // The target nucleon has annihilated 3->4
1026 common.Pprojectile.setPx( 0.0 );
1027 common.Pprojectile.setPy( 0.0 );
1028 common.Pprojectile.setPz( 0.0 );
1029 common.Pprojectile.setE( common.SqrtS );
1030
1031 common.Pprojectile.transform( common.toLab );
1032
1033 G4LorentzVector Pquark = G4LorentzVector( 0.0, 0.0, -common.SqrtS/2.0, common.SqrtS/2.0 );
1034 G4LorentzVector Paquark = G4LorentzVector( 0.0, 0.0, +common.SqrtS/2.0, common.SqrtS/2.0 );
1035
1036 if ( common.RotateStrings ) {
1037 Pquark *= common.RandomRotation; Paquark *= common.RandomRotation;
1038 }
1039 Pquark.transform(common.toLab); projectile->GetNextParton()->Set4Momentum(Pquark);
1040 Paquark.transform(common.toLab); projectile->GetNextAntiParton()->Set4Momentum(Paquark);
1041
1042 projectile->Splitting();
1043
1044 // Calculation of the creation time
1045 // Creation time and position of target nucleon were determined in ReggeonCascade() of G4FTFModel
1046 projectile->SetTimeOfCreation( target->GetTimeOfCreation() );
1047 projectile->SetPosition( target->GetPosition() );
1048 projectile->Set4Momentum( common.Pprojectile );
1049
1050 projectile->IncrementCollisionCount( 1 );
1051 target->IncrementCollisionCount( 1 );
1052
1053 return true;
1054 } // End of if ( CandidatsN != 0 )
1055
1056 return true;
1057}
1058
1059
1060//============================================================================
1061
1062G4double G4FTFAnnihilation::ChooseX( G4double /* Alpha */, G4double /* Beta */ ) const {
1063 // If for sampling Xs other values of Alfa and Beta instead of 0.5 will be
1064 // chosen the method will be implemented
1065 //G4double tmp = Alpha*Beta;
1066 //tmp *= 1.0;
1067 return 0.5;
1068}
1069
1070
1071//============================================================================
1072
1073G4ThreeVector G4FTFAnnihilation::GaussianPt( G4double AveragePt2, G4double maxPtSquare ) const {
1074 // @@ this method is used in FTFModel as well. Should go somewhere common!
1075 G4double Pt2 = 0.0;
1076 if ( AveragePt2 <= 0.0 ) {
1077 Pt2 = 0.0;
1078 } else {
1079 Pt2 = -AveragePt2 * G4Log( 1.0 + G4UniformRand() *
1080 ( G4Exp( -maxPtSquare/AveragePt2 ) -1.0 ) );
1081 }
1082 G4double Pt = std::sqrt( Pt2 );
1083 G4double phi = G4UniformRand() * twopi;
1084 return G4ThreeVector ( Pt*std::cos( phi ), Pt*std::sin( phi ), 0.0 );
1085}
1086
1087
1088//============================================================================
1089
1090void G4FTFAnnihilation::UnpackBaryon( G4int IdPDG, G4int& Q1, G4int& Q2, G4int& Q3 ) const {
1091 G4int AbsId = std::abs( IdPDG );
1092 Q1 = AbsId / 1000;
1093 Q2 = ( AbsId % 1000 ) / 100;
1094 Q3 = ( AbsId % 100 ) / 10;
1095 if ( IdPDG < 0 ) { Q1 = -Q1; Q2 = -Q2; Q3 = -Q3; } // Anti-baryon
1096 return;
1097}
1098
1099
1100//============================================================================
1101
1103 throw G4HadronicException( __FILE__, __LINE__,
1104 "G4FTFAnnihilation copy constructor not meant to be called" );
1105}
1106
1107
1108//============================================================================
1109
1110const G4FTFAnnihilation & G4FTFAnnihilation::operator=( const G4FTFAnnihilation& ) {
1111 throw G4HadronicException( __FILE__, __LINE__,
1112 "G4FTFAnnihilation = operator not meant to be called" );
1113}
1114
1115
1116//============================================================================
1117
1118G4bool G4FTFAnnihilation::operator==( const G4FTFAnnihilation& ) const {
1119 throw G4HadronicException( __FILE__, __LINE__,
1120 "G4FTFAnnihilation == operator not meant to be called" );
1121}
1122
1123
1124//============================================================================
1125
1126G4bool G4FTFAnnihilation::operator!=( const G4FTFAnnihilation& ) const {
1127 throw G4HadronicException( __FILE__, __LINE__,
1128 "G4DiffractiveExcitation != operator not meant to be called" );
1129}
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
G4double G4Log(G4double x)
Definition: G4Log.hh:227
CLHEP::HepLorentzVector G4LorentzVector
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
double mag2() const
void setZ(double)
HepLorentzRotation & rotateY(double delta)
HepLorentzRotation & rotateZ(double delta)
HepLorentzRotation inverse() const
double theta() const
Hep3Vector boostVector() const
HepLorentzVector & transform(const HepRotation &)
virtual ~G4FTFAnnihilation()
virtual G4bool Annihilate(G4VSplitableHadron *aPartner, G4VSplitableHadron *bPartner, G4VSplitableHadron *&AdditionalString, G4FTFParameters *theParameters) const
void SetTarMinNonDiffMass(const G4double aValue)
void SetProjMinDiffMass(const G4double aValue)
void SetTarMinDiffMass(const G4double aValue)
void SetProjMinNonDiffMass(const G4double aValue)
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
void Set4Momentum(const G4LorentzVector &aMomentum)
Definition: G4Parton.hh:148
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
G4double powA(G4double A, G4double y) const
Definition: G4Pow.hh:230
void SetTimeOfCreation(G4double aTime)
void SetStatus(const G4int aStatus)
const G4ParticleDefinition * GetDefinition() const
void Set4Momentum(const G4LorentzVector &a4Momentum)
virtual G4Parton * GetNextParton()=0
virtual void SetSecondParton(G4int PDGcode)=0
virtual G4Parton * GetNextAntiParton()=0
void SetDefinition(const G4ParticleDefinition *aDefinition)
const G4LorentzVector & Get4Momentum() const
const G4ThreeVector & GetPosition() const
void IncrementCollisionCount(G4int aCount)
virtual void SetFirstParton(G4int PDGcode)=0
void SetPosition(const G4ThreeVector &aPosition)
T sqr(const T &x)
Definition: templates.hh:128