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 ( const G4QNucleus aNucleus,
const G4QHadron aPrimary 
)

Definition at line 68 of file G4QFragmentation.cc.

References G4QString::Boost(), G4QNucleus::ChooseImpactXandY(), G4QNucleus::CoulombBarrier(), DBL_MAX, G4QPartonPair::DIFFRACTIVE, G4QNucleus::DoLorentzBoost(), G4QNucleus::DoLorentzRotation(), ExciteDiffParticipants(), ExciteSingDiffParticipants(), FatalException, G4cerr, G4cout, G4endl, G4Exception(), G4UniformRand, G4QCHIPSWorld::Get(), G4QParton::Get4Momentum(), G4QString::Get4Momentum(), G4QHadron::Get4Momentum(), G4QNucleus::GetA(), G4QHadron::GetAntiColor(), G4QHadron::GetBaryonNumber(), G4QHadron::GetCharge(), G4QPartonPair::GetCollisionType(), G4QHadron::GetColor(), G4QProbability::GetCutPomProbability(), G4QNucleus::GetGSMass(), G4QHadron::GetMass(), G4QNucleus::GetN(), G4QHadron::GetNextAntiParton(), G4QNucleus::GetNextNucleon(), G4QHadron::GetNextParton(), G4QNucleus::GetNucleons4Momentum(), G4QNucleus::GetOuterRadius(), G4QNucleus::GetPDG(), G4QParton::GetPDGCode(), G4QHadron::GetPDGCode(), G4QDiffractionRatio::GetPointer(), G4QuasiFreeRatios::GetPointer(), G4QProbability::GetPomDiffProbability(), G4QProbability::GetPomInelProbability(), G4QHadron::GetPosition(), G4QHadron::GetQC(), G4QDiffractionRatio::GetRatio(), G4QuasiFreeRatios::GetRatios(), G4QContent::GetSPDGCode(), G4QNucleus::GetThickness(), G4QParton::GetType(), G4QNucleus::GetZ(), G4QHadron::IncrementCollisionCount(), G4QNucleus::Init3D(), G4QNucleus::InitByPDG(), IsSingleDiffractive(), LT, G4QPDGCode::MakeTwoBaryons(), G4QPartonPair::PROJECTILE, G4QDiffractionRatio::ProjFragment(), G4QParton::ReduceDiQADiQ(), G4QuasiFreeRatios::Scatter(), G4QParton::Set4Momentum(), G4QHadron::Set4Momentum(), G4QInteraction::SetNumberOfDiffractiveCollisions(), G4QInteraction::SetNumberOfDINRCollisions(), G4QInteraction::SetNumberOfSoftCollisions(), G4QParton::SetPDGCode(), G4QInteraction::SetTarget(), G4InuclParticleNames::sm, G4QPartonPair::SOFT, sqr(), G4QNucleus::StartLoop(), G4QNucleus::SubtractNucleon(), SwapPartons(), and G4QPartonPair::TARGET.

00069 {
00070   static const G4double mProt= G4QPDGCode(2212).GetMass(); // Mass of proton
00071   static const G4double mProt2= mProt*mProt;               // SquaredMass of proton
00072   static const G4double mPi0= G4QPDGCode(111).GetMass();   // Mass of Pi0
00073   static const G4double thresh= 1000;                      // Diffraction threshold (MeV)
00074   theWorld= G4QCHIPSWorld::Get();                          // Pointer to CHIPS World
00075   theQuasiElastic=G4QuasiFreeRatios::GetPointer();         // Pointer to CHIPS quasiElastic
00076   theDiffraction=G4QDiffractionRatio::GetPointer();        // Pointer to CHIPS Diffraction
00077   theResult = new G4QHadronVector;        // Define theResultingHadronVector
00078   G4bool stringsInitted=false;            // Strings are initiated
00079   G4QHadron aProjectile = aPrimary;       // As a primary is const
00080   G4LorentzRotation toZ;                  // Lorentz Transformation to the projectileSystem
00081   G4LorentzVector proj4M=aProjectile.Get4Momentum(); // Projectile 4-momentum in LS
00082 #ifdef edebug
00083   G4LorentzVector targ4M=aProjectile.Get4Momentum(); // Target 4-momentum in LS
00084   G4double tgMass=aNucleus.GetGSMass();   // Ground state mass of the nucleus
00085   G4double cM=0.;
00086   G4double cs=(proj4M+targ4M).mag2();   // s of the compound
00087   if(cs > 0.) cM=std::sqrt(cs);
00088   G4cout<<"G4QFragmentation::Construct: *Called*, p4M="<<proj4M<<", A="<<aNucleus<<tgMass
00089         <<",M="<<cM<<",s="<<cs<<",t4M="<<targ4M<<G4endl;
00090 #endif
00091   G4int tZ=aNucleus.GetZ();
00092   G4int tN=aNucleus.GetN();
00093   G4int tPDG=90000000+tZ*1000+tN;
00094   toZ.rotateZ(-proj4M.phi());
00095   toZ.rotateY(-proj4M.theta());
00096   G4LorentzVector zProj4M=toZ*proj4M;     // Proj 4-momentum in LS rotated to Z axis
00097   aProjectile.Set4Momentum(zProj4M);      // Now the projectile moves along Z axis
00098 #ifdef edebug
00099   G4int totChg=aProjectile.GetCharge()+tZ;// Charge of the projectile+target for the CHECK
00100   G4int totBaN=aProjectile.GetBaryonNumber()+tZ+tN;// Baryon Number of Proj+Targ for CHECK
00101   G4LorentzVector tgLS4M(0.,0.,0.,tgMass);// Target 4-momentum in LS
00102   G4LorentzVector totLS4M=proj4M+tgLS4M;  // Total 4-momentum in LS
00103   G4LorentzVector totZLS4M=zProj4M+tgLS4M;// Total 4-momentum in LS with momentum along Z
00104   G4cout<<"-EMC-G4QFragmentation::Construct:tLS4M="<<totLS4M<<",tZLS4M="<<totZLS4M<<G4endl;
00105   // === From nere all consideration is made in the rotated LS frame (proj is along Z) ===
00106 #endif
00107   G4LorentzRotation toLab(toZ.inverse()); // Lorentz Transfornation "ZLS"->LS (at the end)
00108   G4int pPDG=aProjectile.GetPDGCode();    // The PDG code of the projectile
00109   G4double projM=aProjectile.GetMass();   // Mass of the projectile
00110   G4QInteractionVector theInteractions;   // A vector of interactions (taken from the Body)
00111   G4QPartonPairVector  thePartonPairs;    // The parton pairs (taken from the Body)
00112   G4int                ModelMode=SOFT;    // The current model type (taken from the Body)
00113   theNucleus=G4QNucleus(tZ,tN);           // Create theNucleus (Body) to Move From LS to CM
00114   theNucleus.InitByPDG(tPDG);             // Reinit the Nucleus for the new Attempt
00115 #ifdef debug
00116   G4cout<<"G4QFragmentation::Construct: Nucleus4Mom="<<theNucleus.Get4Momentum()<<G4endl;
00117 #endif
00118   theNucleus.Init3D();                    // 3D-initialisation(nucleons) of theNucleusClone
00119   // Now we can make the Quasi-Elastic (@@ Better to select a nucleon from the perifery)
00120   std::pair<G4double,G4double> ratios=std::make_pair(0.,0.);
00121   G4int apPDG=std::abs(pPDG);
00122   if(apPDG>99)                            // Diffraction or Quasi-elastic 
00123   {
00124    G4double pMom=proj4M.vect().mag();                  // proj.Momentum in MeV (indepUnits)
00125    ratios = theQuasiElastic->GetRatios(pMom, pPDG, tZ, tN);
00126    G4double qeRat = ratios.first*ratios.second;        // quasi-elastic part [qe/in]
00127    G4double difRat= theDiffraction->GetRatio(pMom, pPDG, tZ, tN); // diffrPart [d/(in-qe)]
00128    //if(qeRat < 1.) difRat /= (1.-qeRat)*.5;             // Double for Top/Bottom @@ ?
00129    if(qeRat<1. && proj4M.e()>thresh) difRat /= 1.-qeRat; // Both Top & Bottom
00130    else difRat=0.;                                     // Close diffraction for low Energy
00131    difRat += qeRat;                                    // for the diffraction selection
00132    G4double rnd=G4UniformRand();
00133    if(rnd < qeRat)                                     // --> Make Quasi-Elastic reaction
00134    {
00135     theNucleus.StartLoop();                            // Prepare Loop ovder nucleons
00136     G4QHadron* pNucleon = theNucleus.GetNextNucleon(); // Get the next nucleon to try
00137     G4LorentzVector pN4M=pNucleon->Get4Momentum();     // Selected Nucleon 4-momentum
00138     G4int pNPDG=pNucleon->GetPDGCode();                // Selected Nucleon PDG code
00139 #ifdef debug
00140     G4cout<<">QE>G4QFragmentation::Construct:TryQE,R="<<ratios.first*ratios.second<<",N4M="
00141           <<pN4M<<",NPDG="<<pNPDG<<G4endl;
00142 #endif
00143     std::pair<G4LorentzVector,G4LorentzVector> QEout=theQuasiElastic->Scatter(pNPDG,pN4M,
00144                                                                               pPDG,proj4M);
00145     G4bool CoulB = true;                               // No Under Coulomb Barrier flag
00146     G4double CB=theNucleus.CoulombBarrier(1, 1);       // Coulomb barrier for protons
00147     if( (pNPDG==2212 && QEout.first.e()-mProt < CB) ||
00148         (pPDG==2212 && QEout.second.e()-mProt < CB) ) CoulB = false; // at least one UCB
00149     if(QEout.first.e() > 0 && CoulB)                   // ==> Successful scattering
00150     {
00151       G4QHadron* qfN = new G4QHadron(pNPDG,QEout.first);
00152       theResult->push_back(qfN);                       // Scattered Quasi-free nucleon  
00153       G4QHadron* qfP = new G4QHadron(pPDG,QEout.second);
00154       theResult->push_back(qfP);                       // Scattered Projectile  
00155       theNucleus.SubtractNucleon(pNucleon);            // Exclude the used nucleon from Nuc
00156       G4LorentzVector r4M=theNucleus.Get4Momentum();   // Nucleus 4-momentum in LS
00157       G4int rPDG=theNucleus.GetPDG();                  // Nuclear PDG
00158       G4QHadron* resNuc = new G4QHadron(rPDG,r4M);     // The residual Nucleus
00159       theResult->push_back(resNuc);                    // Fill the residual nucleus
00160 #ifdef debug
00161       G4cout<<"-->QE-->G4QFragmentation::Construct:QEDone, N4M="<<QEout.first<<", p4M="
00162             <<QEout.second<<G4endl;
00163 #endif
00164       return;                                          // The Quasielastic is the only act
00165     }
00166    } // End of quasi-elastic reaction
00167    else if(rnd < difRat)                               // --> Make diffractive reaction
00168    {
00169 #ifdef debug
00170      G4cout<<"-->Dif-->G4QFragmentation::Construct: qe="<<qeRat<<", dif="<<difRat-qeRat
00171            <<",P="<<proj4M.vect().mag()<<", tZ="<<tZ<<", tN="<<tN<<G4endl;
00172 #endif
00173      G4QHadronVector* out=0;
00174      //if(G4UniformRand()>0.5) out=theDiffraction->TargFragment(pPDG, proj4M, tZ, tN);
00175      //else                    out=theDiffraction->ProjFragment(pPDG, proj4M, tZ, tN);
00176      //theDiffraction->TargFragment(pPDG, proj4M, tZ, tN); // !! is not debugged !!
00177      out=theDiffraction->ProjFragment(pPDG, proj4M, tZ, tN);
00178      G4int nSec=out->size();                           // #of secondaries in diffReaction
00179      if(nSec>1) for(G4int i=0; i<nSec; i++) theResult->push_back((*out)[i]);
00180      else if(nSec>0)
00181      {
00182 #ifdef debug
00183        G4cout<<"-Warning-G4QFragmentation::Construct: 1 secondary in Diffractionp 4M="
00184              <<proj4M<<", s4M="<<(*out)[0]->Get4Momentum()<<G4endl;
00185 #endif
00186        delete (*out)[0];
00187      }
00188      out->clear();                                     // Clean up the output QHadronVector
00189      delete out;                                       // Delete the output QHadronVector
00190      if(nSec>1) return;
00191    } // End of diffraction
00192   }
00193 #ifdef edebug
00194   G4LorentzVector sum1=theNucleus.GetNucleons4Momentum(); // Sum ofNucleons4M inRotatedLS
00195   G4cout<<"-EMC-G4QFragmentation::Construct: Nuc4M="<<sum1<<G4endl;
00196 #endif
00197   G4ThreeVector theCurrentVelocity(0.,0.,0.);        // "CM" velosity (temporary)
00198   // @@ "target Nucleon" == "Proton at rest" case (M.K. ?)
00199   G4double nCons = 1;                                // 1 or baryonNum of the Projectile
00200   G4int projAbsB=std::abs(aProjectile.GetBaryonNumber());// Fragment/Baryon (Meson/AntiB)
00201   if(projAbsB>1) nCons = projAbsB;                   // @@ what if this is a meson ?
00202   // Very important! Here the projectile 4M is recalculated in the ZLS (previously in LS)
00203   proj4M = aProjectile.Get4Momentum();               // 4-mom of theProjectileHadron inZLS
00204   G4double pz_per_projectile = proj4M.pz()/nCons;    // Momentum per nucleon (hadron?)
00205   // @@ use M_A/A instead of mProt ------------ M.K.
00206   G4double e_per_projectile = proj4M.e()/nCons+mProt;// @@ Add MassOfTargetProtonAtRest
00207   G4double vz = pz_per_projectile/e_per_projectile;  // Speed of the "oneNuclenCM"
00208 #ifdef debug
00209   G4cout<<"G4QFragmentation::Construct: Projectile4M="<<proj4M<<", Vz="<<vz<<", nC="
00210         <<nCons<<", pE="<<e_per_projectile<<G4endl;
00211 #endif
00212   theCurrentVelocity.setZ(vz);                       // CM (w/r to one nucleon) velosity
00213   theNucleus.DoLorentzBoost(-theCurrentVelocity);    // BoostTgNucleus to"CM"
00214 #ifdef edebug
00215   G4LorentzVector sum2=theNucleus.GetNucleons4Momentum();// Sum of Nucleons 4M in RotatedCM
00216   G4cout<<"-EMC-G4QFragmentation::Construct: AfterBoost, v="<<vz<<", Nuc4M="<<sum2<<G4endl;
00217 #endif
00218   G4LorentzVector cmProjMom = proj4M;                // Copy the original proj4M in LS
00219   cmProjMom.boost(-theCurrentVelocity);              // Bring the LS proj4Mom to "CM"
00220   G4double kE=cmProjMom.e()-projM;
00221 #ifdef debug
00222   G4cout<<"G4QFragmentation::Construct: kE="<<kE<<G4endl;
00223 #endif
00224   G4int maxCt=1;
00225   if(kE > 720.) maxCt=static_cast<int>(std::log(kE/270.)); // 270 MeV !
00226   // @@ The maxCuts can improve the performance at low energies
00227   //G4int maxCuts = 7;
00228   G4int maxCuts=std::min( 7 , std::max(1, maxCt) );
00229 #ifdef debug
00230   G4cout<<"G4QFragmentation::Construct: Proj4MInCM="<<cmProjMom<<", pPDG="<<pPDG<<G4endl;
00231 #endif
00232   //
00233   // ---------->> Find collisions meeting collision conditions
00234   //
00235   G4QHadron* cmProjectile = new G4QHadron(pPDG,cmProjMom); // HipCopy of the CMProjectile
00236   // @@ Do not forget to delete the probability! 
00237   G4QProbability theProbability(pPDG);               // thePDG must be a data member
00238   G4double outerRadius = theNucleus.GetOuterRadius();// Get the nucleus frontiers
00239 #ifdef debug
00240   G4cout<<"G4QFrag::Constr:OutR="<<outerRadius<<",mC="<<maxCuts<<",A="<<theNucleus<<G4endl;
00241 #endif
00242   G4QHadron* pNucleon=0;
00243   // Check the reaction threshold 
00244   G4int theNA=theNucleus.GetA();
00245   G4LorentzVector pNuc4M=theNucleus.Get4Momentum()/theNA;
00246   G4double s_value = (cmProjMom + pNuc4M).mag2();          // Squared CM Energy of compound
00247   G4double ThresholdMass = projM + theNucleus.GetGSMass()/theNA;
00248 #ifdef debug
00249   G4cout<<"G4QFrag::Construc: p4M="<<cmProjMom<<", tgN4M="<<pNuc4M<<", s="<<s_value<<", ThreshM="
00250         <<ThresholdMass<<G4endl;
00251 #endif
00252   ModelMode = SOFT;                                  // NOT-Diffractive hadronization
00253   if (s_value < 0.)                                  // At ThP=0 is impossible(virtNucl)
00254   {
00255     G4cerr<<"***G4QFragmentation::Construct: s="<<s_value<<", pN4M="<<pNuc4M<<G4endl;
00256     G4Exception("G4QFragmentation::Construct:","72",FatalException,"LowEnergy(NegativeS)");
00257   }
00258   else if(s_value < mProt2)
00259   {
00260     theNucleus.StartLoop();                          // To get the same nucleon
00261     G4QHadron* aTarget=0;                            // Prototype of the target
00262     G4QHadron* pProjectile=0;                        // Prototype of the projectile
00263     G4QHadron* bNucleon=0;                           // Prototype of the best nucleon
00264     G4double   maxS=0.;                              // Maximum s found
00265     while((bNucleon=theNucleus.GetNextNucleon()))    // Loop over all nuclei to get theBest
00266     {
00267       G4LorentzVector cp4M=bNucleon->Get4Momentum(); // 4-mom of the current nucleon
00268       G4double cs=(cmProjMom + cp4M).mag2();         // Squared CM Energy of compound
00269       if(cs > maxS)                                  // Remember nucleon with the biggest s
00270       {
00271         maxS=cs;
00272         pNucleon=bNucleon;
00273       }
00274     }
00275     aTarget = new G4QHadron(*pNucleon);              // Copy selected nucleon for String
00276     pProjectile =cmProjectile;
00277     theNucleus.DoLorentzBoost(theCurrentVelocity);   // Boost theResNucleus toRotatedLS
00278     theNucleus.SubtractNucleon(pNucleon);            // Pointer to theUsedNucleon to delete
00279     theNucleus.DoLorentzBoost(-theCurrentVelocity);  // Boost theResNucleus back to CM
00280     G4QContent QQC=aTarget->GetQC()+pProjectile->GetQC(); // QContent of the compound
00281     G4LorentzVector Q4M=aTarget->Get4Momentum()+pProjectile->Get4Momentum(); // 4-mom of Q
00282     delete aTarget;
00283     delete pProjectile;
00284     //if(maxNuc>1)                                     // Absorb moreNucleons to theQuasmon
00285     //{
00286     //  for(G4int i=1; i<maxNuc; ++i)
00287     //  {
00288     //    pNucleon=theNucleus.GetNextNucleon();        // Get the next nucleon
00289     //    QQC+=pNucleon->GetQC();                      // Add it to the Quasmon
00290     //    Q4M+=pNucleon->Get4Momentum();
00291     //    theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
00292     //    theNucleus.SubtractNucleon(pNucleon);        // Exclude the used nucleon from Nuc
00293     //    theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
00294     //  }
00295     //}
00296     // 4-Mom should be converted to LS
00297     Q4M.boost(theCurrentVelocity);
00298     Q4M=toLab*Q4M;
00299     G4Quasmon* stringQuasmon = new G4Quasmon(QQC, Q4M);
00300     theQuasmons.push_back(stringQuasmon);
00301     theNucleus.DoLorentzBoost(theCurrentVelocity);   // BoostTheResidualNucleus toRotatedLS
00302     theNucleus.DoLorentzRotation(toLab);// Recove Z-direction in LS ("LS"->LS) for rNucleus
00303     return;
00304   }
00305   if (s_value < sqr(ThresholdMass))                    // --> Only diffractive interaction
00306   {
00307 #ifdef debug
00308     G4cout<<"G4QFragmentation::Construct:*OnlyDiffraction*ThM="<<ThresholdMass<<">sqrt(s)="
00309           <<std::sqrt(s_value)<<" -> only Diffraction is possible"<<G4endl; // @@ Dif toQuasmon
00310 #endif
00311     ModelMode = DIFFRACTIVE;
00312   }
00313   // Clean up all previous interactions and reset the counters
00314 #ifdef debug
00315   G4cout<<"G4QFragmentation::Construct: theIntSize="<<theInteractions.size()<<G4endl;
00316 #endif
00317   std::for_each(theInteractions.begin(),theInteractions.end(), DeleteQInteraction());
00318   theInteractions.clear();
00319   G4int totalCuts = 0;
00320   G4int attCnt=0;
00321   //G4int maxAtt=227;
00322   G4int maxAtt=27;
00323   G4double prEn=proj4M.e();                           // For mesons
00324   G4int proB=aProjectile.GetBaryonNumber();
00325   if     (proB>0) prEn-=aProjectile.GetMass();        // For baryons
00326   else if(proB<0) prEn+=mProt;                        // For anti-baryons
00327 #ifdef debug
00328   G4double impactUsed = 0.;
00329   G4cout<<"G4QFragmentation::Construct: estimated energy, prEn="<<prEn<<G4endl;
00330 #endif
00331   while(!theInteractions.size() && ++attCnt < maxAtt) // Till Interaction is created
00332   {
00333 #ifdef debug
00334     G4cout<<"G4QFragmentation::Construct: *EnterTheInteractionLOOP*, att#"<<attCnt<<G4endl;
00335 #endif
00336     // choose random impact parameter
00337     std::pair<G4double, G4double> theImpactParameter;
00338     theImpactParameter = theNucleus.ChooseImpactXandY(outerRadius);
00339     G4double impactX = theImpactParameter.first; 
00340     G4double impactY = theImpactParameter.second;
00341 #ifdef debug
00342     G4cout<<"G4QFragmentation::Construct: Impact Par X="<<impactX<<", Y="<<impactY<<G4endl;
00343 #endif
00344     G4double impar=std::sqrt(impactX*impactX+impactY*impactY);   
00345     G4int nA=theNucleus.GetA();
00346     G4double eflen=theNucleus.GetThickness(impar);   // EffectiveLength
00347     maxEn=eflen*stringTension;                       // max absorbed energy in IndUnits=MeV
00348     maxNuc=static_cast<int>(eflen*tubeDensity+0.5);  // max #0f involved nuclear nucleons
00349 #ifdef debug
00350     G4cout<<"G4QFragment::Construct: pE="<<prEn<<" <? mE="<<maxEn<<", mN="<<maxNuc<<G4endl;
00351 #endif
00352     if(prEn < maxEn)                                 // Create DIN interaction and go out
00353     {
00354       theNucleus.StartLoop();                        // Initialize newSelection forNucleons
00355       pNucleon=theNucleus.GetNextNucleon();          // Select a nucleon
00356       G4QHadron* aTarget = new G4QHadron(*pNucleon); // Copy selected nucleon for String
00357       G4QInteraction* anInteraction = new G4QInteraction(cmProjectile);
00358       anInteraction->SetTarget(aTarget); 
00359       anInteraction->SetNumberOfDINRCollisions(1);   // Consider this interaction as DINR
00360       theInteractions.push_back(anInteraction);      //--> now theInteractions not empty
00361       theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
00362       theNucleus.SubtractNucleon(pNucleon);          // Pointer to the used nucleon
00363       theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
00364 #ifdef debug
00365       G4cout<<"G4QFragmentation::Construct: DINR interaction is created"<<G4endl;
00366 #endif
00367       break;                                         // Break the WHILE of interactions
00368     }
00369     // LOOP over nuclei of the target nucleus to select collisions
00370     theNucleus.StartLoop();                          // To get the same nucleon
00371     G4int nucleonCount = 0;
00372 #ifdef debug
00373     G4cout<<"G4QFragment::Construct:BeforeWhileOveNuc, A="<<nA<<",p4M="<<cmProjMom<<G4endl;
00374 #endif
00375     while( (pNucleon=theNucleus.GetNextNucleon()) && nucleonCount<nA && totalCuts<maxCuts)
00376     {
00377       ++nucleonCount;
00378       // Needs to be moved to Probability class @@@
00379       s_value = (cmProjMom + pNucleon->Get4Momentum()).mag2();
00380 #ifdef debug
00381       G4cout<<"G4QFrag::Constr:N# "<<nucleonCount<<", s="<<s_value<<", tgN4M="
00382             <<pNucleon->Get4Momentum()<<G4endl;
00383 #endif
00384       if(s_value<=10000.)
00385       {
00386 #ifdef debug
00387         G4cout<<"G4QFragmentation::Construct: SKIP, s<.01 GeV^2, p4M="<<cmProjMom
00388               <<",t4M="<<pNucleon->Get4Momentum()<<G4endl;
00389 #endif
00390         continue;
00391       }
00392 #ifdef sdebug
00393       G4cout<<"G4QFragmentation::Construct:LOOPovNuc,nC="<<nucleonCount<<", s="<<s_value<<G4endl;
00394       G4cout<<"G4QFragmentation::Construct:LOOPovNuc, R="<<pNucleon->GetPosition()<<G4endl;
00395 #endif
00396       G4double Distance2 = sqr(impactX - pNucleon->GetPosition().x()) +
00397                            sqr(impactY - pNucleon->GetPosition().y());
00398 #ifdef sdebug
00399       G4cout<<"G4QFragmentation::Construct: s="<<s_value<<", D2="<<Distance2<<G4endl;
00400 #endif
00401       G4double Probability = theProbability.GetPomInelProbability(s_value, Distance2); // PomINEL
00402       // test for inelastic collision
00403 #ifdef sdebug
00404       G4cout<<"G4QFragmentation::Construct: Probubility="<<Probability<<G4endl;
00405 #endif
00406       G4double rndNumber = G4UniformRand();           // For the printing purpose
00407       // ModelMode = DIFFRACTIVE;
00408 #ifdef sdebug
00409       G4cout<<"G4QFragmentation::Construct: NLOOP prob="<<Probability<<", rndm="<<rndNumber
00410             <<", d="<<std::sqrt(Distance2)<<G4endl;
00411 #endif
00412       if (Probability > rndNumber) // Inelastic (diffractive or soft) interaction (JOB)
00413       {
00414         G4QHadron* aTarget = new G4QHadron(*pNucleon);// Copy for String (ValgrindComplain)
00415 #ifdef edebug
00416         G4cout<<"--->EMC-->G4QFragmentation::Construct: Target Nucleon is filled, 4M/PDG="
00417               <<aTarget->Get4Momentum()<<aTarget->GetPDGCode()<<G4endl;
00418 #endif
00419         // Now the energy of the nucleons must be updated in CMS
00420         theNucleus.DoLorentzBoost(theCurrentVelocity);// Boost theResNucleus toRotatedLS
00421         theNucleus.SubtractNucleon(pNucleon);         // Pointer to the used nucleon
00422         theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
00423         if((theProbability.GetPomDiffProbability(s_value,Distance2)/Probability >
00424             G4UniformRand() && ModelMode==SOFT ) || ModelMode==DIFFRACTIVE)
00425         { 
00426           // --------------->> diffractive interaction @@ IsSingleDiffractive called once
00427           if(IsSingleDiffractive()) ExciteSingDiffParticipants(cmProjectile, aTarget);
00428           else                          ExciteDiffParticipants(cmProjectile, aTarget);
00429           G4QInteraction* anInteraction = new G4QInteraction(cmProjectile);
00430           anInteraction->SetTarget(aTarget); 
00431           anInteraction->SetNumberOfDiffractiveCollisions(1); // Why not increment? M.K.?
00432           theInteractions.push_back(anInteraction);   //--> now theInteractions not empty
00433           // @@ Why not breake the NLOOP, if only one diffractive can happend?
00434           totalCuts++;                               // UpdateOfNucleons in't necessary
00435 #ifdef debug
00436           G4cout<<"G4QFragmentation::Construct:NLOOP DiffInteract, tC="<<totalCuts<<G4endl;
00437 #endif
00438         }
00439         else
00440         {
00441           // ---------------->> nondiffractive = soft interaction
00442           // sample nCut+1 (cut Pomerons) pairs of strings can be produced
00443           G4int nCut;                                // Result in a chosen number of cuts
00444           G4double* running = new G4double[nCutMax]; // @@ This limits the max cuts
00445           for(nCut = 0; nCut < nCutMax; nCut++)      // Calculates multiCut probabilities
00446           {
00447             running[nCut]= theProbability.GetCutPomProbability(s_value, Distance2, nCut+1);
00448             if(nCut) running[nCut] += running[nCut-1];// Sum up with the previous one
00449           }
00450           G4double random = running[nCutMax-1]*G4UniformRand();
00451           for(nCut = 0; nCut < nCutMax; nCut++) if(running[nCut] > random) break;
00452           delete [] running;
00453 #ifdef debug
00454           G4cout<<"G4QFragmentation::Construct: NLOOP-Soft Chosen nCut="<<nCut<<G4endl;
00455 #endif
00456           // @@ If nCut>0 interaction with a few nucleons is possible
00457           // @@ nCut is found with big efforts and now nCut=0 ?? M.K. ?? !!
00458           //nCut = 0; // @@ in original code ?? @@
00459           aTarget->IncrementCollisionCount(nCut+1); // @@ What about multyNucleon target?
00460           cmProjectile->IncrementCollisionCount(nCut+1);
00461           G4QInteraction* anInteraction = new G4QInteraction(cmProjectile);
00462           anInteraction->SetTarget(aTarget);
00463           anInteraction->SetNumberOfSoftCollisions(nCut+1);
00464           theInteractions.push_back(anInteraction);
00465           totalCuts += nCut+1;
00466 #ifdef debug
00467           G4cout<<"G4QFragmentation::Construct:NLOOP SoftInteract, tC="<<totalCuts<<G4endl;
00468           impactUsed=Distance2;
00469 #endif
00470         }
00471       }
00472     } // End of While over nucleons
00473     // When nucleon count is incremented, the LOOP stops, so nucleonCount==1 always!
00474 #ifdef debug
00475     G4cout<<"G4QFragmentation::Construct: NUCLEONCOUNT="<<nucleonCount<<G4endl;
00476 #endif
00477   }
00478   G4int nInt=theInteractions.size();
00479 #ifdef debug
00480   G4cout<<"G4QFrag::Con:CUT="<<totalCuts<<",ImpPar="<<impactUsed<<",#ofInt="<<nInt<<G4endl;
00481 #endif
00482   // --- Use this line ---
00483   if(!nInt || (nInt==1 && theInteractions[0]->GetNumberOfDINRCollisions()==1)) // @@ ?? @@
00484   {
00485     G4QHadron* aTarget=0;
00486     G4QHadron* pProjectile=0;
00487     if(nInt)                                         // Take Targ/Proj from the Interaction
00488     {
00489         aTarget=theInteractions[0]->GetTarget();
00490         pProjectile=theInteractions[0]->GetProjectile();
00491       delete theInteractions[0];
00492       theInteractions.clear();
00493     }
00494     else                                             // Create a new target nucleon
00495     {
00496       theNucleus.StartLoop();                        // To get the same nucleon
00497       pNucleon=theNucleus.GetNextNucleon();          // Get the nucleon to create
00498       aTarget = new G4QHadron(*pNucleon);            // Copy selected nucleon for String
00499       pProjectile =cmProjectile;
00500       theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
00501       theNucleus.SubtractNucleon(pNucleon);          // Pointer to theUsedNucleon to delete
00502       theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
00503     }
00504     G4QContent QQC=aTarget->GetQC()+pProjectile->GetQC(); // QContent of the compound
00505     G4LorentzVector Q4M=aTarget->Get4Momentum()+pProjectile->Get4Momentum(); // 4-mom of Q
00506     delete aTarget;
00507     delete pProjectile;
00508     //if(maxNuc>1)                                     // Absorb moreNucleons to theQuasmon
00509     //{
00510     //  for(G4int i=1; i<maxNuc; ++i)
00511     //  {
00512     //    pNucleon=theNucleus.GetNextNucleon();        // Get the next nucleon
00513     //    QQC+=pNucleon->GetQC();                      // Add it to the Quasmon
00514     //    Q4M+=pNucleon->Get4Momentum();
00515     //    theNucleus.DoLorentzBoost(theCurrentVelocity); // Boost theResNucleus toRotatedLS
00516     //    theNucleus.SubtractNucleon(pNucleon);        // Exclude the used nucleon from Nuc
00517     //    theNucleus.DoLorentzBoost(-theCurrentVelocity);// Boost theResNucleus back to CM
00518     //  }
00519     //}
00520     // 4-Mom should be converted to LS
00521     Q4M.boost(theCurrentVelocity);
00522     Q4M=toLab*Q4M;
00523     G4Quasmon* stringQuasmon = new G4Quasmon(QQC, Q4M);
00524     theQuasmons.push_back(stringQuasmon);
00525     theNucleus.DoLorentzBoost(theCurrentVelocity);   // BoostTheResidualNucleus toRotatedLS
00526     theNucleus.DoLorentzRotation(toLab);// Recove Z-direction in LS ("LS"->LS) for rNucleus
00527     return;
00528   }
00529   //
00530   // ------------------ now build the parton pairs for the strings ------------------
00531   //
00532 #ifdef debug
00533   G4cout<<"G4QFragmentation::Construct: Before PartPairCreation nInt="<<nInt<<G4endl;
00534 #endif
00535   for(G4int i=0; i<nInt; i++)
00536   {
00537     theInteractions[i]->SplitHadrons();
00538 #ifdef edebug
00539     G4QHadron* projH=theInteractions[i]->GetProjectile(); // Projectile of theInteraction
00540     G4QHadron* targH=theInteractions[i]->GetTarget();     // Target of the Interaction
00541     G4LorentzVector pSP(0.,0.,0.,0.);                // Sum of parton's 4mom's for proj
00542     G4LorentzVector tSP(0.,0.,0.,0.);                // Sum of parton's 4mom's for proj
00543     std::list<G4QParton*> projCP=projH->GetColor();  // Pointers to proj Color-partons
00544     std::list<G4QParton*> projAC=projH->GetAntiColor();// PointersTo projAntiColorPartons
00545     std::list<G4QParton*> targCP=targH->GetColor();  // Pointers to targ Color-partons
00546     std::list<G4QParton*> targAC=targH->GetAntiColor();// PointersTo targAntiColorPartons
00547     std::list<G4QParton*>::iterator picp = projCP.begin();
00548     std::list<G4QParton*>::iterator pecp = projCP.end();
00549     std::list<G4QParton*>::iterator piac = projAC.begin();
00550     std::list<G4QParton*>::iterator peac = projAC.end();
00551     std::list<G4QParton*>::iterator ticp = targCP.begin();
00552     std::list<G4QParton*>::iterator tecp = targCP.end();
00553     std::list<G4QParton*>::iterator tiac = targAC.begin();
00554     std::list<G4QParton*>::iterator teac = targAC.end();
00555     for(; picp!=pecp&& piac!=peac&& ticp!=tecp&& tiac!=teac; ++picp,++piac,++ticp,++tiac)
00556     {
00557       pSP+=(*picp)->Get4Momentum();
00558       pSP+=(*piac)->Get4Momentum();
00559       tSP+=(*ticp)->Get4Momentum();
00560       tSP+=(*tiac)->Get4Momentum();
00561     }
00562     G4cout<<"-EMC-G4QFragmentation::Construct: Interaction#"<<i<<",dP4M="
00563           <<projH->Get4Momentum()-pSP<<",dT4M="<<targH->Get4Momentum()-tSP<<G4endl;
00564 #endif
00565   }  
00566   // 
00567   // ------->> make soft collisions (ordering is vital)
00568   //
00569   G4QInteractionVector::iterator it;
00570 #ifdef debug
00571   G4cout<<"G4QFragmentation::Construct: Creation ofSoftCollisionPartonPair STARTS"<<G4endl;
00572 #endif
00573   G4bool rep=true;
00574   while(rep && theInteractions.size())
00575   {
00576    for(it = theInteractions.begin(); it != theInteractions.end(); ++it)
00577    {
00578     G4QInteraction* anIniteraction = *it;
00579     G4QPartonPair*  aPair=0;
00580     G4int nSoftCollisions = anIniteraction->GetNumberOfSoftCollisions();
00581 #ifdef debug
00582     G4cout<<"G4QFragmentation::Construct: #0f SOFT collisions ="<<nSoftCollisions<<G4endl;
00583 #endif
00584     if (nSoftCollisions)
00585     { 
00586       G4QHadron* pProjectile = anIniteraction->GetProjectile();
00587       G4QHadron* pTarget     = anIniteraction->GetTarget();
00588       for (G4int j = 0; j < nSoftCollisions; j++)
00589       {
00590         aPair = new G4QPartonPair(pTarget->GetNextParton(),
00591                                   pProjectile->GetNextAntiParton(),
00592                                   G4QPartonPair::SOFT, G4QPartonPair::TARGET);
00593         thePartonPairs.push_back(aPair); // A target pair (Why TAGRET?)
00594         aPair = new G4QPartonPair(pProjectile->GetNextParton(),
00595                                   pTarget->GetNextAntiParton(),
00596                                   G4QPartonPair::SOFT, G4QPartonPair::PROJECTILE);
00597         thePartonPairs.push_back(aPair); // A projectile pair (Why Projectile?)
00598 #ifdef debug
00599         G4cout<<"--->G4QFragmentation::Construct: SOFT, 2 parton pairs are filled"<<G4endl;
00600 #endif
00601       }  
00602       delete *it;
00603       it=theInteractions.erase(it);      // Soft interactions are converted & erased
00604       if( it != theInteractions.begin() )// To avoid going below begin() (for Windows)
00605       {
00606         it--;
00607         rep=false;
00608 #ifdef debug
00609         G4cout<<"G4QFragmentation::Construct: *** Decremented ***"<<G4endl;
00610 #endif
00611       }
00612       else
00613       {
00614         rep=true;
00615 #ifdef debug
00616         G4cout<<"G4QFragmentation::Construct: *** IT Begin ***"<<G4endl;
00617 #endif
00618         break;
00619       }
00620     }
00621     else rep=false;
00622 #ifdef debug
00623     G4cout<<"G4QFragmentation::Construct: #0fSC="<<nSoftCollisions<<", r="<<rep<<G4endl;
00624 #endif
00625    }
00626 #ifdef debug
00627    G4cout<<"G4QFragmentation::Construct: *** IT While *** , r="<<rep<<G4endl;
00628 #endif
00629   }
00630 #ifdef debug
00631   G4cout<<"G4QFragmentation::Construct: -> Parton pairs for SOFT strings are made"<<G4endl;
00632 #endif  
00633   //
00634   // ---------->> make the rest as the diffractive interactions
00635   //
00636   for(unsigned i = 0; i < theInteractions.size(); i++) // Interactions are reduced bySoft
00637   {
00638     // The double or single diffraction is defined by the presonce of proj/targ partons
00639     G4QInteraction* anIniteraction = theInteractions[i];
00640     G4QPartonPair* aPartonPair;
00641 #ifdef debug
00642     G4cout<<"G4QFragmentation::Construct: CreationOfDiffractivePartonPairs, i="<<i<<G4endl;
00643 #endif
00644     // the projectile diffraction parton pair is created first
00645     G4QHadron* pProjectile = anIniteraction->GetProjectile();
00646     G4QParton* aParton = pProjectile->GetNextParton();
00647     if (aParton)
00648     {
00649       aPartonPair = new G4QPartonPair(aParton, pProjectile->GetNextAntiParton(), 
00650                                       G4QPartonPair::DIFFRACTIVE,
00651                                       G4QPartonPair::PROJECTILE);
00652       thePartonPairs.push_back(aPartonPair);
00653 #ifdef debug
00654       G4cout<<"G4QFragmentation::Construct: proj Diffractive PartonPair is filled"<<G4endl;
00655 #endif
00656     }
00657     // then the target diffraction parton pair is created
00658     G4QHadron* aTarget = anIniteraction->GetTarget();
00659     aParton = aTarget->GetNextParton();
00660     if (aParton)
00661     {
00662       aPartonPair = new G4QPartonPair(aParton, aTarget->GetNextAntiParton(), 
00663                                       G4QPartonPair::DIFFRACTIVE, G4QPartonPair::TARGET);
00664       thePartonPairs.push_back(aPartonPair);
00665 #ifdef debug
00666       G4cout<<"G4QFragmentation::Constr: target Diffractive PartonPair is filled"<<G4endl;
00667 #endif
00668     }
00669   }
00670 #ifdef debug
00671   G4cout<<"G4QFragmentation::Construct: DiffractivePartonPairs are created"<<G4endl;
00672 #endif  
00673   //
00674   // ---------->> clean-up  Interactions and cmProjectile, if necessary
00675   //
00676   std::for_each(theInteractions.begin(),theInteractions.end(), DeleteQInteraction());
00677   theInteractions.clear();
00678   delete cmProjectile;
00679 #ifdef debug
00680   G4cout<<"G4QFragmentation::Construct: Temporary objects are cleaned up"<<G4endl;
00681 #endif  
00682   // This function prepares theBoost for transformation of secondaries to LS (-ProjRot!)
00683   theNucleus.DoLorentzBoost(theCurrentVelocity);// Boost theResidualNucleus to RotatedLS
00684   // @@ Nucleus isn't completely in LS, it needs the toZ (-ProjRot) rotation to consE/M
00685 #ifdef debug
00686   G4cout<<"--------->>G4QFragmentation::Construct: ------->> Strings are created "<<G4endl;
00687 #endif
00688   G4QPartonPair* aPair;
00689   G4QString* aString=0;
00690   while(thePartonPairs.size()) // @@ At present noDifference in stringBuild (? M.K.)
00691   {
00692     aPair = thePartonPairs.back();           // Get the parton pair
00693     thePartonPairs.pop_back();               // Clean up thePartonPairPointer in the Vector
00694 #ifdef debug
00695     G4cout<<"G4QFragmentation::Construct: StringType="<<aPair->GetCollisionType()<<G4endl;
00696 #endif
00697     aString= new G4QString(aPair);
00698 #ifdef debug
00699     G4cout<<"G4QFragmentation::Construct:NewString4M="<<aString->Get4Momentum()<<G4endl;
00700 #endif
00701     aString->Boost(theCurrentVelocity);       // ! Strings are moved to ZLS when pushed !
00702     strings.push_back(aString);
00703     stringsInitted=true;
00704     delete aPair;
00705   } // End of the String Creation LOOP
00706 #ifdef edebug
00707   G4LorentzVector sum=theNucleus.Get4Momentum();// Nucleus 4Mom in rotatedLS
00708   G4int rChg=totChg-theNucleus.GetZ();
00709   G4int rBaN=totBaN-theNucleus.GetA();
00710   G4int nStrings=strings.size();
00711   G4cout<<"-EMC-G4QFragmentation::Construct:#ofString="<<nStrings<<",tNuc4M="<<sum<<G4endl;
00712   for(G4int i=0; i<nStrings; i++)
00713   {
00714     G4QString* prString=strings[i];
00715     G4LorentzVector strI4M=prString->Get4Momentum();
00716     sum+=strI4M;
00717     G4int      sChg=prString->GetCharge();
00718     G4int      sBaN=prString->GetBaryonNumber();
00719     G4int      LPDG=prString->GetLeftParton()->GetPDGCode();
00720     G4int      RPDG=prString->GetRightParton()->GetPDGCode();
00721     G4QContent LQC =prString->GetLeftParton()->GetQC();
00722     G4QContent RQC =prString->GetRightParton()->GetQC();
00723     rChg-=sChg;
00724     rBaN-=sBaN;
00725     G4cout<<"-EMC-G4QFragmentation::Construct: String#"<<i<<", 4M="<<strI4M<<",LPDG="<<LPDG
00726           <<LQC<<",RPDG="<<RPDG<<RQC<<", Ch="<<sChg<<", BN="<<sBaN<<G4endl;
00727   }
00728   G4cout<<"-EMC-G4QFragm::Constr: r4M="<<sum-totZLS4M<<",rC="<<rChg<<",rB="<<rBaN<<G4endl;
00729 #endif
00730   if(!stringsInitted)
00731   {
00732     G4cerr<<"******G4QFragmentation::Construct:***** No strings are created *****"<<G4endl;
00733     G4Exception("G4QFragmentation::Construct:","72",FatalException,"NoStrings're created");
00734   }
00735 #ifdef debug
00736   G4cout<<"G4QFragmentation::Constr: BeforeRotation, #0fStrings="<<strings.size()<<G4endl;
00737 #endif
00738   //
00739   // ---------------- At this point the strings must be already created in "LS" -----------
00740   //
00741   for(unsigned astring=0; astring < strings.size(); astring++)
00742             strings[astring]->LorentzRotate(toLab); // Recove Z-direction in LS ("LS"->LS)
00743   theNucleus.DoLorentzRotation(toLab); // Recove Z-direction in LS ("LS"->LS) for rNucleus
00744   // Now everything is in LS system
00745 #ifdef edebug
00746   G4LorentzVector sm=theNucleus.Get4Momentum();    // Nucleus 4Mom in LS
00747   G4int rCg=totChg-theNucleus.GetZ();
00748   G4int rBC=totBaN-theNucleus.GetA();
00749   G4int nStrs=strings.size();
00750   G4cout<<"-EMCLS-G4QFragmentation::Constr: #ofS="<<nStrings<<",tNuc4M(E=M)="<<sum<<G4endl;
00751   for(G4int i=0; i<nStrs; i++)
00752   {
00753     G4LorentzVector strI4M=strings[i]->Get4Momentum();
00754     sm+=strI4M;
00755     G4int sChg=strings[i]->GetCharge();
00756     rCg-=sChg;
00757     G4int sBaN=strings[i]->GetBaryonNumber();
00758     rBC-=sBaN;
00759     G4cout<<"-EMCLS-G4QFragm::Construct:String#"<<i<<",4M="<<strI4M<<strI4M.m()<<",Charge="
00760           <<sChg<<",BaryN="<<sBaN<<G4endl;
00761   }
00762   G4cout<<"-EMCLS-...G4QFragm::Constr:r4M="<<sm-totLS4M<<",rC="<<rCg<<",rB="<<rBC<<G4endl;
00763 #endif
00764   //
00765   // --- Strings are created, but we should try to get rid of negative mass strings -----
00766   //
00767   SwapPartons();
00768 #ifdef edebug
00769   sm=theNucleus.Get4Momentum();    // Nucleus 4Mom in LS
00770   rCg=totChg-theNucleus.GetZ();
00771   rBC=totBaN-theNucleus.GetA();
00772   nStrs=strings.size();
00773   G4cout<<"-EMCLS-G4QFrag::Constr:AfterSwap #ofS="<<nStrings<<",tNuc4M(E=M)="<<sum<<G4endl;
00774   for(G4int i=0; i<nStrs; i++)
00775   {
00776     G4LorentzVector strI4M=strings[i]->Get4Momentum();
00777     sm+=strI4M;
00778     G4int sChg=strings[i]->GetCharge();
00779     rCg-=sChg;
00780     G4int sBaN=strings[i]->GetBaryonNumber();
00781     rBC-=sBaN;
00782     G4cout<<"-EMCLS-G4QFragm::Construct:String#"<<i<<",4M="<<strI4M<<strI4M.m()<<",Charge="
00783           <<sChg<<",BaryN="<<sBaN<<G4endl;
00784   }
00785   G4cout<<"-EMCLS-...G4QFragm::Constr:r4M="<<sm-totLS4M<<",rC="<<rCg<<",rB="<<rBC<<G4endl;
00786 #endif
00787   //
00788   // --- Strings are created, but we should get rid of too light strings (Mmin+MPi0) -----
00789   //
00790   G4int problem=0;                                   // 0="no problem", incremented by ASIS
00791   G4QStringVector::iterator ist;
00792   G4bool con=true;
00793   while(con && strings.size())
00794   {
00795    for(ist = strings.begin(); ist < strings.end(); ++ist)
00796    {
00797     G4bool bad=true;
00798     G4LorentzVector cS4M=(*ist)->Get4Momentum();
00799     G4double cSM2=cS4M.m2();                         // Squared mass of the String
00800     G4QParton* cLeft=(*ist)->GetLeftParton();
00801     G4QParton* cRight=(*ist)->GetRightParton();
00802     G4int cLT=cLeft->GetType();
00803     G4int cRT=cRight->GetType();
00804     G4int cLPDG=cLeft->GetPDGCode();
00805     G4int cRPDG=cRight->GetPDGCode();
00806     G4int aLPDG=0;
00807     G4int aRPDG=0;
00808     if     (cLPDG > 7) aLPDG=  cLPDG/100;
00809     else if(cLPDG <-7) aLPDG=(-cLPDG)/100;
00810     if     (cRPDG > 7) aRPDG=  cRPDG/100;
00811     else if(cRPDG <-7) aRPDG=(-cRPDG)/100;
00812     G4int L1=0;
00813     G4int L2=0;
00814     if(aLPDG)
00815     {
00816       L1=aLPDG/10;
00817       L2=aLPDG%10;
00818     }
00819     G4int R1=0;
00820     G4int R2=0;
00821     if(aRPDG)
00822     {
00823       R1=aRPDG/10;
00824       R2=aRPDG%10;
00825     }
00826     G4double cSM=cSM2;
00827     if(cSM2>0.) cSM=std::sqrt(cSM2);
00828 #ifdef debug
00829     G4cout<<"G4QFrag::Constr:NeedsFusion? cLPDG="<<cLPDG<<",cRPDG="<<cRPDG<<",cM(cM2If<0)="
00830           <<cSM<<",c4M"<<cS4M<<G4endl;
00831 #endif
00832     if(cSM>0.)                                       // Mass can be calculated
00833     {
00834       G4bool single=true;
00835       G4double miM=0.;                               // Proto of the Min HadronString Mass
00836       if(cLT==2 && cRT==2)
00837       {
00838         if(L1!=R1 && L1!=R2 && L2!=R1 && L2!=R2)     // Unreducable DiQ-aDiQ
00839         {
00840           single=false;
00841           G4QPDGCode tmp;
00842           std::pair<G4int,G4int> paB=tmp.MakeTwoBaryons(L1, L2, R1, R2);
00843           miM=G4QPDGCode(paB.first).GetMass()+G4QPDGCode(paB.second).GetMass();
00844         }
00845       }
00846       if(single) miM=G4QPDGCode((*ist)->GetQC().GetSPDGCode()).GetMass() + mPi0;//MinHSMass
00847         //if(single) miM=G4QPDGCode((*ist)->GetQC().GetSPDGCode()).GetMass();//MinHSMass
00848 #ifdef debug
00849       G4cout<<"G4QFrag::Const:*IsItGood? realM="<<std::sqrt(cSM2)<<" > GSM="<<miM<<G4endl;
00850 #endif
00851       if(std::sqrt(cSM2) > miM) bad=false;           // String is OK
00852     }
00853     if(bad)                                          // String should be merged with others
00854     {
00855 #ifdef debug
00856       G4cout<<"G4QFrag::Const:TryFuse,L1="<<L1<<",L2="<<L2<<",R1="<<R1<<",R2="<<R2<<G4endl;
00857 #endif
00858       G4int cST=cLT+cRT;
00859       G4double excess=-DBL_MAX;                      // The value to be maximized excess M
00860       G4double maxiM2=-DBL_MAX;                      // The value to be maximized M2
00861       G4QStringVector::iterator sst;                 // Selected partner string
00862       G4QStringVector::iterator pst;
00863       G4int sLPDG=0;                                 // selectedLeft (like inStringPartner)
00864       G4int sRPDG=0;                                 // selectedRight(like inStringPartner)
00865       G4int sOrd=0;                                  // selected Order of PartonFusion
00866       G4bool minC=true;                              // for the case when M2<0
00867       if(cSM2>0.) minC=false;                        // If M2>0 already don'tSearchFor M2>0
00868       for(pst = strings.begin(); pst < strings.end(); pst++) if(pst != ist)
00869       {
00870         G4LorentzVector sS4M=(*pst)->Get4Momentum(); // Partner's 4-momentum
00871         G4LorentzVector pS4M=sS4M+cS4M;              // Summed 4-momentum
00872         G4int nLPDG=0;                               // new Left (like in theStringPartner)
00873         G4int nRPDG=0;                               // new Right(like in theStringPartner)
00874         G4double pExcess=-DBL_MAX;                   // Prototype of the excess
00875         G4double pSM2=pS4M.m2();                     // Squared mass of the Fused Strings
00876 #ifdef debug
00877         G4cout<<"->G4QFragm::Construct: sum4M="<<pS4M<<",M2="<<pSM2<<",p4M="<<sS4M<<G4endl;
00878 #endif
00879         //if(pSM2>0.)                                  // The partner can be a candidate
00880         //{
00881         G4QParton* pLeft=(*pst)->GetLeftParton();
00882         G4QParton* pRight=(*pst)->GetRightParton();
00883         G4int pLT=pLeft->GetType();
00884         G4int pRT=pRight->GetType();
00885         G4int pLPDG=pLeft->GetPDGCode();
00886         G4int pRPDG=pRight->GetPDGCode();
00887         G4int LPDG=0;
00888         G4int RPDG=0;
00889         if     (pLPDG > 7) LPDG=  pLPDG/100;
00890         else if(pLPDG <-7) LPDG=(-pLPDG)/100;
00891         if     (pRPDG > 7) RPDG=  pRPDG/100;
00892         else if(pRPDG <-7) RPDG=(-pRPDG)/100;
00893         G4int pL1=0;
00894         G4int pL2=0;
00895         if(LPDG)
00896         {
00897           pL1=LPDG/10;
00898           pL2=LPDG%10;
00899         }
00900         G4int pR1=0;
00901         G4int pR2=0;
00902         if(RPDG)
00903         {
00904           pR1=RPDG/10;
00905           pR2=RPDG%10;
00906         }
00907         G4int pST=pLT+pRT;
00908 #ifdef debug
00909         G4cout<<"G4QFragm::Construct: Partner/w pLPDG="<<pLPDG<<", pRPDG="<<pRPDG<<", pM2="
00910               <<pSM2<<G4endl;
00911 #endif
00912         // Different fromCompactAlrorithm ofStringFusionAfterDecay (no DiQaDiQ reduction)
00913         G4int tf=0;                                // Type combination flag
00914         G4int af=0;                                // Annihilatio combination flag
00915         if     (cST==2 && pST==2)                  // QaQ + QaQ = DiQaDiQ (always)
00916         {
00917           tf=1;
00918           af=1;
00919         }
00920         else if(cST==2 && pST==3)                  // QaQ + QDiQ/aQaDiQ = QDiQ/aQaDiQ (s)
00921         {
00922           tf=2;
00923           if     (pLPDG > 7 &&
00924                   ( (cLPDG<0 && (-cLPDG==pL1 || -cLPDG==pL2 || -cLPDG==pRPDG) ) ||
00925                     (cRPDG<0 && (-cRPDG==pL1 || -cRPDG==pL2 || -cRPDG==pRPDG) )
00926                   )
00927                  ) af=1;
00928           else if(pRPDG > 7 &&
00929                   ( (cLPDG<0 && (-cLPDG==pR1 || -cLPDG==pR2 || -cLPDG==pLPDG) ) ||
00930                     (cRPDG<0 && (-cRPDG==pR1 || -cRPDG==pR2 || -cRPDG==pLPDG) )
00931                   )
00932                  ) af=2;
00933           else if(pLPDG <-7 &&
00934                   ( (cLPDG>0 && ( cLPDG==pL1 || cLPDG==pL2 || cLPDG==-pRPDG) ) ||
00935                     (cRPDG>0 && ( cRPDG==pL1 || cRPDG==pL2 || cRPDG==-pRPDG) )
00936                   )
00937                  ) af=3;
00938           else if(pRPDG <-7 &&
00939                   ( (cLPDG>0 && ( cLPDG==pR1 || cLPDG==pR2 || cLPDG==-pLPDG) ) ||
00940                     (cRPDG>0 && ( cRPDG==pR1 || cRPDG==pR2 || cRPDG==-pLPDG) )
00941                   )
00942                  ) af=4;
00943 #ifdef debug
00944           else G4cout<<"G4QFragmentation::Construct:2(QaQ+QDiQ/aQaDiQ) Can't fuse"<<G4endl;
00945 #endif
00946         }
00947         else if(cST==3 && pST==2)                  // QDiQ/aQaDiQ + QaQ = QDiQ/aQaDiQ (s)
00948         {
00949           tf=3;
00950           if     (cLPDG > 7 &&
00951                   ( (pLPDG<0 && (-pLPDG==L1 || -pLPDG==L2 || -pLPDG==cRPDG) ) ||
00952                     (pRPDG<0 && (-pRPDG==L1 || -pRPDG==L2 || -pRPDG==cRPDG) )
00953                   )
00954                  ) af=1;
00955           else if(cRPDG > 7 &&
00956                   ( (pLPDG<0 && (-pLPDG==R1 || -pLPDG==R2 || -pLPDG==cLPDG) ) ||
00957                     (pRPDG<0 && (-pRPDG==R1 || -pRPDG==R2 || -pRPDG==cLPDG) )
00958                   )
00959                  ) af=2;
00960           else if(cLPDG <-7 &&
00961                   ( (pLPDG>0 && ( pLPDG==L1 || pLPDG==L2 || pLPDG==-cRPDG) ) ||
00962                     (pRPDG>0 && ( pRPDG==L1 || pRPDG==L2 || pRPDG==-cRPDG) )
00963                   )
00964                  ) af=3;
00965           else if(cRPDG <-7 &&
00966                   ( (pLPDG>0 && ( pLPDG==R1 || pLPDG==R2 || pLPDG==-cLPDG) ) ||
00967                     (pRPDG>0 && ( pRPDG==R1 || pRPDG==R2 || pRPDG==-cLPDG) )
00968                   )
00969                  ) af=4;
00970 #ifdef debug
00971           else G4cout<<"G4QFragmentation::Construct:3(QDiQ/aQaDiQ+QaQ) Can't fuse"<<G4endl;
00972 #endif
00973         }
00974         else if(cST==2 && pST==4)                  // QaQ + aDiQDiQ = QaQ (double)
00975         {
00976           tf=4;
00977           if     (pLPDG > 7) // pRPDG <-7
00978           {
00979             if     ( (-cLPDG==pL1 || -cLPDG==pL2) && (cRPDG==pR1 || cRPDG==pR2) ) af=1;
00980             else if( (-cRPDG==pL1 || -cRPDG==pL2) && (cLPDG==pR1 || cLPDG==pR2) ) af=2;
00981           }
00982           else if(pRPDG > 7) // pLPDG <-7
00983           {
00984             if     ( (-cRPDG==pR1 || -cRPDG==pR2) && (cLPDG==pL1 || cLPDG==pL2) ) af=3;
00985             else if( (-cLPDG==pR1 || -cLPDG==pR2) && (cRPDG==pL1 || cRPDG==pL2) ) af=4;
00986           }
00987 #ifdef debug
00988           else G4cout<<"-G4QFragmentation::Construct: 4 (QaQ+aQDiQDiQ) Can't fuse"<<G4endl;
00989 #endif
00990         }
00991         else if(cST==4 && pST==2)                  // aDiQDiQ + QaQ = QaQ (double)
00992         {
00993           tf=5;
00994           if     (cLPDG > 7) // cRPDG<-7
00995           {
00996             if     ( (-pLPDG==L1 || -pLPDG==L2) && (pRPDG==R1 || pRPDG==R2) ) af=1;
00997             else if( (-pRPDG==L1 || -pRPDG==L2) && (pLPDG==R1 || pLPDG==R2) ) af=2;
00998           }
00999           else if(cRPDG > 7) // cLPDG<-7
01000           {
01001             if     ( (-pRPDG==R1 || -pRPDG==R2) && (pLPDG==L1 || pLPDG==L2) ) af=3;
01002             else if( (-pLPDG==R1 || -pLPDG==R2) && (pRPDG==L1 || pRPDG==L2) ) af=4;
01003           }
01004 #ifdef debug
01005           else G4cout<<"-G4QFragmentation::Construct: 5 (aQDiQDiQ+QaQ) Can't fuse"<<G4endl;
01006 #endif
01007         }
01008         else if(cST==3 && pST==3)                  // QDiQ + aQaDiQ = QaQ (double)
01009         {
01010           tf=6;
01011           if(pLPDG > 7)
01012           {
01013             if     (cLPDG<-7 && (-cRPDG==pL1 || -cRPDG==pL2) && (pRPDG==L1 || pRPDG==L2))
01014               af=1;
01015             else if(cRPDG<-7 && (-cLPDG==pL1 || -cLPDG==pL2) && (pRPDG==R1 || pRPDG==R2))
01016               af=2;
01017           }
01018           else if(pRPDG > 7)
01019           {
01020             if     (cLPDG<-7 && (-cRPDG==pR1 || -cRPDG==pR2) && (pLPDG==L1 || pLPDG==L2))
01021               af=3;
01022             else if(cRPDG<-7 && (-cLPDG==pR1 || -cLPDG==pR2) && (pLPDG==R1 || pLPDG==R2))
01023               af=4;
01024           }
01025           else if(cLPDG > 7)
01026           {
01027             if     (pLPDG<-7 && (-pRPDG==L1 || -pRPDG==L2) && (cRPDG==pL1 || cRPDG==pL2))
01028               af=5;
01029             else if(pRPDG<-7 && (-pLPDG==L1 || -pLPDG==L2) && (cRPDG==pR1 || cRPDG==pR2))
01030               af=6;
01031           }
01032           else if(cRPDG > 7)
01033           {
01034             if     (pLPDG<-7 && (-pRPDG==R1 || -pRPDG==R2) && (cLPDG==pL1 || cLPDG==pL2))
01035               af=7;
01036             else if(pRPDG<-7 && (-pLPDG==R1 || -pLPDG==R2) && (cLPDG==pR1 || cLPDG==pR2))
01037               af=8;
01038           }
01039 #ifdef debug
01040           else G4cout<<"-G4QFragmentation::Construct: 6 (QDiQ+aQaDiQ) Can't fuse"<<G4endl;
01041 #endif
01042         }
01043 #ifdef debug
01044         G4cout<<"G4QFragmentation::Const: ***Possibility***, tf="<<tf<<", af="<<af<<G4endl;
01045 #endif
01046         if(tf && af)
01047         {
01048           // Strings can be fused, update the max excess and remember usefull switches
01049           G4int order=0;                           // LL/RR (1) or LR/RL (2) PartonFusion
01050           switch (tf)
01051           {
01052             case 1: // ------------------------------------> QaQ + QaQ = DiQaDiQ (always)
01053               if     (cLPDG > 0 && pLPDG > 0)
01054               {
01055                 order= 1;
01056                 if     (cLPDG > pLPDG) nLPDG=cLPDG*1000+pLPDG*100+1;
01057                 else if(cLPDG < pLPDG) nLPDG=pLPDG*1000+cLPDG*100+1;
01058                 else                   nLPDG=pLPDG*1000+cLPDG*100+3;
01059                 if     (cRPDG < pRPDG) nRPDG=cRPDG*1000+pRPDG*100-1;
01060                 else if(cRPDG > pRPDG) nRPDG=pRPDG*1000+cRPDG*100-1;
01061                 else                   nRPDG=pRPDG*1000+cRPDG*100-3;
01062               }
01063               else if(cLPDG < 0 && pLPDG < 0)
01064               {
01065                 order= 1;
01066                 if     (cRPDG > pRPDG) nRPDG=cRPDG*1000+pRPDG*100+1;
01067                 else if(cRPDG < pRPDG) nRPDG=pRPDG*1000+cRPDG*100+1;
01068                 else                   nRPDG=pRPDG*1000+cRPDG*100+3;
01069                 if     (cLPDG < pLPDG) nLPDG=cLPDG*1000+pLPDG*100-1;
01070                 else if(cLPDG > pLPDG) nLPDG=pLPDG*1000+cLPDG*100-1;
01071                 else                   nLPDG=pLPDG*1000+cLPDG*100-3;
01072               }
01073               else if(cRPDG > 0 && pLPDG > 0)
01074               {
01075                 order=-1;
01076                 if     (cRPDG > pLPDG) nLPDG=cRPDG*1000+pLPDG*100+1;
01077                 else if(cRPDG < pLPDG) nLPDG=pLPDG*1000+cRPDG*100+1;
01078                 else                   nLPDG=pLPDG*1000+cRPDG*100+3;
01079                 if     (cLPDG < pRPDG) nRPDG=cLPDG*1000+pRPDG*100-1;
01080                 else if(cLPDG > pRPDG) nRPDG=pRPDG*1000+cLPDG*100-1;
01081                 else                   nRPDG=pRPDG*1000+cLPDG*100-3;
01082               }
01083               else if(cRPDG < 0 && pLPDG < 0)
01084               {
01085                 order=-1;
01086                 if     (cLPDG > pRPDG) nRPDG=cLPDG*1000+pRPDG*100+1;
01087                 else if(cLPDG < pRPDG) nRPDG=pRPDG*1000+cLPDG*100+1;
01088                 else                   nRPDG=pRPDG*1000+cLPDG*100+3;
01089                 if     (cRPDG < pLPDG) nLPDG=cRPDG*1000+pLPDG*100-1;
01090                 else if(cRPDG > pLPDG) nLPDG=pLPDG*1000+cRPDG*100-1;
01091                 else                   nLPDG=pLPDG*1000+cRPDG*100-3;
01092               }
01093               break;
01094             case 2: // ------------------------> QaQ + QDiQ/aQaDiQ = QDiQ/aQaDiQ (single)
01095              switch (af)
01096              {
01097                case 1: // ....................... pLPDG > 7
01098                  if(cLPDG < 0)
01099                  {
01100                    order= 1;
01101                    if(-cLPDG==pRPDG)
01102                    {
01103                      nLPDG=pLPDG;
01104                      nRPDG=cRPDG;
01105                    }
01106                    else
01107                    {
01108                      if     (cRPDG > pRPDG) nRPDG=cRPDG*1000+pRPDG*100+1;
01109                      else if(cRPDG < pRPDG) nRPDG=pRPDG*1000+cRPDG*100+1;
01110                      else                   nRPDG=pRPDG*1000+cRPDG*100+3;
01111                      if  (-cLPDG == pL1)    nLPDG=pL2;
01112                      else                   nLPDG=pL1; // -cLPDG == pL2
01113                    }
01114                  }
01115                  else // cRPDG < 0
01116                  {
01117                    order=-1;
01118                    if(-cRPDG==pRPDG)
01119                    {
01120                      nLPDG=pLPDG;
01121                      nRPDG=cLPDG;
01122                    }
01123                    else
01124                    {
01125                      if     (cLPDG > pRPDG) nRPDG=cLPDG*1000+pRPDG*100+1;
01126                      else if(cLPDG < pRPDG) nRPDG=pRPDG*1000+cLPDG*100+1;
01127                      else                   nRPDG=pRPDG*1000+cLPDG*100+3;
01128                      if  (-cRPDG == pL1)    nLPDG=pL2;
01129                      else                   nLPDG=pL1; // -cRPDG == pL2
01130                    }
01131                  }
01132                  break;
01133                case 2: // ....................... pRPDG > 7
01134                  if(cLPDG < 0)
01135                  {
01136                    order=-1;
01137                    if(-cLPDG==pLPDG)
01138                    {
01139                      nLPDG=cRPDG;
01140                      nRPDG=pRPDG;
01141                    }
01142                    else
01143                    {
01144                      if     (cRPDG > pLPDG) nLPDG=cRPDG*1000+pLPDG*100+1;
01145                      else if(cRPDG < pLPDG) nLPDG=pLPDG*1000+cRPDG*100+1;
01146                      else                   nLPDG=pLPDG*1000+cRPDG*100+3;
01147                      if  (-cLPDG == pR1)    nRPDG=pR2;
01148                      else                   nRPDG=pR1; // -cLPDG == pR2
01149                    }
01150                  }
01151                  else // cRPDG < 0
01152                  {
01153                    order= 1;
01154                    if(-cRPDG==pLPDG)
01155                    {
01156                      nLPDG=cLPDG;
01157                      nRPDG=pRPDG;
01158                    }
01159                    else
01160                    {
01161                      if     (cLPDG > pLPDG) nLPDG=cLPDG*1000+pLPDG*100+1;
01162                      else if(cLPDG < pLPDG) nLPDG=pLPDG*1000+cLPDG*100+1;
01163                      else                   nLPDG=pLPDG*1000+cLPDG*100+3;
01164                      if  (-cRPDG == pR1)    nRPDG=pR2;
01165                      else                   nRPDG=pR1; // -cRPDG == pR2
01166                    }
01167                  }
01168                  break;
01169                case 3: // ....................... pLPDG <-7
01170                  if(cLPDG > 0)
01171                  {
01172                    order= 1;
01173                    if(cLPDG==-pRPDG)
01174                    {
01175                      nLPDG=pLPDG;
01176                      nRPDG=cRPDG;
01177                    }
01178                    else
01179                    {
01180                      if     (cRPDG < pRPDG) nRPDG=cRPDG*1000+pRPDG*100-1;
01181                      else if(cRPDG > pRPDG) nRPDG=pRPDG*1000+cRPDG*100-1;
01182                      else                   nRPDG=pRPDG*1000+cRPDG*100-3;
01183                      if  ( cLPDG == pL1)    nLPDG=-pL2;
01184                      else                   nLPDG=-pL1; // cLPDG == pL2
01185                    }
01186                  }
01187                  else // cRPDG > 0
01188                  {
01189                    order=-1;
01190                    if(cRPDG==-pRPDG)
01191                    {
01192                      nLPDG=pLPDG;
01193                      nRPDG=cLPDG;
01194                    }
01195                    else
01196                    {
01197                      if     (cLPDG < pRPDG) nRPDG=cLPDG*1000+pRPDG*100-1;
01198                      else if(cLPDG > pRPDG) nRPDG=pRPDG*1000+cLPDG*100-1;
01199                      else                   nRPDG=pRPDG*1000+cLPDG*100-3;
01200                      if  ( cRPDG == pL1)    nLPDG=-pL2;
01201                      else                   nLPDG=-pL1; // cRPDG == pL2
01202                    }
01203                  }
01204                  break;
01205                case 4: // ....................... pRPDG <-7
01206                  if(cLPDG > 0)
01207                  {
01208                    order=-1;
01209                    if(cLPDG==-pLPDG)
01210                    {
01211                      nLPDG=cRPDG;
01212                      nRPDG=pRPDG;
01213                    }
01214                    else
01215                    {
01216                      if     (cRPDG < pLPDG) nLPDG=cRPDG*1000+pLPDG*100-1;
01217                      else if(cRPDG > pLPDG) nLPDG=pLPDG*1000+cRPDG*100-1;
01218                      else                   nLPDG=pLPDG*1000+cRPDG*100-3;
01219                      if  ( cLPDG == pR1)    nRPDG=-pR2;
01220                      else                   nRPDG=-pR1; // cLPDG == pR2
01221                    }
01222                  }
01223                  else // cRPDG > 0
01224                  {
01225                    order= 1;
01226                    if(cRPDG==-pLPDG)
01227                    {
01228                      nLPDG=cLPDG;
01229                      nRPDG=pRPDG;
01230                    }
01231                    else
01232                    {
01233                      if     (cLPDG < pLPDG) nLPDG=cLPDG*1000+pLPDG*100-1;
01234                      else if(cLPDG > pLPDG) nLPDG=pLPDG*1000+cLPDG*100-1;
01235                      else                   nLPDG=pLPDG*1000+cLPDG*100-3;
01236                      if  ( cRPDG == pR1)    nRPDG=-pR2;
01237                      else                   nRPDG=-pR1; // cRPDG == pR2
01238                    }
01239                  }
01240                  break;
01241              }
01242              break;
01243             case 3: // ------------------------> QDiQ/aQaDiQ + QaQ = QDiQ/aQaDiQ (single)
01244              switch (af)
01245              {
01246                case 1: // ....................... cLPDG > 7
01247                  if(pLPDG < 0)
01248                  {
01249                    order= 1;
01250                    if(-pLPDG==cRPDG)
01251                    {
01252                      nLPDG=cLPDG;
01253                      nRPDG=pRPDG;
01254                    }
01255                    else
01256                    {
01257                      if     (pRPDG > cRPDG) nRPDG=pRPDG*1000+cRPDG*100+1;
01258                      else if(pRPDG < cRPDG) nRPDG=cRPDG*1000+pRPDG*100+1;
01259                      else                   nRPDG=cRPDG*1000+pRPDG*100+3;
01260                      if  (-pLPDG == L1)     nLPDG=L2;
01261                      else                   nLPDG=L1; // -pLPDG == L2
01262                    }
01263                  }
01264                  else // pRPDG < 0
01265                  {
01266                    order=-1;
01267                    if(-pRPDG==cRPDG)
01268                    {
01269                      nLPDG=cLPDG;
01270                      nRPDG=pLPDG;
01271                    }
01272                    else
01273                    {
01274                      if     (pLPDG > cRPDG) nLPDG=pLPDG*1000+cRPDG*100+1;
01275                      else if(pLPDG < cRPDG) nLPDG=cRPDG*1000+pLPDG*100+1;
01276                      else                   nLPDG=cRPDG*1000+pLPDG*100+3;
01277                      if  (-pRPDG == L1)     nRPDG=L2;
01278                      else                   nRPDG=L1; // -pRPDG == L2
01279                    }
01280                  }
01281                  break;
01282                case 2: // ....................... cRPDG > 7
01283                  if(pLPDG < 0)
01284                  {
01285                    order=-1;
01286                    if(-pLPDG==cLPDG)
01287                    {
01288                      nLPDG=pRPDG;
01289                      nRPDG=cRPDG;
01290                    }
01291                    else
01292                    {
01293                      if     (pRPDG > cLPDG) nRPDG=pRPDG*1000+cLPDG*100+1;
01294                      else if(pRPDG < cLPDG) nRPDG=cLPDG*1000+pRPDG*100+1;
01295                      else                   nRPDG=cLPDG*1000+pRPDG*100+3;
01296                      if  (-pLPDG == R1)     nLPDG=R2;
01297                      else                   nLPDG=R1; // -pLPDG == R2
01298                    }
01299                  }
01300                  else // pRPDG < 0
01301                  {
01302                    order= 1;
01303                    if(-pRPDG==cLPDG)
01304                    {
01305                      nLPDG=pLPDG;
01306                      nRPDG=cRPDG;
01307                    }
01308                    else
01309                    {
01310                      if     (pLPDG > cLPDG) nLPDG=pLPDG*1000+cLPDG*100+1;
01311                      else if(pLPDG < cLPDG) nLPDG=cLPDG*1000+pLPDG*100+1;
01312                      else                   nLPDG=cLPDG*1000+pLPDG*100+3;
01313                      if  (-pRPDG == R1)     nRPDG=R2;
01314                      else                   nRPDG=R1; // -pRPDG == R2
01315                    }
01316                  }
01317                  break;
01318                case 3: // ....................... cLPDG <-7 (cRPDG <0)
01319                  if(pLPDG > 0)
01320                  {
01321                    order= 1;
01322                    if(pLPDG==-cRPDG)
01323                    {
01324                      nLPDG=cLPDG;
01325                      nRPDG=pRPDG;
01326                    }
01327                    else
01328                    {
01329                      if     (pRPDG < cRPDG) nRPDG=pRPDG*1000+cRPDG*100-1;
01330                      else if(pRPDG > cRPDG) nRPDG=cRPDG*1000+pRPDG*100-1;
01331                      else                   nRPDG=cRPDG*1000+pRPDG*100-3;
01332                      if  ( pLPDG == L1)     nLPDG=-L2;
01333                      else                   nLPDG=-L1; // pLPDG == L2
01334                    }
01335                  }
01336                  else // pRPDG > 0
01337                  {
01338                    order=-1;
01339                    if(pRPDG==-cRPDG)
01340                    {
01341                      nLPDG=cLPDG;
01342                      nRPDG=pLPDG;
01343                    }
01344                    else
01345                    {
01346                      if     (pLPDG < cRPDG) nLPDG=pLPDG*1000+cRPDG*100-1;
01347                      else if(pLPDG > cRPDG) nLPDG=cRPDG*1000+pLPDG*100-1;
01348                      else                   nLPDG=cRPDG*1000+pLPDG*100-3;
01349                      if  ( pRPDG == L1)     nRPDG=-L2;
01350                      else                   nRPDG=-L1; // pRPDG == L2
01351                    }
01352                  }
01353                  break;
01354                case 4: // ....................... cRPDG <-7 (cLPDG <0)
01355                  if(pLPDG > 0)                       // pRPDG & cLPDG are anti-quarks
01356                  {
01357                    order=-1;
01358                    if(pLPDG==-cLPDG)
01359                    {
01360                      nLPDG=pRPDG;
01361                      nRPDG=cRPDG;
01362                    }
01363                    else
01364                    {
01365                      if     (pRPDG < cLPDG) nRPDG=pRPDG*1000+cLPDG*100-1;
01366                      else if(pRPDG > cLPDG) nRPDG=cLPDG*1000+pRPDG*100-1;
01367                      else                   nRPDG=cLPDG*1000+pRPDG*100-3;
01368                      if  ( pLPDG == R1)     nLPDG=-R2;
01369                      else                   nLPDG=-R1; // pLPDG == R2
01370                    }
01371                  }
01372                  else // pRPDG > 0
01373                  {
01374                    order= 1;
01375                    if(pRPDG==-cLPDG)
01376                    {
01377                      nLPDG=pLPDG;
01378                      nRPDG=cRPDG;
01379                    }
01380                    else
01381                    {
01382                      if     (pLPDG < cLPDG) nLPDG=pLPDG*1000+cLPDG*100-1;
01383                      else if(pLPDG > cLPDG) nLPDG=cLPDG*1000+pLPDG*100-1;
01384                      else                   nLPDG=cLPDG*1000+pLPDG*100-3;
01385                      if  ( pRPDG == R1)     nRPDG=-R2;
01386                      else                   nRPDG=-R1; // pRPDG == R2
01387                    }
01388                  }
01389                  break;
01390              }
01391              break;
01392             case 4: // ------------------------------------> QaQ + aDiQDiQ = QaQ (double)
01393              switch (af)
01394              {
01395                case 1: // ....................... pLPDG > 7 && pRPDG <-7 === LL/RR
01396                  order= 1;
01397                  if(-cLPDG == pL1) nLPDG= pL2;
01398                  else              nLPDG= pL1;
01399                  if( cRPDG == pR1) nRPDG=-pR2;
01400                  else              nRPDG=-pR1;
01401                  break;
01402                case 2: // ...................... pLPDG > 7 && pRPDG <-7 === LR/RL
01403                  order=-1;
01404                  if(-cRPDG == pL1) nLPDG= pL2;
01405                  else              nLPDG= pL1;
01406                  if( cLPDG == pR1) nRPDG=-pR2;
01407                  else              nRPDG=-pR1;
01408                  break;
01409                case 3: // ...................... pRPDG > 7 && pLPDG <-7 === LL/RR
01410                  order= 1;
01411                  if( cLPDG == pL1) nLPDG=-pL2;
01412                  else              nLPDG=-pL1;
01413                  if(-cRPDG == pR1) nRPDG= pR2;
01414                  else              nRPDG= pR1;
01415                  break;
01416                case 4: // ...................... pRPDG > 7 && pLPDG <-7 === LR/RL
01417                  order=-1;
01418                  if( cRPDG == pL1) nLPDG=-pL2;
01419                  else              nLPDG=-pL1;
01420                  if(-cLPDG == pR1) nRPDG= pR2;
01421                  else              nRPDG= pR1;
01422                  break;
01423              }
01424              break;
01425             case 5: // ------------------------------------> aDiQDiQ + QaQ = QaQ (double)
01426              switch (af)
01427              {
01428                case 1: // ...................... cLPDG > 7 && cRPDG <-7 === LL/RR
01429                  order= 1;
01430                  if(-pLPDG == L1) nLPDG= L2;
01431                  else             nLPDG= L1;
01432                  if( pRPDG == R1) nRPDG=-R2;
01433                  else             nRPDG=-R1;
01434                  break;
01435                case 2: // ...................... cLPDG > 7 && cRPDG <-7 === LR/RL
01436                  order=-1;
01437                  if(-pRPDG == L1) nRPDG= L2;
01438                  else             nRPDG= L1;
01439                  if( pLPDG == R1) nLPDG=-R2;
01440                  else             nLPDG=-R1;
01441                  break;
01442                case 3: // ...................... cRPDG > 7 && cLPDG <-7 === LL/RR
01443                  order= 1;
01444                  if( pLPDG == L1) nLPDG=-L2;
01445                  else             nLPDG=-L1;
01446                  if(-pRPDG == R1) nRPDG= R2;
01447                  else             nRPDG= R1;
01448                  break;
01449                case 4: // ...................... cRPDG > 7 && cLPDG <-7 === LR/RL
01450                  order=-1;
01451                  if( pRPDG == L1) nRPDG=-L2;
01452                  else             nRPDG=-L1;
01453                  if(-pLPDG == R1) nLPDG= R2;
01454                  else             nLPDG= R1;
01455                  break;
01456              }
01457              break;
01458             case 6: // ------------------------------------> QDiQ + aQaDiQ = QaQ (double)
01459              switch (af)
01460              {
01461                case 1:
01462                  order=-1;
01463                  if(-cRPDG == pL1) nLPDG= pL2;
01464                  else              nLPDG= pL1;
01465                  if( pRPDG ==  L1) nRPDG= -L2;
01466                  else              nRPDG= -L1;
01467                  break;
01468                case 2:
01469                  order= 1;
01470                  if(-cLPDG == pL1) nLPDG= pL2;
01471                  else              nLPDG= pL1;
01472                  if( pRPDG ==  R1) nRPDG= -R2;
01473                  else              nRPDG= -R1;
01474                  break;
01475                case 3:
01476                  order= 1;
01477                  if(-cRPDG == pR1) nRPDG= pR2;
01478                  else              nRPDG= pR1;
01479                  if( pLPDG ==  L1) nLPDG= -L2;
01480                  else              nLPDG= -L1;
01481                  break;
01482                case 4:
01483                  order=-1;
01484                  if(-cLPDG == pR1) nRPDG= pR2;
01485                  else              nRPDG= pR1;
01486                  if( pLPDG ==  R1) nLPDG= -R2;
01487                  else              nLPDG= -R1;
01488                  break;
01489                case 5:
01490                  order=-1;
01491                  if(-pRPDG ==  L1) nRPDG=  L2;
01492                  else              nRPDG=  L1;
01493                  if( cRPDG == pL1) nLPDG=-pL2;
01494                  else              nLPDG=-pL1;
01495                  break;
01496                case 6:
01497                  order= 1;
01498                  if(-pLPDG ==  L1) nLPDG=  L2;
01499                  else              nLPDG=  L1;
01500                  if( cRPDG == pR1) nRPDG=-pR2;
01501                  else              nRPDG=-pR1;
01502                  break;
01503                case 7:
01504                  order= 1;
01505                  if(-pRPDG ==  R1) nRPDG=  R2;
01506                  else              nRPDG=  R1;
01507                  if( cLPDG == pL1) nLPDG=-pL2;
01508                  else              nLPDG=-pL1;
01509                  break;
01510                case 8:
01511                  order=-1;
01512                  if(-pLPDG ==  R1) nLPDG=  R2;
01513                  else              nLPDG=  R1;
01514                  if( cLPDG == pR1) nRPDG=-pR2;
01515                  else              nRPDG=-pR1;
01516                  break;
01517              }
01518              break;
01519           }
01520           if(!order) G4cerr<<"-Warning-G4QFrag::Constr: t="<<tf<<", a="<<af<<", cL="<<cLPDG
01521                            <<", cR="<<cRPDG<<", pL="<<pLPDG<<", pR="<<pRPDG<<G4endl;
01522           else
01523           {
01524             // With theNewHypotheticalPartons the min mass must be calculated & compared
01525             G4int LT=1;
01526             if(std::abs(nLPDG) > 7) ++LT;
01527             G4int RT=1;
01528             if(std::abs(nRPDG) > 7) ++RT;
01529             G4double minM=0.;
01530             G4bool sing=true;
01531             if(cLT==2 && cRT==2)
01532             {
01533               aLPDG=0;
01534               aRPDG=0;
01535               if(cLPDG>0)
01536               {
01537                 aLPDG=nLPDG/100;
01538                 aRPDG=(-nRPDG)/100;
01539               }
01540               else //cRPDG>0
01541               {
01542                 aRPDG=nRPDG/100;
01543                 aLPDG=(-nLPDG)/100;
01544               }
01545               G4int nL1=aLPDG/10;
01546               G4int nL2=aLPDG%10;
01547               G4int nR1=aRPDG/10;
01548               G4int nR2=aRPDG%10;
01549               if(nL1!=nR1 && nL1!=nR2 && nL2!=nR1 && nL2!=nR2) // Unreducable DiQ-aDiQ
01550               {
01551 #ifdef debug
01552                 G4cout<<"G4QFragmentation::Const:aLPDG="<<aLPDG<<", aRPDG="<<aRPDG<<G4endl;
01553 #endif
01554                 sing=false;
01555                 G4QPDGCode tmp;
01556                 std::pair<G4int,G4int> pB=tmp.MakeTwoBaryons(nL1, nL2, nR1, nR2);
01557                 minM=G4QPDGCode(pB.first).GetMass()+G4QPDGCode(pB.second).GetMass();
01558               }
01559             }
01560             if(sing)
01561             {
01562               std::pair<G4int,G4int> newPair = std::make_pair(nLPDG,nRPDG);
01563               G4QContent newStQC(newPair);        // NewString QuarkContent
01564 #ifdef debug
01565               G4cout<<"G4QFr::Con: LPDG="<<nLPDG<<",RPDG="<<nRPDG<<",QC="<<newStQC<<G4endl;
01566 #endif
01567               G4int minPDG=newStQC.GetSPDGCode(); // PDG of the Lightest Hadron=String
01568               minM=G4QPDGCode(minPDG).GetMass() + mPi0; // Min SingleHadron=String Mass
01569             }
01570             // Compare this mass
01571             G4bool win=false;
01572             G4double    pSM=0.;
01573             if(pSM2>0.) pSM=std::sqrt(pSM2);
01574             if(minC && pSM2 > maxiM2)             // Up to now any positive mass is good
01575             {
01576               maxiM2=pSM2;
01577               win=true;
01578             }
01579             else if(!minC || pSM > minM)
01580             {
01581               pExcess=pSM-minM;
01582               if(minC || pExcess > excess)
01583               {
01584                 minC=false;
01585                 excess=pExcess;
01586                 win=true;
01587               }
01588             }
01589             if(win)
01590             {
01591               sst=pst;
01592               sLPDG=nLPDG;
01593               sRPDG=nRPDG;
01594               sOrd=order;
01595             }
01596           } // End of IF(new partons are created)
01597         } // End of IF(compatible partons)
01598         //} // End of positive squared mass of the fused string
01599       } // End of the LOOP over the possible partners (with the exclusive if for itself)
01600       if(sOrd)                                       // The best pStringCandidate was found
01601       {
01602         G4LorentzVector cL4M=cLeft->Get4Momentum();
01603         G4LorentzVector cR4M=cRight->Get4Momentum();
01604         G4QParton* pLeft=(*sst)->GetLeftParton();
01605         G4QParton* pRight=(*sst)->GetRightParton();
01606         G4LorentzVector pL4M=pLeft->Get4Momentum();
01607         G4LorentzVector pR4M=pRight->Get4Momentum();
01608 #ifdef debug
01609         G4cout<<"G4QFragmentation::Const:cS4M="<<cS4M<<" fused/w pS4M="<<pL4M+pR4M<<G4endl;
01610 #endif
01611         if(sOrd>0)
01612         {
01613           pL4M+=cL4M;
01614           pR4M+=cR4M;
01615         }
01616         else
01617         {
01618           pL4M+=cR4M;
01619           pR4M+=cL4M;
01620         }
01621         pLeft->SetPDGCode(sLPDG);
01622         pLeft->Set4Momentum(pL4M);
01623         pRight->SetPDGCode(sRPDG);
01624         pRight->Set4Momentum(pR4M);
01625         delete (*ist);
01626         strings.erase(ist);
01627 #ifdef debug
01628         G4LorentzVector ss4M=pL4M+pR4M;
01629         G4cout<<"G4QFragmentation::Construct:Created,4M="<<ss4M<<",m2="<<ss4M.m2()<<G4endl;
01630 #endif
01631         if( ist != strings.begin() ) // To avoid going below begin() (for Windows)
01632         {
01633           ist--;
01634           con=false;
01635 #ifdef debug
01636           G4cout<<"G4QFragmentation::Construct: *** IST Decremented ***"<<G4endl;
01637 #endif
01638         }
01639         else
01640         {
01641           con=true;
01642 #ifdef debug
01643           G4cout<<"G4QFragmentation::Construct: *** IST Begin ***"<<G4endl;
01644 #endif
01645           break;
01646         }
01647       } // End of the IF(the best partnerString candidate was found)
01648       else
01649       {
01650 #ifdef debug
01651         G4cout<<"-Warning-G4QFragm::Const:S4M="<<cS4M<<",M2="<<cSM2<<" Leave ASIS"<<G4endl;
01652 #endif
01653         ++problem;
01654         con=false;
01655       }
01656     } // End of IF
01657     else con=false;
01658    } // End of loop over ist iterator
01659 #ifdef debug
01660    G4cout<<"G4QFragmentation::Construct: *** IST While *** , con="<<con<<G4endl;
01661 #endif
01662   } // End of "con" while 
01663 #ifdef edebug
01664   // This print has meaning only if something appear between it and the StringFragmLOOP
01665   G4LorentzVector t4M=theNucleus.Get4Momentum();    // Nucleus 4Mom in LS
01666   G4int rC=totChg-theNucleus.GetZ();
01667   G4int rB=totBaN-theNucleus.GetA();
01668   G4int nStr=strings.size();
01669   G4cout<<"-EMCLS-G4QFr::Const: AfterSUPPRESION #ofS="<<nStr<<",tNuc4M(E=M)="<<sum<<G4endl;
01670   for(G4int i=0; i<nStr; i++)
01671   {
01672     G4LorentzVector strI4M=strings[i]->Get4Momentum();
01673     t4M+=strI4M;
01674     G4int sChg=strings[i]->GetCharge();
01675     rC-=sChg;
01676     G4int sBaN=strings[i]->GetBaryonNumber();
01677     rB-=sBaN;
01678     G4cout<<"-EMCLS-G4QFragm::Construct: St#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
01679           <<", C="<<sChg<<", B="<<sBaN<<G4endl;
01680   }
01681   G4cout<<"-EMCLS-G4QFragm::Construct:r4M="<<t4M-totLS4M<<",rC="<<rC<<",rB="<<rB<<G4endl;
01682 #endif
01683   //
01684   // --- If a problem is foreseen then the DiQaDiQ strings should be reduced if possible --
01685   //
01686 #ifdef debug
01687     G4cout<<"G4QFragmentation::Construct: problem="<<problem<<G4endl;
01688 #endif
01689   if(problem)
01690   {
01691     G4int nOfStr=strings.size();
01692 #ifdef debug
01693     G4cout<<"G4QFragmentation::Construct:SecurityDiQaDiQReduction,#OfStr="<<nOfStr<<G4endl;
01694 #endif
01695     for (G4int astring=0; astring < nOfStr; astring++)
01696     {
01697       G4QString* curString=strings[astring];
01698       G4QParton* cLeft=curString->GetLeftParton();
01699       G4QParton* cRight=curString->GetRightParton();
01700       G4int LT=cLeft->GetType();
01701       G4int RT=cRight->GetType();
01702       G4int sPDG=cLeft->GetPDGCode();
01703       G4int nPDG=cRight->GetPDGCode();
01704       if(LT==2 && RT==2)
01705       {
01706 #ifdef debug
01707         G4cout<<"G4QFragmentation::Constr:TrySelfReduString,L="<<sPDG<<",R="<<nPDG<<G4endl;
01708 #endif
01709         if( cLeft->ReduceDiQADiQ(cLeft, cRight) ) // DiQ-aDiQ pair was successfully reduced
01710         {
01711           sPDG=cLeft->GetPDGCode();
01712           nPDG=cRight->GetPDGCode();
01713 #ifdef debug
01714           G4cout<<"+G4QFragm::Const:#"<<astring<<" Reduced, L="<<sPDG<<",R="<<nPDG<<G4endl;
01715 #endif
01716         }
01717 #ifdef debug
01718         else G4cout<<"--*--G4QFragm::Const:#"<<astring<<" DQ-aDQ reduction Failed"<<G4endl;
01719 #endif
01720       } // End of the found DiQ/aDiQ pair
01721       else if(sPDG==3 && nPDG==-3)
01722       {
01723         sPDG= 1;
01724         nPDG=-1;
01725         cLeft->SetPDGCode(sPDG);
01726         cRight->SetPDGCode(nPDG);
01727       }
01728       else if(sPDG==-3 && nPDG==3)
01729       {
01730         sPDG=-1;
01731         nPDG= 1;
01732         cLeft->SetPDGCode(sPDG);
01733         cRight->SetPDGCode(nPDG);
01734       }
01735     }
01736     SwapPartons();
01737   } // End of IF(problem)
01738 #ifdef edebug
01739   G4LorentzVector u4M=theNucleus.Get4Momentum();    // Nucleus 4Mom in LS
01740   G4int rCh=totChg-theNucleus.GetZ();
01741   G4int rBa=totBaN-theNucleus.GetA();
01742   G4int nStri=strings.size();
01743   G4cout<<"-EMCLS-G4QFr::Const: FinalConstruct, #ofSt="<<nStri<<",tN4M(E=M)="<<t4M<<G4endl;
01744   for(G4int i=0; i<nStri; i++)
01745   {
01746     G4LorentzVector strI4M=strings[i]->Get4Momentum();
01747     u4M+=strI4M;
01748     G4int sChg=strings[i]->GetCharge();
01749     rCh-=sChg;
01750     G4int sBaN=strings[i]->GetBaryonNumber();
01751     rBa-=sBaN;
01752     G4cout<<"-EMCLS-G4QFragm::Construct: St#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
01753           <<", C="<<sChg<<", B="<<sBaN<<G4endl;
01754   }
01755   G4cout<<"-EMCLS-G4QFragm::Construct:r4M="<<u4M-totLS4M<<",rC="<<rCh<<",rB="<<rBa<<G4endl;
01756 #endif
01757 } // End of the Constructer

G4QFragmentation::~G4QFragmentation (  ) 

Definition at line 1759 of file G4QFragmentation.cc.

01760 {
01761   std::for_each(strings.begin(), strings.end(), DeleteQString() );
01762 }


Member Function Documentation

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

Definition at line 4432 of file G4QFragmentation.cc.

References G4cerr, G4cout, and G4endl.

Referenced by Breeder().

04434 {//                                             ^L^^ Curent ^^R^
04435   G4int Ord=0;
04436   //       Curent   Partner
04437   if      (LS==2 && MPS==2 )                 // Fuse 2 Q-aQ strings to DiQ-aDiQ
04438   {
04439 #ifdef debug
04440     G4cout<<"G4QFragmentation::AnnihilationOrder: QaQ/QaQ->DiQ-aDiQ, uPDG="<<uPDG<<G4endl;
04441 #endif
04442     if     ( (uPDG>0 && sPDG>0 && mPDG<0 && nPDG<0) || 
04443              (uPDG<0 && sPDG<0 && mPDG>0 && nPDG>0) ) Ord= 1; // LL/RR
04444     else if( (uPDG>0 && nPDG>0 && mPDG<0 && sPDG<0) || 
04445              (uPDG<0 && nPDG<0 && mPDG>0 && sPDG>0) ) Ord=-1; // LR/RL
04446     else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 22 fusion, L="<<uPDG
04447                <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04448   }
04449   else if ( LS==2 && MPS==3 )
04450   {
04451     if     (uPDG > 7)                                // Fuse pLDiQ
04452     {
04453 #ifdef debug
04454       G4cout<<"G4QFragmentation::AnnihOrder: pLDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
04455 #endif
04456       if     ( sPDG<0 && (-sPDG==uPDG/1000 || -sPDG==(uPDG/100)%10) ) Ord= 1; // LL/RR
04457       else if( nPDG<0 && (-nPDG==uPDG/1000 || -nPDG==(uPDG/100)%10) ) Ord=-1; // LR/RL
04458       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pLDiQ, L="<<uPDG
04459                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04460     }
04461     else if (mPDG > 7)                               // Fuse pRDiQ
04462     {
04463 #ifdef debug
04464       G4cout<<"G4QFragmentation::AnnihOrder: pRDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
04465 #endif
04466       if     ( sPDG<0 && (-sPDG==mPDG/1000 || -sPDG==(mPDG/100)%10) ) Ord=-1; // LR/RL
04467       else if( nPDG<0 && (-nPDG==mPDG/1000 || -nPDG==(mPDG/100)%10) ) Ord= 1; // LL/RR
04468       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pRDiQ, L="<<uPDG
04469                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04470     }
04471     else if (uPDG <-7)                               // Fuse pLaDiQ
04472     {
04473 #ifdef debug
04474       G4cout<<"G4QFragmentation::AnnihOrder: pLaDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
04475 #endif
04476       if     ( sPDG>0 && (sPDG==(-uPDG)/1000 || sPDG==((-uPDG)/100)%10) ) Ord= 1; // LL/RR
04477       else if( nPDG>0 && (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord=-1; // LR/RL
04478       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pLaDiQ, L="<<uPDG
04479                  <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
04480     }
04481     else if (mPDG <-7)                              // Fuse pRaDiQ
04482     {
04483 #ifdef debug
04484       G4cout<<"G4QFragmentation::AnnihOrder: pRaDiQ, sPDG="<<sPDG<<", nPDG="<<nPDG<<G4endl;
04485 #endif
04486       if     ( sPDG>0 && (sPDG==(-mPDG)/1000 || sPDG==((-mPDG)/100)%10) ) Ord=-1; // LR/RL
04487       else if( nPDG>0 && (nPDG==(-mPDG)/1000 || nPDG==((-mPDG)/100)%10) ) Ord= 1; // LL/RR
04488       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong pRaDiQ, L="<<uPDG
04489                  <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
04490     }
04491     else if( (sPDG<0 && (-sPDG==mPDG || -sPDG==uPDG) ) ||
04492              (nPDG<0 && (-nPDG==mPDG || -nPDG==uPDG) ) ) Ord= 2; // @@ Annihilation fusion
04493 #ifdef debug
04494     else G4cout<<"-Warning-G4QFragmentation::AnnihilatOrder: Wrong 23StringFusion"<<G4endl;
04495     G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
04496           <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04497 #endif
04498   }
04499   else if ( LS==3 && MPS==2 )
04500   {
04501     if     (sPDG > 7)                                // Fuse cLDiQ
04502     {
04503 #ifdef debug
04504       G4cout<<"G4QFragmentation::AnnihOrder: cLDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
04505 #endif
04506       if     ( uPDG<0 && (-uPDG==sPDG/1000 || -uPDG==(sPDG/100)%10) ) Ord= 1; // LL/RR
04507       else if( mPDG<0 && (-mPDG==sPDG/1000 || -mPDG==(sPDG/100)%10) ) Ord=-1; // LR/RL
04508       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cLDiQ, L="<<uPDG
04509                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04510     }
04511     else if (nPDG > 7)                               // Fuse cRDiQ
04512     {
04513 #ifdef debug
04514       G4cout<<"G4QFragmentation::AnnihOrder: cRDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
04515 #endif
04516       if     ( uPDG<0 && (-uPDG==nPDG/1000 || -uPDG==(nPDG/100)%10) ) Ord=-1; // LR/RL
04517       else if( mPDG<0 && (-mPDG==nPDG/1000 || -mPDG==(nPDG/100)%10) ) Ord= 1; // LL/RR
04518       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cRDiQ, L="<<uPDG
04519                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04520     }
04521     else if (sPDG <-7)                               // Fuse cLaDiQ
04522     {
04523 #ifdef debug
04524       G4cout<<"G4QFragmentation::AnnihOrder: cLaDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
04525 #endif
04526       if     ( uPDG>0 && (uPDG==(-sPDG)/1000 || uPDG==((-sPDG)/100)%10) ) Ord= 1; // LL/RR
04527       else if( mPDG>0 && (mPDG==(-sPDG)/1000 || mPDG==((-sPDG)/100)%10) ) Ord=-1; // LR/RL
04528       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cLaDiQ, L="<<uPDG
04529                  <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
04530     }
04531     else if (nPDG <-7)                              // Fuse cRaDiQ
04532     {
04533 #ifdef debug
04534       G4cout<<"G4QFragmentation::AnnihOrder: cRaDiQ, uPDG="<<uPDG<<", mPDG="<<mPDG<<G4endl;
04535 #endif
04536       if     ( uPDG>0 && (uPDG==(-nPDG)/1000 || uPDG==((-nPDG)/100)%10) ) Ord=-1; // LR/RL
04537       else if( mPDG>0 && (mPDG==(-nPDG)/1000 || mPDG==((-nPDG)/100)%10) ) Ord= 1; // LL/RR
04538       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong cRaDiQ, L="<<uPDG
04539                  <<", R="<<mPDG<<", cL="<<sPDG<<", cR="<<nPDG<<G4endl;
04540     }
04541     else if( (uPDG<0 && (-uPDG==sPDG || -uPDG==nPDG) ) ||
04542              (mPDG<0 && (-mPDG==sPDG || -mPDG==nPDG) ) ) Ord=2; // @@ Annihilation fusion
04543 #ifdef debug
04544     else G4cout<<"-Warning-G4QFragmentation::AnnihilatOrder: Wrong 32StringFusion"<<G4endl;
04545     G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
04546           <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04547 #endif
04548   }
04549   else if ( (LS==2 && MPS==4) || (LS==4 && MPS==2) )
04550   {
04551     if     (uPDG > 7)  // Annihilate pLDiQ
04552     {
04553 #ifdef debug
04554       G4cout<<"G4QFragmentation::AnnihilOrder:pLDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
04555 #endif
04556       if     ( sPDG<0 && (-sPDG==uPDG/1000 || -sPDG==(uPDG/100)%10) &&
04557                (nPDG==(-mPDG)/1000 || nPDG==((-mPDG)/100)%10) ) Ord= 1; // LL/RR
04558       else if( nPDG<0 && (-nPDG==uPDG/1000 || -nPDG==(uPDG/100)%10) &&
04559                (sPDG==(-mPDG)/1000 || sPDG==((-mPDG)/100)%10) ) Ord=-1; // LR/RL
04560       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 pLDiQ, L="<<uPDG
04561                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04562     }
04563     else if (mPDG >7) // Annihilate pRDiQ
04564     {
04565 #ifdef debug
04566       G4cout<<"G4QFragmentation::AnnihilOrder:PRDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
04567 #endif
04568       if     ( sPDG<0 && (-sPDG==mPDG/1000 || -sPDG==(mPDG/100)%10) &&
04569                (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord=-1; // LR/RL
04570       else if( nPDG<0 && (-nPDG==mPDG/1000 || -nPDG==(mPDG/100)%10) &&
04571                (sPDG==(-uPDG)/1000 || sPDG==((-uPDG)/100)%10) ) Ord= 1; // LL/RR
04572       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 pLDiQ, L="<<uPDG
04573                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04574     }
04575     else if (sPDG > 7)   // Annihilate cLDiQ
04576     {
04577 #ifdef debug
04578       G4cout<<"G4QFragmentation::AnnihilOrder:cLDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04579 #endif
04580       if     ( uPDG<0 && (-uPDG==sPDG/1000 || -uPDG==(sPDG/100)%10) &&
04581                (mPDG==(-nPDG)/1000 || mPDG==((-nPDG)/100)%10) ) Ord= 1; // LL/RR
04582       else if( mPDG<0 && (-mPDG==sPDG/1000 || -mPDG==(sPDG/100)%10) &&
04583                (uPDG==(-nPDG)/1000 || uPDG==((-nPDG)/100)%10) ) Ord=-1; // LR/RL
04584       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 cLDiQ, L="<<uPDG
04585                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04586     }
04587     else if (nPDG > 7)   // Annihilate cRDiQ
04588     {
04589 #ifdef debug
04590       G4cout<<"G4QFragmentation::AnnihilOrder:cRDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04591 #endif
04592       if     ( uPDG<0 && (-uPDG==nPDG/1000 || -uPDG==(nPDG/100)%10) &&
04593                (mPDG==(-sPDG)/1000 || mPDG==((-sPDG)/100)%10) ) Ord=-1; // LR/RL
04594       else if( mPDG<0 && (-mPDG==nPDG/1000 || -mPDG==(nPDG/100)%10) &&
04595                (uPDG==(-sPDG)/1000 || uPDG==((-sPDG)/100)%10) ) Ord= 1; // LL/RR
04596       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 24 cRDiQ, L="<<uPDG
04597                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04598     }
04599 #ifdef debug
04600     else G4cout<<"-Warning-G4QFragmentation::AnnihilOrder: Wrong 24 StringFusion"<<G4endl;
04601     G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
04602           <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04603 #endif
04604   }
04605   else if ( LS==3 && MPS==3 )
04606   {
04607     if     (uPDG > 7)  // Annihilate pLDiQ
04608     {
04609 #ifdef debug
04610       G4cout<<"G4QFragmentation::AnnihilOrder: pLDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
04611 #endif
04612       if     ( sPDG<-7 && (-nPDG==uPDG/1000 || -nPDG==(uPDG/100)%10) &&
04613                (mPDG==(-sPDG)/1000 || mPDG==((-sPDG)/100)%10) ) Ord=-1; // LR/RL
04614       else if( nPDG<-7 && (-sPDG==uPDG/1000 || -sPDG==(uPDG/100)%10) &&
04615                (mPDG==(-nPDG)/1000 || mPDG==((-nPDG)/100)%10) ) Ord= 1; // LL/RR
04616       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 pLDiQ, L="<<uPDG
04617                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04618     }
04619     else if(mPDG > 7)  // Annihilate pRDiQ
04620     {
04621 #ifdef debug
04622       G4cout<<"G4QFragmentation::AnnihilOrder: pRDiQ, sPDG="<<sPDG<<",nPDG="<<nPDG<<G4endl;
04623 #endif
04624       if     ( sPDG<-7 && (-nPDG==mPDG/1000 || -nPDG==(mPDG/100)%10) &&
04625                (uPDG==(-sPDG)/1000 || uPDG==((-sPDG)/100)%10) ) Ord= 1; // LL/RR
04626       else if( nPDG<-7 && (-sPDG==mPDG/1000 || -sPDG==(mPDG/100)%10) &&
04627                (uPDG==(-nPDG)/1000 || uPDG==((-nPDG)/100)%10) ) Ord=-1; // LR/RL
04628       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 pRDiQ, L="<<uPDG
04629                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04630     }
04631     else if(sPDG > 7)  // Annihilate cLDiQ
04632     {
04633 #ifdef debug
04634       G4cout<<"G4QFragmentation::AnnihilOrder: cLDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04635 #endif
04636       if     ( uPDG<-7 && (-mPDG==sPDG/1000 || -mPDG==(sPDG/100)%10) &&
04637                (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord=-1; // LR/RL
04638       else if( mPDG<-7 && (-uPDG==sPDG/1000 || -uPDG==(sPDG/100)%10) &&
04639                (nPDG==(-mPDG)/1000 || nPDG==((-mPDG)/100)%10) ) Ord= 1; // LL/RR
04640       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 cLDiQ, L="<<uPDG
04641                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04642     }
04643     else if(nPDG > 7)  // Annihilate cRDiQ
04644     {
04645 #ifdef debug
04646       G4cout<<"G4QFragmentation::AnnihilOrder: cRDiQ, uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04647 #endif
04648       if     ( uPDG<-7 && (-mPDG==nPDG/1000 || -mPDG==(nPDG/100)%10) &&
04649                (nPDG==(-uPDG)/1000 || nPDG==((-uPDG)/100)%10) ) Ord= 1; // LL/RR
04650       else if( mPDG<-7 && (-uPDG==nPDG/1000 || -sPDG==(nPDG/100)%10) &&
04651                (sPDG==(-mPDG)/1000 || sPDG==((-mPDG)/100)%10) ) Ord=-1; // LR/RL
04652       else G4cerr<<"-Warning-G4QFragmentation::AnnihilationOrder: Wrong 33 cRDiQ, L="<<uPDG
04653                  <<",R="<<mPDG<<",cL="<<sPDG<<",cR="<<nPDG<<G4endl;
04654     }
04655 #ifdef debug
04656     else G4cout<<"-Warning-G4QFragmentation::AnnihilOrder: Wrong 33 StringFusion"<<G4endl;
04657     G4cout<<"G4QFragmentation::AnnihilationOrder: Ord="<<Ord<<",sPDG="<<sPDG<<",nPDG="
04658           <<nPDG<<", uPDG="<<uPDG<<",mPDG="<<mPDG<<G4endl;
04659 #endif
04660   }
04661   return Ord;
04662 }

void G4QFragmentation::Breeder (  )  [protected]

Definition at line 2449 of file G4QFragmentation.cc.

References G4QContent::AddParton(), AnnihilationOrder(), DBL_MAX, G4Quasmon::DecayQHadron(), edebug, FatalException, G4QString::FragmentString(), G4cerr, G4cout, G4endl, G4Exception(), G4QParton::Get4Momentum(), G4QString::Get4Momentum(), G4QHadron::Get4Momentum(), G4QNucleus::GetA(), G4QHadron::GetBaryonNumber(), G4QString::GetBaryonNumber(), G4QHadron::GetCharge(), G4QString::GetCharge(), G4QString::GetDirection(), G4QString::GetLeftParton(), G4QPDGCode::GetMass(), G4QNucleus::GetPDG(), G4QPDGCode::GetPDGCode(), G4QHadron::GetPDGCode(), G4QParton::GetPDGCode(), G4QHadron::GetQC(), G4QString::GetQC(), G4QHadron::GetQPDG(), G4QChipolino::GetQPDG1(), G4QChipolino::GetQPDG2(), G4QString::GetRightParton(), G4QContent::GetSPDGCode(), G4QParton::GetType(), G4QNucleus::GetZ(), LT, G4QParton::ReduceDiQADiQ(), ReducePair(), G4QHadron::Set4Momentum(), G4QParton::Set4Momentum(), G4QParton::SetPDGCode(), G4QHadron::SetQC(), G4QHadron::SetQPDG(), sqr(), and SumPartonPDG().

Referenced by Fragment().

02450 { // This is the member function, which returns the resulting vector of Hadrons & Quasmons
02451   static const G4double  eps = 0.001;                              // Tolerance in MeV
02452   //static const G4QContent vacQC(0,0,0,0,0,0);
02453   static const G4LorentzVector vac4M(0.,0.,0.,0.);
02454   //
02455   // ------------ At this point the strings are fragmenting to hadrons in LS -------------
02456   //
02457 #ifdef edebug
02458   G4LorentzVector totLS4M=theNucleus.Get4Momentum();    // Nucleus 4Mom in LS
02459   G4int totChg=theNucleus.GetZ();
02460   G4int totBaN=theNucleus.GetA();
02461   G4int nStri=strings.size();
02462   G4cout<<"-EMCLS-G4QFr::Breed: CHECKRecovery #ofS="<<nStri<<",N4M(E=M)="<<totLS4M<<G4endl;
02463   for(G4int i=0; i<nStri; i++)
02464   {
02465     G4LorentzVector strI4M=strings[i]->Get4Momentum();
02466     totLS4M+=strI4M;
02467     G4int sChg=strings[i]->GetCharge();
02468     totChg+=sChg;
02469     G4int sBaN=strings[i]->GetBaryonNumber();
02470     totBaN+=sBaN;
02471     G4cout<<"-EMCLS-G4QFragm::Breeder: St#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
02472           <<", C="<<sChg<<", B="<<sBaN<<G4endl;
02473   }
02474 #endif
02475   G4int nOfStr=strings.size();
02476 #ifdef debug
02477   G4cout<<"G4QFragmentation::Breeder: BeforeFragmentation, #OfStr="<<nOfStr<<G4endl;
02478 #endif
02479   G4LorentzVector ft4M(0.,0.,0.,0.);
02480   G4QContent      ftQC(0,0,0,0,0,0);
02481   G4bool          ftBad=false;
02482   for(G4int i=0; i < nOfStr; ++i)
02483   {
02484     G4QString* crStr=strings[i];
02485     G4LorentzVector pS4M=crStr->Get4Momentum();     // String 4-momentum
02486     ft4M+=pS4M;
02487     G4QContent pSQC=crStr->GetQC();                 // String Quark Content
02488     ftQC+=pSQC;
02489     if(pS4M.m2() < 0.) ftBad=true;
02490 #ifdef debug
02491     G4cout<<">G4QFrag::Br:1stTest,S#"<<i<<",P="<<crStr<<",4M="<<pS4M<<",QC="<<pSQC<<G4endl;
02492 #endif
02493   }
02494   if(ftBad)
02495   {
02496     G4Quasmon* stringQuasmon = new G4Quasmon(ftQC, ft4M);
02497 #ifdef debug
02498     G4cout<<"->G4QFragmentation::Breeder:*TotQ*,QC="<<ftQC<<",4M="<<ft4M<<ft4M.m()<<G4endl;
02499 #endif
02500     theQuasmons.push_back(stringQuasmon);
02501     G4LorentzVector r4M=theNucleus.Get4Momentum();  // Nucleus 4-momentum in LS
02502     G4int rPDG=theNucleus.GetPDG();
02503     G4QHadron* resNuc = new G4QHadron(rPDG,r4M);
02504     theResult->push_back(resNuc);                   // Fill the residual nucleus
02505     return;
02506   }
02507   for (G4int astring=0; astring < nOfStr; astring++)
02508   {
02509 #ifdef edebug
02510     G4LorentzVector sum=theNucleus.Get4Momentum();  // Nucleus 4Mom in LS
02511     G4int rChg=totChg-theNucleus.GetZ();
02512     G4int rBaN=totBaN-theNucleus.GetA();
02513     G4int nOfHadr=theResult->size();
02514     G4cout<<"-EMCLS-G4QFragmentation::Breeder:#ofSt="<<nOfStr<<",#ofHad="<<nOfHadr<<G4endl;
02515     for(G4int i=astring; i<nOfStr; i++)
02516     {
02517       G4LorentzVector strI4M=strings[i]->Get4Momentum();
02518       sum+=strI4M;
02519       G4int sChg=strings[i]->GetCharge();
02520       rChg-=sChg;
02521       G4int sBaN=strings[i]->GetBaryonNumber();
02522       rBaN-=sBaN;
02523       G4cout<<"-EMCLS-G4QF::Breed:S#"<<i<<",4M="<<strI4M<<",C="<<sChg<<",B="<<sBaN<<G4endl;
02524     }
02525     for(G4int i=0; i<nOfHadr; i++)
02526     {
02527       G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
02528       sum+=hI4M;
02529       G4int hChg=(*theResult)[i]->GetCharge();
02530       rChg-=hChg;
02531       G4int hBaN=(*theResult)[i]->GetBaryonNumber();
02532       rBaN-=hBaN;
02533       G4cout<<"-EMCLS-G4QFr::Breed: H#"<<i<<",4M="<<hI4M<<",C="<<hChg<<",B="<<hBaN<<G4endl;
02534     }
02535     G4cout<<"....-EMCLS-G4QFrag::Br:r4M="<<sum-totLS4M<<",rC="<<rChg<<",rB="<<rBaN<<G4endl;
02536 #endif
02537     G4QString* curString=strings[astring];
02538     if(!curString->GetDirection()) continue;  // Historic for the dead strings: DoesNotWork
02539     G4int curStrChg = curString->GetCharge();
02540     G4int curStrBaN = curString->GetBaryonNumber();
02541     G4LorentzVector curString4M = curString->Get4Momentum();
02542 #ifdef debug
02543     G4cout<<"=--=>G4QFragmentation::Breeder: String#"<<astring<<",s4M/m="<<curString4M
02544           <<curString4M.m()<<", LPart="<<curString->GetLeftParton()->GetPDGCode()
02545           <<", RPart="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
02546 #endif
02547     G4QHadronVector* theHadrons = 0;           // Prototype of theStringFragmentationOUTPUT
02548     theHadrons=curString->FragmentString(true);// !! Fragmenting the String !!
02549     if (!theHadrons)                           // The string can not be fragmented
02550     {
02551       // First try to correct the diQ-antiDiQ strings, converting them to Q-antiQ
02552       G4QParton* cLeft=curString->GetLeftParton();
02553       G4QParton* cRight=curString->GetRightParton();
02554       G4int sPDG=cLeft->GetPDGCode();
02555       G4int nPDG=cRight->GetPDGCode();
02556       G4int LT=cLeft->GetType();
02557       G4int RT=cRight->GetType();
02558       G4int LS=LT+RT;
02559       if(LT==2 && RT==2)
02560       {
02561 #ifdef debug
02562         G4cout<<"G4QFragmentation::Breeder:TryReduceString, L="<<sPDG<<",R="<<nPDG<<G4endl;
02563 #endif
02564         if( cLeft->ReduceDiQADiQ(cLeft, cRight) ) // DiQ-aDiQ pair was successfully reduced
02565         {
02566           LT=1;
02567           RT=1;
02568           LS=2;
02569           sPDG=cLeft->GetPDGCode();
02570           nPDG=cRight->GetPDGCode();
02571 #ifdef debug
02572           G4cout<<"G4QFragmentation::Breeder:AfterReduction,L="<<sPDG<<",R="<<nPDG<<G4endl;
02573 #endif
02574           theHadrons=curString->FragmentString(true);
02575           cLeft=curString->GetLeftParton();
02576           cRight=curString->GetRightParton();
02577 #ifdef debug
02578           G4cout<<"G4QFrag::Breed:L="<<cLeft->Get4Momentum()<<",R="<<cRight->Get4Momentum()
02579                 <<G4endl;
02580 #endif
02581         }
02582 #ifdef debug
02583         else G4cout<<"^G4QFragmentation::Breeder: DQ-aDQ reduction to Q-aQ Failed"<<G4endl;
02584 #endif
02585       } // End of the SelfReduction
02586 #ifdef debug
02587       G4cout<<"G4QFrag::Breed:AfterRedAttempt, theH="<<theHadrons<<", L4M="
02588             <<cLeft->Get4Momentum()<<", R4M="<<cRight->Get4Momentum()<<G4endl;
02589 #endif
02590       unsigned next=astring+1;                 // The next string position
02591       if (!theHadrons)                         // The string can not be fragmented
02592       {
02593         G4int fusionDONE=0; // StringFusion didn't happen (1=Fuse L+L/R+R, -1=Fuse L+R/R+L)
02594         if(next < strings.size())              // TheString isn't theLastString can fuse
02595         {
02596           G4int fustr=0;                       // The found partner index (never can be 0)
02597           G4int swap=0;                        // working interger for swapping parton PDG
02598           G4double Vmin=DBL_MAX;               // Prototype of the found Velocity Distance 
02599           G4int dPDG=nPDG;
02600           G4int qPDG=sPDG;
02601           if(dPDG<-99 || (dPDG>0&&dPDG<7) || qPDG>99 || (qPDG<0 && qPDG>-7))
02602           {
02603             swap=qPDG;
02604             qPDG=dPDG;
02605             dPDG=swap;
02606           }
02607           if(dPDG>99) dPDG/=100;
02608           if(qPDG<-99) qPDG=-(-qPDG)/100;
02609 #ifdef debug
02610           G4cout<<"G4QFrag::Breed:TryFuseStringS, q="<<qPDG<<", a="<<dPDG<<", n="<<next
02611                 <<G4endl;
02612 #endif
02613           G4ThreeVector curV=curString4M.vect()/curString4M.e();
02614           G4int reduce=0;                      // a#of reduced Q-aQ pairs
02615           G4int restr=0;                       // To use beyon the LOOP for printing
02616           G4int MPS=0;                         // PLS for the selected string
02617           for (restr=next; restr < nOfStr; restr++)
02618           {
02619             reduce=0;
02620             G4QString* reString=strings[restr];
02621             G4QParton* Left=reString->GetLeftParton();
02622             G4QParton* Right=reString->GetRightParton();
02623             G4int uPDG=Left->GetPDGCode();
02624             G4int mPDG=Right->GetPDGCode();
02625             G4int PLT =Left->GetType();
02626             G4int PRT =Right->GetType();
02627             G4int aPDG=mPDG;
02628             G4int rPDG=uPDG;
02629             if(aPDG<-99 || (aPDG>0 && aPDG<7) || rPDG>99 || (rPDG<0 && rPDG>-7))
02630             {
02631               swap=rPDG;
02632               rPDG=aPDG;
02633               aPDG=swap;
02634             }
02635             if(aPDG > 99) aPDG/=100;
02636             if(rPDG <-99) rPDG=-(-rPDG)/100;
02637             // Try to reduce two DQ-aDQ strings
02638 #ifdef debug
02639             G4cout<<"G4QFragm::Breed: TryReduce #"<<restr<<",q="<<rPDG<<",a="<<aPDG<<G4endl;
02640 #endif
02641             if(LT==2 && RT==2 && PLT==2 && PRT==2)    // Have a chance for the reduction
02642             {
02643               G4int cQ1=(-qPDG)/10;
02644               G4int cQ2=(-qPDG)%10;
02645               G4int cA1=dPDG/10;
02646               G4int cA2=dPDG%10;
02647               G4int pQ1=(-rPDG)/10;
02648               G4int pQ2=(-rPDG)%10;
02649               G4int pA1=aPDG/10;
02650               G4int pA2=aPDG%10;
02651 #ifdef debug
02652                   G4cout<<"G4QFragment::Breeder: cQ="<<cQ1<<","<<cQ2<<", cA="<<cA1<<","<<cA2
02653                     <<", pQ="<<pQ1<<","<<pQ2<<", pA="<<pA1<<","<<pA2<<G4endl;
02654 #endif
02655               G4bool iQA = (cA1==pQ1 || cA1==pQ2 || cA2==pQ1 || cA2==pQ2);
02656               G4bool iAQ = (cQ1==pA1 || cQ1==pA2 || cQ2==pA1 || cQ2==pA2);
02657               if(iQA) reduce++;
02658               if(iAQ) reduce++;
02659               if  (reduce==2)                  // Two quark pairs can be reduced
02660               {
02661                 if(sPDG>0 && uPDG<0)           // LL/RR Reduction
02662                 {
02663                   std::pair<G4int,G4int> resLL=ReducePair(sPDG/100, (-uPDG)/100);
02664                   G4int newCL=resLL.first;
02665                   G4int newPL=resLL.second;
02666                   if(!newCL || !newPL)
02667                   {
02668                     G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PL="<<newPL<<G4endl;
02669                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LL-");
02670                   }
02671                   std::pair<G4int,G4int> resRR=ReducePair((-nPDG)/100, mPDG/100);
02672                   G4int newCR=resRR.first;
02673                   G4int newPR=resRR.second;
02674                   if(!newCR || !newPR)
02675                   {
02676                     G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PR="<<newPR<<G4endl;
02677                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RR-");
02678                   }
02679                   cLeft->SetPDGCode(newCL);    // Reset the left quark of curString
02680                   cRight->SetPDGCode(-newCR);  // Reset the right quark of curString
02681                   Left->SetPDGCode(-newPL);    // Reset the left quark of reString
02682                   Right->SetPDGCode(newPR);    // Reset the right quark of reString
02683                   break;                       // Break out of the reString internal LOOP
02684                 }
02685                 else if(sPDG<0 && uPDG>0)           // LL/RR Reduction
02686                 {
02687                   std::pair<G4int,G4int> resLL=ReducePair((-sPDG)/100, uPDG/100);
02688                   G4int newCL=resLL.first;
02689                   G4int newPL=resLL.second;
02690                   if(!newCL || !newPL)
02691                   {
02692                     G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PL="<<newPL<<G4endl;
02693                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LL+");
02694                   }
02695                   std::pair<G4int,G4int> resRR=ReducePair(nPDG/100, (-mPDG)/100);
02696                   G4int newCR=resRR.first;
02697                   G4int newPR=resRR.second;
02698                   if(!newCR || !newPR)
02699                   {
02700                     G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PR="<<newPR<<G4endl;
02701                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RR+");
02702                   }
02703                   cLeft->SetPDGCode(-newCL);   // Reset the left quark of curString
02704                   cRight->SetPDGCode(newCR);   // Reset the right quark of curString
02705                   Left->SetPDGCode(newPL);     // Reset the left quark of reString
02706                   Right->SetPDGCode(-newPR);   // Reset the right quark of reString
02707                   break;                       // Break out of the reString internal LOOP
02708                 }
02709                 else if(sPDG>0 && mPDG<0)                // LR Reduction
02710                 {
02711                   std::pair<G4int,G4int> resLL=ReducePair(sPDG/100, (-mPDG)/100);
02712                   G4int newCL=resLL.first;
02713                   G4int newPR=resLL.second;
02714                   if(!newCL || !newPR)
02715                   {
02716                     G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PR="<<newPR<<G4endl;
02717                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LR");
02718                   }
02719                   std::pair<G4int,G4int> resRR=ReducePair((-nPDG)/100, uPDG/100);
02720                   G4int newCR=resRR.first;
02721                   G4int newPL=resRR.second;
02722                   if(!newCR || !newPR)
02723                   {
02724                     G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PL="<<newPL<<G4endl;
02725                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-LR");
02726                   }
02727                   cLeft->SetPDGCode(newCL);    // Reset the left quark of curString
02728                   cRight->SetPDGCode(-newCR);  // Reset the right quark of curString
02729                   Left->SetPDGCode(newPL);     // Reset the left quark of reString
02730                   Right->SetPDGCode(-newPR);   // Reset the right quark of reString
02731                   break;                       // Break out of the reString internal LOOP
02732                 }
02733                 else                           // RL Reduction
02734                 {
02735                   std::pair<G4int,G4int> resLL=ReducePair((-sPDG)/100, mPDG/100);
02736                   G4int newCL=resLL.first;
02737                   G4int newPR=resLL.second;
02738                   if(!newCL || !newPR)
02739                   {
02740                     G4cerr<<"*G4QFragmentation::Breeder:CL="<<newCL<<",PR="<<newPR<<G4endl;
02741                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RL");
02742                   }
02743                   std::pair<G4int,G4int> resRR=ReducePair(nPDG/100, (-uPDG)/100);
02744                   G4int newCR=resRR.first;
02745                   G4int newPL=resRR.second;
02746                   if(!newCR || !newPR)
02747                   {
02748                     G4cerr<<"*G4QFragmentation::Breeder:CR="<<newCR<<",PL="<<newPL<<G4endl;
02749                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"2-RL");
02750                   }
02751                   cLeft->SetPDGCode(-newCL);   // Reset the left quark of curString
02752                   cRight->SetPDGCode(newCR);   // Reset the right quark of curString
02753                   Left->SetPDGCode(-newPL);    // Reset the left quark of reString
02754                   Right->SetPDGCode(newPR);    // Reset the right quark of reString
02755                   break;                       // Break out of the reString internal LOOP
02756                 }
02757               } // End of IF(possible reduction)
02758             }
02759             // Check StringsCanBeFused: all QaQ+QaQ(22), single QaQ+QDiQ/aQaDtQ(23/32),
02760             //                          double QaQ+DiQaDiQ(24/42), QDiQ+aDiQaQ(34/43)
02761 #ifdef debug
02762             G4cout<<"G4QFragm::Breed:TryFuse/w #"<<restr<<",q="<<rPDG<<",a="<<aPDG<<G4endl;
02763 #endif
02764             G4int PLS=PLT+PRT;
02765             if( (LS==2 && PLS==2) ||                           // QaQ+QaQ always to DiQaDiQ
02766                 ( ( (LS==2 && PLS==3) || (LS==3 && PLS==2) ) &&// QaQ w QDiQ/aQaDiQ(single)
02767                   ( (aPDG> 7 && (-dPDG==aPDG/10   || -dPDG==aPDG%10) )   || // cAQ w DQ
02768                     (dPDG> 7 && (-aPDG==dPDG/10   || -aPDG==dPDG%10) )   || // AQ w cDQ
02769                     (rPDG<-7 && (qPDG==(-rPDG)/10 || qPDG==(-rPDG)%10) ) || // cQ w ADQ
02770                     (qPDG<-7 && (rPDG==(-qPDG)/10 || rPDG==(-qPDG)%10) )    // Q w cADQ
02771                     //|| (aPDG< 0 && -aPDG==qPDG) || (dPDG< 0 && -dPDG==rPDG) // aQ w Q 
02772                   )
02773                 )                 ||                           // -----------------------
02774                 ( ( LS==2 && PLS==4                          &&// QaQ w DiQaDiQ (double)
02775                     (aPDG> 7 && (-dPDG == aPDG/10 || -dPDG == aPDG%10) ) &&
02776                     (rPDG<-7 && (qPDG==(-rPDG)/10 || qPDG==(-rPDG)%10) )
02777                   )       ||
02778                   ( LS==4 && PLS==2                          &&// DiQaDiQ w QaQ (double)
02779                     (dPDG> 7 && (-aPDG == dPDG/10 || -aPDG == dPDG%10) ) &&
02780                     (qPDG<-7 && (rPDG==(-qPDG)/10 || rPDG==(-qPDG)%10) )
02781                   )
02782                 )                 ||                           // -----------------------
02783                 ( LS==3 && PLS==3                            &&// QDiQ w aDiQaQ (double)
02784                   ( (aPDG> 7 && (-dPDG == aPDG/10 || -dPDG == aPDG%10) &&
02785                      qPDG<-7 && (rPDG==(-qPDG)/10 || rPDG==(-qPDG)%10)
02786                     )       ||
02787                     (dPDG> 7 && (-aPDG == dPDG/10 || -aPDG == dPDG%10) &&
02788                      rPDG<-7 && (dPDG==(-rPDG)/10 || dPDG==(-rPDG)%10) 
02789                     )
02790                   )
02791                 )
02792               )
02793             {
02794               G4LorentzVector reString4M = reString->Get4Momentum();
02795               G4ThreeVector reV = reString4M.vect()/reString4M.e();
02796               G4double dV=(curV-reV).mag2();   // Squared difference between relVelocities
02797 #ifdef debug
02798               G4cout<<"G4QFragmentation::Breeder: StringCand#"<<restr<<", q="<<rPDG<<", a="
02799                     <<aPDG<<", L="<<uPDG<<", R="<<mPDG<<",dV="<<dV<<G4endl;
02800 #endif
02801               if(dV < Vmin)
02802               {
02803                 Vmin=dV;
02804                 fustr=restr;
02805                 MPS=PLS;
02806               }
02807             }
02808           }
02809           if(reduce==2)                        // String mutual reduction happened
02810           {
02811 #ifdef debug
02812             G4cout<<"-G4QFragmentation::Breeder:Reduced #"<<astring<<" & #"<<restr<<G4endl;
02813 #endif
02814             astring--;                         // String was QCreduced using another String
02815             continue;                          // Repeat fragmentation of the same string
02816           }
02817           if(fustr)                            // The partner was found -> fuse strings
02818           {
02819 #ifdef debug
02820             G4cout<<"G4QFragm::Breeder: StPartner#"<<fustr<<",LT="<<LT<<",RT="<<RT<<G4endl;
02821 #endif
02822             G4QString* fuString=strings[fustr];
02823             G4QParton* Left=fuString->GetLeftParton();
02824             G4QParton* Right=fuString->GetRightParton();
02825             G4int uPDG=Left->GetPDGCode();
02826             G4int mPDG=Right->GetPDGCode();
02827             G4int rPDG=uPDG;
02828             G4int aPDG=mPDG;
02829             if(aPDG<-99 || (aPDG>0 && aPDG<7) || rPDG>99 || (rPDG<0 && rPDG>-7))
02830             {
02831               swap=rPDG;
02832               rPDG=aPDG;
02833               aPDG=swap;
02834             }
02835             if(aPDG > 99) aPDG/=100;
02836             if(rPDG <-99) rPDG=-(-rPDG)/100;
02837             // Check that the strings can fuse (no anti-diquarks assumed)
02838             G4LorentzVector resL4M(0.,0.,0.,0.);
02839             G4LorentzVector resR4M(0.,0.,0.,0.);
02840             G4LorentzVector L4M=cLeft->Get4Momentum();
02841             G4LorentzVector R4M=cRight->Get4Momentum();
02842 #ifdef debug
02843             G4cout<<"G4QFragmentation::Breeder:BeforeFuDir,sL="<<sPDG<<",nR="<<nPDG<<",uL="
02844                   <<uPDG<<",mR="<<mPDG<<",L4M="<<L4M<<",R4M="<<R4M<<G4endl;
02845 #endif
02846             G4LorentzVector PL4M=Left->Get4Momentum();
02847             G4LorentzVector PR4M=Right->Get4Momentum();
02848             fusionDONE=AnnihilationOrder(LS, MPS, uPDG, mPDG, sPDG, nPDG);
02849             if     (fusionDONE>0)
02850             {
02851               if(fusionDONE>1)                             // Anihilation algorithm
02852               {
02853                 if     ( (uPDG<0 || nPDG<0) && -uPDG==nPDG ) Left->SetPDGCode(sPDG);
02854                 else if( (mPDG<0 || sPDG<0) && -mPDG==sPDG ) Right->SetPDGCode(nPDG);
02855                 else if( (uPDG<0 || sPDG<0) && -uPDG==sPDG ) Left->SetPDGCode(nPDG);
02856                 else if( (mPDG<0 || nPDG<0) && -mPDG==nPDG ) Right->SetPDGCode(sPDG);
02857               }
02858               {
02859                 Left->SetPDGCode(SumPartonPDG(uPDG, sPDG));
02860                 Right->SetPDGCode(SumPartonPDG(mPDG, nPDG));
02861               }
02862               Left->Set4Momentum(L4M+PL4M);
02863               Right->Set4Momentum(R4M+PR4M);
02864 #ifdef debug
02865               G4cout<<"G4QFragmentation::Breeder:LL/RR s4M="<<fuString->Get4Momentum()
02866                     <<",S="<<L4M+PL4M+R4M+PR4M<<", L="<<Left->Get4Momentum()<<", R="
02867                     <<Right->Get4Momentum()<<G4endl;
02868 #endif
02869             }
02870             else if(fusionDONE<0)
02871             {
02872               Left->SetPDGCode(SumPartonPDG(uPDG, nPDG));
02873               Left->Set4Momentum(L4M+PR4M);
02874               Right->SetPDGCode(SumPartonPDG(mPDG, sPDG));
02875               Right->Set4Momentum(R4M+PL4M);
02876 #ifdef debug
02877               G4cout<<"G4QFragmentation::Breeder:LR/RL s4M="<<fuString->Get4Momentum()
02878                     <<",S="<<L4M+PL4M+R4M+PR4M<<", L="<<Left->Get4Momentum()<<", R="
02879                     <<Right->Get4Momentum()<<G4endl;
02880 #endif
02881             }
02882 #ifdef debug
02883             else G4cout<<"-Warning-G4QFragmentation::Breeder: WrongStringFusion"<<G4endl;
02884 #endif
02885 #ifdef edebug
02886             G4cout<<"#EMC#G4QFragmentation::Breeder:StringFused,F="<<fusionDONE<<",L="<<L4M
02887                   <<",R="<<R4M<<",pL="<<PL4M<<",pR="<<PR4M<<",nL="<<Left->Get4Momentum()
02888                   <<",nR="<<Right->Get4Momentum()<<",S="<<fuString->Get4Momentum()<<G4endl;
02889 #endif
02890             if(fusionDONE)
02891             {
02892 #ifdef debug
02893               G4cout<<"###G4QFragmentation::Breeder: Str#"<<astring<<" fused/w Str#"<<fustr
02894                     <<"->"<<fuString->Get4Momentum()<<fuString->Get4Momentum().m()<<G4endl;
02895 #endif
02896               continue;                          // @@ killing of the curString is excluded
02897             }
02898           }
02899 #ifdef debug
02900           else
02901           {
02902 
02903             G4cout<<"**G4QFragmentation::Breeder:*NoPart*M="<<curString->Get4Momentum().m()
02904                   <<", F="<<fusionDONE<<", LPDG="<<curString->GetLeftParton()->GetPDGCode()
02905                   <<", RPDG="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
02906           }
02907 #endif
02908         }
02909         if(!fusionDONE)                          // Fusion of theString failed, try hadrons
02910         {
02911           G4int nHadr=theResult->size();         // #of collected resulting hadrons upToNow
02912 #ifdef debug
02913           G4cout<<"+++4QFragmentation::Breeder:*TryHadr* M="<<curString->Get4Momentum().m()
02914                 <<", nH="<<nHadr<<", LPDG="<<curString->GetLeftParton()->GetPDGCode()
02915                 <<", RPDG="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
02916 #endif
02917           // The only solution now is to try fusion with the secondary hadron
02918           while( (nHadr=theResult->size()) && !theHadrons)
02919           {
02920 #ifdef edebug
02921             for(G4int i=0; i<nHadr; i++)
02922             {
02923               G4LorentzVector h4M=(*theResult)[i]->Get4Momentum();
02924               G4int hPDG=(*theResult)[i]->GetPDGCode();
02925               G4QContent hQC=(*theResult)[i]->GetQC();
02926               G4cout<<"-EMC-G4QFrag::Breed:H#"<<i<<",4M="<<h4M<<hQC<<",PDG="<<hPDG<<G4endl;
02927             }
02928 #endif
02929             G4int fusDONE=0;                      // String+Hadron fusion didn't happen
02930             G4int fuhad=-1;                       // The found hadron index
02931             G4int newPDG=0;                       // PDG ofTheParton afterMerging with Hadr
02932             G4int secPDG=0;                       // Second PDG oParton afterMerging w/Hadr
02933             G4double maM2=-DBL_MAX;               // Prototype of the max ResultingStringM2
02934             G4LorentzVector selH4M(0.,0.,0.,0.);  // 4-mom of the selected hadron
02935             G4QHadron* selHP=0;                   // Pointer to the used hadron for erasing
02936             G4QString* cString=strings[astring];  // Must be the last string by definition
02937             G4LorentzVector cString4M = cString->Get4Momentum();
02938             cLeft=cString->GetLeftParton();
02939             cRight=cString->GetRightParton();
02940             G4int sumT=cLeft->GetType()+cRight->GetType();
02941             sPDG=cLeft->GetPDGCode();
02942             nPDG=cRight->GetPDGCode();
02943             G4int cMax=0;                         // Both or only one cuark can merge
02944             for (G4int reh=0; reh < nHadr; reh++)
02945             {
02946               G4QHadron* curHadr=(*theResult)[reh];
02947               G4int curPDG=curHadr->GetPDGCode(); // PDGCode of the hadron
02948               G4QContent curQC=curHadr->GetQC();  // Quark content of the hadron
02949               if(curPDG==331 && sPDG!=3 && nPDG!=3 && sPDG!=-3 && nPDG!=-3) // eta' red
02950               {
02951                 if(sPDG==2 || sPDG==-2 || nPDG==2 || nPDG==-2)
02952                                                              curQC=G4QContent(0,1,0,0,1,0);
02953                 else                                         curQC=G4QContent(1,0,0,1,0,0);
02954               }
02955               else if(curPDG==221 && sPDG!=2 && nPDG!=2 && sPDG!=-2 && nPDG!=-2) // eta
02956                                                              curQC=G4QContent(1,0,0,1,0,0);
02957               else if(curPDG==111 && sPDG!=1 && nPDG!=1 && sPDG!=-1 && nPDG!=-1) // eta
02958                                                              curQC=G4QContent(0,1,0,0,1,0);
02959               G4int partPDG1=curQC.AddParton(sPDG);
02960               G4int partPDG2=curQC.AddParton(nPDG);
02961 #ifdef debug
02962               G4cout<<"G4QFragmentation::Breeder: Hadron # "<<reh<<", QC="<<curQC
02963                       <<", P1="<<partPDG1<<", P2="<<partPDG2<<G4endl;
02964 #endif
02965               if(partPDG1 || partPDG2)            // Hadron can merge at least w/one parton
02966               {
02967                 G4int cCur=1;
02968                 if(sumT>3 && partPDG1 && partPDG2) cCur=2;
02969                 G4LorentzVector curHadr4M = curHadr->Get4Momentum();
02970                 G4double M2=(cString4M+curHadr4M).m2();// SquaredMass of theResultingString
02971 #ifdef debug
02972                 G4cout<<"G4QFragmentation::Breeder:*IN*Hadron#"<<reh<<",M2="<<M2<<G4endl;
02973 #endif
02974                 if( (sumT<4 || cCur>=cMax) && M2 > maM2) // DeepAnnihilation for DiQ-aDiQ 
02975                 {
02976                   maM2=M2;
02977                   fuhad=reh;
02978                   if(partPDG1)
02979                   {
02980                     fusDONE= 1;
02981                     newPDG=partPDG1;
02982                     if(partPDG2)
02983                     {
02984                       secPDG=partPDG2;
02985                       cMax=cCur;
02986                     }
02987                   }
02988                   else
02989                   {
02990                     fusDONE=-1;
02991                     newPDG=partPDG2;
02992                   }
02993 #ifdef debug
02994                   G4cout<<"G4QFrag::Br:*Selected*,P1="<<partPDG1<<",P2="<<partPDG2<<G4endl;
02995 #endif
02996                   selH4M=curHadr4M;
02997                   selHP=curHadr;
02998                 } // End of IF(update selection)
02999               } // End of IF(HadronCanMergeWithTheString)
03000             } // End of the LOOP over Hadrons
03001 #ifdef debug
03002             G4cout<<"G4QFragmentation::Breeder: fuh="<<fuhad<<",fus="<<fusDONE<<G4endl;
03003 #endif
03004             if(fuhad>-1)                          // The partner was found -> fuse H&S
03005             {
03006               if     (fusDONE>0)                  // Fuse hadron with the left parton
03007               {
03008                 cLeft->SetPDGCode(newPDG);
03009                 G4LorentzVector newLeft=cLeft->Get4Momentum()+selH4M;
03010                 cLeft->Set4Momentum(newLeft);
03011                 if(secPDG && cMax>1)
03012                 {
03013 #ifdef debug
03014                   G4cout<<"G4QFragm::Br:TryReduce,nPDG="<<newPDG<<",sPDG="<<secPDG<<G4endl;
03015 #endif
03016                   cLeft->ReduceDiQADiQ(cLeft, cRight);
03017                 }
03018 #ifdef debug
03019                 G4cout<<"G4QFragmentation::Breeder: Left, s4M="<<curString->Get4Momentum()
03020                       <<", L4M="<<newLeft<<", R4M="<<cRight->Get4Momentum()<<", h4M="
03021                       <<selH4M<<", newL="<<newPDG<<", oldR="<<cRight->GetPDGCode()<<G4endl;
03022 #endif
03023               }
03024               else if(fusDONE<0)                  // Fuse hadron with the right parton
03025               {
03026                 cRight->SetPDGCode(newPDG);
03027                 G4LorentzVector newRight=cRight->Get4Momentum()+selH4M;
03028                 cRight->Set4Momentum(newRight);
03029 #ifdef debug
03030                 G4cout<<"G4QFragmentation::Breeder: Right, s4M="<<curString->Get4Momentum()
03031                       <<", L4M="<<cLeft->Get4Momentum()<<", R4M="<<newRight<<", h4M="
03032                       <<selH4M<<", newR="<<newPDG<<", oldL="<<cLeft->GetPDGCode()<<G4endl;
03033 #endif
03034               }
03035 #ifdef debug
03036               else G4cout<<"-G4QFragmentation::Breeder: Wrong String+HadronFusion"<<G4endl;
03037 #endif
03038 #ifdef debug
03039               if(fusDONE) G4cout<<"####G4QFragmentation::Breeder: String #"<<astring
03040                                 <<" is fused with Hadron #"<<fuhad
03041                                 <<", new4Mom="<<curString->Get4Momentum()
03042                                 <<", M2="<<curString->Get4Momentum().m2()
03043                                 <<", QC="<<curString->GetQC()<<G4endl;
03044 #endif
03045             }
03046             else
03047             {
03048 #ifdef debug
03049               G4cout<<"**G4QFragmentation::Breeder:*NoH*,M="<<curString->Get4Momentum().m()
03050                     <<", LPDG="<<curString->GetLeftParton()->GetPDGCode()
03051                     <<", RPDG="<<curString->GetRightParton()->GetPDGCode()<<G4endl;
03052               // @@ Temporary exception for the future solution
03053               //G4Exception("G4QFragmentation::Breeder:","72",FatalException,"SHNotFused");
03054 #endif
03055               break;                           // Breake the While LOOP
03056             } // End of the namespace where both Fusion and reduction have failed
03057             // The fused hadron must be excluded from theResult
03058 #ifdef debug
03059             G4cout<<"G4QFragmentation::Breeder: before HR, nH="<<theResult->size()<<G4endl;
03060             G4int icon=0;                              // Loop counter
03061 #endif
03062             G4QHadronVector::iterator ih;
03063 #ifdef debug
03064             G4bool found=false;
03065 #endif
03066             for(ih = theResult->begin(); ih != theResult->end(); ih++)
03067             {
03068 #ifdef debug
03069               G4cout<<"G4QFrag::Breeder:#"<<icon<<", i="<<(*ih)<<", sH="<<selHP<<G4endl;
03070               icon++;
03071 #endif
03072               if((*ih)==selHP)
03073               {
03074 #ifdef debug
03075                 G4cout<<"G4QFragm::Breed: *HadronFound*,PDG="<<selHP->GetPDGCode()<<G4endl;
03076 #endif
03077                 G4LorentzVector p4M=selHP->Get4Momentum();
03078                 //
03079                 curString4M+=p4M;
03080                 G4int Chg=selHP->GetCharge();
03081                 G4int BaN=selHP->GetBaryonNumber();
03082                 curStrChg+=Chg;
03083                 curStrBaN+=BaN;
03084 #ifdef edebug
03085                 G4cout<<"-EMC->>G4QFragmentation::Breeder: S+=H, 4M="<<curString4M<<", M="
03086                       <<curString4M.m()<<", Charge="<<curStrChg<<", B="<<curStrBaN<<G4endl;
03087 #endif
03088                 delete selHP;                          // delete the Hadron
03089                 theResult->erase(ih);                  // erase the Hadron from theResult
03090 #ifdef debug
03091                 found=true;
03092 #endif
03093                 break;                                 // beak the LOOP over hadrons
03094               }
03095             } // End of the LOOP over hadrons
03096 #ifdef debug
03097             if(!found) G4cout<<"*G4QFragmentation::Breeder:nH="<<theResult->size()<<G4endl;
03098 #endif
03099             // New attempt of the string decay
03100             theHadrons=curString->FragmentString(true);
03101 #ifdef debug
03102             G4cout<<"G4QFrag::Breeder: tH="<<theHadrons<<",nH="<<theResult->size()<<G4endl;
03103 #endif
03104           } // End of the while LOOP over the fusion with hadrons
03105 #ifdef debug
03106           G4cout<<"*G4QFragmentation::Breeder: *CanTryToDecay?* nH="<<theHadrons<<", next="
03107                 <<next<<" =? nS="<<strings.size()<<", nR="<<theResult->size()<<G4endl;
03108 #endif
03109           if(!theHadrons && next == strings.size() && !(theResult->size()))// TryToDecay
03110           {
03111             G4QContent miQC=curString->GetQC();    // QContent of the Lightest Hadron
03112             G4int miPDG=miQC.GetSPDGCode();         // PDG of the Lightest Hadron
03113             if(miPDG == 10)                        // ==> Decay Hadron-Chipolino
03114             {
03115               G4QChipolino QCh(miQC);              // define theTotalResidual as aChipolino
03116               G4QPDGCode   h1QPDG=QCh.GetQPDG1();  // QPDG of the first hadron
03117               G4double     h1M   =h1QPDG.GetMass();// Mass of the first hadron
03118               G4QPDGCode   h2QPDG=QCh.GetQPDG2();  // QPDG of the second hadron 
03119               G4double     h2M   =h2QPDG.GetMass();// Mass of the second hadron
03120               G4double     ttM   =curString4M.m(); // Real Mass of the Chipolino
03121               if(h1M+h2M<ttM+eps)                  // Two particles decay of Chipolino
03122               {
03123                 G4LorentzVector h14M(0.,0.,0.,h1M);
03124                 G4LorentzVector h24M(0.,0.,0.,h2M);
03125                 if(std::fabs(ttM-h1M-h2M)<=eps)
03126                 {
03127                   G4double part1=h1M/(h1M+h2M);
03128                   h14M=part1*curString4M;
03129                   h24M=curString4M-h14M;
03130                 }
03131                 else
03132                 {
03133                   if(!G4QHadron(curString4M).DecayIn2(h14M,h24M))
03134                   {
03135                     G4cerr<<"***G4QFragmentation::Breeder: tM="<<ttM<<"->h1="<<h1QPDG<<"("
03136                           <<h1M<<")+h2="<<h1QPDG<<"("<<h2M<<")="<<h1M+h2M<<G4endl;
03137                     G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChiDec");
03138                   }
03139                 }
03140                 G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
03141                 theResult->push_back(h1H);         // (delete equivalent)  
03142 #ifdef debug
03143                 G4LorentzVector f4M=h1H->Get4Momentum();
03144                 G4int           fPD=h1H->GetPDGCode();
03145                 G4int           fCg=h1H->GetCharge();
03146                 G4int           fBN=h1H->GetBaryonNumber();
03147                 G4cout<<"-EMC->>G4QFragment::Breeder: String=Hadr ChiPro1 is filled, f4M="
03148                       <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
03149 #endif
03150                 G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
03151                 theResult->push_back(h2H);         // (delete equivalent)  
03152 #ifdef debug
03153                 G4LorentzVector s4M=h2H->Get4Momentum();
03154                 G4int           sPD=h2H->GetPDGCode();
03155                 G4int           sCg=h2H->GetCharge();
03156                 G4int           sBN=h2H->GetBaryonNumber();
03157                 G4cout<<"-EMC->>G4QFragmentation::Breeder: String=Hadr ChiPro2 is filled, s4M="
03158                       <<s4M<<", sPDG="<<sPD<<", sCg="<<sCg<<", sBN="<<sBN<<G4endl;
03159 #endif
03160 #ifdef edebug
03161                 G4cout<<"-EMC-..Chi..G4QFragmentation::Breeder: DecayCHECK, Ch4M="
03162                       <<curString4M<<", d4M="<<curString4M-h14M-h24M<<G4endl;
03163 #endif
03164                 break;                               // Go out of the main StringDecay LOOP
03165               }
03166               else
03167               {
03168                 G4Quasmon* stringQuasmon = new G4Quasmon(miQC, curString4M);// String->Quas
03169                 theQuasmons.push_back(stringQuasmon);
03170                 break;                               // Go out of the main StringDecay LOOP
03171               }
03172             }
03173             else if(miPDG)                                 // Decay Hadron as a Resonans
03174             {
03175               if     (miPDG>0 &&   miPDG%10 < 3) miPDG+=2; // Convert to Resonans
03176               else if(miPDG<0 && (-miPDG)%10< 3) miPDG-=2; // Convert to antiResonans
03177               G4Quasmon Quasm;
03178               G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
03179               G4QHadronVector* tmpQHadVec=Quasm.DecayQHadron(sHad); // It deletes sHad
03180               G4int tmpN=tmpQHadVec->size();
03181 #ifdef debug
03182               G4cout<<"G4QFragmentation::Breeder: Decay the Last, Res#H="<<tmpN<<G4endl;
03183 #endif
03184               if(tmpN>1)
03185               {
03186                 for(G4int aH=0; aH < tmpN; aH++)
03187                 {
03188                   theResult->push_back((*tmpQHadVec)[aH]);//TheDecayProdOfHadronDecIsFilled
03189 #ifdef debug
03190                   G4QHadron*   prodH =(*tmpQHadVec)[aH];
03191                   G4LorentzVector p4M=prodH->Get4Momentum();
03192                   G4int           PDG=prodH->GetPDGCode();
03193                   G4int           Chg=prodH->GetCharge();
03194                   G4int           BaN=prodH->GetBaryonNumber();
03195                   G4cout<<"-EMC->>G4QFragment::Breeder:String=Hadr,H#"<<aH<<" filled, 4M="
03196                         <<p4M<<", PDG="<<PDG<<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
03197 #endif
03198                 }
03199               }
03200               else
03201               {
03202                 G4Quasmon* stringQuasmon = new G4Quasmon(miQC, curString4M);// String->Quas
03203 #ifdef debug
03204                 G4cout<<"G4QFragmentat::Breeder:==> to Quasm="<<miQC<<curString4M<<", Nuc="
03205                       <<theNucleus<<theNucleus.Get4Momentum()<<", NString="<<strings.size()
03206                       <<", nR="<<theResult->size()<<", nQ="<<theQuasmons.size()<<G4endl;
03207 #endif
03208                 theQuasmons.push_back(stringQuasmon);
03209                 delete sHad;
03210                 tmpQHadVec->clear();
03211                 delete tmpQHadVec;  // WhoCallsDecayQHadron is responsible for clear&delete
03212                 break;                               // Go out of the main StringDecay LOOP
03213               }
03214               tmpQHadVec->clear();
03215               delete tmpQHadVec;  // Who calls DecayQHadron is responsible for clear&delete
03216               break;                               // Go out of the main String Decay LOOP
03217             }
03218           } // End of the DecayOfTheLast
03219         } // End of IF(String-Hadron fusion)
03220       } // End of IF(NO_Hadrons) for String-String and String-Hadron fusion
03221       // The last hope is to CORREC the string, using other strings (ForwardInLOOP)
03222 #ifdef debug
03223       G4cout<<"G4QFragmentation::Breeder: theH="<<theHadrons<<"?=0, next="<<next<<G4endl;
03224 #endif
03225       if(!theHadrons && next < strings.size())       // ForwardInLOOP strings exist
03226       {
03227         // @@ string can be not convertable to one hadron (2,0.0,0,2,0) - To be improved
03228         G4QContent miQC=curString->GetQC(); // QContent of the Lightest Hadron
03229         G4int miPDG=miQC.GetSPDGCode();// PDG of the Lightest Hadron
03230 #ifdef debug
03231         G4cout<<"---->>G4QFragmentation::Breeder: SQC="<<miQC<<", miSPDG="<<miPDG<<G4endl;
03232 #endif
03233         G4double miM=0.;               // Prototype of the Mass of the Cur LightestHadron
03234         if(miPDG!=10) miM=G4QPDGCode(miPDG).GetMass(); // Mass of theCurLightestOneHadron
03235         else
03236         {
03237           G4QChipolino QCh(miQC);      // define the TotalString as a Chipolino
03238           miM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass();//MinMass of theStringChipo
03239         }
03240         G4double cM2=curString4M.m2(); // Actual squared mass of the Cur String
03241 #ifdef debug
03242         G4cout<<"---->>G4QFragmentation::Breeder: minMass="<<miM<<", realM2="<<cM2<<G4endl;
03243 #endif
03244         G4double   cM=0.;
03245         if(cM2>0.)
03246         {
03247           cM=std::sqrt(cM2);
03248           if(std::fabs(cM-miM) < eps)    // Convert to hadron(2 hadrons) w/o calculations
03249           {
03250             if(miPDG!=10)
03251             {
03252               G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
03253               theResult->push_back(sHad);// Fill the curString as a hadron
03254 #ifdef debug
03255               G4cout<<"----->>G4QFragmentation::Breeder:S->H="<<miPDG<<curString4M<<G4endl;
03256 #endif
03257             }
03258             else
03259             {
03260               G4QChipolino QCh(miQC);               // define TotalResidual as a Chipolino
03261               G4QPDGCode   h1QPDG=QCh.GetQPDG1();   // QPDG of the first hadron
03262               G4double     h1M   =h1QPDG.GetMass(); // Mass of the first hadron
03263               G4QPDGCode   h2QPDG=QCh.GetQPDG2();   // QPDG of the second hadron 
03264               G4double     h2M   =h2QPDG.GetMass(); // Mass of the second hadron
03265               G4double     pt1   =h1M/(h1M+h2M);    // 4-mom part of the first hadron
03266               G4LorentzVector h14M=pt1*curString4M; // 4-mom of the first hadron
03267               G4LorentzVector h24M=curString4M-h14M;// 4-mom of the second hadron
03268               G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
03269               theResult->push_back(h1H);            // (delete equivalent)  
03270 #ifdef debug
03271               G4LorentzVector f4M=h1H->Get4Momentum();
03272               G4int           fPD=h1H->GetPDGCode();
03273               G4int           fCg=h1H->GetCharge();
03274               G4int           fBN=h1H->GetBaryonNumber();
03275               G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=2HadrAR Prod-F is filled, f4M="
03276                     <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
03277 #endif
03278               G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
03279               theResult->push_back(h2H);         // (delete equivalent)  
03280 #ifdef debug
03281               G4LorentzVector s4M=h2H->Get4Momentum();
03282               G4int           sPD=h2H->GetPDGCode();
03283               G4int           sCg=h2H->GetCharge();
03284               G4int           sBN=h2H->GetBaryonNumber();
03285               G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=2HadrAR Prod-S is filled, s4M="
03286                     <<s4M<<", sPDG="<<sPD<<", sCg="<<sCg<<", sBN="<<sBN<<G4endl;
03287 #endif
03288             }
03289             continue;                    // Continue the LOOP over the curStrings
03290           }
03291           else                           // Try to recover (+/-) to min Mass
03292           {
03293             G4ThreeVector cP=curString4M.vect(); // Momentum of the curString
03294             G4double      cE=curString4M.e();    // Energy of the curString
03295             G4ThreeVector curV=cP/cE;    // curRelativeVelocity
03296             G4double miM2=miM*miM;
03297             G4int restr=0;               // To use beyon the LOOP for printing
03298             G4int fustr=0;               // Selected String-partner (0 = NotFound)
03299             G4double selX=0.;            // Selected value of x
03300             G4double maD=-DBL_MAX;       // Maximum Free Mass
03301             G4double Vmin=DBL_MAX;       // min Velocity Distance
03302             G4LorentzVector s4M(0.,0.,0.,0.); // Selected 4-mom of the hadron
03303 #ifdef debug
03304             G4cout<<"G4QFr::Breed:TryRecover,V="<<curV<<",cM2="<<cM2<<",miM="<<miM<<G4endl;
03305 #endif
03306             nOfStr=strings.size();
03307             for(restr=next; restr < nOfStr; ++restr) if(restr != astring)
03308             {
03309 #ifdef debug
03310               G4cout<<"G4QFragmentation::Breeder: rS="<<restr<<", nS="<<nOfStr<<G4endl;
03311 #endif
03312               G4QString* pString=strings[restr];
03313 #ifdef debug
03314               G4cout<<"G4QFragmentation::Breeder: pString="<<pString<<G4endl;
03315 #endif
03316               G4LorentzVector p4M=pString->Get4Momentum();
03317 #ifdef debug
03318               G4cout<<"G4QFragmentation::Breeder: p4M="<<p4M<<G4endl;
03319 #endif
03320               G4ThreeVector pP=p4M.vect();  // Momentum of the partnerString
03321               G4double      pE=p4M.e();     // Energy of the partnerString
03322               G4double D2=cE*pE-cP.dot(pP); 
03323               G4double pM2=p4M.m2();
03324 #ifdef debug
03325               G4cout<<"G4QFrag::Breeder: pM2="<<pM2<<",miM2="<<miM2<<",cM2="<<cM2<<G4endl;
03326 #endif
03327               G4double dM4=pM2*(miM2-cM2);
03328               G4double D=D2*D2+dM4;
03329 #ifdef debug
03330               G4cout<<"G4QFragmentation::Breeder: D="<<D<<",dM4="<<dM4<<",D2="<<D2<<G4endl;
03331 #endif
03332               G4double x=-1.;               // Bad preexpectation 
03333               if(D > 0. && pM2>.01) x=(std::sqrt(D)-D2)/pM2; // what we should get from p
03334 #ifdef debug
03335               else G4cout<<"G4QFragment::Breeder: D="<<D<<",D2="<<D2<<",pM4="<<dM4<<G4endl;
03336               G4cout<<"G4QFragmentation::Breeder: pM2="<<pM2<<",D2="<<D2<<",x="<<x<<G4endl;
03337 #endif
03338               if(x > 0. && x < 1.)          // We are getting x part of p4M
03339               {
03340                 G4QContent pQC=pString->GetQC(); // Quark Content of The Partner
03341                 G4int pPDG=pQC.GetSPDGCode();// PDG of The Lightest Hadron for the Partner
03342                 G4double pM=0.;             // Mass of the LightestHadron
03343                 if(pPDG==10)
03344                 {
03345                   G4QChipolino QCh(pQC);    // define the TotalString as a Chipolino
03346                   pM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass();// Mass of Chipolino
03347                 }
03348                 else pM=G4QPDGCode(pPDG).GetMass();// Mass of theLightestHadron for Partner
03349                 G4double rM=std::sqrt(pM2); // Real mass of the string-partner
03350                 G4double delta=(1.-x)*rM-pM;// @@ Minimum CM disterbance measure
03351                 if(delta > 0. && delta > maD)
03352                 {
03353                   maD=delta;
03354 #ifdef debug
03355                   G4cout<<"G4QFragmentation::Breeder: Subtr,S#"<<restr<<",d="<<maD<<G4endl;
03356 #endif
03357                   fustr=restr;
03358                   selX=x;
03359                   s4M=p4M;
03360                 }
03361               }
03362               else if(x <= 0.)               // We are adding to p4M, so use RelVelocity
03363               {
03364                 G4ThreeVector pV=pP/pE;      // curRelativeVelocity
03365                 G4double dV=(curV-pV).mag2();// SquaredDifferenceBetweenRelVelocities
03366                 if(dV < Vmin)
03367                 {
03368 #ifdef debug
03369                   G4cout<<"G4QFragmentation::Breeder: FreeAdd,S#"<<restr<<",x="<<x<<G4endl;
03370 #endif
03371                   Vmin=dV;
03372                   fustr=restr;
03373                   selX=x;
03374                   s4M=p4M;
03375                 }
03376               }
03377 #ifdef debug
03378               G4cout<<"G4QFragmentation::Breeder:EndOfLOOP r="<<restr<<"<"<<nOfStr<<G4endl;
03379 #endif
03380             } // End of the LOOP over string-partners for Correction
03381 #ifdef debug
03382             G4cout<<"G4QFragmentation::Breeder: AfterLOOP fustr="<<fustr<<G4endl;
03383 #endif
03384             if(fustr)
03385             {
03386 #ifdef edebug
03387               G4LorentzVector sum4M=s4M+curString4M;
03388               G4cout<<"G4QFragmentation::Breeder: Found Sum4M="<<sum4M<<G4endl;
03389 #endif
03390               G4QString* pString=strings[fustr];
03391               curString4M+=selX*s4M;
03392               if(std::abs(miPDG)%10 > 2)                  // Decay String-Hadron-Resonance
03393               {
03394                 G4Quasmon Quasm;
03395                 G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
03396                 G4QHadronVector* tmpQHadVec=Quasm.DecayQHadron(sHad); // It deletes sHad
03397 #ifdef debug
03398                 G4cout<<"G4QFragmentation::Breeder:DecStH,nH="<<tmpQHadVec->size()<<G4endl;
03399 #endif
03400                 for(unsigned aH=0; aH < tmpQHadVec->size(); aH++)
03401                 {
03402                   theResult->push_back((*tmpQHadVec)[aH]);//TheDecayProdOfHadron is filled
03403 #ifdef debug
03404                   G4QHadron*   prodH =(*tmpQHadVec)[aH];
03405                   G4LorentzVector p4M=prodH->Get4Momentum();
03406                   G4int           PDG=prodH->GetPDGCode();
03407                   G4int           Chg=prodH->GetCharge();
03408                   G4int           BaN=prodH->GetBaryonNumber();
03409                   G4cout<<"-EMC->>G4QFragmentation::Breeder:St=Had,pH#"<<aH<<" filled, 4M="
03410                         <<p4M<<", PDG="<<PDG<<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
03411 #endif
03412                 }
03413                 tmpQHadVec->clear();
03414                 delete tmpQHadVec;  // Who calls DecayQHadron is responsibleRorClear&Delete
03415               }
03416               else if(miPDG == 10)                   // ==> Decay Hadron-Chipolino
03417               {
03418                 G4QChipolino QCh(miQC);              // define theTotalResid as aChipolino
03419                 G4QPDGCode   h1QPDG=QCh.GetQPDG1();  // QPDG of the first hadron
03420                 G4double     h1M   =h1QPDG.GetMass();// Mass of the first hadron
03421                 G4QPDGCode   h2QPDG=QCh.GetQPDG2();  // QPDG of the second hadron 
03422                 G4double     h2M   =h2QPDG.GetMass();// Mass of the second hadron
03423                 G4double     ttM   =curString4M.m(); // Real Mass of the Chipolino
03424                 if(h1M+h2M<ttM+eps)                  // Two particles decay of Chipolino
03425                 {
03426                   G4LorentzVector h14M(0.,0.,0.,h1M);
03427                   G4LorentzVector h24M(0.,0.,0.,h2M);
03428                   if(std::fabs(ttM-h1M-h2M)<=eps)
03429                   {
03430                     G4double part1=h1M/(h1M+h2M);
03431                     h14M=part1*curString4M;
03432                     h24M=curString4M-h14M;
03433                   }
03434                   else
03435                   {
03436                     if(!G4QHadron(curString4M).DecayIn2(h14M,h24M))
03437                     {
03438                       G4cerr<<"***G4QFragmentation::Breeder: tM="<<ttM<<"->h1="<<h1QPDG
03439                             <<"("<<h1M<<")+h2="<<h1QPDG<<"("<<h2M<<")="<<h1M+h2M<<G4endl;
03440                       G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChDe");
03441                     }
03442                   }
03443                   G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
03444                   theResult->push_back(h1H);        // (delete equivalent)  
03445 #ifdef debug
03446                   G4LorentzVector f4M=h1H->Get4Momentum();
03447                   G4int           fPD=h1H->GetPDGCode();
03448                   G4int           fCg=h1H->GetCharge();
03449                   G4int           fBN=h1H->GetBaryonNumber();
03450                   G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=Hadr Prod-F's filled, f4M="
03451                         <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
03452 #endif
03453                   G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
03454                   theResult->push_back(h2H);        // (delete equivalent)  
03455 #ifdef debug
03456                   G4LorentzVector s4M=h2H->Get4Momentum();
03457                   G4int           sPD=h2H->GetPDGCode();
03458                   G4int           sCg=h2H->GetCharge();
03459                   G4int           sBN=h2H->GetBaryonNumber();
03460                   G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=Hadr Prod-S's filled, s4M="
03461                         <<s4M<<", sPDG="<<sPD<<", sCg="<<sCg<<", sBN="<<sBN<<G4endl;
03462 #endif
03463 #ifdef edebug
03464                   G4cout<<"-EMC-Chipo.G4QFragmentation::Breeder:DecCHECK,c4M="<<curString4M
03465                         <<", ChQC="<<miQC<<", d4M="<<curString4M-h14M-h24M<<G4endl;
03466 #endif
03467                 }
03468                 else
03469                 {
03470                   G4cerr<<"***G4QFragm::Breeder:tM="<<ttM<<miQC<<"->h1="<<h1QPDG<<"(" <<h1M
03471                         <<")+h2="<<h1QPDG<<"("<<h2M<<") = "<<h1M+h2M<<G4endl;
03472                   G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChiDecMa");
03473                 }
03474               }
03475               else
03476               {
03477                 G4QHadron* sHad = new G4QHadron(miPDG,curString4M);
03478                 theResult->push_back(sHad);         // The original string-hadron is filled
03479 #ifdef debug
03480                 G4cout<<"-EMC->>G4QFragmentation::Breeder:Str=Hadr Filled, 4M="
03481                       <<curString4M<<", PDG="<<miPDG<<G4endl;
03482 #endif
03483               }
03484               G4double corF=1-selX;
03485               G4QParton* Left=pString->GetLeftParton();
03486               G4QParton* Right=pString->GetRightParton();
03487               Left->Set4Momentum(corF*Left->Get4Momentum());
03488               Right->Set4Momentum(corF*Right->Get4Momentum());
03489 #ifdef edebug
03490               G4cout<<"-EMC-...Cor...G4QFragmentation::Breeder:CorCHECK Sum="<<sum4M
03491                     <<" =? "<<curString4M+pString->Get4Momentum()<<", M="<<miM<<" ?= "
03492                     <<curString4M.m()<<G4endl;
03493 #endif
03494 #ifdef debug
03495               G4cout<<"---->>G4QFragmentation::Breeder:*Corrected* String->Hadr="<<miPDG
03496                     <<curString4M<<" by String #"<<fustr<<G4endl;
03497 #endif
03498               continue;                            // Continue the LOOP over the curStrings
03499             } // End of Found combination for the String on string correction
03500           } // End of the Try-to-recover String+String correction algorithm
03501         } // End of IF(CM2>0.)
03502       } // End of IF(Can try to correct by String-String)
03503 #ifdef debug
03504       else G4cout<<"***G4QFragmentation::Breeder: **No SSCorrection**,next="<<next<<G4endl;
03505 #endif
03506       // ------------ At this point we can reduce the 3/-3 meson to 1/-1 meson ------------
03507       G4QParton* lpcS=curString->GetLeftParton();
03508       G4QParton* rpcS=curString->GetRightParton();
03509       G4int lPDGcS=lpcS->GetPDGCode();
03510       G4int rPDGcS=rpcS->GetPDGCode();
03511       if     (lPDGcS==3 && rPDGcS==-3)
03512       {
03513         lpcS->SetPDGCode( 1);
03514         rpcS->SetPDGCode(-1);
03515       }
03516       else if(lPDGcS==-3 && rPDGcS==3)
03517       {
03518         lpcS->SetPDGCode(-1);
03519         rpcS->SetPDGCode( 1);
03520       }
03521       // -------- Now the only hope is Correction, using the already prodused Hadrons -----
03522       G4int nofRH=theResult->size();            // #of resulting Hadrons
03523 #ifdef debug
03524       G4cout<<"G4QFragmentation::Breeder: theH="<<theHadrons<<", #OfH="<<nofRH<<G4endl;
03525 #endif
03526       if(!theHadrons && nofRH)                  // Hadrons are existing for SH Correction
03527       {
03528 #ifdef debug
03529         G4cout<<"!G4QFragmentation::Breeder:Can try SHCor, nH="<<theResult->size()<<G4endl;
03530 #endif
03531         // @@ string can be not convertable to one hadron (2,0.0,0,2,0) - To be improved
03532         G4QContent miQC=curString->GetQC();     // QContent of the Lightest Hadron
03533         G4int miPDG=miQC.GetSPDGCode();         // PDG of the Lightest Hadron
03534         G4double miM=0.;                        // Prototype ofMass of theCurLightestHadron
03535         if(miPDG==10)                           // Mass of the Cur Lightest ChipolinoHadron
03536         {
03537           G4QChipolino QCh(miQC);               // define the TotalString as a Chipolino
03538           miM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass();//MinMass of theStringChipo
03539         }
03540         else miM=G4QPDGCode(miPDG).GetMass();   // Mass of the Cur Lightest Hadron
03541         G4double spM=0.;                        // Mass of the selected Hadron-Partner
03542         G4ThreeVector cP=curString4M.vect();    // Momentum of the curString
03543         G4double      cE=curString4M.e();       // Energy of the curString
03544         G4ThreeVector curV=cP/cE;               // curRelativeVelocity
03545         G4int reha=0;                           // Hadron # to use beyon the LOOP
03546         G4int fuha=-1;                          // Selected Hadron-partner (0 = NotFound)
03547         G4double dMmin=DBL_MAX;                 // min Excess of the mass
03548         G4LorentzVector s4M(0.,0.,0.,0.);       // Selected 4-mom of the Hadron+String
03549         G4double sM=0.;                         // Selected Mass of the Hadron+String
03550         for (reha=0; reha < nofRH; reha++)      // LOOP over already collected hadrons
03551         {
03552           G4QHadron* pHadron=(*theResult)[reha];// Pointer to the current Partner-Hadron
03553           G4LorentzVector p4M=pHadron->Get4Momentum();
03554           G4double         pM=p4M.m();          // Mass of the Partner-Hadron
03555           G4LorentzVector t4M=p4M+curString4M;  // Total momentum of the compound
03556           G4double        tM2=t4M.m2();         // Squared total mass of the compound
03557           if(tM2 >= sqr(pM+miM+eps))            // Condition of possible correction
03558           {
03559             G4double tM=std::sqrt(tM2);         // Mass of the Hadron+String compound
03560             G4double dM=tM-pM-miM;              // Excess of the compound mass
03561             if(dM < dMmin)
03562             {
03563               dMmin=dM;
03564               fuha=reha;
03565               spM=pM;
03566               s4M=t4M;
03567               sM=tM;
03568             }
03569           }
03570 #ifdef debug
03571           else G4cout<<"G4QFragmentation::Breeder:H# "<<reha<<",tM="<<std::sqrt(tM2)<<" < "
03572                      <<" mS="<<miM<<" + mH="<<pM<<" = "<<pM+miM<<G4endl;
03573 #endif
03574         } // End of the LOOP over string-partners for Correction
03575 #ifdef debug
03576         G4cout<<"G4QFragment::Breeder: fuha="<<fuha<<", dMmin="<<dMmin<<G4endl;
03577 #endif
03578         if(fuha>-1)                             // The hadron-partner was found
03579         { 
03580           G4QHadron* pHadron=(*theResult)[fuha];// Necessary for update
03581           G4LorentzVector mi4M(0.,0.,0.,miM);   // Prototype of the new String=Hadron
03582           if(miM+spM<sM+eps)                    // Decay into CorrectedString+theSameHadron
03583           {
03584             G4LorentzVector sp4M(0.,0.,0.,spM);
03585             if(std::fabs(sM-miM-spM)<=eps)
03586             {
03587               G4double part1=miM/(miM+spM);
03588               mi4M=part1*s4M;
03589               sp4M=s4M-mi4M;
03590             }
03591             else
03592             {
03593               if(!G4QHadron(s4M).DecayIn2(mi4M,sp4M))
03594               {
03595                 G4cerr<<"***G4QFragmentation::Breeder: *SH*, tM="<<sM<<"->h1=("<<miPDG<<")"
03596                       <<miM<<" + h2="<<spM<<" = "<<miM+spM<<G4endl;
03597                 G4Exception("G4QFragmentation::Breeder:","72",FatalException,"SHChipoDec");
03598               }
03599             }
03600             pHadron->Set4Momentum(sp4M);
03601 #ifdef debug
03602             G4cout<<"-EMC->...>G4QFragmentation::Breeder: H# "<<fuha<<" is updated, new4M="
03603                   <<sp4M<<G4endl;
03604 #endif
03605           }
03606           else
03607           {
03608             G4cerr<<"***G4QFragm::Breeder: HS Failed, tM="<<sM<<"->h1M=("<<miPDG<<")"<<miM
03609                   <<"+h2M="<<spM<<" = "<<miM+spM<<G4endl;
03610             G4Exception("G4QFragmentation::Breeder:","72",FatalException,"HSChipoDecMass");
03611           }
03612           if(std::abs(miPDG)%10 > 2)                  // Decay Hadron-Resonans
03613           {
03614             G4Quasmon Quasm;
03615             G4QHadron* sHad = new G4QHadron(miPDG,mi4M);
03616             G4QHadronVector* tmpQHadVec=Quasm.DecayQHadron(sHad); // It deletes sHad
03617 #ifdef debug
03618             G4cout<<"G4QFragment::Breeder:*HS* DecStrHad, nH="<<tmpQHadVec->size()<<G4endl;
03619 #endif
03620             for(unsigned aH=0; aH < tmpQHadVec->size(); aH++)
03621             {
03622               theResult->push_back((*tmpQHadVec)[aH]);// TheDecayProductOfTheHadronIsFilled
03623 #ifdef debug
03624               G4QHadron*   prodH =(*tmpQHadVec)[aH];
03625               G4LorentzVector p4M=prodH->Get4Momentum();
03626               G4int           PDG=prodH->GetPDGCode();
03627               G4int           Chg=prodH->GetCharge();
03628               G4int           BaN=prodH->GetBaryonNumber();
03629               G4cout<<"-EMC->>G4QFragmentation::Breeder: Str+Hadr PrH#"<<aH<<" filled, 4M="
03630                     <<p4M<<", PDG="<<PDG<<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
03631 #endif
03632             }
03633             tmpQHadVec->clear();
03634             delete tmpQHadVec;  // Who calls DecayQHadron is responsible for clear & delete
03635           }
03636           else if(miPDG == 10)                   // ==> Decay Hadron-Chipolino
03637           {
03638             G4QChipolino QCh(miQC);              // define the TotalResidual as a Chipolino
03639             G4QPDGCode   h1QPDG=QCh.GetQPDG1();  // QPDG of the first hadron
03640             G4double     h1M   =h1QPDG.GetMass();// Mass of the first hadron
03641             G4QPDGCode   h2QPDG=QCh.GetQPDG2();  // QPDG of the second hadron 
03642             G4double     h2M   =h2QPDG.GetMass();// Mass of the second hadron
03643             G4double     ttM   =curString4M.m(); // Real Mass of the Chipolino
03644             if(h1M+h2M<miM+eps)                  // Two particles decay of Chipolino
03645             {
03646               G4LorentzVector h14M(0.,0.,0.,h1M);
03647               G4LorentzVector h24M(0.,0.,0.,h2M);
03648               if(std::fabs(ttM-h1M-h2M)<=eps)
03649               {
03650                 G4double part1=h1M/(h1M+h2M);
03651                 h14M=part1*mi4M;
03652                 h24M=mi4M-h14M;
03653               }
03654               else
03655               {
03656                 if(!G4QHadron(mi4M).DecayIn2(h14M,h24M))
03657                 {
03658                   G4cerr<<"***G4QFragmentation::Breeder: HS tM="<<ttM<<"->h1="<<h1QPDG<<"("
03659                         <<h1M<<")+h2="<<h1QPDG<<"("<<h2M<<")="<<h1M+h2M<<G4endl;
03660                   G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ChipoDec");
03661                 }
03662               }
03663               G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
03664               theResult->push_back(h1H);         // (delete equivalent)  
03665 #ifdef debug
03666               G4LorentzVector f4M=h1H->Get4Momentum();
03667               G4int           fPD=h1H->GetPDGCode();
03668               G4int           fCg=h1H->GetCharge();
03669               G4int           fBN=h1H->GetBaryonNumber();
03670               G4cout<<"-EMC->>G4QFragmentation::Breeder: CorStrHadr Prod-1 is filled, f4M="
03671                     <<f4M<<", fPDG="<<fPD<<", fCg="<<fCg<<", fBN="<<fBN<<G4endl;
03672 #endif
03673               G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
03674               theResult->push_back(h2H);         // (delete equivalent)  
03675 #ifdef debug
03676               G4LorentzVector n4M=h2H->Get4Momentum();
03677               G4int           nPD=h2H->GetPDGCode();
03678               G4int           nCg=h2H->GetCharge();
03679               G4int           nBN=h2H->GetBaryonNumber();
03680               G4cout<<"-EMC->>G4QFragmentation::Breeder: CorStrHadr Prod-2 is filled, n4M="
03681                     <<n4M<<", nPDG="<<nPD<<", nCg="<<nCg<<", nBN="<<nBN<<G4endl;
03682 #endif
03683 #ifdef edebug
03684               G4cout<<"-EMC-...HS-Chipo...G4QFragmentation::Breeder:DecCHECK, Ch4M="<<mi4M
03685                     <<", ChQC="<<miQC<<", d4M="<<mi4M-h14M-h24M<<G4endl;
03686 #endif
03687             }
03688           }
03689           else
03690           {
03691             G4QHadron* sHad = new G4QHadron(miPDG, mi4M);
03692             theResult->push_back(sHad);          // The original string=hadron is filled
03693 #ifdef debug
03694             G4cout<<"----->>G4QFragmentation::Breeder: CorStr=Hadr is Filled, 4M="
03695                   <<curString4M<<", StPDG="<<miPDG<<G4endl;
03696 #endif
03697           }
03698 #ifdef edebug
03699           G4cout<<"-EMC-...Cor...G4QFragmentation::Breeder:StHadCor CHECK Sum="<<s4M
03700                 <<" =? "<<mi4M+pHadron->Get4Momentum()<<G4endl;
03701 #endif
03702 #ifdef debug
03703           G4cout<<"------->>G4QFragmentation::Breeder: *Corrected* String+Hadr="<<miPDG
03704                 <<mi4M<<" by Hadron #"<<reha<<G4endl;
03705 #endif
03706           continue;                    // Continue the LOOP over the curStrings
03707         }
03708         else
03709         {
03710 #ifdef debug
03711           G4cout<<"G4QFragmentation::Breeder: Str+Hadr Failed, 4M="<<curString4M
03712                 <<", PDG="<<miPDG<<" -> Now try to recover the string as a hadron"<<G4endl;
03713 #endif
03714           //for (reha=0; reha < nofRH; reha++)      // LOOP over already collected hadrons
03715           //{
03716           //  G4QHadron* pHadron=(*theResult)[reha];// Pointer to the CurrentPartnerHadron
03717           //  G4LorentzVector p4M=pHadron->Get4Momentum();
03718           //  G4double         pM=p4M.m();          // Mass of the Partner-Hadron
03719           //  G4LorentzVector t4M=p4M+curString4M;  // Total momentum of the compound
03720           //  G4double        tM2=t4M.m2();         // Squared total mass of the compound
03721           //  if(tM2 >= sqr(pM+miM+eps))            // Condition of possible correction
03722           //  {
03723           //    G4double tM=std::sqrt(tM2);         // Mass of the Hadron+String compound
03724           //    G4double dM=tM-pM-miM;              // Excess of the compound mass
03725           //    if(dM < dMmin)
03726           //    {
03727           //      dMmin=dM;
03728           //      fuha=reha;
03729           //      spM=pM;
03730           //      s4M=t4M;
03731           //      sM=tM;
03732           //    }
03733           //  }
03734           //} // End of the LOOP over string-partners for Correction
03735         }
03736         // @@@ convert string to Quasmon with curString4M
03737         G4QContent curStringQC=curString->GetQC();
03738         G4Quasmon* stringQuasmon = new G4Quasmon(curStringQC, curString4M);
03739         theQuasmons.push_back(stringQuasmon);
03740         continue;                      // Continue the LOOP over the curStrings
03741       } // End of IF(Can try the String-Hadron correction
03742     } // End of IF(NO_Hadrons) = Problem solution namespace
03743     G4Quasmon tmpQ;                                 // @@ an issue of Q to decay resonances
03744     G4int nHfin=0;
03745     if(theHadrons) nHfin=theHadrons->size();
03746     else // !! Sum Up all strings and convert them in a Quasmon (Exception for development)
03747     {
03748       G4LorentzVector ss4M(0.,0.,0.,0.);
03749       G4QContent      ssQC(0,0,0,0,0,0);
03750       G4int tnSt=strings.size();
03751       for(G4int i=astring; i < tnSt; ++i)
03752       {
03753         G4LorentzVector pS4M=strings[i]->Get4Momentum(); // String 4-momentum
03754         ss4M+=pS4M;
03755         G4QContent pSQC=strings[i]->GetQC();             // String Quark Content
03756         ssQC+=pSQC;
03757 #ifdef debug
03758         G4cout<<"=--=>G4QFragmentation::Breeder:S#"<<i<<",4M="<<pS4M<<",QC="<<pSQC<<G4endl;
03759 #endif
03760       }
03761 #ifdef debug
03762       G4cout<<"==>G4QFragmentation::Breeder:AllStrings are summed up in a Quasmon"<<G4endl;
03763 #endif
03764       G4Quasmon* stringQuasmon = new G4Quasmon(ssQC, ss4M);
03765       theQuasmons.push_back(stringQuasmon);
03766       break;                                   // break the LOOP over Strings
03767     }
03768 #ifdef debug
03769     G4cout<<"G4QFragmentation::Breeder: Trying to decay hadrons #ofHRes="<<nHfin<<G4endl;
03770 #endif
03771     for(G4int aTrack=0; aTrack<nHfin; aTrack++)
03772     {
03773       G4QHadron* curHadron=(*theHadrons)[aTrack];
03774       G4int hPDG=curHadron->GetPDGCode();
03775       G4LorentzVector curH4M=curHadron->Get4Momentum();
03776       G4int           curHCh=curHadron->GetCharge();
03777       G4int           curHBN=curHadron->GetBaryonNumber();
03778 #ifdef debug
03779       G4cout<<"----->>G4QFragmentation::Breeder:S#"<<astring<<",H#"<<aTrack<<",PDG="<<hPDG
03780             <<",4M="<<curHadron->Get4Momentum()<<G4endl;
03781 #endif
03782       if(std::abs(hPDG)%10 > 2)
03783       {
03784         G4QHadronVector* tmpQHadVec=tmpQ.DecayQHadron(curHadron); // It deletes curHadron
03785 #ifdef debug
03786         G4cout<<"G4QFragmentation::Breeder:-DECAY'S DONE-,nH="<<tmpQHadVec->size()<<G4endl;
03787 #endif
03788         for(unsigned aH=0; aH < tmpQHadVec->size(); aH++)
03789         {
03790           theResult->push_back((*tmpQHadVec)[aH]);// TheDecayProduct of TheHadron is filled
03791           //
03792           G4QHadron*   prodH =(*tmpQHadVec)[aH];
03793           G4LorentzVector p4M=prodH->Get4Momentum();
03794           G4int           Chg=prodH->GetCharge();
03795           G4int           BaN=prodH->GetBaryonNumber();
03796           curString4M-=p4M;
03797           curStrChg-=Chg;
03798           curStrBaN-=BaN;
03799           curH4M-=p4M;
03800           curHCh-=Chg;
03801           curHBN-=BaN;
03802 #ifdef edebug
03803           G4int           PDG=prodH->GetPDGCode();
03804           G4cout<<"-EMC->>G4QFragmentation::Breeder:String*Filled, 4M="<<p4M<<", PDG="<<PDG
03805                 <<", Chg="<<Chg<<", BaN="<<BaN<<G4endl;
03806 #endif
03807         }
03808 #ifdef edebug
03809         G4cout<<"-EMC-.G4QFr::Br:Dec,r4M="<<curH4M<<",rC="<<curHCh<<",rB="<<curHBN<<G4endl;
03810 #endif
03811         tmpQHadVec->clear();
03812         delete tmpQHadVec;  // Who calls DecayQHadron is responsible for clear & delete
03813       }
03814       else                                      // Chipolino is not checked here
03815       {
03816         theResult->push_back(curHadron);        // The original hadron is filled
03817         //
03818         curString4M-=curH4M;
03819         G4int curCh=curHadron->GetCharge();
03820         G4int curBN=curHadron->GetBaryonNumber();
03821         curStrChg-=curCh;
03822         curStrBaN-=curBN;
03823 #ifdef edebug
03824         G4cout<<"-EMC->>-->>G4QFragmentation::Breeder: curH filled 4M="<<curH4M<<",PDG="
03825               <<curHadron->GetPDGCode()<<", Chg="<<curCh<<", BaN="<<curBN<<G4endl;
03826 #endif
03827       }
03828     }
03829     // clean up (the issues are filled to theResult)
03830     if(theHadrons) delete theHadrons;
03831 #ifdef edebug
03832     G4cout<<"-EMC-.........G4QFragmentation::Breeder: StringDecay CHECK, r4M="<<curString4M
03833           <<", rChg="<<curStrChg<<", rBaN="<<curStrBaN<<G4endl;
03834 #endif
03835     // Trap with the debugging warning --- Starts ---
03836     if(curStrChg || curStrBaN || curString4M.t() > eps || std::fabs(curString4M.x()) > eps
03837        || std::fabs(curString4M.y()) > eps || std::fabs(curString4M.z()) > eps )
03838     {
03839       G4double dEn=curString4M.t();
03840       G4double dPx=curString4M.x();
03841       G4double dPy=curString4M.y();
03842       G4double dPz=curString4M.z();
03843       G4int nHadr=theResult->size();
03844       G4double hEn=0.;
03845       G4double hPx=0.;
03846       G4double hPy=0.;
03847       G4double hPz=0.;
03848       G4int    hCh=0;
03849       G4int    hBN=0;
03850       G4double mEn=0.;
03851       G4double mPx=0.;
03852       G4double mPy=0.;
03853       G4double mPz=0.;
03854       G4int    mCh=0;
03855       G4int    mBN=0;
03856       for(G4int i=0; i<nHadr; i++)
03857       {
03858         mEn=hEn; // Previous hadron
03859         mPx=hPx;
03860         mPy=hPy;
03861         mPz=hPz;
03862         mCh=hCh;
03863         mBN=hBN;
03864         G4QHadron* curHadr = (*theResult)[i];
03865         G4LorentzVector hI4M = curHadr->Get4Momentum();
03866         hEn=hI4M.t();
03867         hPx=hI4M.x();
03868         hPy=hI4M.y();
03869         hPz=hI4M.z();
03870         hCh=curHadr->GetCharge();
03871         hBN=curHadr->GetBaryonNumber();
03872         G4cout<<"G4QFragmentation::Breeder: H#"<<i<<", d4M="<<curString4M+hI4M
03873               <<",dCh="<<hCh+curStrChg<<",dBN="<<hBN+curStrBaN<<G4endl;
03874         if( !(hCh+curStrChg) && !(hBN+curStrBaN) && std::fabs(dEn+hEn)<eps &&
03875             std::fabs(dPx+hPx)<eps && std::fabs(dPy+hPy)<eps && std::fabs(dPz+hPz)<eps )
03876         {
03877           G4cout<<"G4QFragmentation::Breeder: ***Cured*** Redundent Hadron # "<<i<<G4endl;
03878           G4QHadron* theLast = (*theResult)[nHadr-1];
03879           curHadr->Set4Momentum(theLast->Get4Momentum()); //4-Mom of CurHadr
03880           G4QPDGCode lQP=theLast->GetQPDG();
03881           if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP);
03882           else curHadr->SetQC(theLast->GetQC());
03883           theResult->pop_back(); // theLastQHadron is excluded from OUTPUT
03884           delete theLast;        //*!!When kill, delete theLastQHadr as an Instance!*
03885           break;
03886         }
03887         if( !(hCh+mCh+curStrChg) && !(hBN+mBN+curStrBaN) && std::fabs(dEn+hEn+mEn)<eps &&
03888             std::fabs(dPx+hPx+mPx)<eps && std::fabs(dPy+hPy+mPy)<eps &&
03889             std::fabs(dPz+hPz+mPz)<eps && i>0)
03890         { 
03891           G4cout<<"G4QFragmentation::Breeder:***Cured*** Redundent 2Hadrons i="<<i<<G4endl;
03892           G4QHadron* preHadr = (*theResult)[i-1];
03893           G4QHadron* theLast = (*theResult)[nHadr-1];
03894           if(i < nHadr-1)        // Only cur can overlap with the two last hadrons
03895           {                      // Put the last to the previous
03896             preHadr->Set4Momentum(theLast->Get4Momentum()); // must be 4-Mom of preHadr
03897             G4QPDGCode lQP=theLast->GetQPDG();
03898             if(lQP.GetPDGCode()!=10) preHadr->SetQPDG(lQP);
03899             else preHadr->SetQC(theLast->GetQC());
03900           }
03901           theResult->pop_back(); // theLastQHadron's excluded from OUTPUT(even if Cur=Last)
03902           delete theLast;        //*!!When kill, delete theLastQHadr as an Instance!*
03903           theLast = (*theResult)[nHadr-2]; // nHadr is not changed -> so it's LastButOne
03904           if(i < nHadr-2)        // The two current and the two Last are not overlaped
03905           {                      // Put the last but one to the current
03906             curHadr->Set4Momentum(theLast->Get4Momentum()); // must be 4-Mom of curHadr
03907             G4QPDGCode lQP=theLast->GetQPDG();
03908             if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP);
03909             else curHadr->SetQC(theLast->GetQC());
03910           }
03911           theResult->pop_back(); // theLastQHadron's excluded from OUTPUT(even for overlap)
03912           delete theLast;        //*!!When kill, delete theLastQHadr as an Instance!*
03913           nHadr=theResult->size(); // Just a precaution... should be nHadr-2
03914           break;
03915         }
03916         // If the redundent particle decay in 3 FS hadrons -> the corresponding Improvement
03917         G4cout<<"*Warning*G4QFragmentation::Breeder: Nonconservation isn't cured!"<<G4endl;
03918       }
03919     }
03920     // Trap with the debugging warning ^^^  Ends  ^^^
03921   } // End of the main LOOP over decaying strings
03922   G4LorentzVector r4M=theNucleus.Get4Momentum(); // Nucleus 4-momentum in LS
03923   G4int rPDG=theNucleus.GetPDG();
03924   G4QHadron* resNuc = new G4QHadron(rPDG,r4M);
03925   theResult->push_back(resNuc);                          // Fill the residual nucleus
03926 #ifdef edebug
03927   G4LorentzVector s4M(0.,0.,0.,0.); // Sum of the Result in LS
03928   G4int rCh=totChg;
03929   G4int rBN=totBaN;
03930   G4int nHadr=theResult->size();
03931   G4int nQuasm=theQuasmons.size();
03932   G4cout<<"-EMCLS-G4QFragmentation::Breeder:#ofHadr="<<nHadr<<", #OfQuasm="<<nQuasm<<",rN="
03933         <<r4M.m()<<"="<<G4QNucleus(rPDG).GetGSMass()<<G4endl;
03934   for(G4int i=0; i<nHadr; i++)
03935   {
03936     G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
03937     s4M+=hI4M;
03938     G4int hChg=(*theResult)[i]->GetCharge();
03939     rCh-=hChg;
03940     G4int hBaN=(*theResult)[i]->GetBaryonNumber();
03941     rBN-=hBaN;
03942     G4cout<<"-EMCLS-G4QFragmentation::Breeder:(1) Hadron#"<<i<<", 4M="<<hI4M<<", PDG="
03943           <<(*theResult)[i]->GetPDGCode()<<", C="<<hChg<<", B="<<hBaN<<G4endl;
03944   }
03945   for(G4int i=0; i<nQuasm; i++)
03946   {
03947     G4LorentzVector hI4M=theQuasmons[i]->Get4Momentum();
03948     s4M+=hI4M;
03949     G4int hChg=theQuasmons[i]->GetCharge();
03950     rCh-=hChg;
03951     G4int hBaN=theQuasmons[i]->GetBaryonNumber();
03952     rBN-=hBaN;
03953     G4cout<<"-EMCLS-G4QFragmentation::Breeder:(1) Quasmon#"<<i<<", 4M="<<hI4M<<", C="<<hChg
03954           <<", B="<<hBaN<<G4endl;
03955   }
03956   G4cout<<"-EMCLS-G4QFragm::Breed: LS r4M="<<s4M-totLS4M<<",rC="<<rCh<<",rB="<<rBN<<G4endl;
03957 #endif
03958   // Now we need to coolect particles for creation of a Quasmon @@ improve !!
03959   G4int nRes=theResult->size();
03960 #ifdef ppdebug
03961   G4cout<<"G4QFragmentation::Breeder: Strings4M="<<ft4M<<", nRes="<<nRes<<G4endl;
03962 #endif
03963   G4ThreeVector LS3Mom=ft4M.v();
03964   G4ThreeVector LSDir=LS3Mom.unit();
03965   if(nRes > 2 && maxEn > 0.)
03966   {
03967     std::list<std::pair<G4double, G4QHadron*> > theSorted;         // Output
03968     std::list<std::pair<G4double, G4QHadron*> >::iterator current; // Input
03969     for(G4int secondary = 0; secondary<nRes-1; ++secondary)
03970     {
03971       G4QHadron*      ih    =theResult->operator[](secondary);
03972       G4LorentzVector h4M   =ih->Get4Momentum();
03973       G4double        hM2   =ih->GetMass2();
03974       G4ThreeVector   h3M   =h4M.v();
03975       G4double        toSort=DBL_MAX;
03976       if(hM2>0.00001) toSort=h4M.e()+h3M.dot(LSDir)/std::sqrt(hM2);// monotonic as rapidity
03977 #ifdef ppdebug
03978       G4cout<<"G4QFragmentation::Breeder:#"<<secondary<<",M2="<<hM2<<",s="<<toSort<<G4endl;
03979 #endif
03980       std::pair<G4double, G4QHadron*> it;
03981       it.first      = toSort;
03982       it.second     = ih;
03983       G4bool inserted = false;
03984       for(current = theSorted.begin(); current!=theSorted.end(); ++current)
03985       {
03986         if((*current).first > toSort)        // The current is smaller then existing
03987         {
03988           theSorted.insert(current, it);     // It shifts the others up
03989           inserted = true;
03990           break;
03991         }
03992       }
03993       if(!inserted) theSorted.push_back(it); // It is bigger than any previous
03994     }
03995     theResult->clear();                      // Clear and refill theResult by StriHardPart
03996     G4LorentzVector q4M(0.,0.,0.,0.);
03997     G4QContent qQC(0,0,0,0,0,0);
03998     for(current = theSorted.begin(); current!=theSorted.end(); ++current)
03999     {
04000       G4QHadron*       ih= (*current).second;
04001       G4LorentzVector h4M= ih->Get4Momentum();
04002       G4int          hPDG= ih->GetPDGCode();
04003       G4double         dE= 0.;
04004       G4bool       tested=true; 
04005       if     (hPDG> 1111 && hPDG< 3335) dE=h4M.e()-ih->GetMass(); // Baryons
04006       else if(hPDG>-1111 && hPDG<1111 && hPDG!=22) dE=h4M.e();    // Mesons (Photons Hard)
04007       //else if(hPDG<-1111 && hPDG>-3335) dE=h4M.e()+ih->GetMass(); // Antiaryons Don'tUse
04008       else tested=false;                                          // Skip other
04009 #ifdef ppdebug
04010       G4cout<<"G4QFragmentation::Breeder:dE="<<dE<<",mE="<<maxEn<<",t="<<tested<<G4endl;
04011 #endif
04012       if(tested && dE < maxEn)
04013       {
04014         maxEn-=dE;
04015         q4M+=h4M;
04016         qQC+=ih->GetQC();
04017 #ifdef debug
04018         G4cout<<"%->G4QFragmentation::Breeder:Exclude,4M="<<h4M<<",dE="<<maxEn<<G4endl;
04019 #endif
04020         delete ih;
04021       }
04022       else  theResult->push_back(ih);                      // Delete equivalent
04023     } // End of Loop over sorted pairs
04024     G4Quasmon* softQuasmon = new G4Quasmon(qQC, q4M);      // SoftPart -> Quasmon
04025 #ifdef debug
04026     G4cout<<"%->G4QFragmentation::Breeder:QuasmonIsFilled,4M="<<q4M<<",QC="<<qQC<<G4endl;
04027 #endif
04028     if(q4M != vac4M) theQuasmons.push_back(softQuasmon);
04029     else delete softQuasmon;
04030     theResult->push_back(resNuc);
04031 #ifdef edebug
04032     G4LorentzVector f4M(0.,0.,0.,0.);                      // Sum of the Result in LS
04033     G4int fCh=totChg;
04034     G4int fBN=totBaN;
04035     G4int nHd=theResult->size();
04036     G4int nQm=theQuasmons.size();
04037     G4cout<<"-EMCLS-G4QFragmentation::Breeder:#ofHadr="<<nHd<<", #OfQuasm="<<nQm<<",rN="
04038           <<r4M.m()<<"="<<G4QNucleus(rPDG).GetGSMass()<<G4endl;
04039     for(G4int i=0; i<nHd; i++)
04040     {
04041       G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
04042       f4M+=hI4M;
04043       G4int hChg=(*theResult)[i]->GetCharge();
04044       fCh-=hChg;
04045       G4int hBaN=(*theResult)[i]->GetBaryonNumber();
04046       fBN-=hBaN;
04047       G4cout<<"-EMCLS-G4QFragmentation::Breeder:(2) Hadron#"<<i<<", 4M="<<hI4M<<", PDG="
04048             <<(*theResult)[i]->GetPDGCode()<<", C="<<hChg<<", B="<<hBaN<<G4endl;
04049     }
04050     for(G4int i=0; i<nQm; i++)
04051     {
04052       G4LorentzVector hI4M=theQuasmons[i]->Get4Momentum();
04053       f4M+=hI4M;
04054       G4int hChg=theQuasmons[i]->GetCharge();
04055       fCh-=hChg;
04056       G4int hBaN=theQuasmons[i]->GetBaryonNumber();
04057       fBN-=hBaN;
04058       G4cout<<"-EMCLS-G4QFragmentation::Breeder:(2) Quasmon#"<<i<<", 4M="<<hI4M<<", C="
04059             <<hChg<<", B="<<hBaN<<G4endl;
04060     }
04061     G4cout<<"-EMCLS-G4QFragm::Breed:, r4M="<<f4M-totLS4M<<",rC="<<fCh<<",rB="<<fBN<<G4endl;
04062 #endif
04063   } // End of the soft Quasmon Creation
04064   return;
04065 } // End of Breeder

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

Definition at line 4312 of file G4QFragmentation.cc.

References FatalException, G4cerr, G4cout, G4endl, G4Exception(), G4UniformRand, and sqr().

Referenced by ExciteDiffParticipants(), and ExciteSingDiffParticipants().

04313 {
04314   // choose an x between Xmin and Xmax with P(x) ~ 1/x @@ M.K. -> 1/sqrt(x)
04315   //G4double range=Xmax-Xmin;
04316   if(Xmax == Xmin) return Xmin;
04317   if( Xmin < 0. || Xmax < Xmin) 
04318   {
04319     G4cerr<<"***G4QFragmentation::ChooseX: Xmin="<<Xmin<<", Xmax="<<Xmax<< G4endl;
04320     G4Exception("G4QFragmentation::ChooseX:","72",FatalException,"Bad X or X-Range");
04321   }
04322   //G4double x;
04323   //do {x=Xmin+G4UniformRand()*range;} while ( Xmin/x < G4UniformRand() );
04324   G4double sxi=std::sqrt(Xmin);
04325   G4double x=sqr(sxi+G4UniformRand()*(std::sqrt(Xmax)-sxi));
04326 #ifdef debug
04327   G4cout<<"G4QFragmentation::ChooseX: DiffractiveX="<<x<<G4endl;
04328 #endif
04329   return x;
04330 } // End of ChooseX

void G4QFragmentation::EvaporateResidual ( G4QHadron hadrNuc  )  [protected]

Definition at line 4790 of file G4QFragmentation.cc.

References G4QEnvironment::DecayAntistrange(), G4QEnvironment::DecayBaryon(), G4QEnvironment::DecayMeson(), G4QNucleus::EvaporateNucleus(), FatalException, G4cerr, G4cout, G4endl, G4Exception(), G4QHadron::Get4Momentum(), G4QHadron::GetBaryonNumber(), G4QContent::GetCharge(), G4QPDGCode::GetMass(), G4QPDGCode::GetPDGCode(), G4QHadron::GetPDGCode(), G4QHadron::GetQC(), G4QChipolino::GetQPDG1(), G4QChipolino::GetQPDG2(), G4QContent::GetSPDGCode(), G4QContent::GetStrangeness(), G4QContent::GetZNSPDGCode(), and sqr().

Referenced by Fragment().

04791 {
04792   static const G4double mAlph = G4QPDGCode(2112).GetNuclMass(2,2,0);
04793   static const G4double mDeut = G4QPDGCode(2112).GetNuclMass(1,1,0);
04794   static const G4double mNeut = G4QPDGCode(2112).GetMass();
04795   static const G4double mProt = G4QPDGCode(2212).GetMass();
04796   static const G4double mAlPr = mAlph+mProt;
04797   static const G4double mAlNt = mAlph+mNeut;
04798   static const G4double dProt = mProt+mProt;
04799   static const G4double dNeut = mNeut+mNeut;
04800   static const G4double dAlph = mAlph+mAlph;
04801   static const G4double eps=.003;
04802   G4QEnvironment envir(theNucleus);
04803   G4int thePDG = qH->GetPDGCode();           // Get PDG code of the Residual Nucleus
04804   G4int theBN  = qH->GetBaryonNumber();      // A (Baryon number of the nucleus)
04805   G4QContent  theQC  = qH->GetQC();          // Quark Content of the hadron
04806   G4int theS=theQC.GetStrangeness();         // S (Strangeness of the nucleus)
04807 #ifdef debug
04808   G4cout<<"G4QFragment::EvaRes:-Called- PDG="<<thePDG<<",4M="<<qH->Get4Momentum()
04809         <<",QC="<<theQC<<", BN="<<theBN<<G4endl;
04810 #endif
04811   if(thePDG==10)
04812   {
04813 #ifdef debug
04814     G4cout<<"G4QFragment::EvaRes: Cgipolino QC="<<theQC<<qH->Get4Momentum()<<G4endl;
04815 #endif
04816     G4QContent   chQC=qH->GetQC();           // Quark content of the Hadron-Chipolino
04817     G4QChipolino QCh(chQC);                  // Define a Chipolino instance for the Hadron
04818     G4LorentzVector ch4M=qH->Get4Momentum(); // 4Mom of the Hadron-Chipolino
04819     G4QPDGCode h1QPDG=QCh.GetQPDG1();        // QPDG of the first hadron
04820     G4double   h1M   =h1QPDG.GetMass();      // Mass of the first hadron
04821     G4QPDGCode h2QPDG=QCh.GetQPDG2();        // QPDG of the second hadron
04822     G4double   h2M   =h2QPDG.GetMass();      // Mass of the second hadron
04823     G4double   chM2  =ch4M.m2();             // Squared Mass of the Chipolino
04824     if( sqr(h1M+h2M) < chM2 )                // Decay is possible
04825     {
04826       G4LorentzVector h14M(0.,0.,0.,h1M);
04827       G4LorentzVector h24M(0.,0.,0.,h2M);
04828       if(!G4QHadron(ch4M).DecayIn2(h14M,h24M))
04829       {
04830         G4cerr<<"***G4QFrag::EvaporateResid: CM="<<std::sqrt(chM2)<<" -> h1="<<h1QPDG<<"("
04831               <<h1M<<") + h2="<<h1QPDG<<"("<<h2M<<") = "<<h1M+h2M<<" **Failed**"<<G4endl;
04832         // throw G4QException("*G4QFragmentation::EvaporateResidual:QChipolino DecIn2 error");
04833         G4Exception("G4QFragmentation::EvaporateResidual()", "HAD_CHPS_0000",
04834                     FatalException, "QChipolino DecIn2 error");
04835       }
04836       delete qH;                             // Kill the primary Chipolino
04837       G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
04838       theResult->push_back(h1H);             // (delete equivalent)
04839 #ifdef debug
04840       G4cout<<"G4QFragm::EvaporateResidual: Chipolino -> H1="<<h1QPDG<<h14M<<G4endl;
04841 #endif
04842       qH = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
04843       theResult->push_back(qH);              // (delete equivalent)
04844 #ifdef debug
04845       G4cout<<"G4QE::EvaporateResidual: Chipolino -> H2="<<h2QPDG<<h24M<<G4endl;
04846 #endif
04847     }
04848     else
04849     {
04850       G4cerr<<"***G4QFragment::EvaporateResid: Chipolino="<<qH->GetQC()<<qH->Get4Momentum()
04851             <<", chipoM="<<std::sqrt(chM2)<<" < m1="<<h1M<<"("<<h1QPDG<<") + m2="<<h2M
04852             <<"("<<h2QPDG<<") = "<<h1M+h2M<<G4endl;
04853       // throw G4QException("G4QFragmentation::EvaporateResidual: LowMassChipolino in Input");
04854       G4Exception("G4QFragmentation::EvaporateResidual()", "HAD_CHPS_0001",
04855                   FatalException, "LowMassChipolino in Input");
04856     }
04857     return;
04858   }
04859   else if(theS<0)                            // Antistrange nucleus
04860   {
04861 #ifdef debug
04862     G4cout<<"G4QFragment::EvaRes: AntistrangeNucleus="<<thePDG<<qH->Get4Momentum()<<G4endl;
04863 #endif
04864     envir.DecayAntistrange(qH, theResult);   // (delete equivalent)
04865     return;
04866   }
04867   else if(theBN==1)
04868   {
04869 #ifdef debug
04870     G4cout<<"G4QFragmentation::EvaporateResid:Baryon="<<thePDG<<qH->Get4Momentum()<<G4endl;
04871 #endif
04872     envir.DecayBaryon(qH, theResult);        // (delete equivalent)
04873     return;
04874   }
04875   else if(!theBN) // @@ In future it is usefull to add the MesonExcitationDecay (?!)
04876   {
04877 #ifdef debug
04878     G4LorentzVector mesLV=qH->Get4Momentum();
04879     G4cout<<"G4QFragmentation::EvaRes:(!)Meson(!) PDG="<<thePDG<<",4M="<<mesLV<<mesLV.m()
04880           <<",QC="<<qH->GetQC()<<",MPDG="<<G4QPDGCode(thePDG).GetMass()<<G4endl;
04881 #endif
04882     envir.DecayMeson(qH, theResult);         // @@ To be written
04883     return;
04884   }
04885   G4int theC=theQC.GetCharge();              // P
04886 #ifdef debug
04887   G4cout<<"G4QFragment::EvaRes: qH.Charge = "<<theC<<G4endl;
04888 #endif
04889   if(!thePDG) thePDG = theQC.GetSPDGCode();  // If there is no PDG code, get it from QC
04890   if( thePDG == 10 && theBN > 0 ) thePDG=theQC.GetZNSPDGCode();
04891   if(theS>0) thePDG-=theS*999999;            // @@ May hide hypernuclear problems (G4) ! @@
04892 #ifdef debug
04893   G4cout<<"G4QFragment::EvaRes: S="<<theS<<", newPDG="<<thePDG<<G4endl;
04894 #endif
04895   G4double totGSM = G4QNucleus(thePDG).GetGSMass();// TheGroundStMass of theTotalResNucleus
04896 #ifdef debug
04897   G4cout<<"G4QFragment::EvaRes: totGSM="<<totGSM<<G4endl;
04898 #endif
04899   if(theBN==2)
04900   {
04901     if(!theC)        totGSM=dNeut;           // nn, nL, LL
04902     else if(theC==2) totGSM=dProt;           // pp
04903     else             totGSM=mDeut;           // np, Lp
04904   }
04905   else if(theBN==5)
04906   {
04907     if     (theC==3) totGSM=mAlPr;           // effective "Alph+p"
04908     else if(theC==2) totGSM=mAlNt;           // effective "Alph+n"
04909   }
04910   else if(theBN==8)   totGSM=dAlph;          // effective "Be8"
04911   // @@ Should be more (else if) for bigger A=theBN
04912   G4LorentzVector q4M = qH->Get4Momentum();  // Get 4-momentum of theTotalResidNucleus
04913   G4double    totMass = q4M.m();             // Get theRealMass of theTotalResidNucleus
04914 #ifdef debug
04915     G4cout<<"G4QFragment::EvaRes: Excitation = "<<totMass-totGSM<<G4endl;
04916 #endif
04917   if(std::fabs(totMass-totGSM) < eps)
04918   {
04919     theResult->push_back(qH);               // fill As It Is
04920   }
04921   else if(totMass > totGSM)
04922   {
04923 #ifdef debug
04924     G4cout<<"G4QFragment::EvaRes: try Evaporate Nucleus PDG="<<thePDG<<G4endl;
04925 #endif
04926     theNucleus.EvaporateNucleus(qH, theResult);
04927 #ifdef debug
04928     G4cout<<"G4QFragment::EvaRes: ** Evaporation is done **"<<G4endl;
04929 #endif
04930     //delete qH;
04931     qH=0;
04932   }
04933   else                                       // Correction must be done
04934   {
04935 #ifdef debug
04936     G4cout<<"-War-G4QFr::EvaRes:*Must correct* "<<theQC<<q4M<<totMass<<"<"<<totGSM<<G4endl;
04937 #endif
04938   }
04939 #ifdef qdebug
04940   if (qH)
04941   {
04942     G4cout<<"-W-G4QFragmentation::EvaporateResid:*Deleted*,PDG="<<qH->GetPDGCode()<<G4endl;
04943     delete qH;
04944   }
04945 #endif
04946   return;
04947 } // End of EvaporateResidual

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

Definition at line 4068 of file G4QFragmentation.cc.

References ChooseX(), G4cout, G4endl, GaussianPt(), G4QHadron::Get4Momentum(), G4QHadron::GetMass(), G4QHadron::Set4Momentum(), and sqr().

Referenced by G4QFragmentation().

04070 {
04071   G4LorentzVector Pprojectile=projectile->Get4Momentum();
04072   G4double Mprojectile=projectile->GetMass();
04073   G4double Mprojectile2=Mprojectile*Mprojectile;
04074   G4LorentzVector Ptarget=target->Get4Momentum();
04075   G4double Mtarget=target->GetMass();
04076   G4double Mtarget2=Mtarget*Mtarget;
04077 #ifdef debug
04078   G4cout<<"G4QFragm::ExciteDiffPartici:Ep="<<Pprojectile.e()<<",Et="<<Ptarget.e()<<G4endl;
04079 #endif
04080   // Transform momenta to cms and then rotate parallel to z axis;
04081   G4LorentzVector Psum=Pprojectile+Ptarget;
04082   G4LorentzRotation toCms(-Psum.boostVector()); // Boost Rotation to CMS
04083   G4LorentzVector Ptmp=toCms*Pprojectile;
04084   if(Ptmp.pz()<=0.) // "String" moving backwards in CMS, abort collision !! ? M.K.
04085   {
04086 #ifdef debug
04087     G4cout<<"G4QFragmentation::ExciteDiffParticipants: *1* abort Collision!! *1*"<<G4endl;
04088 #endif
04089     return false; 
04090   }         
04091   toCms.rotateZ(-Ptmp.phi());
04092   toCms.rotateY(-Ptmp.theta());
04093 #ifdef debug
04094   G4cout<<"G4QFragment::ExciteDiffParticipantts:BeforBoost Pproj="<<Pprojectile<<", Ptarg="
04095         <<Ptarget<<G4endl;
04096 #endif
04097   G4LorentzRotation toLab(toCms.inverse()); // Boost Rotation to LabSys (LS)
04098   Pprojectile.transform(toCms);
04099   Ptarget.transform(toCms);
04100 #ifdef debug
04101   G4cout<< "G4QFragment::ExciteDiffParticipantts: AfterBoost Pproj="<<Pprojectile<<"Ptarg="
04102         <<Ptarget<<", cms4M="<<Pprojectile+Ptarget<<G4endl;
04103   G4cout<<"G4QFragment::ExciteDiffParticipants: ProjX+="<<Pprojectile.plus()<<", ProjX-="
04104         <<Pprojectile.minus()<<", TargX+="<< Ptarget.plus()<<", TargX-="<<Ptarget.minus()
04105         <<G4endl;
04106 #endif
04107   G4LorentzVector Qmomentum(0.,0.,0.,0.);
04108   G4int whilecount=0;
04109 #ifdef debug
04110   G4cout<<"G4QFragmentation::ExciteDiffParticipants: Before DO"<<G4endl;
04111 #endif
04112   do
04113   {
04114     //  Generate pt  
04115     G4double maxPtSquare=sqr(Ptarget.pz());
04116 #ifdef debug
04117     G4cout<<"G4QFragmentation::ExciteDiffParticipants: maxPtSq="<<maxPtSquare<<G4endl;
04118     if(whilecount++>=500 && whilecount%100==0) // @@ M.K. Hardwired limits 
04119     G4cout<<"G4QFragmentation::ExciteDiffParticipantts: can loop, loopCount="<<whilecount
04120           <<", maxPtSquare="<<maxPtSquare<<G4endl;
04121 #endif
04122     if(whilecount>1000)                        // @@ M.K. Hardwired limits 
04123     {
04124 #ifdef debug
04125       G4cout<<"G4QFragmentation::ExciteDiffParticipants: *2* abort Loop!! *2*"<<G4endl;
04126 #endif
04127       return false;    //  Ignore this interaction 
04128     }
04129     Qmomentum=G4LorentzVector(GaussianPt(widthOfPtSquare,maxPtSquare),0);
04130 #ifdef debug
04131     G4cout<<"G4QFragment::ExciteDiffParticipants: generated Pt="<<Qmomentum<<", ProjPt="
04132           <<Pprojectile+Qmomentum<<", TargPt="<<Ptarget-Qmomentum<<G4endl;
04133 #endif
04134     //  Momentum transfer
04135     G4double Xmin=0.;
04136     G4double Xmax=1.;
04137     G4double Xplus =ChooseX(Xmin,Xmax);
04138     G4double Xminus=ChooseX(Xmin,Xmax);
04139 #ifdef debug
04140     G4cout<<"G4QFragment::ExciteDiffParticip: X-plus="<<Xplus<<",X-minus="<<Xminus<<G4endl;
04141 #endif
04142     G4double pt2=Qmomentum.vect().mag2();
04143     G4double Qplus =-pt2/Xminus/Ptarget.minus();
04144     G4double Qminus= pt2/Xplus /Pprojectile.plus();
04145     Qmomentum.setPz((Qplus-Qminus)/2);
04146     Qmomentum.setE( (Qplus+Qminus)/2);
04147 #ifdef debug
04148     G4cout<<"G4QFragment::ExciteDiffParticip: Qplus="<<Qplus<<", Qminus="<<Qminus<<", pt2="
04149           <<pt2<<", Qmomentum="<<Qmomentum<<", ProjM="<<(Pprojectile+Qmomentum).mag()
04150           <<", TargM="<<(Ptarget-Qmomentum).mag()<<G4endl;
04151 #endif
04152   } while((Pprojectile+Qmomentum).mag2()<=Mprojectile2 ||
04153           (Ptarget-Qmomentum).mag2()<=Mtarget2);
04154   Pprojectile += Qmomentum;
04155   Ptarget     -= Qmomentum;
04156 #ifdef debug
04157   G4cout<<"G4QFragment::ExciteDiffParticipan: Proj(Q)="<<Pprojectile<<", Targ(Q)="<<Ptarget
04158         <<", Proj(back)="<<toLab*Pprojectile<<", Targ(bac)="<< toLab*Ptarget << G4endl;
04159 #endif
04160   // Transform back and update SplitableHadron Participant.
04161   Pprojectile.transform(toLab);
04162   Ptarget.transform(toLab);
04163 #ifdef debug
04164   G4cout<< "G4QFragmentation::ExciteDiffParticipants: TargetMass="<<Ptarget.mag()<<G4endl;
04165 #endif
04166   target->Set4Momentum(Ptarget);  
04167 #ifdef debug
04168   G4cout<<"G4QFragment::ExciteDiffParticipants:ProjectileMass="<<Pprojectile.mag()<<G4endl;
04169 #endif
04170   projectile->Set4Momentum(Pprojectile);
04171   return true;
04172 } // End of ExciteDiffParticipants

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

Definition at line 4176 of file G4QFragmentation.cc.

References ChooseX(), G4cout, G4endl, G4UniformRand, GaussianPt(), G4QHadron::Get4Momentum(), G4QHadron::GetMass(), G4QHadron::GetMass2(), G4QHadron::Set4Momentum(), and sqr().

Referenced by G4QFragmentation().

04178 {
04179   G4LorentzVector Pprojectile=projectile->Get4Momentum();
04180   G4double Mprojectile=projectile->GetMass();
04181   G4double Mprojectile2=Mprojectile*Mprojectile;
04182   G4LorentzVector Ptarget=target->Get4Momentum();
04183   G4double Mtarget=target->GetMass();
04184   G4double Mtarget2=Mtarget*Mtarget;
04185 #ifdef debug
04186   G4cout<<"G4QFragm::ExSingDiffPartici:Ep="<<Pprojectile.e()<<",Et="<<Ptarget.e()<<G4endl;
04187 #endif
04188   G4bool KeepProjectile= G4UniformRand() > 0.5;
04189   // Reset minMass of the non diffractive particle to its value, (minus for rounding...)
04190   if(KeepProjectile ) 
04191   {
04192 #ifdef debug
04193     G4cout<<"--1/2--G4QFragmentation::ExSingDiffParticipants: Projectile is fixed"<<G4endl;
04194 #endif
04195     Mprojectile2 = projectile->GetMass2()*(1.-perCent); // Isn't it too big reduction? M.K.
04196   }
04197   else
04198   {
04199 #ifdef debug
04200     G4cout<<"---1/2---G4QFragmentation::ExSingDiffParticipants: Target is fixed"<<G4endl;
04201 #endif
04202     Mtarget2 = target->GetMass2()*(1.-perCent); // @@ Isn't it too big reduction? M.K.
04203   }
04204   // @@ From this point it repeats the Diffractional excitation (? Use flag ?)
04205   // Transform momenta to cms and then rotate parallel to z axis;
04206   G4LorentzVector Psum=Pprojectile+Ptarget;
04207   G4LorentzRotation toCms(-Psum.boostVector()); // Boost Rotation to CMS
04208   G4LorentzVector Ptmp=toCms*Pprojectile;
04209   if(Ptmp.pz()<=0.) // "String" moving backwards in CMS, abort collision !! ? M.K.
04210   {
04211 #ifdef debug
04212     G4cout<<"G4QFragment::ExciteSingDiffParticipants: *1* abort Collision!! *1*"<<G4endl;
04213 #endif
04214     return false; 
04215   }         
04216   toCms.rotateZ(-Ptmp.phi());
04217   toCms.rotateY(-Ptmp.theta());
04218 #ifdef debug
04219   G4cout<<"G4QFragm::ExciteSingDiffParticipantts: Be4Boost Pproj="<<Pprojectile<<",Ptarg="
04220         <<Ptarget<<G4endl;
04221 #endif
04222   G4LorentzRotation toLab(toCms.inverse()); // Boost Rotation to LabSys (LS)
04223   Pprojectile.transform(toCms);
04224   Ptarget.transform(toCms);
04225 #ifdef debug
04226   G4cout<< "G4QFragment::ExciteDiffParticipantts: AfterBoost Pproj="<<Pprojectile<<"Ptarg="
04227         <<Ptarget<<", cms4M="<<Pprojectile+Ptarget<<G4endl;
04228 
04229   G4cout<<"G4QFragment::ExciteDiffParticipantts: ProjX+="<<Pprojectile.plus()<<", ProjX-="
04230         <<Pprojectile.minus()<<", TargX+="<< Ptarget.plus()<<", TargX-="<<Ptarget.minus()
04231         <<G4endl;
04232 #endif
04233   G4LorentzVector Qmomentum(0.,0.,0.,0.);
04234   G4int whilecount=0;
04235   do
04236   {
04237     //  Generate pt  
04238     G4double maxPtSquare=sqr(Ptarget.pz());
04239     if(whilecount++>=500 && whilecount%100==0) // @@ M.K. Hardwired limits 
04240 #ifdef debug
04241     G4cout<<"G4QFragment::ExciteSingDiffParticipantts: can loop, loopCount="<<whilecount
04242           <<", maxPtSquare="<<maxPtSquare<<G4endl;
04243 #endif
04244     if(whilecount>1000)                        // @@ M.K. Hardwired limits 
04245     {
04246 #ifdef debug
04247       G4cout<<"G4QFragmentation::ExciteSingDiffParticipants: *2* abort Loop!! *2*"<<G4endl;
04248 #endif
04249       return false;    //  Ignore this interaction 
04250     }
04251     Qmomentum=G4LorentzVector(GaussianPt(widthOfPtSquare,maxPtSquare),0);
04252 #ifdef debug
04253     G4cout<<"G4QFragm::ExciteSingDiffParticipants: generated Pt="<<Qmomentum<<", ProjPt="
04254           <<Pprojectile+Qmomentum<<", TargPt="<<Ptarget-Qmomentum<<G4endl;
04255 #endif
04256     //  Momentum transfer
04257     G4double Xmin=0.;
04258     G4double Xmax=1.;
04259     G4double Xplus =ChooseX(Xmin,Xmax);
04260     G4double Xminus=ChooseX(Xmin,Xmax);
04261 #ifdef debug
04262     G4cout<<"G4QFragm::ExciteSingDiffPartici:X-plus="<<Xplus<<",X-minus="<<Xminus<<G4endl;
04263 #endif
04264     G4double pt2=G4ThreeVector(Qmomentum.vect()).mag2();
04265     G4double Qplus =-pt2/Xminus/Ptarget.minus();
04266     G4double Qminus= pt2/Xplus /Pprojectile.plus();
04267     if (KeepProjectile)
04268       Qminus=(projectile->GetMass2()+pt2)/(Pprojectile.plus()+Qplus) - Pprojectile.minus();
04269     else Qplus=Ptarget.plus() - (target->GetMass2()+pt2)/(Ptarget.minus()-Qminus);  
04270     Qmomentum.setPz((Qplus-Qminus)/2);
04271     Qmomentum.setE( (Qplus+Qminus)/2);
04272 #ifdef debug
04273     G4cout<<"G4QFragm::ExciteDiffParticip: Qplus="<<Qplus<<", Qminus="<<Qminus<<", pt2="
04274           <<pt2<<", Qmomentum="<<Qmomentum<<", ProjM="<<(Pprojectile+Qmomentum).mag()
04275           <<", TargM="<<(Ptarget-Qmomentum).mag()<<G4endl;
04276 #endif
04277     // while is different from the Double Diffractive Excitation (@@ !)
04278     //} while((Pprojectile+Qmomentum).mag2()<= Mprojectile2 ||
04279     //        (Ptarget-Qmomentum).mag2()<=Mtarget2);
04280   } while((Ptarget-Qmomentum).mag2()<=Mtarget2 ||
04281           (Pprojectile+Qmomentum).mag2()<=Mprojectile2 ||
04282           (Ptarget-Qmomentum).e() < 0. || (Pprojectile+Qmomentum).e() < 0.);
04283   Pprojectile += Qmomentum;
04284   Ptarget     -= Qmomentum;
04285 #ifdef debug
04286   G4cout<<"G4QFragmentation::ExciteSingDiffParticipan: Proj(Q)="<<Pprojectile<<"(E="
04287         <<Pprojectile.e()<<"), Targ(Q)="<<Ptarget<<"(E="<<Ptarget.e()
04288         <<"), Proj(back)="<<toLab*Pprojectile<<", Targ(bac)="<< toLab*Ptarget << G4endl;
04289 #endif
04290   // Transform back and update SplitableHadron Participant.
04291   Pprojectile.transform(toLab);
04292   Ptarget.transform(toLab);
04293 #ifdef debug
04294   G4cout<< "G4QFragm::ExciteSingleDiffParticipants: TargetMass="<<Ptarget.mag()<<G4endl;
04295 #endif
04296   target->Set4Momentum(Ptarget);  
04297 #ifdef debug
04298   G4cout<<"G4QFragm::ExciteSingleParticipants:ProjectileMass="<<Pprojectile.mag()<<G4endl;
04299 #endif
04300   projectile->Set4Momentum(Pprojectile);
04301   return true;
04302 } // End of ExciteSingleDiffParticipants

G4QHadronVector * G4QFragmentation::Fragment (  ) 

Definition at line 1764 of file G4QFragmentation.cc.

References G4QEnvironment::AddQuasmon(), Breeder(), G4QNucleus::CoulombBarrier(), EvaporateResidual(), FatalException, G4QEnvironment::Fragment(), G4cerr, G4cout, G4endl, G4Exception(), G4UniformRand, G4Quasmon::Get4Momentum(), G4QHadron::Get4Momentum(), G4QNucleus::GetA(), G4QHadron::GetBaryonNumber(), G4QHadron::GetCharge(), G4QPDGCode::GetMass(), G4QNucleus::GetPDG(), G4QPDGCode::GetPDGCode(), G4QHadron::GetPDGCode(), G4QHadron::GetQC(), G4QNucleus::GetQCZNS(), G4QCHIPSWorld::GetQParticle(), G4QHadron::GetQPDG(), G4QChipolino::GetQPDG1(), G4QChipolino::GetQPDG2(), G4QContent::GetSPDGCode(), G4QNucleus::GetZ(), G4QParticle::MinMassOfFragm(), G4Quasmon::Set4Momentum(), G4QHadron::Set4Momentum(), G4QHadron::SetPDGCode(), G4QHadron::SetQC(), G4Quasmon::SetQC(), and G4QHadron::SetQPDG().

Referenced by G4QInelastic::PostStepDoIt().

01765 { // This is the member function fragmenting Strings & Quasmons (in nuclear matter)
01766   static const G4QPDGCode nQPDG(2112);
01767   static const G4double   mProt = G4QPDGCode(2212).GetMass(); // Mass of proton
01768   static const G4double   mNeut = G4QPDGCode(2112).GetMass(); // Mass of neutron
01769   static const G4double   mPiCh = G4QPDGCode(211).GetMass();  // Mass of chgdPion
01770   static const G4double   mPiZr = G4QPDGCode(111).GetMass();  // Mass of neutrPion
01771   //static const G4double   mHe3 = G4QPDGCode(2112).GetNuclMass(2,1,0);
01772   static const G4LorentzVector  nul4M(0.,0.,0.,0.);          // Zero (vacuum) 4M
01773   //static const G4double eps=0.003;
01774 #ifdef debug
01775   G4cout<<"*******>G4QFragmentation::Fragment: ***Called***, Res="<<theResult<<G4endl;
01776 #endif
01777   G4int striNum=strings.size();                             // Find out if there're strings
01778   G4int hadrNum=theResult->size();                          // Find out if there're hadrons
01779 #ifdef edebug
01780   G4int nQm=theQuasmons.size();
01781   G4LorentzVector totLS4M=theNucleus.Get4Momentum();        // Nucleus 4Mom in LS
01782   G4int totChg=theNucleus.GetZ();
01783   G4int totBaN=theNucleus.GetA();
01784   G4cout<<"-EMCLS-G4QF::Fragment: CHECKRecovery, #ofS="<<striNum<<", #Nuc4M(E=M)="<<totLS4M
01785         <<",#Q="<<nQm<<",#H="<<hadrNum<<G4endl;
01786   for(G4int i=0; i < striNum; i++)
01787   {
01788     G4LorentzVector strI4M=strings[i]->Get4Momentum();
01789     totLS4M+=strI4M;
01790     G4int sChg=strings[i]->GetCharge();
01791     totChg+=sChg;
01792     G4int sBaN=strings[i]->GetBaryonNumber();
01793     totBaN+=sBaN;
01794     G4cout<<"-EMCLS-G4QFragm::Fragment: String#"<<i<<", 4M="<<strI4M<<", M="<<strI4M.m()
01795           <<", C="<<sChg<<", B="<<sBaN<<G4endl;
01796   }
01797   for(G4int i=0; i < nQm; i++)
01798   {
01799     G4LorentzVector hI4M=theQuasmons[i]->Get4Momentum();
01800     totLS4M+=hI4M;
01801     G4int hChg=theQuasmons[i]->GetCharge();
01802     totChg+=hChg;
01803     G4int hBaN=theQuasmons[i]->GetBaryonNumber();
01804     totBaN+=hBaN;
01805     G4cout<<"-EMCLS-G4QFragmentation::Fragment: Quasmon#"<<i<<", 4M="<<hI4M<<", C="<<hChg
01806           <<", B="<<hBaN<<G4endl;
01807   }
01808   for(G4int i=0; i < hadrNum; i++)
01809   {
01810     G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
01811     totLS4M+=hI4M;
01812     G4int hChg=(*theResult)[i]->GetCharge();
01813     totChg+=hChg;
01814     G4int hBaN=(*theResult)[i]->GetBaryonNumber();
01815     totBaN+=hBaN;
01816     G4cout<<"-EMCLS-G4QFr::Fragment:H#"<<i<<",4M="<<hI4M<<",C="<<hChg<<",B="<<hBaN<<G4endl;
01817   }
01818 #endif
01819 #ifdef debug
01820   G4cout<<"***>G4QFragmentation::Fragment: #OfStr="<<striNum<<", #OfRes="<<hadrNum<<G4endl;
01821 #endif
01822   if(!striNum && hadrNum)                                   // Quasi-elastic or decoupled p
01823   {
01824 #ifdef debug
01825     G4cout<<"***>G4QFragmentation::Fragment:**Quasi-Elastic**,#OfResult="<<hadrNum<<G4endl;
01826 #endif
01827     return theResult;
01828   }
01829   else if(striNum) Breeder();                               // Strings fragmentation
01830   else                                                      // No strings, make HadrNucleus
01831   {
01832     if(hadrNum)
01833     {
01834       for(G4int ih=0; ih<hadrNum; ih++) delete (*theResult)[ih];
01835       theResult->clear();
01836     }
01837     G4LorentzVector r4M=theNucleus.Get4Momentum();          // Nucleus 4-momentum in LS
01838     G4int rPDG=theNucleus.GetPDG();                         // Nuclear PDG
01839     G4QHadron* resNuc = new G4QHadron(rPDG,r4M);            // Nucleus -> Hadron
01840     theResult->push_back(resNuc);                           // Fill the residual nucleus
01841   }
01842   G4int nQuas=theQuasmons.size();                           // Size of the Quasmon OUTPUT
01843   G4int theRS=theResult->size();                            // Size of Hadron Output by now
01844 #ifdef debug
01845   G4cout<<"***>G4QFragmentation::Fragment:beforeEnv,#OfQ="<<nQuas<<",#OfR="<<theRS<<G4endl;
01846 #endif
01847   if(nQuas && theRS)
01848   {
01849     G4QHadron* resNuc = (*theResult)[theRS-1];              // Pointer to Residual Nucleus
01850     G4LorentzVector resNuc4M = resNuc->Get4Momentum();      // 4-Momentum of the Nucleuz
01851     G4int           resNucPDG= resNuc->GetPDGCode();        // PDG Code of the Nucleus
01852     if(resNucPDG==90000000 || resNuc4M.m2()<800000.)        // m_N^2 = 880000 MeV^2
01853     {
01854       resNuc4M=G4LorentzVector(0.,0.,0.,0.);
01855       if(resNucPDG == 90000000) resNuc->Set4Momentum(resNuc4M);
01856     }
01857 #ifdef edebug
01858     G4int rnChg=resNuc->GetCharge();
01859     G4int rnBaN=resNuc->GetBaryonNumber();
01860 #endif
01861     G4QNucleus      theEnv(resNucPDG);                      // NucleusHadron->NucleusAtRest
01862     delete resNuc;                                          // Delete resNucleus as aHadron
01863     theResult->pop_back();                                  // Exclude the nucleus from HV
01864     --theRS;                                                // Reduce the OUTPUT by theNucl
01865 #ifdef debug
01866     G4cout<<"G4QFragmentation::Fragment:#OfRemainingHadron="<<theRS<<",A="<<theEnv<<G4endl;
01867 #endif
01868     // Now we need to be sure that the compound nucleus is heavier than the Ground State
01869     for(G4int j=theRS-1; j>-2; --j)                         // try to reach M_compound>M_GS
01870     {
01871       G4LorentzVector qsum4M=resNuc4M;                      // Proto compound 4-momentum
01872       G4QContent qsumQC=theEnv.GetQCZNS();                  // Proto compound Quark Content
01873 #ifdef debug
01874       G4cout<<"G4QFragmentation::Fragm:rN4M"<<qsum4M<<qsum4M.m()<<",rNQC="<<qsumQC<<G4endl;
01875 #endif
01876       G4Quasmon* firstQ=0;                                  // Prototype of theFirstQuasmon
01877       G4LorentzVector first4M;                              // Proto of the FirstQuasmon 4M
01878       G4QContent firstQC;                                   // Proto of the FirstQuasmon QC
01879       for(G4int i=0; i<nQuas; ++i)                          // LOOP over Quasmons
01880       {
01881         G4Quasmon* curQuasm=theQuasmons[i];                 // current Quasmon
01882         G4LorentzVector cur4M=curQuasm->Get4Momentum();     // 4-Mom of the Quasmon
01883         G4QContent curQC=curQuasm->GetQC();                 // Quark Content of the Quasmon
01884         qsum4M+=cur4M;                                      // Add quasmon's 4-momentum
01885         qsumQC+=curQC;                                      // Add quasmon's Quark Content
01886 #ifdef debug
01887         G4cout<<"G4QFr::Fr:Q#"<<i<<",Q4M="<<cur4M<<",QQC="<<curQC<<",sQC="<<qsumQC<<G4endl;
01888 #endif
01889         if(!i)                                              // Remember 1-st for correction
01890         {
01891           firstQ =curQuasm;
01892           first4M=cur4M;
01893           firstQC=curQC;
01894         }
01895       }
01896       G4int miPDG=qsumQC.GetSPDGCode();                     // PDG of minM of hadron/fragm.
01897       G4double gsM=0.;                                      // Proto minM of had/frag forQC
01898 #ifdef debug
01899       G4cout<<"G4QFragmentation::Fragment: QC="<<qsumQC<<",PDG="<<miPDG<<G4endl;
01900 #endif
01901       if(miPDG == 10)
01902       {
01903         G4QChipolino QCh(qsumQC);                           // define TotNuc as a Chipolino
01904         gsM=QCh.GetQPDG1().GetMass()+QCh.GetQPDG2().GetMass(); // Sum of Hadron Masses
01905         //gsM=theWorld->GetQParticle(QCh.GetQPDG1())->MinMassOfFragm() +
01906         //    theWorld->GetQParticle(QCh.GetQPDG2())->MinMassOfFragm();
01907       }
01908       // @@ it is not clear, why it does not work ?!
01909       //else if(miPDG>80000000)                             // Compound Nucleus
01910       //{
01911       //  G4QNucleus rtN(qsumQC);                           // CreatePseudoNucl for totComp
01912       //  gsM=rtN.GetGSMass();                              // MinMass of residQ+(Env-ParC)
01913       //}
01914       else if(miPDG < 80000000 && std::abs(miPDG)%10 > 2)
01915                            gsM=theWorld->GetQParticle(G4QPDGCode(miPDG))->MinMassOfFragm();
01916       else gsM=G4QPDGCode(miPDG).GetMass();                 // minM of hadron/fragm. for QC
01917       G4double reM=qsum4M.m();                              // real mass of the compound
01918 #ifdef debug
01919       G4cout<<"G4QFragmentation::Fragment: PDG="<<miPDG<<",rM="<<reM<<",GSM="<<gsM<<G4endl;
01920 #endif
01921       if(reM > gsM) break;                                  // CHIPS can be called
01922       if(j > -1)                                            // Can try to add hadrons to Q0
01923       {
01924         G4QHadron* cH = (*theResult)[j];                    // Pointer to the last Hadron
01925         G4LorentzVector h4M = cH->Get4Momentum();           // 4-Momentum of the Hadron
01926         G4QContent      hQC = cH->GetQC();                  // QC of the Hadron
01927         firstQ->Set4Momentum(first4M+h4M);                  // Update the Quasmon's 4-Mom
01928         firstQ->SetQC(firstQC+hQC);                         // Update the Quasmon's QCont
01929         delete cH;                                          // Delete the Hadron
01930         theResult->pop_back();                              // Exclude the hadron from HV
01931 #ifdef debug
01932         G4cout<<"G4QFragm::Fragm: H#"<<j<<",hQC="<<hQC<<",hPDG="<<cH->GetPDGCode()<<G4endl;
01933 #endif
01934       }
01935       else
01936       {
01937         G4cerr<<"*G4QFr::Fr:PDG="<<miPDG<<",M="<<reM<<",GSM="<<gsM<<",QC="<<qsumQC<<G4endl;
01938         G4Exception("G4QFragmentation::Fragment:","27",FatalException,"Can't recover GSM");
01939       }
01940     }
01941     G4double nucE=resNuc4M.e();                             // Total energy of the nuclEnv
01942     if(nucE < 1.E-12) nucE=0.;                              // Computer accuracy safety
01943     else if(resNucPDG==22 && nQuas==1)                      // NuclEnv for nQ=1 is a photon
01944     {
01945       G4Quasmon* aQuasm=theQuasmons[0];                     // the only Quasmon
01946       aQuasm->Set4Momentum(aQuasm->Get4Momentum()+resNuc4M);// add the gammaEnv to the Q
01947       nucE=0.;
01948     }
01949     G4ThreeVector   nucVel(0.,0.,0.);                       // Proto of the NucleusVelocity
01950     G4QHadronVector* output=0;                              // NucleusFragmentation Hadrons
01951     G4QEnvironment* pan= new G4QEnvironment(theEnv);        // ---> DELETED --->----------+
01952 #ifdef debug
01953     G4cout<<"G4QFragm::Fragm: nucE="<<nucE<<",nQ="<<nQuas<<G4endl; //                     |
01954 #endif
01955     if(nucE) nucVel=resNuc4M.vect()/nucE;                   // The NucleusVelocity        |
01956 #ifdef edebug
01957     G4LorentzVector sq4M=resNuc4M-totLS4M;                  // 4-mom deficit              |
01958     G4int           sqCg=rnChg-totChg;                      // Charge deficit             |
01959     G4int           sqBN=rnBaN-totBaN;                      // Baryon number deficit      |
01960 #endif
01961     for(G4int i=0; i<nQuas; ++i)                            // LOOP over Quasmons         |
01962     {                                                       //                            |
01963       G4Quasmon* curQuasm=theQuasmons[i];                   // current Quasmon            |
01964 #ifdef debug
01965       if(nucE) G4cout<<"G4QFr::Fr:V="<<nucVel<<",Q="<<curQuasm->Get4Momentum()<<",R=" //  |
01966                      <<resNuc4M<<resNucPDG<<G4endl;         //                            |
01967 #endif
01968       if(nucE) curQuasm->Boost(-nucVel);                    // Boost it to CMS of Nucleus |
01969       pan->AddQuasmon(curQuasm);                            // Fill the predefined Quasmon|
01970 #ifdef edebug
01971       G4LorentzVector cQ4M=curQuasm->Get4Momentum();        // Just for printing          |
01972       G4cout<<"G4QFragmentation::Fragment: Quasmon# "<<i<<" added, 4M="<<cQ4M<<G4endl; // |
01973       sq4M+=cQ4M;                                           // Sum up total 4Mom          |
01974       sqCg+=curQuasm->GetCharge();                          // Sum up the Charge          |
01975       sqBN+=curQuasm->GetBaryonNumber();                    // Sum up the baryon number   |
01976 #endif
01977     }                                                       //                            |
01978 #ifdef edebug
01979     G4cout<<"-EMCLS-G4QFrag::Fragm: r4M="<<sq4M<<", rC="<<sqCg<<", rB="<<sqBN<<G4endl; // |
01980 #endif
01981     try                                                     //                            |
01982     {                                                       //                            |
01983 #ifdef debug
01984     G4cout<<"G4QFrag::Fragm: *** Before Del Output ***"<<G4endl; //                       |
01985 #endif
01986       delete output;                                        //                            |
01987 #ifdef debug
01988     G4cout<<"G4QFrag::Fragm: *** After Del Output ***"<<G4endl; //                        |
01989 #endif
01990       output = pan->Fragment();// DESTROYED after theHadrons are transferred to theResult |
01991     }                                                       //                          | |
01992     catch (G4QException& error)                             //                          | |
01993     {                                                       //                          | |
01994       G4cerr<<"***G4QFragmentation::Fragment: G4QE Exception is catched"<<G4endl; //    | |
01995       // G4Exception("G4QFragmentation::Fragment:","27",FatalException,"CHIPSCrash");//    | |
01996       G4Exception("G4QFragmentation::Fragment()", "HAD_CHPS_0027",
01997                   FatalException, "CHIPSCrash");
01998     }                                                       //                          | |
01999 #ifdef debug
02000     G4cout<<"G4QFrag::Fragm: *** Before Del Pan ***"<<G4endl; //                        | |
02001 #endif
02002     delete pan;                              // Delete the Nuclear Environment <-----<--+-*
02003 #ifdef debug
02004     G4cout<<"G4QFrag::Fragm: *** After Del Pan ***"<<G4endl; //                         |
02005 #endif
02006     if(output)                               // Output exists                           |
02007     {                                        //                                         |
02008       G4int nOut=output->size();             // #ofHadrons in the Nuclear Fragmentation |
02009       for(G4int j=0; j<nOut; j++)            // LOOP over Hadrons transferring to LS    |
02010       {                                      //                                         |
02011         G4QHadron* curHadr=(*output)[j];     // Hadron from the nucleus fragmentation   |
02012         if(nucE) curHadr->Boost(nucVel);     // Boost it back to Laboratory System      |
02013         G4int hPDG=curHadr->GetPDGCode();    // PDGC of the hadron                      |
02014         G4LorentzVector h4M=curHadr->Get4Momentum(); // 4-mom of the hadron             |
02015         if((hPDG!=90000000 && hPDG!=22) || h4M!=nul4M) theResult->push_back(curHadr); //|
02016         else delete curHadr;                 // delete zero-photons                     |
02017       }                                      //                                         |
02018       delete output;                         // Delete the OUTPUT <-----<-----<-----<---+
02019     }
02020   }
02021   else if(!striNum) G4cout<<"-Warning-G4QFragmentation::Fragment:Nothing was done"<<G4endl;
02022 #ifdef debug
02023   G4cout<<"=--=>G4QFragmentation::Fragment: Final #OfResult="<<theResult->size()<<G4endl;
02024 #endif
02025   G4int nQ =theQuasmons.size();
02026   if(nQ) theQuasmons.clear();                              // @@ Not necesary ?
02027   G4int nHd=theResult->size();
02028 #ifdef edebug
02029   G4LorentzVector f4M(0.,0.,0.,0.);                        // Sum of the Result in LS
02030   G4int fCh=totChg;
02031   G4int fBN=totBaN;
02032   G4cout<<"-EMCLS-G4QFragmentation::Fragment: #ofHadr="<<nHd<<", #OfQuasm="<<nQ<<G4endl;
02033   for(G4int i=0; i<nHd; i++)
02034   {
02035     G4LorentzVector hI4M=(*theResult)[i]->Get4Momentum();
02036     f4M+=hI4M;
02037     G4int hChg=(*theResult)[i]->GetCharge();
02038     fCh-=hChg;
02039     G4int hBaN=(*theResult)[i]->GetBaryonNumber();
02040     fBN-=hBaN;
02041     G4cout<<"-EMCLS-G4QFragmentation::Fragment: Hadron#"<<i<<", 4M="<<hI4M<<", PDG="
02042           <<(*theResult)[i]->GetPDGCode()<<", C="<<hChg<<", B="<<hBaN<<G4endl;
02043   }
02044   G4cout<<"-EMCLS-G4QFrag::Fragm: r4M="<<f4M-totLS4M<<", rC="<<fCh<<", rB="<<fBN<<G4endl;
02045 #endif
02046   //G4QHadron* resNuc = theResult->back();              // Pointer to the Residual Nucleus
02047   G4QHadron* resNuc = (*theResult)[nHd-1];              // Pointer to the Residual Nucleus
02048   G4int rnBn = resNuc->GetBaryonNumber();
02049   G4int rnCg = resNuc->GetCharge();
02050   if(rnBn==1 && (rnCg==-2 || rnCg==3 || rnCg==-1 || rnCg==2)) // E/Delta decay
02051   {
02052     G4LorentzVector tot4M=resNuc->Get4Momentum();       // 4-mom to be split
02053     G4int nPDG=2212;                                    // Proton as a default
02054     G4int mPDG=211;                                     // PiPlus as a default
02055     G4double nM=mProt;                                  // Proton mass as a default
02056     if(rnCg<0)
02057     {
02058       nPDG=2112;
02059       mPDG=-211;
02060       nM=mNeut;
02061     }
02062     G4LorentzVector m14M(0.,0.,0.,mPiCh);
02063     G4LorentzVector n4M(0.,0.,0.,nM);
02064     if(rnCg==-2 || rnCg==3)                             // Decay In 3
02065     {
02066       G4LorentzVector m24M(0.,0.,0.,mPiCh);
02067       if(!G4QHadron(tot4M).DecayIn3(m14M,m24M,n4M))
02068       {
02069         G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> m1="<<mPiCh<<" + m2="<<mPiCh
02070               <<" + nM="<<nM<<" = "<<2*mPiCh+nM<<G4endl;
02071         G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecayIn3");
02072       }
02073       theResult->pop_back();
02074       delete resNuc;
02075       G4QHadron* m1H = new G4QHadron(mPDG,m14M);
02076       theResult->push_back(m1H);
02077 #ifdef debug
02078       G4cout<<"G4QFragment::Fragment:DecayIn3, M1="<<mPDG<<m14M<<G4endl;
02079 #endif
02080       G4QHadron* m2H = new G4QHadron(mPDG,m24M);
02081       theResult->push_back(m2H);
02082 #ifdef debug
02083       G4cout<<"G4QFragment::Fragment:DecayIn3, M2="<<mPDG<<m24M<<G4endl;
02084 #endif
02085       G4QHadron* nH = new G4QHadron(nPDG,n4M);
02086       theResult->push_back(nH);
02087 #ifdef debug
02088       G4cout<<"G4QFragment::Fragment:DecayIn3, Nucleon="<<nPDG<<n4M<<G4endl;
02089 #endif
02090     }
02091     else                                            // Decay in 2
02092     {
02093       if(!G4QHadron(tot4M).DecayIn2(m14M,n4M))
02094       {
02095         G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> m1="<<mPiCh
02096               <<" + nM="<<nM<<" = "<<mPiCh+nM<<G4endl;
02097         G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecayIn2");
02098       }
02099       theResult->pop_back();
02100       delete resNuc;
02101       G4QHadron* m1H = new G4QHadron(mPDG,m14M);
02102       theResult->push_back(m1H);
02103 #ifdef debug
02104       G4cout<<"G4QFragment::Fragment:DecayIn2, M1="<<mPDG<<m14M<<G4endl;
02105 #endif
02106       G4QHadron* nH = new G4QHadron(nPDG,n4M);
02107       theResult->push_back(nH);
02108 #ifdef debug
02109       G4cout<<"G4QFragment::Fragment:DecayIn2, Nucleon="<<nPDG<<n4M<<G4endl;
02110 #endif
02111     }
02112   }
02113   if(rnBn==2)                                       // Di-baryon
02114   {
02115     if(!rnCg)                                       // Di-neutron pair
02116     {
02117       G4LorentzVector tot4M=resNuc->Get4Momentum(); // 4-mom to be split
02118       G4LorentzVector n14M(0.,0.,0.,mNeut);
02119       G4LorentzVector n24M(0.,0.,0.,mNeut);
02120       if(!G4QHadron(tot4M).DecayIn2(n14M,n24M))
02121       {
02122         G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> n*2="<<2*mNeut<<G4endl;
02123         G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecay-2n");
02124       }
02125       theResult->pop_back();
02126       delete resNuc;
02127       G4QHadron* n1H = new G4QHadron(2112,n14M);
02128       theResult->push_back(n1H);
02129 #ifdef debug
02130       G4cout<<"G4QFragment::Fragment:DecayIn2, Neutron1="<<n14M<<G4endl;
02131 #endif
02132       G4QHadron* n2H = new G4QHadron(2112,n24M);
02133       theResult->push_back(n2H);
02134 #ifdef debug
02135       G4cout<<"G4QFragment::Fragment:DecayIn2, Neutron2="<<n24M<<G4endl;
02136 #endif
02137     }
02138     else if(rnCg==2)                                // Di-proton pair
02139     {
02140       G4LorentzVector tot4M=resNuc->Get4Momentum(); // 4-mom to be split
02141       G4LorentzVector n14M(0.,0.,0.,mProt);
02142       G4LorentzVector n24M(0.,0.,0.,mProt);
02143       if(!G4QHadron(tot4M).DecayIn2(n14M,n24M))
02144       {
02145         G4cerr<<"***G4QFrag::Frag: tM="<<tot4M.m()<<" -> n*2="<<2*mProt<<G4endl;
02146         G4Exception("G4QFragmentation::Breeder:","72",FatalException,"ImpossibleDecay-2p");
02147       }
02148       theResult->pop_back();
02149       delete resNuc;
02150       G4QHadron* n1H = new G4QHadron(2212,n14M);
02151       theResult->push_back(n1H);
02152 #ifdef debug
02153       G4cout<<"G4QFragment::Fragment:DecayIn2, Proton1="<<n14M<<G4endl;
02154 #endif
02155       G4QHadron* n2H = new G4QHadron(2212,n24M);
02156       theResult->push_back(n2H);
02157 #ifdef debug
02158       G4cout<<"G4QFragment::Fragment:DecayIn2, Proton2="<<n24M<<G4endl;
02159 #endif
02160     }
02161   } // End of the residual dibaryon decay
02162   // Now we should check and correct the final state dibaryons (NN-pairs) and 90000000->22
02163   nHd=theResult->size();
02164   G4int maxChg=0;                              // max Charge of the hadron found
02165 #ifdef debug
02166   G4int maxBN=0;                               // max Baryon Number of the hadron found
02167 #endif
02168   G4QContent maxQC(0,0,0,0,0,0);               // QC for maxChgH for particle UndCoulBar QC
02169   for(G4int i=0; i<nHd; ++i)
02170   {
02171     G4int found=0;
02172     G4QHadron* cHadr = (*theResult)[i];
02173     G4int hPDG= cHadr->GetPDGCode();
02174     if(hPDG==90000000 || hPDG==22)
02175     {
02176       G4QHadron* curHadr=(*theResult)[i];
02177       G4LorentzVector curh4M=curHadr->Get4Momentum();
02178       if     ( curh4M.e() > 0.) curHadr->SetPDGCode(22);
02179       else if( curh4M == nul4M) // Kill such a creature
02180       {
02181         G4QHadron* theLast = (*theResult)[nHd-1];
02182         if(theLast != curHadr) // Copy the Last to the current hadron
02183         {
02184           curHadr->Set4Momentum(theLast->Get4Momentum()); //4-Mom of CurHadr
02185           G4QPDGCode lQP=theLast->GetQPDG();
02186           if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP);
02187           else curHadr->SetQC(theLast->GetQC());
02188         }
02189         theResult->pop_back(); // theLastQHadron is excluded from OUTPUT
02190         --nHd;
02191         delete theLast;        //*!!When kill, delete theLastQHadr as an Instance!*
02192         if(i == nHd-1) break;  // @@ Why it was anyway break ??
02193       }
02194     }
02195     //else if(hPDG==2212 || hPDG==2112) // @@ Why this isotopic correction is necessary ?? 
02196     else if(2 > 3) // @@ The isotopic exchange (correction) is closed for acceleration
02197     {
02198       for(G4int j=i+1; j<nHd; ++j)
02199       {
02200         G4int pPDG=(*theResult)[j]->GetPDGCode();
02201         if(hPDG==pPDG)                       // The pp or nn pair is found
02202         {
02203           G4LorentzVector h4M=(*theResult)[i]->Get4Momentum();
02204           G4LorentzVector p4M=(*theResult)[j]->Get4Momentum();
02205           G4LorentzVector d4M=h4M+p4M;
02206           G4double E=d4M.m();                // Proto of tot CM energy (@@ was .mag() ??)
02207           if(hPDG==2212) E -= mProt+mProt;   // Reduction to tot kin energy in CM
02208           else           E -= mNeut+mNeut;
02209           if(E < 140. && G4UniformRand() < .6)// A close pair was found @@ Par 140. @@
02210           {
02211             G4int          piPDG= 211;       // Pi+ default for nn pairs
02212             if(hPDG==2212) piPDG=-211;       // Pi- for pp pairs
02213             for(G4int k=0; k<nHd; ++k)
02214             {
02215               G4int mPDG=(*theResult)[k]->GetPDGCode();
02216               // @@ if the isotopic exchange is made to increase Pi0, then only piPDG
02217               // @@ if the isotopic exchange is made to reduce Pi0, then only pi0
02218               if(mPDG==111 || mPDG==piPDG)   // Appropriate for correction pion is found
02219               {
02220                 G4LorentzVector m4M=(*theResult)[k]->Get4Momentum();// Must meson be close?
02221                 G4double mN=mProt;           // Final nucleon after charge exchange (nn)
02222                 G4int  nPDG=2212;            // Default for (nn)
02223                 G4int  tPDG=-211;            // Proto Pion after charge exchange from Pi0
02224                 if(hPDG==2212)               // (pp)
02225                 {
02226                   mN=mNeut;
02227                   nPDG=2112;
02228                   tPDG= 211;
02229                 }
02230                 G4double mPi=mPiZr;          // Pion after the charge exchange from Pi+/-
02231                 G4int   sPDG=111;
02232                 if(mPDG==111)
02233                 {
02234                   mPi=mPiCh;                 // Pion after the charge exchange from Pi0
02235                   sPDG=tPDG;
02236                 }
02237                 //G4cout<<"G4QFrag::Frag: H="<<hPDG<<", P="<<pPDG<<", M="<<mPDG<<", N="
02238                 //      <<nPDG<<", S="<<sPDG<<G4endl;
02239                 G4double D=mPi+mN;           // The same for both identical nucleons
02240                 G4LorentzVector t4M=m4M+h4M; // meson+ 1st nicleon
02241                 G4LorentzVector n4M=h4M;
02242                 G4double D2=D*D;
02243                 G4double S=t4M.m2();         //  (@@ was .mag2() ??)
02244                 if(S > D2)         found= 1; // 1st nucleon correction can be done
02245                 else                         // Try the 2nd nucleon
02246                 {
02247                   t4M=m4M+p4M;               // meson+ 1st nicleon
02248                   n4M=p4M;
02249                   S=t4M.m2();                //  (@@ was .mag2() ??)
02250                   if(S > D2)      found=-1;  // 2nd nucleon correction can be done
02251                 }
02252                 if(found)                    // Isotopic Correction
02253                 {
02254                   G4ThreeVector tV=t4M.vect()/t4M.e();
02255                   //G4cout<<"G4QFragment::Fragment: Before 4M/M2="<<m4M<<m4M.m2()<<G4endl;
02256                   m4M.boost(-tV);            // boost the meson to piN CM
02257                   //G4cout<<"G4QFragment::Fragment: After 4M/M2="<<m4M<<m4M.m2()<<G4endl;
02258                   n4M.boost(-tV);            // boost the nucleon to piN CM
02259                   G4double mPi2=mPi*mPi;
02260                   G4double mN2=mN*mN;
02261                   G4double C=S-mPi2-mN2;
02262                   G4double p2=(C*C/4.-mPi2*mN2)/S;
02263                   if(p2 < 0.) G4cout<<"-Warning-G4QFragment::Fragment: P2="<<p2<<G4endl;
02264                   G4double pc2=m4M.vect().mag2();
02265                   //G4double nc2=n4M.vect().mag2();
02266                   G4double r=1.;
02267                   if(pc2 < .00000000000001)
02268                           G4cout<<"-Warning-G4QFragment::Fragment: PC2="<<pc2<<m4M<<G4endl;
02269                   else r=std::sqrt(p2/pc2);
02270                   m4M.setV(r*m4M.vect());     // conservs the pion direction (not close!)
02271                   m4M.setE(std::sqrt(mPi2+p2));
02272                   //G4cout<<"G4QFragment::Fragment: Changed 4M/M2="<<m4M<<m4M.m2()<<", pc2="
02273                   //      <<pc2<<", nc2="<<nc2<<G4endl;
02274                   n4M.setV(r*n4M.vect());
02275                   n4M.setE(std::sqrt(mN2+p2));
02276                   m4M.boost(tV);               // Boost the meson back to the Lab system
02277                   n4M.boost(tV);               // Boost the nucleon back to the Lab system
02278                   (*theResult)[k]->SetPDGCode(sPDG);
02279                   (*theResult)[k]->Set4Momentum(m4M);
02280                   if(found > 0)                // Nucleon correction
02281                   {
02282                     (*theResult)[i]->SetPDGCode(nPDG);
02283                     (*theResult)[i]->Set4Momentum(n4M);
02284                   }
02285                   else
02286                   {
02287                     (*theResult)[j]->SetPDGCode(nPDG);
02288                     (*theResult)[j]->Set4Momentum(n4M);
02289                   }
02290                   break;                       // Break the pion LOOP
02291                 }
02292               }
02293             } // End of the pion LOOP
02294             if(found) break;                   // Break the nucleon partner LOOP
02295           } // End of Par 140. IF
02296         } // End of the identical nucleon IF
02297       } // End of the nucleon partner LOOP
02298     } // End of cur=nucleon IF (now closed)
02299     // Here we can find a hadron with the maximum charge = the residual nuclear environment
02300     G4int hChg=cHadr->GetCharge();
02301     if(hChg > maxChg)
02302     {
02303       maxChg = hChg;
02304       maxQC = cHadr->GetQC();
02305 #ifdef debug
02306       maxBN = cHadr->GetBaryonNumber();
02307 #endif
02308     }
02309   } // End of the primary hadron LOOP
02310   G4QNucleus ResNucEnv(maxQC); // vacuum if not found (check maxChg & maxBN when used)
02311 #ifdef debug
02312   G4cout<<"G4QFragmentation::Fra: ResNucEnv with A="<<maxBN<<", Z="<<maxChg<<G4endl;
02313 #endif
02314   // --- The photon && UCB suppressor ---
02315   G4LorentzVector sum(0.,0.,0.,0.);            // total 4-mom of the found gammas
02316   G4QContent sumQC(0,0,0,0,0,0);               // aquired positive particle UndCuBar QC
02317   G4int sumCount=0;                            // Counter of the found gammas
02318   G4int nHadr=theResult->size();               // #of hadrons in the output so far
02319   G4bool frag=false;                           // presence of fragments (A>1)
02320   if(nHadr>2) for(unsigned f=0; f<theResult->size(); f++) //Check that there's a fragment
02321   {
02322     G4int fBN=(*theResult)[f]->GetBaryonNumber(); // Baryon number of the fragment
02323 #ifdef debug
02324     G4int fPDG=(*theResult)[f]->GetPDGCode();  // PDG code of the possible fragment
02325     G4LorentzVector fLV=(*theResult)[f]->Get4Momentum(); // 4Mom of the possible fragment
02326     G4cout<<"G4QFragmentation::Fra:"<<f<<",PDG="<<fPDG<<",fBN="<<fBN<<",f4M="<<fLV<<G4endl;
02327 #endif
02328     if(fBN>1)                                  // At least one fragment (A>1) is found
02329     {
02330       frag=true;
02331       break;
02332     }
02333   }
02334 #ifdef debug
02335   G4cout<<"G4QFrag::Frag:=>Before Gamma Suppression<=, nH="<<nHadr<<",frag="<<frag<<G4endl;
02336 #endif
02337   if(nHadr>2 && frag) for(G4int h=nHadr-1; h>=0; h--)//Collect gammas & kill DecayedHadrons
02338   {
02339     G4QHadron* curHadr = (*theResult)[h];      // Get a pointer to the current Hadron
02340     G4int   hF = curHadr->GetNFragments();     // This is historic ... (was decayed flag)
02341     G4int hPDG = curHadr->GetPDGCode();        // PDG of the hadron
02342     G4LorentzVector h4M=curHadr->Get4Momentum();// 4Mom of the hadron
02343     if(hPDG==89999003||hPDG==90002999)G4cout<<"-Warning-G4QFr::Fr:nD-/pD++="<<hPDG<<G4endl;
02344 #ifdef debug
02345     G4cout<<"G4QFragmentation::Fragm: h#"<<h<<", hPDG="<<hPDG<<", hNFrag="<<hF<<G4endl;
02346 #endif
02347     G4int hChg = curHadr->GetCharge();         // Charge of the hadron
02348     G4bool UCB = false;                        // Not UCB yet
02349     if(hChg > 0 && hPDG!=321)                  // All positive but not K+
02350     {
02351       G4int hBN = curHadr->GetBaryonNumber();  // Baryon Number of the hadron
02352       G4double hCB=ResNucEnv.CoulombBarrier(hChg,hBN); // Coulomb barrier
02353       if(h4M.e()-h4M.m() < hCB) UCB = true;    // The hadron should be absorbed
02354     }
02355     if(hF || hPDG==22 || UCB)                  // Must be absorbed (decayed, photon, UCB)
02356     {
02357       G4int last=theResult->size()-1;
02358       G4QHadron* theLast = (*theResult)[last]; //Get Ptr to the Last Hadron
02359       if(hPDG==22 || UCB)                      // Absorb if this is gamma
02360       {
02361         sum+=h4M;                              // Add 4Mom of hadron to the "sum"
02362         sumCount++;
02363         if(UCB) sumQC+=curHadr->GetQC();       // Collect the absorbed QC
02364 #ifdef debug
02365         G4cout<<"G4QFragmentation::Frag: gam4M="<<h4M<<" is added to s4M="<<sum<<G4endl;
02366 #endif
02367       }
02368       nHadr = static_cast<G4int>(theResult->size())-1;
02369       if(h < last)                             // Need swap theCurHadron with the Last
02370       {
02371         curHadr->SetNFragments(0);
02372         curHadr->Set4Momentum(theLast->Get4Momentum());
02373         G4QPDGCode lQP=theLast->GetQPDG();     // The QPDG of the last
02374         if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
02375         else curHadr->SetQC(theLast->GetQC()); // CurHadrPDG instead of LastHadrPDG
02376 #ifdef debug
02377         G4cout<<"G4QFragmentation::Fragment: Exchange with the last is done"<<G4endl;
02378 #endif
02379       }
02380       theResult->pop_back();                   // theLastQHadron is excluded from theResult
02381       delete theLast;
02382 #ifdef debug
02383       G4cout<<"G4QFragmentation::Fragment: The last is compessed"<<G4endl;
02384 #endif
02385     }
02386   }
02387 #ifdef debug
02388   G4cout<<"G4QFragment::Frag: nH="<<nHadr<<"="<<theResult->size()<<", sum="<<sum<<G4endl;
02389 #endif
02390   if(nHadr > 1) for(unsigned hdr=0; hdr<theResult->size()-1; hdr++)//Ord:theBigestIsTheLast
02391   {
02392     G4QHadron* curHadr = (*theResult)[hdr];    // Get a pointer to the current Hadron
02393 #ifdef debug
02394     G4cout<<"G4QFrag::Frag: h#"<<hdr<<"<"<<nHadr<<", hPDG="<<curHadr->GetPDGCode()<<G4endl;
02395 #endif
02396     G4QHadron* theLast = (*theResult)[theResult->size()-1]; //Get Ptr to the Last Hadron
02397     G4int hB           = curHadr->GetBaryonNumber();
02398     G4int lB           = theLast->GetBaryonNumber();
02399 #ifdef debug
02400     G4cout<<"G4QFra::Fra:hBN="<<hB<<"<lBN="<<lB<<",lstPDG="<<theLast->GetPDGCode()<<G4endl;
02401 #endif
02402     if(lB < hB)                                // Must be swapped
02403     {
02404       G4QPDGCode   hQPDG = curHadr->GetQPDG();
02405       G4LorentzVector h4m= curHadr->Get4Momentum();
02406       curHadr->Set4Momentum(theLast->Get4Momentum());
02407       G4QPDGCode lQP=theLast->GetQPDG();       // The QPDG of the last
02408       if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
02409       else curHadr->SetQC(theLast->GetQC());   // CurHadrPDG instead of LastHadrPDG
02410       theLast->Set4Momentum(h4m);
02411       theLast->SetQPDG(hQPDG);
02412     }
02413   }
02414   nHadr=theResult->size(); // --> At this point the last hadron is the biggest nucleus
02415   if(sumCount)
02416   {
02417     G4QHadron* theLast = (*theResult)[nHadr-1];// Get a pointer to the Last Hadron
02418     G4int nucEnvBN=theLast->GetBaryonNumber(); // Initial A of residualNuclearEnvironment
02419     if ( nucEnvBN > 0 )                       // "Absorb phot/UCB & evaporate/decay" case
02420     {
02421       G4QHadron* theNew  = new G4QHadron(theLast); // Make New Hadron of the Last Hadron
02422 #ifdef debug
02423       G4cout<<"G4QFra::Fra:BeforeLastSub,n="<<nHadr<<",PDG="<<theNew->GetPDGCode()<<G4endl;
02424 #endif
02425       theResult->pop_back();                   // the last QHadron is excluded from OUTPUT
02426       delete theLast;//*!When kill,DON'T forget to delete theLastQHadron as an instance!*
02427       nHadr--;                                 // TheLastHadron only virtually exists now
02428       G4QContent newQC=theNew->GetQC();        // QContent of the fragment=ResNuclEnv
02429       G4LorentzVector new4M=theNew->Get4Momentum(); // 4-mom of the fragment=ResNuclEnv
02430 #ifdef debug
02431       G4cout<<"G4QFra::Fra:gSum4M="<<sum<<" is added to "<<new4M<<", QC="<<newQC<<G4endl;
02432 #endif
02433       G4LorentzVector exRes4M = new4M + sum;   //Icrease 4Mom of theLast by sum 4Mon
02434       G4QContent exResQC = newQC + sumQC;      //Icrease QCont of theLast by sumQC
02435       theNew->Set4Momentum(exRes4M);
02436       theNew->SetQC(exResQC);
02437 #ifdef debug
02438       G4cout<<"G4QFra::Fra:BeforeEvap, n="<<nHadr<<", nPDG="<<theNew->GetPDGCode()<<G4endl;
02439 #endif
02440       EvaporateResidual(theNew); // Try to evaporate theNucl. (del. equiv.)
02441       nHadr=theResult->size();
02442     } // End of "the last is the nucleus" case
02443     else G4cout<<"-Warning-G4QFragmentation::Fragment:RA="<<nucEnvBN<<",E/M cons?"<<G4endl;
02444   } // End of "There are gammas to suppress"
02445   // End of the Gamma Suppression
02446   return theResult;
02447 } // End of fragmentation

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

Definition at line 4333 of file G4QFragmentation.cc.

References G4cout, G4endl, G4UniformRand, and sqr().

Referenced by ExciteDiffParticipants(), and ExciteSingDiffParticipants().

04334 {
04335 #ifdef debug
04336   G4cout<<"G4QFragmentation::GaussianPt:width2="<<widthSq<<",maxPt2="<<maxPtSquare<<G4endl;
04337 #endif
04338   G4double pt2=0.;
04339   G4double rm=maxPtSquare/widthSq;                      // Negative
04340   if(rm>-.01) pt2=widthSq*(std::sqrt(1.-G4UniformRand()*(1.-sqr(1.+rm)))-1.);
04341   else        pt2=widthSq*std::log(1.-G4UniformRand()*(1.-std::exp(rm)));
04342   pt2=std::sqrt(pt2);                                   // It is not pt2, but pt now
04343   G4double phi=G4UniformRand()*twopi;
04344   return G4ThreeVector(pt2*std::cos(phi),pt2*std::sin(phi),0.);    
04345 } // End of GaussianPt

G4bool G4QFragmentation::IsSingleDiffractive (  )  [inline, protected]

Definition at line 77 of file G4QFragmentation.hh.

References G4UniformRand.

Referenced by G4QFragmentation().

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

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

Definition at line 4412 of file G4QFragmentation.cc.

References G4cout, and G4endl.

Referenced by Breeder().

04413 {
04414 #ifdef debug
04415   G4cout<<"G4QFragmentation::ReducePair: **Called** P1="<<P1<<", P2="<<P2<<G4endl;
04416 #endif
04417   G4int P11=P1/10;
04418   G4int P12=P1%10;
04419   G4int P21=P2/10;
04420   G4int P22=P2%10;
04421   if     (P11==P21) return std::make_pair(P12,P22);
04422   else if(P11==P22) return std::make_pair(P12,P21);
04423   else if(P12==P21) return std::make_pair(P11,P22);
04424   else if(P12==P22) return std::make_pair(P11,P21);
04425   //#ifdef debug
04426   G4cout<<"-Warning-G4QFragmentation::ReducePair:**Failed**, P1="<<P1<<", P2="<<P2<<G4endl;
04427   //#endif
04428   return std::make_pair(0,0);                         // Reduction failed
04429 }

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

Definition at line 4304 of file G4QFragmentation.cc.

04305 {
04306   nCutMax            = nC;             // max number of pomeron cuts
04307   stringTension      = stT;            // string tension for absorbed energy
04308   tubeDensity        = tbD;            // Flux Tube Density of nuclear nucleons
04309   widthOfPtSquare    = -2*SigPt*SigPt; // width^2 of pt for string excitation
04310 }

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

Definition at line 4347 of file G4QFragmentation.cc.

References FatalException, G4cerr, G4endl, and G4Exception().

Referenced by Breeder().

04348 {
04349   if      (PDG1 < 7 && PDG1 > 0 && PDG2 < 7 && PDG2 > 0) // Sum up two Q in DiQ (S=0)
04350   {
04351     if(PDG1 > PDG2) return PDG1*1000+PDG2*100+1;
04352     else            return PDG2*1000+PDG1*100+1;
04353   }
04354   else if (PDG1 >-7 && PDG1 < 0 && PDG2 >-7 && PDG2 < 0) // Sum up two AQ in ADiQ (S=0)
04355   {
04356     if(-PDG1 > -PDG2) return PDG1*1000+PDG2*100-1;
04357     else              return PDG2*1000+PDG1*100-1;
04358   }
04359   else if (PDG1 <-99 && PDG2 < 7 && PDG2 > 0) // Sum up Q and ADiQ in AQ
04360   {
04361     G4int PDG=-PDG1/100;
04362     if(PDG2==PDG/10) return -PDG%10;
04363     if(PDG2==PDG%10) return -PDG/10;
04364     else
04365     {
04366       G4cerr<<"***4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
04367       G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"Q&ADiQ notMatch");
04368     }
04369   }
04370   else if (PDG2 <-99 && PDG1 < 7 && PDG1 > 0) // Sum up ADiQ and Q in AQ
04371   {
04372     G4int PDG=-PDG2/100;
04373     if(PDG1==PDG/10) return -PDG%10;
04374     if(PDG1==PDG%10) return -PDG/10;
04375     else
04376     {
04377       G4cerr<<"***4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
04378       G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"ADiQ&Q notMatch");
04379     }
04380   }
04381   else if (PDG1 > 99 && PDG2 >-7 && PDG2 < 0) // Sum up DiQ and AQ in Q
04382   {
04383     G4int PDG=PDG1/100;
04384     if(PDG2==-PDG/10) return PDG%10;
04385     if(PDG2==-PDG%10) return PDG/10;
04386     else
04387     {
04388       G4cerr<<"***4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
04389       G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"DiQ&AQ notMatch");
04390     }
04391   }
04392   else if (PDG2 > 99 && PDG1 >-7 && PDG1 < 0) // Sum up AQ and DiQ in Q
04393   {
04394     G4int PDG=PDG2/100;
04395     if(PDG1==-PDG/10) return PDG%10;
04396     if(PDG1==-PDG%10) return PDG/10;
04397     else
04398     {
04399       G4cerr<<"***G4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
04400       G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"AQ&DiQ notMatch");
04401     }
04402   }
04403   else
04404   {
04405     G4cerr<<"***G4QFragmentation::SumPartonPDG: PDG1="<<PDG1<<", PDG2="<<PDG2<<G4endl;
04406     G4Exception("G4QFragmentation::SumPartonPDG:","72",FatalException,"Can'tSumUpPartons");
04407   }
04408   return 0;
04409 } // End of SumPartonPDG

void G4QFragmentation::SwapPartons (  )  [protected]

Definition at line 4664 of file G4QFragmentation.cc.

References DBL_MAX, G4cout, G4endl, G4QParton::Get4Momentum(), G4QParton::GetPDGCode(), G4QParton::GetType(), LE, and G4QParton::Set4Momentum().

Referenced by G4QFragmentation().

04665 {
04666   static const G4double baryM=800.;                  // Mass excess for baryons
04667   G4QStringVector::iterator ist;
04668   for(ist = strings.begin(); ist < strings.end(); ist++)
04669   {
04670     G4QParton* cLeft=(*ist)->GetLeftParton();        // Current String Left Parton 
04671     G4QParton* cRight=(*ist)->GetRightParton();      // Current String Right Parton 
04672     G4LorentzVector cL4M=cLeft->Get4Momentum();
04673     G4LorentzVector cR4M=cRight->Get4Momentum();
04674     G4LorentzVector cS4M=cL4M+cR4M;
04675     G4double cSM2=cS4M.m2();                         // Squared mass of the String
04676     if(std::fabs(cSM2)<.01)                          // Small correction
04677     {
04678       G4double dM2=.001-cSM2;
04679       G4double E=cS4M.e();
04680       G4double dE=std::sqrt(E*E+dM2)-E;
04681       G4double LE=cL4M.e();
04682       G4double RE=cR4M.e();
04683       if(LE<RE) cLeft->Set4Momentum( G4LorentzVector(LE+dE) );
04684       else      cRight->Set4Momentum( G4LorentzVector(RE+dE) );
04685       cSM2=.001;                                     // Correction
04686     }
04687     if(cSM2<0.011)                                   // Parton Swapping is needed
04688     {
04689       G4int cLPDG=cLeft->GetPDGCode();
04690       G4int cRPDG=cRight->GetPDGCode();
04691       G4int cLT=cLeft->GetType();
04692       G4int cRT=cRight->GetType();
04693       G4QStringVector::iterator sst;                 // Selected partner string
04694       G4QStringVector::iterator pst;                 // LOOP iterator
04695       G4double maxM=-DBL_MAX;                        // Swapping providing the max mass
04696       G4int    sDir=0;                               // Selected direction of swapping
04697 #ifdef debug
04698       G4cout<<"G4QFragmentation::SwapPartons: M2=="<<cSM2<<", 4M="<<cS4M<<",LPDG="<<cLPDG
04699             <<",RPDG="<<cRPDG<<G4endl;
04700 #endif
04701       for(pst = strings.begin(); pst < strings.end(); pst++) if(pst != ist)
04702       {
04703         G4QParton* pLeft=(*pst)->GetLeftParton();    // Partner String Left Parton 
04704         G4QParton* pRight=(*pst)->GetRightParton();  // Partner String Right Parton 
04705         G4int pLPDG=pLeft->GetPDGCode();
04706         G4int pRPDG=pRight->GetPDGCode();
04707         G4LorentzVector pL4M=pLeft->Get4Momentum();
04708         G4LorentzVector pR4M=pRight->Get4Momentum();
04709         G4int pLT=pLeft->GetType();
04710         G4int pRT=pRight->GetType();
04711 #ifdef debug
04712         G4cout<<"G4QFragmentation::SwapPartons: p4M="<<cS4M<<",pM2="<<cS4M.m2()<<",LPDG="
04713               <<pLPDG<<",RPDG="<<pRPDG<<G4endl;
04714 #endif
04715         G4double LM=0.;
04716         G4double RM=0.;
04717         if(((cLPDG<-7 || (cLPDG>0 && cLPDG< 7) ) && (pLPDG<-7 || (pLPDG>0 && pLPDG< 7) ))||
04718            ((cLPDG> 7 || (cLPDG<0 && cLPDG>-7) ) && (pLPDG> 7 || (pLPDG<0 && cLPDG>-7) )))
04719         {
04720           G4double pLM2=(cL4M+pR4M).m2();                      // new partner M2
04721           G4double cLM2=(cR4M+pL4M).m2();                      // new partner M2
04722           if(pLM2>0. && cLM2>0.)
04723           {
04724             G4double pLM=std::sqrt(pLM2);
04725             if(cLT+pRT==3) pLM-=baryM;
04726             G4double cLM=std::sqrt(cLM2);
04727             if(cRT+pLT==3) cLM-=baryM;
04728             LM=std::min(pLM2,cLM2);
04729           }
04730         }
04731         if(((cRPDG<-7 || (cRPDG>0 && cRPDG< 7) ) && (pRPDG<-7 || (pRPDG>0 && pRPDG< 7) ))||
04732            ((cRPDG> 7 || (cRPDG<0 && cRPDG>-7) ) && (pRPDG> 7 || (pRPDG<0 && cRPDG>-7) )) )
04733         {
04734           G4double pRM2=(cR4M+pL4M).m2();                      // new partner M2
04735           G4double cRM2=(cL4M+pR4M).m2();                      // new partner M2
04736           if(pRM2>0. && cRM2>0.)
04737           {
04738             G4double pRM=std::sqrt(pRM2);
04739             if(cRT+pLT==3) pRM-=baryM;
04740             G4double cRM=std::sqrt(cRM2);
04741             if(cLT+pRT==3) cRM-=baryM;
04742             RM=std::min(pRM,cRM);
04743           }
04744         }
04745         G4int dir=0;
04746         G4double sM=0.;
04747         if( LM && LM > RM )
04748         {
04749           dir= 1;
04750           sM=LM;
04751         }
04752         else if(RM)
04753         {
04754           dir=-1;
04755           sM=RM;
04756         }
04757         if(sM > maxM)
04758         {
04759           sst=pst;
04760           maxM=sM;
04761           sDir=dir;
04762         }
04763       }
04764       if(sDir)
04765       {
04766         G4QParton* pLeft=(*sst)->GetLeftParton();    // Partner String Left Parton 
04767         G4QParton* pRight=(*sst)->GetRightParton();  // Partner String Right Parton 
04768         G4QParton* swap=pLeft;                       // Prototype remember the partner Left
04769         if(sDir>0)                                   // swap left partons
04770         {
04771           (*sst)->SetLeftParton(cLeft);
04772           (*ist)->SetLeftParton(swap);
04773         }
04774         else
04775         {
04776           swap=pRight;
04777           (*sst)->SetRightParton(cRight);
04778           (*ist)->SetRightParton(swap);
04779         }
04780       }
04781 #ifdef debug
04782       else G4cout<<"***G4QFragmentation::SwapPartons:**Failed**,cLPDG="<<cLPDG<<",cRPDG="
04783                  <<cRPDG<<",-->cM2="<<cSM2<<G4endl;
04784 #endif
04785     }
04786   }
04787 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:07 2013 for Geant4 by  doxygen 1.4.7