G4QEnvironment.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //       1         2         3         4         5         6         7         
00027 //34567890123456789012345678901234567890123456789012345678901234567890123456789
00028 //
00029 //
00030 // $Id$
00031 //
00032 //      ---------------- G4QEnvironment ----------------
00033 //             by Mikhail Kossov, August 2000.
00034 //  class for Multy Quasmon Environment used by the CHIPS Model
00035 // ------------------------------------------------------------
00036 // Short description: The G4QEnvironment class corresponds to the nuclear
00037 // environment,  containing excited nucleons or nuclear clusters
00038 // (G4Quasmons). In the constructer the nucleus (G4QNucleus) is clusterized
00039 // and then the projectile hadron (or hadrons) can create one (or a few)
00040 // Quasmons, which are fragmented by the Fragment member function. As a
00041 // result a vector of G4QHadrons is created, which can include the residual
00042 // nucleus in the ground state.
00043 //---------------------------------------------------------------------
00044  
00045 //#define debug
00046 //#define pdebug
00047 //#define qdebug
00048 //#define chdebug
00049 //#define sdebug
00050 //#define ppdebug
00051 //#define cdebug
00052 //#define cldebug
00053 //#define edebug
00054 //#define rdebug
00055 //#define fdebug
00056 //#define ffdebug
00057 //#define pcdebug
00058 //#define mudebug
00059 
00060 #include <cmath>
00061 #include <cstdlib>
00062 
00063 #include "G4QEnvironment.hh"
00064 #include "G4PhysicalConstants.hh"
00065 #include "G4SystemOfUnits.hh"
00066 
00067 using namespace std;
00068 
00069 G4QEnvironment::G4QEnvironment(const G4QNucleus& theEnv)
00070  : theEnvironment(theEnv)
00071 {
00072   theQFScat = G4QFreeScattering::GetPointer();
00073   G4int envPDG = theEnv.GetPDG();
00074   G4QPDGCode envQPDG(envPDG);
00075   G4int envA = envQPDG.GetBaryNum();
00076   G4double envM = envQPDG.GetMass();
00077   theWorld = 0;
00078   nBarClust = 0;
00079   f2all = 0;
00080   totCharge = envQPDG.GetCharge();
00081   totBaryoN = envA;
00082   tot4Mom = G4LorentzVector(0.,0.,0.,envM);
00083   theTargetPDG = 0;
00084 #ifdef debug
00085   G4cout << "G4QEnviron::Const: t4M=" << tot4Mom << ",tC=" << totCharge
00086          << ",tB=" << totBaryoN << G4endl;
00087 #endif
00088 }
00089 
00090 
00091 G4QEnvironment::G4QEnvironment(const G4QHadronVector& projHadrons,
00092                                const G4int targPDG)
00093  : theEnvironment(90000000)     // User is responsible for projHadrons(Vector)
00094 {
00095   //static const G4double mNeut= G4QPDGCode(2112).GetMass();
00096   //static const G4QContent neutQC(2,1,0,0,0,0);
00097   static const G4QPDGCode pimQPDG(-211);
00098   theQFScat = G4QFreeScattering::GetPointer();
00099   theWorld = G4QCHIPSWorld::Get();        // Get a pointer to the CHIPS World
00100   nBarClust = 0;
00101   totCharge = 0;
00102   totBaryoN = 0;
00103   f2all = 0;
00104   G4bool fake=false;                      // At present only fake pi-
00105   theTargetPDG=targPDG;                   // Remenber it for error message
00106   G4int nHadrons=projHadrons.size();      // A#of hadrons in the input Vector
00107 
00108 #ifdef debug
00109   G4cout<<"--->>G4QE::Const: Called targPDG="<<targPDG<<", nInpHadr="<<nHadrons<<G4endl;
00110 #endif
00111   if(nHadrons<1 || targPDG==90000000)    // No projectile Hadrons or no target Nucleus
00112   {
00113     G4cout << "---Warning---G4QEnv::Const:a#ofINPHadr=" << nHadrons
00114            << ",tPDG=" << targPDG << G4endl;
00115     //throw G4QException("***G4QEnvironment: There is no one projectile or vacuum target");
00116     if(nHadrons)              // The projectiles are copied to the output
00117     {
00118       for (G4int ih=0; ih<nHadrons; ih++)
00119       {
00120         G4QHadron* curQH    = new G4QHadron(projHadrons[ih]);
00121 #ifdef debug
00122         G4cout << "*G4QE::Const:iH#" << ih << "," << curQH->GetQC()
00123                << curQH->Get4Momentum() << G4endl;
00124 #endif
00125 
00126         if (curQH->GetPDGCode() == 10) {
00127           // Chipolino is found in the input -> Decay
00128 
00129           G4QContent   chQC=curQH->GetQC();
00130           // Quark content of the Hadron-Chipolino
00131           G4QChipolino QCh(chQC);
00132           // Define a Chipolino instance for the Hadron
00133 
00134           G4LorentzVector ch4M=curQH->Get4Momentum(); // 4Mom of the Hadron-Chipolino
00135           G4QPDGCode h1QPDG=QCh.GetQPDG1();  // QPDG of the first hadron
00136           G4double   h1M   =h1QPDG.GetMass();// Mass of the first hadron
00137           G4QPDGCode h2QPDG=QCh.GetQPDG2();  // QPDG of the second hadron
00138           G4double   h2M   =h2QPDG.GetMass();// Mass of the second hadron
00139           G4double   chM2  =ch4M.m2();       // Squared Mass of the Chipolino
00140           if( sqr(h1M+h2M) < chM2 )          // Decay is possible
00141           {
00142             G4LorentzVector h14M(0.,0.,0.,h1M);
00143             G4LorentzVector h24M(0.,0.,0.,h2M);
00144             if(!G4QHadron(ch4M).DecayIn2(h14M,h24M))
00145             {
00146               G4ExceptionDescription ed;
00147               ed << "QChip DecIn2 error: CM=" << std::sqrt(chM2) << " -> h1="
00148                  << h1QPDG << "(" << h1M << ") + h2=" << h1QPDG << "(" << h2M
00149                  << ") = " << h1M+h2M << " **Failed**" << G4endl;
00150               G4Exception("G4QEnvironment::G4QEnvironment()", "HAD_CHPS_0000",
00151                           FatalException, ed);
00152             }
00153             delete curQH;                    // Kill the primary Chipolino
00154             G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
00155             theQHadrons.push_back(h1H);      // (delete equivalent)
00156             curQH    = new G4QHadron(h1H);   // ... just to remember independently
00157             theProjectiles.push_back(curQH); // Remember it for the error message
00158 
00159 #ifdef debug
00160             G4cout<<"G4QE::Constr: QChipolino -> H1="<<h1QPDG<<h14M<<G4endl;
00161 #endif
00162             curQH = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
00163             theQHadrons.push_back(curQH);    // (delete equivalent)
00164 #ifdef debug
00165             G4cout<<"G4QE::Constr: QChipolino -> H2="<<h2QPDG<<h24M<<G4endl;
00166 #endif
00167           }
00168           else
00169           {
00170             G4ExceptionDescription ed;
00171             ed << "LowMassChipolino in Input: " << ih << "," << curQH->GetQC()
00172                << curQH->Get4Momentum() << ", chipoM=" << std::sqrt(chM2) << " < m1="
00173                << h1M << "(" << h1QPDG << ") + m2=" << h2M << "(" << h2QPDG << ") = "
00174                << h1M+h2M << G4endl;
00175             G4Exception("G4QEnvironment::G4QEnvironment()", "HAD_CHPS_0001",
00176                         FatalException, ed);
00177           }
00178         }
00179         theQHadrons.push_back(curQH);        // (delete equivalent)
00180         curQH    = new G4QHadron(curQH);     // ... just to remember independently
00181         theProjectiles.push_back(curQH);     // Remenber it for the error message
00182       }
00183     }
00184     else if(targPDG!=90000000)               // No projHadrons,fill targetNucleus to output
00185     {
00186       G4QHadron* curQH    = new G4QHadron(targPDG);
00187 #ifdef debug
00188       G4cout<<"**G4QE::Const:No iHad,eH="<<curQH->GetQC()<<curQH->Get4Momentum()<<G4endl;
00189 #endif
00190       theQHadrons.push_back(curQH);          // (delete equivalent)
00191     }
00192     if (nHadrons<0) G4cout<<"***Warning****G4QE::Const:NH="<<nHadrons<<" < 0 !"<<G4endl;
00193     return;
00194   }
00195   G4QPDGCode targQPDG(targPDG);
00196 #ifdef debug
00197   G4cout<<"G4QE::C:targQPDG="<<targQPDG<<G4endl;
00198 #endif
00199   G4int    targA=targQPDG.GetBaryNum();
00200   G4double targM=targQPDG.GetMass();
00201   totCharge=targQPDG.GetCharge();
00202   totBaryoN=targA;
00203   tot4Mom=G4LorentzVector(0.,0.,0.,targM);
00204   // === Print out of the input information at Creation time & tot 4-mom Calculation ===
00205 #ifdef debug
00206   G4cout<<"G4QE::C:PDG="<<targPDG<<",C="<<totCharge<<",M="<<targM<<",n="<<nHadrons<<G4endl;
00207 #endif
00208   for(G4int ipr=0; ipr<nHadrons; ipr++)// LOOP is used for the tot4Mom calc. & for printing
00209   {
00210     G4QHadron* prHadr = projHadrons[ipr];
00211     G4QHadron* curQH  = new G4QHadron(prHadr);// Remenber it for _
00212     theProjectiles.push_back(curQH);          // the error message
00213     G4LorentzVector h4Mom = prHadr->Get4Momentum();
00214     tot4Mom      += h4Mom;
00215     totCharge    += prHadr->GetCharge();
00216     totBaryoN    += prHadr->GetBaryonNumber();
00217 #ifdef debug
00218     G4int           hPDG  = prHadr->GetPDGCode();
00219     G4int           hNFrag= prHadr->GetNFragments();
00220     G4QContent      hQC   = prHadr->GetQC();
00221     G4cout<<"G4QE::C:#"<<ipr<<",PDG="<<hPDG<<hQC<<",4M="<<h4Mom<<",hNFr="<<hNFrag<<G4endl;
00222 #endif
00223   }
00224 #ifdef debug
00225   G4cout<<"G4QEnv::Const:tC="<<totCharge<<",tB="<<totBaryoN<<",tot4M="<<tot4Mom<<G4endl;
00226 #endif
00227 #ifdef debug
00228   G4cout<<"G4QEnv::Const: --> tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;
00229 #endif
00230   G4int nP=theWorld->GetQPEntries();         // A#of init'ed particles in CHIPS World
00231   //G4int nCl=nP-90;                           // A#of init'ed clusters in CHIPS World
00232   G4int nCl=nP-53;           // @@ A#ofClusters in CHIPSWorld (53=nQHM in G4QPDGCode.hh)
00233 #ifdef debug
00234   G4cout<<"G4QEnv:Const:Before NCI:n="<<nP<<",F="<<projHadrons[0]->GetNFragments()<<",tC="
00235         <<totCharge<<",tB="<<totBaryoN<<", nCl="<<nCl<<G4endl;
00236 #endif
00237   InitClustersVector(nCl,targA);             // Init Clusters as Particles (to interact)
00238 #ifdef debug
00239   G4cout<<"G4QEnv::Const:NucClust,n="<<nCl<<",F="<<projHadrons[0]->GetNFragments()<<",tC="
00240         <<totCharge<<",tB="<<totBaryoN<<G4endl;
00241 #endif
00242   if(targPDG>80000000)                        // ==> Nuclear target (including NUCPDG)
00243   {
00244     theEnvironment.InitByPDG(targPDG);        // Create nuclear environment
00245 #ifdef debug
00246     G4cout<<"G4QEnv::Const:nH="<<nHadrons<<",PDG="<<projHadrons[0]->GetPDGCode()<<",tC="
00247           <<totCharge<<",tB="<<totBaryoN<<G4endl;
00248 #endif
00249     if(nHadrons==1)
00250     {
00251       G4QHadron* opHad=projHadrons[0];
00252       G4int opPDG=opHad->GetPDGCode();
00253 #ifdef debug
00254       G4cout<<"G4QEnviron::Constructor: *** Only one input hadron*** PDG="<<opPDG<<G4endl;
00255 #endif
00256       if(opPDG==22)                           // *** Check photon's NuclearSplitThreshold
00257       {
00258         G4double exMass=tot4Mom.m();
00259 #ifdef debug
00260         G4cout<<"G4QEnvironment::Const: exM="<<exMass-targM<<" > mPi0 ?"<<G4endl;
00261 #endif      
00262         if(exMass<targM+135.977) // Nucleus is below the pion production threshold
00263         {
00264           G4QNucleus exEnviron(tot4Mom,targPDG);
00265           // @@ One can put here the pbpt= (M.K.) @@ What about d,t,alpha splitting?
00266           if(targM>999.&&!exEnviron.SplitBaryon())//Nucleus is below SplitFragmentThreshold
00267           {
00268 #ifdef debug
00269             G4cout<<"G4QEnv::Const:Photon's added to Output, Env="<<theEnvironment<<G4endl;
00270 #endif      
00271             G4QHadron* photon = new G4QHadron(opHad); // Fill projPhoton to Output
00272 #ifdef debug
00273             G4cout<<"**G4QE::Const:Phot="<<photon->GetQC()<<photon->Get4Momentum()<<G4endl;
00274 #endif
00275             theQHadrons.push_back(photon);      // (delete equivalent)
00276             return;
00277           }
00278           else if(targM<=999.)                  // Target is a nucleon
00279           {
00280             G4LorentzVector prot4m(0.,0.,0.,targM); // Prototype of secondary proton 4mom
00281             G4LorentzVector gam4m(0.,0.,0.,0.);     // Prototype for secondary gamma 4mom
00282             if(!G4QHadron(tot4Mom).DecayIn2(prot4m,gam4m))
00283             {
00284 #ifdef debug
00285               G4cout<<"*War*G4QEnv::Const:(P)Photon->Output, Env="<<theEnvironment<<G4endl;
00286 #endif      
00287               G4QHadron* photon = new G4QHadron(opHad); // Fill projPhoton to Output
00288 #ifdef debug
00289               G4cout<<"**G4QE::Const:Ph="<<photon->GetQC()<<photon->Get4Momentum()<<G4endl;
00290 #endif
00291               theQHadrons.push_back(photon);    // (delete equivalent)
00292               return;
00293             }
00294             G4QHadron* proton = new G4QHadron(targPDG,prot4m); // Fill tgProton to Output
00295             theQHadrons.push_back(proton);      // (delete equivalent)
00296             G4QHadron* photon = new G4QHadron(22,gam4m);       // Fill prPhoton to Output
00297             theQHadrons.push_back(photon);      // (delete equivalent)
00298             theEnvironment.InitByPDG(90000000); // Create nuclear environment
00299 #ifdef debug
00300             G4cout<<"G4QEnv::Const:Fill gamma and N from gam+N"<<targPDG<<prot4m<<G4endl;
00301 #endif      
00302             return;
00303           }
00304         }
00305       }
00306       else if(opPDG==13 || opPDG==15)
00307       {
00308         G4int         nuPDG=14;
00309         if(opPDG==15) nuPDG=16;
00310         G4LorentzVector mu4m=opHad->Get4Momentum();
00311         //G4double qpen=-180.*log(G4UniformRand()); // Energy of target-quark-parton(T=180)
00312         G4double qpen=465.*sqrt(sqrt(G4UniformRand())); // UniformDistr for 3-q nucleon
00313         G4double qpct=2*G4UniformRand()-1.;         // Cos(thet) of target-quark-parton
00314         G4double qpst=sqrt(1.-qpct*qpct);           // Sin(theta) of target-quark-parton
00315         G4double qppt=qpen*qpst;                    // PT of target-quark-parton
00316         G4double qphi=twopi*G4UniformRand();        // Phi of target-quark-parton
00317         G4LorentzVector qi4m(qppt*sin(qphi),qppt*cos(qphi),qpen*qpct,qpen); // quark-parton
00318         G4LorentzVector qt4m=mu4m+qi4m;             // Total 4mom (iniQP+lepton)
00319         G4LorentzVector nu4m(0.,0.,0.,0.);          // Prototype of secondary neutrino 4mom
00320         G4LorentzVector qf4m(0.,0.,0.,0.);          // Prototype for secondary quark-parton
00321         G4QContent targQC=targQPDG.GetQuarkContent(); // QC of the target nucleus (local!)
00322         targQC+=G4QContent(1,0,0,0,1,0);      // Make iso-shift with fake pi- is added
00323         G4LorentzVector fn4m=G4LorentzVector(0.,0.,0.,0.); // Prototype of the residual 4M
00324         G4QNucleus fnN(targQC,fn4m);          // Define the final state nucleus
00325         G4double   fnm=fnN.GetMZNS();         // GS Mass of the final state nucleus
00326         //G4QContent resiQC=targQC-neutQC; // QC of resid nucleus (-neutron)
00327         //G4QNucleus rsN(resiQC,fn4m);          // Define the final state nucleus
00328         //G4double   rsm=rsN.GetMZNS()+mNeut;   // GS Mass of residual nucleus w/o neutron
00329         G4double   tm=0.;                     // Prototype of RealMass of the final nucleus
00330         G4LorentzVector tg4m=G4LorentzVector(0.,0.,0.,targM); // 4mom of all target nucleus
00331         G4LorentzVector fd4m=tg4m-qi4m;       // 4mom of the residual coloured nuclear sys.
00332 #ifdef debug
00333         //G4cout<<"-->>G4QEnv::Const:rM="<<rsm<<",fM="<<fnm<<",tM="<<targM<<G4endl;
00334         G4cout<<"G4QEnvironment::Const:mu4M="<<mu4m<<",t4M="<<qt4m<<",tgQP="<<qi4m<<G4endl;
00335 #endif      
00336         while (tm<=fnm)
00337         {
00338           if(!G4QHadron(qt4m).DecayIn2(nu4m,qf4m))
00339           {
00340             G4cout<<"***G4QE::Constr:Muon error (1) 4M="<<mu4m<<". Fill as it is."<<G4endl;
00341             G4QHadron* lepton = new G4QHadron(opHad); // Fill projMuon to Output
00342             theQHadrons.push_back(lepton);        // (delete equivalent)
00343             return;
00344           }
00345 #ifdef mudebug
00346           G4cout<<"G4QEnv::Const:i="<<qi4m<<",t="<<qt4m<<"->n="<<nu4m<<"+q="<<qf4m<<G4endl;
00347 #endif
00348           fn4m=fd4m+qf4m;
00349           tm=fn4m.m();                 // Real mass of the final nucleus
00350 #ifdef mudebug
00351           G4cout<<"--G4QEnv::Const:M="<<tm<<",GSM=="<<fnm<<G4endl;
00352 #endif
00353         }
00354         fnN.Set4Momentum(fn4m);
00355         // (mu,q->nu,q) reaction succeded and Neutrino can be pushed to Output
00356         G4QHadron* neutrino = 0;              // NeutrinoPrototype to be filled to Output
00357 #ifdef mudebug
00358         G4cout<<"G4QEnv::Const:fM="<<tm<<fn4m<<",GSM="<<fnm<<G4endl;
00359 #endif      
00360         if(tm<fnm)                            // Final Nucleus is below the GS threshold
00361         {
00362           qf4m=G4LorentzVector(0.,0.,0.,fnm); // Final nucleus 4M for the final decay
00363           qt4m=tg4m+mu4m;
00364           if(!G4QHadron(qt4m).DecayIn2(nu4m,qf4m)) // Decay in Nucleus+nu_mu
00365           {
00366             G4cout<<"***G4QE::Constr:Muon error (2) 4M="<<mu4m<<". Fill as it is."<<G4endl;
00367             G4QHadron* muon = new G4QHadron(opHad); // Fill projMuon to Output
00368             theQHadrons.push_back(muon);        // (delete equivalent)
00369             return;
00370           }
00371           G4QHadron* fnuc = new G4QHadron(targQC,qf4m); // Fill Final Nucleus to Output
00372           //theQHadrons.push_back(fnuc);      // (delete equivalent)
00373           EvaporateResidual(fnuc);            // Try to evaporate residual (del. equiv.)
00374           neutrino = new G4QHadron(nuPDG,nu4m);// Fill Neutrino to Output
00375           theEnvironment.InitByPDG(90000000); // Create nuclear environment
00376 #ifdef debug
00377           G4cout<<"G4QEnv::Const:Fill neutrino (1) "<<nuPDG<<nu4m<<G4endl;
00378 #endif      
00379           theQHadrons.push_back(neutrino);    // (delete equivalent)
00380           return;
00381         }
00382         neutrino = new G4QHadron(nuPDG,nu4m); // Fill Neutrino to Output
00383 #ifdef debug
00384         G4cout<<"G4QEnv::Const:Fill neutrino (2) "<<nuPDG<<nu4m<<G4endl;
00385 #endif      
00386         theQHadrons.push_back(neutrino);      // (delete equivalent)
00387         if(tm<fnm+135.98)                     // FinalNucleus is below thePionThreshold(HE)
00388         {
00389           if(!fnN.SplitBaryon()) // Final Nucleus is below the splittingFragmentThreshold
00390           {
00391 #ifdef mudebug
00392             G4cout<<"G4QEnv::Const: impossible to split nucleon after mu->nu"<<G4endl;
00393 #endif      
00394             G4LorentzVector ga4m(0.,0.,0.,0.);
00395             qf4m=G4LorentzVector(0.,0.,0.,fnm);// Final nucleus 4M for the final decay
00396             if(!G4QHadron(fn4m).DecayIn2(ga4m,qf4m)) // Decay in Nucleus+photon
00397             {
00398               G4cout<<"***G4QE::Constr:LepCapError(3),M="<<fn4m.m()<<"<"<<fnm<<G4endl;
00399               G4QHadron* resid = new G4QHadron(targQC,qt4m); // Fill ResidNucleus to Output
00400               theQHadrons.push_back(resid);   // (delete equivalent)
00401               theEnvironment.InitByPDG(90000000);// Create nuclear environment
00402               return;
00403             }
00404             G4QHadron* photon = new G4QHadron(22,ga4m); // Fill projPhoton to Output
00405 #ifdef debug
00406             G4cout<<"G4QEnv::Const:Fill photon "<<ga4m<<G4endl;
00407 #endif      
00408             theQHadrons.push_back(photon);    // (delete equivalent)
00409             G4QHadron* fnuc = new G4QHadron(targQC,qf4m); // Fill Final Nucleus to Output
00410 #ifdef debug
00411             G4cout<<"G4QEnv::Const:Fill target "<<targQC<<qf4m<<" in any form"<<G4endl;
00412 #endif      
00413             EvaporateResidual(fnuc);          // Try to evaporate residual (del. equiv.)
00414             theEnvironment.InitByPDG(90000000);// Create nuclear environment
00415             return;
00416           }
00417         }
00418         // At this poin it is possible to convert mu- to pi-
00419         fn4m=qf4m-qi4m;
00420         opHad->SetQPDG(pimQPDG);              //Convert (mu-)u->d to (virt pi-)u->d capture
00421         fake=false;                           // normal pi- for q-muon scattering
00422         //fake=true;                          // fake pi- for q-muon scattering *****
00423         //if(G4UniformRand()>.5) fake=false;  // normal pi- for q-muon scattering *****
00424         opHad->Set4Momentum(fn4m);
00425       }
00426     }
00427     for(G4int ih=0; ih<nHadrons; ih++)        // ==> The main LOOP over projQHadrons
00428     {
00429       G4QHadron* curHadr=projHadrons[ih];     // Pointer to current projectile Hadron
00430       G4int hNFrag = curHadr->GetNFragments();// #0 means intermediate (skip)
00431       G4LorentzVector ch4M=curHadr->Get4Momentum(); // 4-momenyum of the current projectile
00432 #ifdef debug
00433       G4cout<<"G4QE:C:"<<ih<<",F="<<hNFrag<<",0="<<projHadrons[0]->GetNFragments()<<G4endl;
00434 #endif
00435       if(!hNFrag&&ch4M.e()>0.)                // => "Final hadron" case
00436       {
00437         G4int envPDG=theEnvironment.GetPDG();
00438         if(envPDG==90000000||(theEnvironment.Get4Momentum().m2())<1.) // ==>"Vacuum"
00439         {
00440           G4int hPDG  = curHadr->GetPDGCode();// A PDG Code of the projQHadron
00441           //if(!hPDG||hPDG==10)        // Check for the validity of the QHadron (@@ 10 OK?)
00442           if(!hPDG)          // Check for the validity of the QHadron
00443           {
00444             //G4cerr<<"--Warning--G4QEnvironment::Constructor: wrong PDG("<<ih<<")="<<hPDG
00445             //    <<", HQC="<<curHadr->GetQC()<<", HM="<<curHadr->GetMass()<<G4endl;
00446             //throw G4QException("***G4QEnvironment::Constructor: theInputHadron is Chip");
00447           }
00448           else
00449           {
00450             G4int hQ = curHadr->GetQCode();  // One more check for valid of the QHadron
00451             if(hQ<0)
00452             {
00453               //G4cerr<<"--Warning--G4QEnv::Constructor:Q<0, PDG=("<<ih<<")"<<hPDG<<G4endl;
00454               //throw G4QException("***G4QEnvironment::Constructor:theInputHadron is bad");
00455             }
00456             else
00457             {
00458               G4QHadron* newHadr = new G4QHadron(curHadr);
00459 #ifdef debug
00460               G4cout<<"*G4QE::Const:H="<<newHadr->GetQC()<<newHadr->Get4Momentum()<<G4endl;
00461 #endif
00462               theQHadrons.push_back(newHadr); // Fill existing hadron (delete equivalent)
00463 #ifdef debug
00464               G4cout<<"G4QEnviron::Constructor: Fill h="<<hPDG<<ch4M<<G4endl;
00465               for(unsigned ipo=0; ipo<theQHadrons.size(); ipo++) // LOOP just for printing
00466               {
00467                 G4int           hPDG  = theQHadrons[ipo]->GetPDGCode();
00468                 G4LorentzVector h4Mom = theQHadrons[ipo]->Get4Momentum();
00469                 G4int           hNFrag= theQHadrons[ipo]->GetNFragments();
00470                 G4QContent      hQC   = theQHadrons[ipo]->GetQC();
00471                 G4cout<<"h#"<<ipo<<": "<<hPDG<<hQC<<",4M="<<h4Mom<<",nFr="<<hNFrag<<G4endl;
00472               }
00473 #endif
00474             } // End of Q-Code check
00475           } // End of proper PDG for i-th Hadron
00476         }
00477         else                                  // Nuclear Environment still exists
00478         {
00479           G4QContent      hQC   = curHadr->GetQC();
00480 #ifdef debug
00481           G4cout<<"G4QE::Const:CreateQuasm, 4M="<<ch4M<<",QC="<<hQC<<",E="<<envPDG<<",tC="
00482                 <<totCharge<<",tB="<<totBaryoN<<G4endl;
00483 #endif
00484           CreateQuasmon(hQC, ch4M, fake);
00485         } // End of Existing Nuclear Environment case
00486       } // End of final hadron case
00487     } // End of the LOOP over input hadrons
00488   } // End of nuclear target case (including neutron=90000001 & proton=90001000)
00489   else                                        // => "Unique hadron" case
00490   {
00491     // the nuclEnviron is already init'ed as vacuum + get the first hadron for interaction
00492     G4QHadron* curHadr=projHadrons[0];        // Pointer to the firstProjecHadron (checked)
00493     G4int hPDG  = curHadr->GetPDGCode();      // A PDG Code of the projQHadron
00494     if(!hPDG||hPDG==10)                       // Check for the validity of the QHadron
00495     {
00496       G4cout<<"---Warning---G4QEnvironment::Constructor:Vacuum,1st Hadron wrong PDG="<<hPDG
00497             <<", HQC="<<curHadr->GetQC()<<", HM="<<curHadr->GetMass()<<G4endl;
00498       //throw G4QException("***G4QEnvironment::Constructor: Fiest input Hadron is wrong");
00499     }
00500     else
00501     {
00502       G4int hQ = curHadr->GetQCode();         // One more check for valid of the QHadron
00503       if(hQ<0)
00504       {
00505         G4cout<<"---Warning---G4QEnviron::Constructor:Vacuum,Q<0, 1st HPDG="<<hPDG<<G4endl;
00506         //throw G4QException("***G4QEnvironment::Constructor:theFirstInputHadron's wrong");
00507       }
00508       else                                // Now we can get 4Mom &  QC of incedent particle
00509       {
00510         G4LorentzVector h4Mom = curHadr->Get4Momentum();
00511         G4QContent      hQC   = curHadr->GetQC();
00512         if(!targPDG||targPDG==10) G4cout<<"G4QEnv::CreateQ; (1) PDG="<<targPDG<<G4endl;
00513         G4QPDGCode      tQPDG(targPDG);
00514         G4int           tQ    = tQPDG.GetQCode();
00515         if(tQ<0||targPDG==10)
00516         {
00517           G4cout<<"---Warning---G4QEnv::Constructor:TrgQC<0, Chipo?,PDG="<<targPDG<<G4endl;
00518           //throw G4QException("***G4QEnvironment::Constructor: Target is wrong");
00519         }
00520         else                                 // Now we can create a unique Quasmon
00521         {
00522           h4Mom+=G4LorentzVector(0.,0.,0.,tQPDG.GetMass()); //Projectile + TargetHadron
00523           hQC+=tQPDG.GetQuarkContent();
00524 #ifdef debug
00525           G4cout<<"G4QEnv::Const:VacHadrTarg="<<h4Mom<<hQC<<",E="<<theEnvironment<<G4endl;
00526 #endif
00527           G4Quasmon* curQuasmon = new G4Quasmon(hQC, h4Mom);
00528           theQuasmons.push_back(curQuasmon); // Insert Quasmon or hadron/gamma (del. eq.)
00529         }
00530       } // End of Q-Code check
00531     } // End of proper PDG for i-th Hadron
00532     if(nHadrons>1) for(G4int ih=0; ih<nHadrons; ih++) // fill other Hadrons to Output
00533     {
00534       G4QHadron* newHadr = new G4QHadron(curHadr);
00535 #ifdef debug
00536       G4cout<<"*G4QE::Const:#"<<ih<<","<<curHadr->GetQC()<<curHadr->Get4Momentum()<<G4endl;
00537 #endif
00538       theQHadrons.push_back(newHadr);        // Fill existing hadron (delete equivalent)
00539     }
00540   } // End of Unique Hadron target treatment
00541 #ifdef chdebug
00542   G4int finCharge=theEnvironment.GetCharge();
00543   G4int finBaryoN=theEnvironment.GetA();
00544   G4int nHad=theQHadrons.size();
00545   if(nHad) for(G4int ih=0; ih<nHad; ih++)
00546   {
00547     finCharge+=theQHadrons[ih]->GetCharge();
00548     finBaryoN+=theQHadrons[ih]->GetBaryonNumber();
00549   }
00550   G4int nQuas=theQuasmons.size();
00551   if(nQuas) for(G4int iq=0; iq<nQuas; iq++)
00552   {
00553     finCharge+=theQuasmons[iq]->GetCharge();
00554     finBaryoN+=theQuasmons[iq]->GetBaryonNumber();
00555   }
00556   if(finCharge!=totCharge || finBaryoN!=totBaryoN)
00557   {
00558     G4cout<<"*::*G4QEnv::C:(0) tC="<<totCharge<<",C="<<finCharge<<",tB="<<totBaryoN
00559           <<",B="<<finBaryoN<<",E="<<theEnvironment<<G4endl;
00560     if(nHad) for(G4int h=0; h<nHad; h++)
00561     {
00562       G4QHadron* cH = theQHadrons[h];
00563       G4cout<<"*:*G4QE::C:h#"<<h<<",QC="<<cH->GetQC()<<",PDG="<<cH->GetPDGCode()<<G4endl;
00564     }
00565     if(nQuas) for(G4int q=0; q<nQuas; q++)
00566     {
00567       G4Quasmon* cQ = theQuasmons[q];
00568       G4cout<<"::G4QE::C:q#"<<q<<",C="<<cQ->GetCharge()<<",QuarkCon="<<cQ->GetQC()<<G4endl;
00569     }
00570   }
00571 #endif
00572 } // End of the G4QEnvironment constructor
00573 
00574 
00575 G4QEnvironment::G4QEnvironment(const G4QEnvironment &right)
00576 {
00577   // theQHadrons (Vector)
00578   theQFScat = G4QFreeScattering::GetPointer();
00579   G4int nQH             = right.theQHadrons.size();
00580   if(nQH) for(G4int ih=0; ih<nQH; ih++)
00581   {
00582     G4QHadron* curQH    = new G4QHadron(right.theQHadrons[ih]);
00583 #ifdef debug
00584     G4cout<<"G4QE::CopyByVal:cH#"<<ih<<","<<curQH->GetQC()<<curQH->Get4Momentum()<<G4endl;
00585 #endif
00586     theQHadrons.push_back(curQH);            // (delete equivalent)
00587   }
00588   // theProjectiles (Vector)
00589   G4int nP              = right.theProjectiles.size();
00590   if(nP) for(G4int ip=0; ip<nP; ip++)
00591   {
00592     G4QHadron* curP     = new G4QHadron(right.theProjectiles[ip]);
00593     theProjectiles.push_back(curP);           // (delete equivalent)
00594   }
00595   theTargetPDG          = right.theTargetPDG;
00596   theWorld              = right.theWorld;
00597   nBarClust             = right.nBarClust;
00598   f2all                 = right.f2all;
00599   tot4Mom               = right.tot4Mom;
00600   totCharge             = right.totCharge;
00601   totBaryoN             = right.totBaryoN;
00602 
00603   // theQuasmons (Vector)
00604   G4int nQ              = right.theQuasmons.size();
00605   if(nQ) for(G4int iq=0; iq<nQ; iq++)
00606   {
00607     G4Quasmon* curQ     = new G4Quasmon(right.theQuasmons[iq]);
00608     theQuasmons.push_back(curQ);             // (delete equivalent)
00609   }
00610 
00611   // theQCandidates (Vector)
00612   G4int nQC             = right.theQCandidates.size();
00613   if(nQC) for(G4int ic=0; ic<nQC; ic++)
00614   {
00615     G4QCandidate* curQC = new G4QCandidate(right.theQCandidates[ic]);
00616     theQCandidates.push_back(curQC);         // (delete equivalent)
00617   }
00618 
00619   theEnvironment        = right.theEnvironment;
00620 }
00621 
00622 G4QEnvironment::G4QEnvironment(G4QEnvironment* right)
00623 {
00624   // theQHadrons (Vector)
00625   theQFScat = G4QFreeScattering::GetPointer();
00626   G4int nQH             = right->theQHadrons.size();
00627   if(nQH) for(G4int ih=0; ih<nQH; ih++)
00628   {
00629     G4QHadron* curQH    = new G4QHadron(right->theQHadrons[ih]);
00630 #ifdef debug
00631     G4cout<<"G4QE::CopyByPtr:cH#"<<ih<<","<<curQH->GetQC()<<curQH->Get4Momentum()<<G4endl;
00632 #endif
00633     theQHadrons.push_back(curQH);            // (delete equivalent)
00634   }
00635 
00636   // theProjectiles (Vector)
00637   G4int nP              = right->theProjectiles.size();
00638   if(nP) for(G4int ip=0; ip<nP; ip++)
00639   {
00640     G4QHadron* curP     = new G4QHadron(right->theProjectiles[ip]);
00641     theProjectiles.push_back(curP);           // (delete equivalent)
00642   }
00643   theTargetPDG          = right->theTargetPDG;
00644   theWorld              = right->theWorld;
00645   nBarClust             = right->nBarClust;
00646   f2all                 = right->f2all;
00647   tot4Mom               = right->tot4Mom;
00648   totCharge             = right->totCharge;
00649   totBaryoN             = right->totBaryoN;
00650 
00651   // theQuasmons (Vector)
00652   G4int nQ              = right->theQuasmons.size();
00653   if(nQ) for(G4int iq=0; iq<nQ; iq++)
00654   {
00655     G4Quasmon* curQ     = new G4Quasmon(right->theQuasmons[iq]);
00656     theQuasmons.push_back(curQ);             // (delete equivalent)
00657   }
00658 
00659   // theQCandidates (Vector)
00660   G4int nQC             = right->theQCandidates.size();
00661   if(nQC) for(G4int ic=0; ic<nQC; ic++)
00662   {
00663     G4QCandidate* curQC = new G4QCandidate(right->theQCandidates[ic]);
00664     theQCandidates.push_back(curQC);         // (delete equivalent)
00665   }
00666 
00667   theEnvironment        = right->theEnvironment;
00668 }
00669 
00670 G4QEnvironment::~G4QEnvironment()
00671 {
00672 #ifdef debug
00673   G4cout<<"~G4QEnvironment: before theQCandidates nC="<<theQCandidates.size()<<G4endl;
00674 #endif
00675   for_each(theQCandidates.begin(), theQCandidates.end(), DeleteQCandidate());
00676 #ifdef debug
00677   G4cout<<"~G4QEnvironment: before theQuasmons nQ="<<theQuasmons.size()<<G4endl;
00678 #endif
00679   for_each(theQuasmons.begin(), theQuasmons.end(), DeleteQuasmon());
00680 #ifdef debug
00681   G4cout<<"~G4QEnvironment: before theQHadrons nH="<<theQHadrons.size()<<G4endl;
00682 #endif
00683   for_each(theQHadrons.begin(), theQHadrons.end(), DeleteQHadron());
00684 #ifdef debug
00685   G4cout<<"~G4QEnvironment: before theProjectiles nP="<<theProjectiles.size()<<G4endl;
00686 #endif
00687   for_each(theProjectiles.begin(), theProjectiles.end(), DeleteQHadron());
00688 #ifdef debug
00689   G4cout<<"~G4QEnvironment: === DONE ==="<<G4endl;
00690 #endif
00691 }
00692 
00693 G4double G4QEnvironment::SolidAngle=0.8;     // Part of Solid Angle to capture (@@A-dep.)
00694 G4bool   G4QEnvironment::EnergyFlux=false;   // Flag for Energy Flux use (not MultyQuasmon)
00695 G4bool   G4QEnvironment::WeakDecays=false;   // Flag for WeakDecays(notUsed hadwaredClosed)
00696 G4bool   G4QEnvironment::ElMaDecays=true;    // Flag for Electromagnetic decays of hadrons
00697 G4double G4QEnvironment::PiPrThresh=141.4;   // Pion Production Threshold for gammas
00698 G4double G4QEnvironment::M2ShiftVir=20000.;  // Shift for M2=-Q2=m_pi^2 of the virtualGamma
00699 G4double G4QEnvironment::DiNuclMass=1880.;   // DoubleNucleon Mass for VirtualNormalization
00700 
00701 // Open decay of particles with possible electromagnetic channels of decay (gammas)
00702 void G4QEnvironment::OpenElectromagneticDecays(){ElMaDecays=true;}
00703 
00704 // Close decay of particles with possible electromagnetic channels of decay (gammas)
00705 void G4QEnvironment::CloseElectromagneticDecays(){ElMaDecays=false;}
00706 
00707 // Fill the private static parameters
00708 void G4QEnvironment::SetParameters(G4double solAn, G4bool efFlag, G4double piThresh,
00709                                    G4double mpisq, G4double dinum)
00710 {
00711   EnergyFlux=efFlag;       // Flag for Energy Flux use instead of Multy Quasmon
00712   SolidAngle=solAn;        // Part of Solid Angle to capture secondaries (@@A-dep)
00713   PiPrThresh=piThresh;     // Pion Production Threshold for gammas
00714   M2ShiftVir=mpisq;        // Shift for M2=-Q2=m_pi^2 of the virtual gamma
00715   DiNuclMass=dinum;        // Double Nucleon Mass for virtual normalization
00716 }
00717 
00718 const G4QEnvironment& G4QEnvironment::operator=(const G4QEnvironment &right)
00719 {
00720   if(this != &right)                          // Beware of self assignment
00721   {
00722     // theQHadrons (Vector)
00723     theQFScat = G4QFreeScattering::GetPointer();
00724     G4int iQH             = theQHadrons.size();
00725     if(iQH) for(G4int ii=0; ii<iQH; ii++) delete theQHadrons[ii];
00726     theQHadrons.clear();
00727     G4int nQH             = right.theQHadrons.size();
00728     if(nQH) for(G4int ih=0; ih<nQH; ih++)
00729     {
00730       G4QHadron* curQH    = new G4QHadron(right.theQHadrons[ih]);
00731 #ifdef debug
00732       G4cout<<"G4QE::Operator=:c#"<<ih<<","<<curQH->GetQC()<<curQH->Get4Momentum()<<G4endl;
00733 #endif
00734       theQHadrons.push_back(curQH);            // (delete equivalent)
00735     }
00736 
00737     theWorld              = right.theWorld;
00738     nBarClust             = right.nBarClust;
00739     f2all                 = right.f2all;
00740 
00741     // theQuasmons (Vector)
00742     G4int iQ              = theQuasmons.size();
00743     if(iQ) for(G4int jq=0; jq<iQ; jq++) delete theQuasmons[jq];
00744     theQuasmons.clear();
00745     G4int nQ              = right.theQuasmons.size();
00746     if(nQ) for(G4int iq=0; iq<nQ; iq++)
00747     {
00748       G4Quasmon* curQ     = new G4Quasmon(right.theQuasmons[iq]);
00749       theQuasmons.push_back(curQ);             // (delete equivalent)
00750     }
00751 
00752     // theQCandidates (Vector)
00753     G4int iQC             = theQCandidates.size();
00754     if(iQC) for(G4int jc=0; jc<iQC; jc++) delete theQCandidates[jc];
00755     theQCandidates.clear();
00756     G4int nQC             = right.theQCandidates.size();
00757     if(nQC) for(G4int ic=0; ic<nQC; ic++)
00758     {
00759       G4QCandidate* curQC = new G4QCandidate(right.theQCandidates[ic]);
00760       theQCandidates.push_back(curQC);        // (delete equivalent)
00761     }
00762 
00763     theEnvironment        = right.theEnvironment;
00764   }
00765   return *this;
00766 }
00767 
00768 // Member function for Quasmon Creation & Environment nucleus modification
00769 void G4QEnvironment::CreateQuasmon(const G4QContent& projQC, const G4LorentzVector& pro4M,
00770                                    G4bool fake)
00771 {
00772   //static const G4double third=1./3.;
00773   static const G4double mNeut= G4QPDGCode(2112).GetMass();
00774   static const G4double mNeu2 = mNeut*mNeut;
00775   static const G4double mProt= G4QPDGCode(2212).GetMass();
00776   static const G4double mPro2 = mProt*mProt;
00777   //static const G4double mLamb= G4QPDGCode(3122).GetMass();
00778   static const G4double mPi  = G4QPDGCode(211).GetMass();
00779   static const G4double mPi2 = mPi*mPi;
00780   //static const G4double mMu  = G4QPDGCode(13).GetMass();
00781   //static const G4double mMu2 = mMu*mMu;
00782   //static const G4QContent gamQC(0,0,0,0,0,0);
00783   //static const G4QContent pimQC(1,0,0,0,1,0);
00784   //static const G4QContent pipQC(0,1,0,1,0,0);
00785   static const G4QContent neutQC(2,1,0,0,0,0);
00786   static const G4QContent protQC(1,2,0,0,0,0);
00787   static const G4QContent deutQC(3,3,0,0,0,0);
00788   static const G4QContent lambQC(1,1,1,0,0,0);
00789   static const G4QNucleus vacuum(90000000);
00790   G4QContent valQ(0,0,0,0,0,0);             // Prototype of the Quasmon's Quark Content
00791   G4LorentzVector q4Mom(0.,0.,0.,0.);       // Prototype of the Quasmon's 4-momentum
00792   nBarClust = 1;                            // By default only quasi-free nucleons
00793   G4LorentzVector proj4M=pro4M;             // Fake equivalence to avoid & const
00794   G4double  projE=proj4M.e();               // energy of the projectile
00795   G4int projPDG=projQC.GetSPDGCode();       // Minimum hadron for the projectile QC
00796   if(projE<0.)
00797   {
00798     G4cout<<"*Warning*G4QEnvironment::CreateQuasmon:Epr="<<projE<<"<0,QC="<<projQC<<G4endl;
00799     projE=0.;
00800     proj4M=G4LorentzVector(0.,0.,0.,0.);
00801   }
00802   G4double  projM2=proj4M.m2();             // projectile's squared mass (print & v.gamma)
00803   G4bool Pr1 = theProjectiles.size() == 1;  // A#ofHadronsInTheInputVector = 1 condition
00804   if(Pr1 && std::fabs(G4QPDGCode(projPDG).GetMass2()-projM2) > .1 ) Pr1=false; // MassShell
00805   G4int     targPDG=theEnvironment.GetPDG();// PDG Code of the target nucleus
00806   if(targPDG>80000000&&targPDG!=90000000&&(theEnvironment.Get4Momentum().m2())>1000.)//Nucl
00807   {
00808     G4double  tgMass=theEnvironment.GetMass();// mass of the target (QEnvironment) nucleus
00809 #ifdef debug
00810     G4cout<<"G4QEnvironment::CreateQ:Interact "<<projQC<<proj4M<<"(m2="<<projM2<<") + A="
00811           <<targPDG<<",M="<<tgMass<<",tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;
00812 #endif
00813     G4int envZ=theEnvironment.GetZ();       // A#of protons in the target nucleus
00814     G4int envN=theEnvironment.GetN();       // A#of neutrons in the target nucleus
00815     G4int envS=theEnvironment.GetS();       // A#of lambdas in the target nucleus
00816     G4int envBN=envZ+envN+envS;             // A baryon number of the target nucleus
00817     G4int nP  =theWorld->GetQPEntries();    // A#of initialized particles in CHIPS World
00818     //G4int nCl =nP-90;                       // A#of initialized clusters in CHIPS World
00819     G4int nCl =nP-53;           // @@ A#ofClusters in CHIPSWorld (53=nQHM in G4QPDGCode.hh)
00820     if(nCl<0) G4cout<<"---Warning---G4QEnv::CreaQ:nP="<<nP<<" for Targ="<<targPDG<<G4endl;
00821     if     (nCl<3) nBarClust=1;             // Fix the maximum Baryon Number for clusters
00822     else if(nCl<9) nBarClust=2;
00823     else
00824     {
00825       G4int v=nCl-9;
00826       G4int d=v/15;
00827       G4int r=v%15;
00828       if(r<7) nBarClust=3+d+d;
00829       else    nBarClust=4+d+d;
00830     }
00831 #ifdef debug
00832     G4cout<<"G4QE::CrQ:TNuc:Z="<<envZ<<",N="<<envN<<",nC="<<nBarClust<<",tC="
00833           <<totCharge<<", tB="<<totBaryoN<<G4endl;
00834 #endif
00835     G4bool pbpt=projE<PiPrThresh+(M2ShiftVir+projM2)/DiNuclMass;// PhotonBelowPionThreshold
00836     G4bool din=false;
00837     G4bool piF=false;
00838     G4bool gaF=false;
00839     if((projM2-mPi2<.00001||projE-mPi<2.7)&&projPDG==-211&&!fake) piF=true;//PiAtRestCase
00840     //if(pbpt&&projPDG==22) din=true; // InCaseOf GammaBelowPiThresh needs DiNucl (?)
00841     if(pbpt&&projPDG==22) gaF=true; // InCaseOf GammaBelowPiThresh needs DiNucl (?)
00842     theEnvironment.SetMaxClust(nBarClust);
00843     nBarClust=theEnvironment.UpdateClusters(din); // Cluster Probabilities upto maxClust
00844 #ifdef debug
00845     G4cout<<"G4QEnv::CreateQ: Nucleus("<<targPDG<<") is created ("<<nBarClust<<" clast's)";
00846     for(G4int ic=0;ic<nBarClust;ic++)
00847       G4cout<<" #"<<ic<<"("<<theEnvironment.GetProbability(ic)<<")";
00848     G4cout<<G4endl;
00849 #endif
00850     theEnvironment.PrepareCandidates(theQCandidates,piF,gaF,proj4M);//Calc.Clust's probab's
00851     G4QNucleus memEnviron=theEnvironment;
00852 #ifdef debug
00853     G4cout<<"G4QE::CrQ:ClusterProbabCalculation tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;
00854 #endif
00855 
00856     G4bool efFlag = false;     // EnergyFlowFlag=FALSE (@@=DEFOLT=@@ make par)
00857     // ***** Change if necessary to compare Energy Flux & Multy Quasmon ******
00858 
00859     G4int efCounter=0;                      // Counter of Energy Flux particles
00860     G4QContent EnFlQC(0,0,0,0,0,0);         // Quark Content of Energy Flux
00861     G4LorentzVector ef4Mom(0.,0.,0.,0.);    // Summed 4-momentum of Energy Flux
00862     G4double proj3M=proj4M.rho();
00863     // --- P-antibar ---  N-antibar  -- LAMBDA-antibar - SIGMA-antibar - SIGMA0-antibar
00864     if((projPDG==-2212||projPDG==-2112||projPDG==-3122||projPDG==-3112||projPDG==-3212||
00865         projPDG==-3222) && envBN>1 && proj3M<10.) // OnlyForAtRestReactions(@@to Interface)
00866     // ^ SIGMA+ antibar
00867     {
00868       // @@ Annihilation on one baryon is implemented (no annihilation on clusters! @@?) @@
00869 #ifdef debug
00870       G4cout<<"G4QE::CreQ:Annihilation on a perif. nucleon, Z="<<envZ<<",N="<<envN<<G4endl;
00871 #endif
00872       G4double   zpn=envZ+envN;             // a#of nucleons in the nucleus
00873       G4double   rnd=zpn*G4UniformRand();   // Random number to find a nucleon
00874       //G4double   envD=.1*envZ*envN/zpn;   // a#of possible quasifree deuterons (@@Param.)
00875       //G4double   rnd=(zpn+envD)*G4UniformRand(); // Random number to find a baryon
00876       //G4double   rnd=(zpn+envS)*G4UniformRand(); // Random number to find a baryon
00877       G4int      targNPDG = 90000000;       // Nucl-Prototype of PDG of Periferal Target
00878       G4QContent targQC(0,0,0,0,0,0);       // Quark Content of Periferal Target
00879       if     (rnd<envN)                     // Neutron is a Periferal Target
00880       {
00881         targNPDG = 90000001;
00882         targQC   = neutQC;
00883       }
00884       else
00885       //     if(rnd<=zpn)                      // Proton is a Periferal Target
00886       {
00887         targNPDG = 90001000;
00888         targQC   = protQC;
00889       }
00890       //else                                  // Deuteron as a Periferal Target
00891       //{
00892       //  targNPDG = 90001001;
00893       //  targQC   = deutQC;
00894       //}
00895       //else                                  // Lambda is a Periferal Target (?)
00896       //{
00897       //  targNPDG = 91000000;
00898       //  targQC   = lambQC;
00899       //}
00900       theEnvironment.Reduce(targNPDG);      // Subtract periferal baryon from Nucleus
00901       G4double resMass=theEnvironment.GetGSMass(); // Nuclear mass after baryon subtraction
00902       G4double barMass=tgMass-resMass;      // Mass of the bound baryon for annihilation
00903       tgMass=resMass;                       // New mass of theEnvironment
00904       q4Mom=G4LorentzVector(0,0,0,barMass)+proj4M;// 4-mom of the intermediate B-Bbar Quasm
00905       valQ=targQC+projQC;                   // Quark Content of intermediate B-Bbar Quasmon
00906 #ifdef debug
00907       G4cout<<"G4QEnviron::CQ:"<<targNPDG<<" + Env="<<theEnvironment<<",QC="<<valQ<<G4endl;
00908 #endif
00909       // Remember the Quasmon parameters, defined by user for recovery after annihilation
00910       G4Quasmon fakeQ;                      // fake Quasmon to get and restore parameters
00911       G4double QTemper=fakeQ.GetTemper();   // Temperature defined by user for Quasmons
00912       G4double QSOverU=fakeQ.GetSOverU();   // S/U defined by user for Quasmons
00913       G4double QEtaSup=fakeQ.GetEtaSup();   // Eta Suppresion defined by user in Quasmons
00914       G4Quasmon::SetParameters(180.,QSOverU,.3); // Parameters for N-barN Annihilation
00915       G4Quasmon::CloseElectromagneticDecays();   // Parameters for N-barN Annihilation
00916       G4Quasmon* pan = new G4Quasmon(valQ,q4Mom);// N-Nbar Quasm creation (del.at 9th line)
00917       G4QNucleus vE(90000000);                   // Annihilation in vacuum (in NuclMatter?)
00918 #ifdef debug
00919       G4cout<<"G4QE::CreQ: before Fragment, vE="<<vE<<",vP="<<vE.GetProbability()<<",QQC="
00920             <<valQ<<",Q4M="<<q4Mom<<G4endl;
00921 #endif
00922       G4QHadronVector* output=pan->Fragment(vE,1);//Output of inVacAnnihilation*DESTROY*<-+
00923 #ifdef debug
00924       G4cout<<"G4QE::CrQ:NucleonAntinucleonAnnihilation's done,N="<<output->size()<<G4endl;
00925 #endif
00926       G4Quasmon::OpenElectromagneticDecays();  // Parameter for multihadronFragmentatation^
00927 #ifdef debug
00928       G4cout<<"G4QE::CrQ:>>AnnihilationIsDone,C="<<totCharge<<",B="<<totBaryoN<<G4endl;// ^
00929 #endif
00930       delete pan;                              // The N-NbarQuasmon is deleted A.S.A.P.   ^
00931       G4QHadronVector input;                   // Input for MultyQuasmon **DESTROY**<---+ ^
00932       //G4int trgPDG = theEnvironment.GetPDG();// New PDG Code for the Residual Nucleus ^ ^
00933       G4LorentzVector trg4M(0.,0.,0.,resMass); // New 4-momentum for the ResidualNucleus^ ^
00934       G4int tNH = output->size();              // For the selection LOOP                ^ ^
00935       G4ThreeVector dir = G4RandomDirection(); // For the selection in LOOP (@@ at rest)^ ^
00936       //G4double ra=std::pow(G4double(totBaryoN),third);  //                            ^ ^
00937       G4double ra=G4QThd(totBaryoN);  //                                                ^ ^
00938 #ifdef debug
00939       G4cout<<"G4QE::CQ:N="<<tNH<<",T="<<totCharge<<","<<totBaryoN<<",A="<<ra<<G4endl;//^ ^
00940 #endif
00941       for (G4int ind=0; ind<tNH; ind++)        // Loop over annihilation  QHadrons      ^ ^
00942       {
00943         //G4QHadron* curHadr = output->operator[](ind); // Pointer to theCurrentHadron  ^ ^
00944         G4QHadron*      curHadr = (*output)[ind];       // Pointer to theCurrentHadron  ^ ^
00945         G4int           shDFL= curHadr->GetNFragments();// A#of decFragments for proj.  ^ ^
00946         G4LorentzVector sh4m = curHadr->Get4Momentum(); // 4Mom for the projectile      ^ ^
00947         G4ThreeVector   shDIR= sh4m.vect().unit();      // unitVector in projMomDirect  ^ ^
00948         G4int           shPDG= curHadr->GetPDGCode();   // PDG Code of the projectile   ^ ^
00949         G4int           shCHG= curHadr->GetCharge();    // Charge of the projectile     ^ ^
00950         G4double        shMOM= sh4m.rho();              // Momentum of the projectile   ^ ^
00951 #ifdef debug
00952         G4cout<<"G4QE::CrQ:"<<ind<<","<<shDFL<<",PDG="<<shPDG<<",4M="<<sh4m<<G4endl; // ^ ^
00953 #endif
00954         G4double solAnCut=SolidAngle;                   // Proto ChargeDependantSolAngle^ ^
00955         if(fabs(ra)<.1) solAnCut=3.;                    // No Nucleus -> no absorption  ^ ^
00956         else if(shMOM<.1)                               // Meson at rest                ^ ^
00957         {                                               //                              ^ ^
00958           if(shCHG<=0.) solAnCut=-3.;                   // Always totally absorbed      ^ ^
00959           else          solAnCut= 3.;                   // Positive are repelled from A ^ ^
00960         }                                               //                              ^ ^
00961         else     solAnCut+=1000*shCHG/shMOM/ra;         // ChargeDepSolAngle(Normal)    ^ ^
00962         //G4double solAnCut=SolidAngle+20*shCHG*sqrt(1.*envZ)/shMOM;//ChargeDepSolAngle ^ ^
00963 #ifdef debug
00964         G4cout<<"G4QE::CrQ: PDG="<<shPDG<<", p="<<shMOM<<", r="<<ra<<G4endl; //         ^ ^
00965 #endif
00966         if(!shDFL)                                      // Final(notDecayed) hadrons    ^ ^
00967         {
00968 #ifdef debug
00969           G4cout<<"G4QE::CQ:>H="<<shPDG<<":"<<dir.dot(shDIR)<<">"<<solAnCut<<G4endl; // ^ ^
00970 #endif
00971           //if((dir.dot(shDIR)>solAnCut||shMOM<120.) && abs(shPDG)>99) // Absorb mesons ^ ^
00972           if(dir.dot(shDIR)>solAnCut && abs(shPDG)>99)  // Absorb mesons                ^ ^
00973           {
00974 #ifdef debug
00975             G4cout<<"G4QE::CQ:>H="<<shPDG<<":"<<dir.dot(shDIR)<<">"<<solAnCut<<", P="// ^ ^
00976                    << shMOM <<" < 120" << G4endl;                           //          ^ ^
00977 #endif
00978             //if (efFlag)
00979             //{ // => Case of "Energy Flux approach"   *** is temporary closed ***      ^ ^
00980             //  G4QContent shQC = curHadr->GetQC();     //                              ^ ^
00981             //  // QuarkContent of the Current Hadron                                   ^ ^
00982             //  ef4Mom+=sh4m;                           //                              ^ ^
00983             //  EnFlQC+=shQC;                           //                              ^ ^
00984             //  efCounter++;                            //                              ^ ^
00985 #ifdef debug
00986                 //  G4int hPDG=curHadr->GetPDGCode();       // Only for gebug printing      ^ ^
00987             //  G4LorentzVector h4M = curHadr->Get4Momentum();  // For debug printing   ^ ^
00988             //  G4cout<<"G4QE::CrQ:#"<<efCounter<<",PDG="<<hPDG<<",h4M="<<h4M<<G4endl;//^ ^
00989 #endif
00990             //} //                                                                      ^ ^
00991             // else                                //=>"MultyQuasFragmentation"(!efFlag)^ ^
00992             {
00993               G4QHadron* mqHadron = new G4QHadron(curHadr);
00994               input.push_back(mqHadron);           // Fill hadron-copy (del equiv)
00995 #ifdef debug
00996               G4int hPDG=curHadr->GetPDGCode();    // Only for debug printing           ^ ^
00997               G4LorentzVector h4M = curHadr->Get4Momentum(); // Only for gebug printing ^ ^
00998               G4cout<<"G4QE::CrQ:Absorb#"<<ind<<", PDG="<<hPDG<<", h4M="<<h4M<<G4endl;//^ ^
00999 #endif
01000               }                                      //                                   ^ ^
01001           }                                        //                                   ^ ^
01002           else                                     // DirectFilling of the output vector^ ^
01003           {                                        //                                   ^ ^
01004 #ifdef debug
01005             G4int hPDG=curHadr->GetPDGCode();      // Only for gebug printing           ^ ^
01006             G4LorentzVector h4M = curHadr->Get4Momentum(); // Only for gebug printing   ^ ^
01007             G4cout<<"G4QE::CrQ: Fill OUT #"<<ind<<",PDG="<<hPDG<<",h4M="<<h4M<<G4endl;//^ ^
01008 #endif
01009             // Just fill a hadron to the output stack (Make EM decays elsewhere)        ^ ^
01010             G4QHadron* curHadron = new G4QHadron(curHadr); //                           ^ ^
01011             theQHadrons.push_back(curHadron);      // TheQHadrs are filled as new Hadrs ^ ^
01012           }
01013         } // End of the IF over projectiles                                             ^ ^
01014       } // End of LOOP over "output" of annihilation                                    ^ ^
01015       for_each(output->begin(), output->end(), DeleteQHadron());     //DESTRUCT output>-^-^
01016       output->clear();                             //                                   ^ ^
01017       delete output;                               // ----------------------------------^-*
01018       if(!efFlag)                                  // =>NotEnergyFlux=MultyQuasmon Case ^
01019       {
01020         G4int noh = theQHadrons.size();            // a#oh hadrons in Output UpToNow    ^
01021         if(noh) for(G4int kh=0; kh<noh; kh++)      // One can escape it but...          ^
01022         {                                          //                                   ^
01023 #ifdef debug
01024           G4cout<<"G4QE::CreateQ:H#"<<kh<<", QC="<<theQHadrons[kh]->GetQC() //          ^
01025                 <<", 4M="<<theQHadrons[kh]->Get4Momentum()<<G4endl;         //          ^
01026 #endif
01027           G4QHadronVector* tmpQHadVec=G4Quasmon().DecayQHadron(theQHadrons[kh]);//d.e<^ ^
01028           G4int tmpS=tmpQHadVec->size();           //                                 ^ ^
01029           intQHadrons.resize(tmpS+intQHadrons.size()); // Resize theQHadrons length   ^ ^
01030           copy(tmpQHadVec->begin(), tmpQHadVec->end(), intQHadrons.end()-tmpS); //    ^ ^
01031           tmpQHadVec->clear();                     //                                 ^ ^
01032           delete tmpQHadVec;           // who calls DecayQHadron must clear & delete  ^ ^
01033         }                                          //                                 ^ ^
01034         theQHadrons.clear(); // deletedWhenDecayed // Now theQHadrons is EmptyVector->^ ^
01035 #ifdef debug
01036         G4int nInH=intQHadrons.size();             // Resulting #of hadrons after decay ^
01037         G4cout<<"G4QE::CrQ:nH="<<nInH<<",C="<<totCharge<<",B="<<totBaryoN<<G4endl;//    ^
01038 #endif
01039         if(!(input.size()))                        // *RETURN* Without Quasmon creation-^
01040         {                                          //                                   ^
01041 #ifdef debug
01042           G4cout<<"*G4QEnv::CrQ:AnnihStack tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;//^
01043 #endif
01044           return;                                  // Do not clear and delete objects --^
01045         }                                          //                                   ^
01046 #ifdef debug
01047         G4cout<<"G4QE::CrQ:fakeQ, restPars tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;//^
01048 #endif
01049         G4Quasmon::SetParameters(QTemper,QSOverU,QEtaSup);//RecoverQParam's after anihil^
01050         G4Quasmon::OpenElectromagneticDecays(); // Parameter for multihadron fragmentat.^
01051         // From this point the new temporary environment is created (multiQuasmon)      ^
01052         G4QEnvironment* muq = new G4QEnvironment(input,theEnvironment.GetPDG());//<--+  ^
01053 #ifdef debug
01054         G4cout<<"G4QE::CrQ:befCl&Dest tC="<<totCharge<<", tB="<<totBaryoN<<G4endl; //^  ^
01055 #endif
01056         for_each(input.begin(), input.end(), DeleteQHadron());     //DESTROING inp >-^--^
01057         input.clear();                             // =Clearing=>---------->---------^==+
01058         theEnvironment = muq->GetEnvironment();    // RestoreResidEnv after interact.^  
01059         G4QHadronVector* outH = muq->GetQHadrons();// Copy of QHadrons *DESTROY* <---^-<--+
01060         G4QuasmonVector* outQ = muq->GetQuasmons();// Copy of Quasmons *DESTROY* <---^--+ ^
01061         delete muq;                                //----->----------->--------------^  ^ ^
01062         noh = outH->size();                        // a#of Not Interacting(Q) Hadrons   ^ ^
01063 #ifdef debug
01064         G4cout<<"G4QEnv::CreateQ:*** #ofNotInterQH="<<noh<<" is found ***"<<G4endl; //  ^ ^
01065 #endif
01066         if(noh) for(G4int nh=0; nh<noh; nh++)      // One can escape it but...          ^ ^
01067         {                                          //                                   ^ ^
01068 #ifdef debug
01069           G4cout<<"G4QE::CreateQ: NotIntQH#"<<nh<<", QC="<<(*outH)[nh]->GetQC()  //     ^ ^
01070                 <<", 4M="<<(*outH)[nh]->Get4Momentum()<<G4endl;                  //     ^ ^
01071 #endif
01072           G4QHadronVector* tmpQHadVec=G4Quasmon().DecayQHadron((*outH)[nh]);//del.eq<-+ ^ ^
01073           G4int tmpS=tmpQHadVec->size();           //                                 ^ ^ ^
01074           intQHadrons.resize(tmpS+intQHadrons.size()); // Resize theQHadrons length   ^ ^ ^
01075           copy(tmpQHadVec->begin(), tmpQHadVec->end(), intQHadrons.end()-tmpS); //    ^ ^ ^
01076           tmpQHadVec->clear();                     //                                 ^ ^ ^
01077           delete tmpQHadVec;           // who calls DecayQHadron must clear & delete->+ ^ ^
01078         }                                          //                                   ^ ^
01079         outH->clear();                             //                                   ^ ^
01080         delete outH;                               // >---->---->---->---->---->---->---^-+
01081         G4int nMQ = outQ->size();                  // A#ofQuasmons in MultyQuasmonOutput^
01082 #ifdef debug
01083         G4LorentzVector eLorV=theEnvironment.Get4Momentum(); //                         ^
01084         G4cout<<"G4QE::CrQ:nMQ="<<nMQ<<",tC="<<totCharge<<", tB="<<totBaryoN<<G4endl;// ^
01085         G4cout<<"G4QE::CrQ:Env4M="<<eLorV<<G4endl; //                                   ^
01086         G4LorentzVector contr4M=eLorV; //                                               ^
01087 #endif
01088         if(nMQ) for(G4int mh=0; mh<nMQ; mh++)      // Can escape CreationDistruct but...^
01089         {                                          //                                   ^
01090           G4Quasmon* curQ = new G4Quasmon((*outQ)[mh]);// Copy to destroy TMP(?)        ^
01091 #ifdef debug
01092           G4LorentzVector qLorV=curQ->Get4Momentum(); //                                ^
01093           G4cout<<"G4QE::CrQ:Q#"<<mh<<",4M="<<qLorV<<curQ->GetQC()<<G4endl; //          ^
01094           contr4M+=qLorV; //                                                            ^
01095 #endif
01096           theQuasmons.push_back(curQ);             // Fill QuasmonCopies in theQuasmons ^
01097         }                                          //                                   ^
01098         for_each(outQ->begin(), outQ->end(), DeleteQuasmon()); // >-------------------->+
01099         outQ->clear();                             //                                   ^
01100         delete outQ;                               // >------------>------------------->+
01101 #ifdef debug
01102         G4int nsHadr  = theQHadrons.size();      // Update the value of OUTPUT entries
01103         G4cout<<"G4QEnvironment::CreateQ: before return nH="<<nsHadr<<G4endl;
01104         if(nsHadr) for(G4int jso=0; jso<nsHadr; jso++)// LOOP over output hadrons 
01105         {
01106           G4int hsNF  = theQHadrons[jso]->GetNFragments(); // A#of secondary fragments
01107           if(!hsNF)                                        // Add only final hadrons
01108           {
01109             G4LorentzVector hLorV=theQHadrons[jso]->Get4Momentum();
01110             G4int           hPDGC=theQHadrons[jso]->GetPDGCode();
01111             G4cout<<"G4QE::CrQ: H#"<<jso<<",4M="<<hLorV<<hPDGC<<G4endl;
01112             contr4M+=hLorV;
01113           }
01114           else
01115             G4cout<<"G4Q::CrQ:"<<jso<<"NF=0,4M="<<theQHadrons[jso]->Get4Momentum()<<G4endl;
01116         }
01117         G4cout<<"G4QEnvironment::CreateQ: before return tot4M="<<contr4M<<G4endl;
01118 #endif
01119         return;                                    // *** RETURN *** 
01120       }
01121       else                                         // ==> Energy Flux case
01122       {
01123         if (!efCounter) return;                    // ***RETURN*** Without Quasmon creation
01124       }
01125     }                                              // End of Hyperon annihilation case
01126     else EnFlQC=projQC;                            // For notAntiBar, don't use EnergyFlux
01127     G4double EnFlP=ef4Mom.rho();                   // Mom. of EnergyFlow forClusterCreation
01128     PrepareInteractionProbabilities(EnFlQC,EnFlP); // InteractionProbabilities for clusters
01129     G4int nCandid = theQCandidates.size();
01130 #ifdef debug
01131     G4cout<<"G4QEnvironment::CrQ: InteractionProbabilities are done, nC="<<nCandid<<G4endl;
01132 #endif
01133     if(nCandid<=0)
01134     {
01135       // G4cout<< "---Warning---G4QEnv::CreaQ:nC=" <<nCandid<< ",E=" <<theEnvironment<<G4endl;
01136       // throw G4QException("G4QEnvironment::CreateQ: Can not select a cluster");
01137       G4ExceptionDescription ed;
01138       ed << "Cannot select a cluster: nC=" << nCandid << ",E="
01139          << theEnvironment << G4endl;
01140       G4Exception("G4QEnvironment::CreateQuasmon()", "HAD_CHPS_0000",
01141                   FatalException, ed);
01142     }
01143     G4double maxP = theQCandidates[nCandid-1]->GetIntegProbability();
01144     G4int i=0;
01145     G4QContent    curQC;                           // Quark Content of the selected cluster
01146     if(nCandid==1||maxP==0.)
01147     {
01148 #ifdef debug
01149       G4cout<<"***G4QEnv::CrQ:MaxP=0||nCand=1: Use all Env., Env="<<theEnvironment<<G4endl;
01150 #endif
01151       curQC=theEnvironment.GetQCZNS();
01152       theEnvironment=vacuum;
01153     }
01154     else
01155     {
01156       G4double totP = maxP * G4UniformRand();
01157 #ifdef debug
01158       G4cout<<"G4QEnvironment::CrQ:nC="<<nCandid<<", maxP="<<maxP<<", totP="<<totP<<G4endl;
01159 #endif
01160       while(theQCandidates[i]->GetIntegProbability()<totP) i++;
01161       G4QCandidate* curCand = theQCandidates[i];// Pointer to selected cluster to interact
01162       curQC   = curCand->GetQC();               // Get QuarkContent of the selected cluster
01163       G4QNucleus targClust(curQC.GetP(),curQC.GetN(),curQC.GetL());//Define Clust as a QNuc
01164       G4double clMass=targClust.GetGSMass();    // Mass of residual nuclear environment
01165 #ifdef cldebug
01166       G4cout<<"G4QEnv::CrQ:Cl#"<<i<<"(of "<<nCandid<<"),QC="<<curQC<<",M="<<clMass<<G4endl;
01167 #endif
01168       G4LorentzVector pq4M=proj4M+G4LorentzVector(0.,0.,0.,clMass); 
01169       if(pq4M.m()>=clMass)
01170       {
01171 #ifdef debug
01172         G4cout<<"G4QEnv::CQ:#"<<i<<"("<<targClust<<curQC<<") Env="<<theEnvironment<<G4endl;
01173 #endif
01174         theEnvironment.Reduce(targClust.GetPDG());// Subtract selected cluster from Nucleus
01175       }
01176       else
01177       {
01178         G4double teMass=theEnvironment.GetGSMass(); //Mass of theResidualNuclearEnvironment
01179         G4LorentzVector te4M=proj4M+G4LorentzVector(0.,0.,0.,teMass);
01180         if(te4M.m()>=teMass)
01181         {
01182 #ifdef debug
01183           G4cout<<"***G4QEnv::CrQ: Deep virtual, use all Env,Env="<<theEnvironment<<G4endl;
01184 #endif
01185           curQC=theEnvironment.GetQCZNS();
01186           theEnvironment=vacuum;
01187         }
01188         else
01189         {
01190           G4QHadron* projH = new G4QHadron(projQC,proj4M);
01191           theQHadrons.push_back(projH);
01192           G4cout<<"---Warning---G4QE::CrQ:Fill Proj asItIs QC/4m="<<projQC<<proj4M<<G4endl;
01193           return;
01194         }
01195       }
01196     }
01197     G4double envMass=theEnvironment.GetGSMass();   // Mass of residual nuclear environment
01198     // @@ Pr1 condition (individual particle) can be taken out of brackets for all if's
01199     if(Pr1&&projPDG==22&&projE<PiPrThresh+(M2ShiftVir+projM2)/DiNuclMass) // ==> Gamma+q
01200     //if(2>3)                                      //@@ TMP:PhotoAbsorbtion by q is closed
01201     {
01202       q4Mom=G4LorentzVector(0.,0.,0.,tgMass-envMass);// PhotoInteracts with BoundedCluster
01203       valQ=curQC;
01204 #ifdef debug
01205       G4cout<<"G4QE::CrQ:Q="<<q4Mom<<valQ<<"+vg="<<proj4M<<",Env="<<theEnvironment<<G4endl;
01206 #endif
01207       G4Quasmon* curQuasmon = new G4Quasmon(valQ, q4Mom, proj4M);//Interaction gam+q inside
01208       theQuasmons.push_back(curQuasmon);  // Insert Quasmon without incid. gamma (del.eq.)
01209     }
01210     else if(Pr1&&(std::fabs(projM2-mPi2)<.00001 && projE-mPi<0.1) && projPDG==-211 &&!fake)
01211     //if(2>3)                                //@@ ***TMP*** PionAbsorbAtRest by q is closed
01212     {
01213       q4Mom=proj4M+G4LorentzVector(0.,0.,0.,tgMass-envMass);// PION + BoundCluster
01214       valQ=EnFlQC+curQC;
01215 #ifdef debug
01216       if(projE<mPi)G4cout<<"*VirtualPiM*G4QE::CrQ:Ener(pi-)="<<projE<<"<mPi="<<mPi<<G4endl;
01217       G4cout<<"G4QEnv::CrQ:Q="<<q4Mom<<valQ<<"+pi="<<proj4M<<",E="<<theEnvironment<<G4endl;
01218 #endif
01219       G4Quasmon* curQuasmon = new G4Quasmon(valQ, q4Mom, -proj4M);//Interact gam+q inside
01220       theQuasmons.push_back(curQuasmon);  // Insert Quasmon without incid. gamma (del.eq.)
01221     }
01222     //else if(Pr1&&projPDG==2212&&G4UniformRand()<.6+.4*std::exp(-envMass/8192))// keepProj
01223     else if(2>3)                          // free flying projectile is closed
01224     {
01225       q4Mom=proj4M;                       // 4M: QUASMON=Projectile
01226       valQ=EnFlQC;                        // qc: QUASMON=Projectile
01227       theEnvironment=memEnviron;
01228 #ifdef debug
01229       G4cout<<"G4QEnv::CreQAll: Q="<<q4Mom<<valQ<<", QEnv="<<theEnvironment<<G4endl;
01230 #endif
01231       G4Quasmon* curQuasmon = new G4Quasmon(valQ, q4Mom);
01232       theQuasmons.push_back(curQuasmon);  // Insert Quasmon (even hadron/gamma) (del.eq.)
01233     }
01234     else if(Pr1&&projPDG==2212&&G4UniformRand()>15./(proj4M.e()-mProt))//ExcitatedCluster
01235     //else if(2>3)                          // No excitation of a cluster by projScattering
01236     {
01237       G4double prM=mProt;                 // mass of the projectile (M) (for future gener.)
01238       G4double prM2=mPro2;                // squared mass of the projectile (M^2)
01239       G4double scM=mProt;                 // mass of the scattered projectile (M')
01240       G4double scM2=mPro2;                // squared mass of the scatteredProjectile (M'^2)
01241       G4QContent scQC=projQC;             // QC of the scattered projectile
01242       G4QContent chQC(0,0,0,0,0,0);       // Change of the Quasmon QC
01243       if(G4UniformRand()<.5*envN/envBN)   // (u->u,d, d->d)? in future make it universal
01244       {
01245         scM=mNeut;                        // Charge exchange reaction
01246         scM2=mNeu2;
01247         scQC=neutQC;
01248         chQC=projQC-scQC;                 // Charge of the created Quasmon must be changed
01249       }
01250       G4double tnM=tgMass-envMass;        // minimal mass of the target cluster (m)
01251       G4double tnM2=tnM*tnM;              // squared mass of the target cluster (m^2)
01252       G4double dtnM=tnM+tnM;              // doubled mass of the target cluster (2*m)
01253       G4double prE=proj4M.e();            // enrgy of the projectile (E)
01254       G4double mu2=tnM2+dtnM*(prE-scM);   // max squared mass of the excited cluster (mu^2)
01255       //G4double mu=std::sqrt(mu2);         // max mass of the excited cluster (mu)
01256       G4double B=.00001;                  // (parameter) slope of the diffraction cone
01257       G4double rmu2=0.;                   // Chosen sqMass of excitedClust (Prototype)
01258       G4double tmax=0.;                   // max -t for scattering (Prototype)
01259       G4double rt=0.;                     // Chosen -t (Prototype)
01260       G4double om=0.;                     // Energy of the excited cluster (Prototype)
01261       G4double ep=0.;                     // Energy of the scattered projectile (eps Proto)
01262       if (prE<prM)G4cout<<"-Warn-G4QEnv::CreQAll:(scat w ex)E="<<prE<<" < M="<<prM<<G4endl;
01263       G4double Pi=std::sqrt(prE*prE-prM2); // Proj momentum (P)
01264       G4double po=0.;                      // Scat momentum (p) (Prototype)
01265       G4double cost=2.;                    // cos(theta) for the scattered proj (Prototype)
01266       G4int cct=0;                         // Counter of cost attempts (@@ can be limited)
01267       while ( std::fabs(cost) > 1. )
01268       {
01269         cct++;
01270 #ifdef debug
01271         G4cout<<"-Warning-G4QEnv::CreQAll: c="<<cct<<" (scat w ex) cost="<<cost<<G4endl;
01272 #endif
01273         rmu2=tnM2*pow(mu2/tnM2,G4UniformRand()); // Chosen SqMass of excitedClust (MMA)
01274         tmax=mu2-rmu2;                    // max -t for scattering
01275         rt=-std::log(1.-G4UniformRand()*(1.-std::exp(-B*tmax)))/B; // Chosem -t
01276         om=(tnM2+rmu2+rt)/dtnM;           // Energy of the excited cluster
01277         ep=prE+tnM-om;                    // Energy of the scattered projectile (epsilon)
01278 #ifdef debug
01279         G4cout<<"G4QEnv::CreQAll: m2="<<tnM2<<" < mu2="<<rmu2<<" < "<<mu2<<"=Max2"<<G4endl;
01280         G4cout<<"G4QEnv::CreQAll: -t="<<rt<<" < "<<tmax<<"=tmax"<<G4endl;
01281         G4cout<<"G4QEnv::CreQAl: om="<<om<<" > m="<<tnM<<", ep="<<ep<<" > M="<<prM<<G4endl;
01282 #endif
01283         if(ep<scM)G4cout<<"+Warn-G4QEnv::CreQAl:(scat w ex)Eo="<<prE<<" < M="<<prM<<G4endl;
01284         po=std::sqrt(ep*ep-scM2);   // Scat momentum (p)
01285         cost=(prE*ep-0.5*(rt+prM2+scM2))/Pi/po; // cos(theta) for the scattered
01286       }
01287       G4double om2=om*om;
01288       if(om2<rmu2)G4cout<<"-Warn-G4QEnv::CreQA:(scat w ex)e2="<<om<<" < mu2="<<tnM<<G4endl;
01289 #ifdef debug
01290       G4cout<<"G4QEnv::CreQAll: ct="<<cost<<",pio="<<Pi*po<<",()="<<cost*Pi*po<<G4endl;
01291       G4double ps=std::sqrt(om2-rmu2);    // Momentum of the excited cluster (p)
01292 #endif
01293       G4double pfc=po*cost;               // Longitudinal projection of the scattered proj
01294       G4double pfs=po*std::sqrt(1.-cost*cost); // Transversal projection of scattered proj
01295       // ---- @@ From here can be a MF for QF nucleon extraction (if used by others)
01296       G4ThreeVector vdir = proj4M.vect(); // 3-Vector in the projectile direction
01297       G4ThreeVector vx(0.,0.,1.);         // ProtoOrt in the direction of the projectile
01298       G4ThreeVector vy(0.,1.,0.);         // First ProtoOrt orthogonal to the direction
01299       G4ThreeVector vz(1.,0.,0.);         // Second ProtoOrt orthoganal to the direction
01300       if(vdir.mag2() > 0.)                // the projectile isn't at rest
01301       {
01302         vx = vdir.unit();                 // Ort in the direction of the projectile
01303         G4ThreeVector vv= vx.orthogonal();// Not normed orthogonal vector (!)
01304         vy = vv.unit();                   // First ort orthogonal to the proj. direction
01305         vz = vx.cross(vy);                // Second ort orthoganal to the proj. direction
01306       }
01307       // ---- @@ End of possible MF (Similar is in G4QCollision)
01308       G4double phi=twopi*G4UniformRand(); // Phi of the Fermi-Mom
01309       G4ThreeVector fp=pfc*vx+pfs*(std::sin(phi)*vy+std::cos(phi)*vz);
01310       G4LorentzVector s4M(fp,ep);
01311 #ifdef debug
01312       G4cout<<"G4QEnv::CreQA:ps="<<po<<"="<<fp.mag()<<",sM="<<prM<<"="<<s4M.m()<<G4endl;
01313       G4cout<<"G4QEnv::CreQA:Ee="<<prE*ep<<" =? "<<(prM2+rt/2-Pi*po*cost)<<G4endl;
01314 #endif
01315       if(std::fabs(s4M.m()-scM)>.001)G4cout<<"-W-G4QE::CQA:M="<<prM<<"#"<<s4M.m()<<G4endl;
01316       G4LorentzVector c4M=proj4M+G4LorentzVector(0.,0.,0.,tnM)-s4M;
01317 #ifdef debug
01318       G4cout<<"G4QEnv::CreQA: ec="<<om<<" = "<<c4M.e()<<", pc="<<ps<<" = "
01319             <<c4M.rho()<<", mc2="<<rmu2<<" = "<<c4M.m2()<<G4endl;
01320       G4cout<<"G4QEnv::CQA:ht="<<(tnM2+rmu2)/2-tnM*om<<"="<<prM2-prE*ep+Pi*po*cost<<G4endl;
01321 #endif
01322       if(std::fabs(c4M.m2()-rmu2)>.1)
01323         G4cout<<"-W-G4QE::CrQ:m2="<<rmu2<<"#"<<c4M.m2()<<",P="<<proj4M<<",M="<<tnM<<G4endl;
01324       G4QHadron* projH = new G4QHadron(scQC,s4M); // Create scattered Projectile Hadron
01325       theQHadrons.push_back(projH);       // Fill it to the output vector
01326       G4Quasmon* curQuasmon = new G4Quasmon(curQC+chQC, c4M); // Q=ExcitedCluster
01327       theQuasmons.push_back(curQuasmon); // Insert Quasmon (even hadron/gamma) (del.eq.)
01328     }
01329     else
01330     {
01331       q4Mom=proj4M+G4LorentzVector(0.,0.,0.,tgMass-envMass); // Projectile + BoundCluster
01332       valQ=EnFlQC+curQC;
01333 #ifdef debug
01334       G4cout<<"G4QEnv::CreQAll: Q="<<q4Mom<<valQ<<", QEnv="<<theEnvironment<<G4endl;
01335 #endif
01336       G4Quasmon* curQuasmon = new G4Quasmon(valQ, q4Mom);
01337       theQuasmons.push_back(curQuasmon); // Insert Quasmon (even hadron/gamma) (del.eq.)
01338     }
01339   }
01340   else
01341   {
01342     G4cout<<"---Warning---G4QEnvironment::CreateQuasmon:Strange targPDG="<<targPDG<<G4endl;
01343     //throw G4QException("***G4QEnvironment::CreateQuasmon: Impossible target");
01344   }
01345 }
01346 
01347 // Calculate a probability to interact with clusters for the givven PDG of the projectile
01348 void G4QEnvironment::PrepareInteractionProbabilities(const G4QContent& projQC, G4double AP)
01349 {
01350   G4double sum    = 0.;                            // Sum of probabilities of interaction
01351   G4double probab = 0.;                            // Interaction probability
01352   G4double denseB = 0.;                            // A#of*prob baryons in dense part
01353   G4double allB   = 0.;                            // A#of*prob baryons in the nucleus
01354   G4int pPDG = projQC.GetSPDGCode();               // PDG code of the projectile particle
01355   if(2>3) {allB=AP; allB=pPDG;}                    // A trick to use not used AP(3M) & pPDG
01356   for (unsigned index=0; index<theQCandidates.size(); index++)
01357   {
01358     G4QCandidate* curCand=theQCandidates[index];   // Intermediate pointer
01359     G4int cPDG = curCand->GetPDGCode();            // PDG Code of the Candidate
01360     G4int cST  = curCand->GetStrangeness();        // Strangeness of the candidate
01361     G4int cBN  = curCand->GetBaryonNumber();       // Baryon Number of the candidate
01362     G4int cCH  = curCand->GetCharge();             // Charge of the candidate
01363 #ifdef sdebug
01364     G4cout<<"G4QE::PIP:=---=> #"<<index<<", cPDG="<<cPDG<<",S="<<cST<<G4endl;
01365 #endif
01366     if(cPDG>80000000&&cPDG!=90000000&&!cST&&cCH>0&&cBN>0&&cCH<=cBN) // ===> Nuclear cluster
01367     {
01368       G4int zc = cCH;                              // "Z" of the cluster
01369       G4int nc = cBN-cCH;                          // "N" of the cluster
01370       G4double nOfCl=curCand->GetPreProbability(); // A number of clusters of the type
01371       G4double dOfCl=curCand->GetDenseProbability();// A number of clusters in dense region
01372 #ifdef sdebug
01373       G4cout<<"G4QE::PIP:Z="<<zc<<",N="<<nc<<",nC="<<nOfCl<<",dC="<<dOfCl<<G4endl;
01374 #endif
01375       if(cPDG==91000000||cPDG==90001000||cPDG==90000001)
01376       {
01377         allB+=nOfCl;
01378         denseB+=dOfCl;
01379       }
01380       G4QContent pQC=curCand->GetQC();             // Quark Content of the candidate
01382       G4QContent qQC=pQC+projQC;                   // Total Quark content of the Compound
01383       G4QPDGCode qQPDG(qQC);
01384       G4int qC   = qQPDG.GetQCode();
01385       G4double d = abs(zc-nc);
01386       G4double fact=1./pow(2.,d);
01387       if (qC<-1) probab=0.;     
01388       //else if(pPDG==-211&&AP<152.&&cBN<2) probab=0.; // PionCaptureByCluster
01389       //else if(pPDG==22&&AP<152. || pPDG>90000000)
01390       else if(pPDG==22 && AP<152.)
01391       {
01392         if(cBN<2) probab=nOfCl*cBN*fact; //Gamma Under Pi Threshold (QuarkCapture)
01393         else probab=0.;
01394       }
01395       else if(pPDG==2212)
01396       {
01397         //if(cBN<2)probab=nOfCl*cBN*fact; // Moving nucleons hits only nucleons
01398         //else probab=0.;
01399         probab=nOfCl*cBN*fact; // Moving nucleons hits composed clusters
01400         //probab=nOfCl*fact; // Moving nucleons hits compact clusters
01401       }
01403       //else if((pPDG==-211||pPDG==-13)&&AP<27.)probab=dOfCl*cBN*fact;//Pi/Mu-CaptureAtRest
01404       //else if(pPDG==-211&&AP<10.)            probab=nOfCl*fact;// special PiCaptureAtRest
01405       //else if(pPDG==-211&&AP<10.)            probab=nOfCl*cBN*(cBN-1)*fact;
01406       //else                                   probab=nOfCl*fact;
01407       else                                   probab=nOfCl*cBN*fact;
01408       //else                                      probab=dOfCl*cBN*fact;
01409       //if(cBN>1) probab=0.;                       // Suppress clusters
01410       //if(cBN>2) probab=0.;                       // Suppress heavy clusters
01411 #ifdef sdebug
01412       G4int pPDG      = projQC.GetSPDGCode();      // PDG code of the projectile particle
01413       G4int rPDG = qQC.GetSPDGCode();
01414       G4double baryn = qQC.GetBaryonNumber();
01415       G4double charge= qQC.GetCharge();
01416       G4double dq= abs(baryn-charge-charge);
01417       G4cout<<"G4QE::PIP:P="<<probab<<",ac="<<cBN<<",dq="<<dq<<",f="<<fact<<",qC="
01418             <<qC<<",rPDG="<<rPDG<<",pPDG="<<pPDG<<",nCP="<<nOfCl<<",dCP="<<dOfCl<<G4endl;
01419 #endif
01420     }
01421     else probab=0.;
01422     sum+=probab;
01423     curCand->SetIntegProbability(sum);
01424   }
01425   if(allB>0.)f2all=(allB-denseB)/allB;
01426   else       f2all=0.;
01427 } // End of PrepareInteractionProbabilities
01428 
01429 //Initialize a Clusters Vector for the Nucleus of the QEnvironment
01430 void G4QEnvironment::InitClustersVector(G4int maxClust, G4int maxA)
01431 {
01432 #ifdef debug
01433   G4cout<<"G4QEnvironment::InitClustersVector called with nC="<<maxClust<<G4endl;
01434 #endif
01435   if(maxClust>=0) for (G4int i=0; i<maxClust; i++) 
01436   {
01437     //G4int clustQCode = i+90; // Q-code of the cluster in the CHIPS World "IsoNuclei"
01438     G4int clustQCode = i+53; // @@ cluster Q-code in CHIPS World (53=nQHM in G4QPDGCode.hh)
01439 #ifdef sdebug
01440     G4cout<<"G4QEnvironment::InitClustersVector: Before Init Q ="<<clustQCode<<G4endl;
01441 #endif
01442     G4QPDGCode clustQPDG(true,clustQCode);
01443     //clustQPDG.InitByQCode(clustQCode);
01444     G4int clusterPDG=clustQPDG.GetPDGCode();
01445     G4int clustB=clustQPDG.GetBaryNum();
01446 #ifdef sdebug
01447     G4cout<<"G4QEnvironment::InitClustersVector: Before insert ="<<clusterPDG<<G4endl;
01448 #endif
01449     //theQCandidates.push_back(new G4QCandidate(clusterPDG)); // (delete equivalent)
01450     if(clustB<=maxA) theQCandidates.push_back(new G4QCandidate(clusterPDG)); // (del.eq.)
01451 #ifdef sdebug
01452     G4cout<<"G4QEnvironment::InitClustersVector: Cluster # "<<i<<" with code = "
01453           <<clusterPDG<<", QC="<<clustQPDG.GetQuarkContent()<<G4endl;
01454 #endif
01455   }
01456 } // End of InitClastersVector
01457 
01458 // Fragmentation of the QEnvironment with MultyQuasmon (the main internal member function)
01459 G4QHadronVector  G4QEnvironment::HadronizeQEnvironment()
01460 {
01461   static const G4int  NUCPDG = 90000000;
01462   static const G4QNucleus vacuum(NUCPDG);
01463   static const G4LorentzVector zeroLV(0.,0.,0.,0.);
01464   //static const G4QContent zeroQC(0,0,0,0,0,0);
01465   static const G4QContent PiQC(0,1,0,1,0,0);
01466   static const G4QContent K0QC(1,0,0,0,0,1);
01467   static const G4QContent KpQC(0,1,0,0,0,1);
01468   static const G4QContent SiPQC(0,2,1,0,0,0);
01469   static const G4QContent SiMQC(2,0,1,0,0,0);
01470   static const G4QContent protQC(1,2,0,0,0,0);
01471   static const G4QContent neutQC(2,1,0,0,0,0);
01472   //static const G4QContent alQC(6,6,0,0,0,0);
01473   static const G4QPDGCode nQPDG(2112);
01474   static const G4QPDGCode pQPDG(2212);
01475   static const G4QPDGCode lQPDG(3122);
01476   static const G4QPDGCode s0QPDG(3122);
01477   static const G4double mPi0 = G4QPDGCode(111).GetMass();
01478   //static const G4double dPi0 = mPi0+mPi0;
01479   static const G4double fPi0 = 4*mPi0;
01480   static const G4double mPi  = G4QPDGCode(211).GetMass();
01481   static const G4double mK   = G4QPDGCode(321).GetMass();
01482   static const G4double mK0  = G4QPDGCode(311).GetMass();
01483   static const G4double mNeut= G4QPDGCode(2112).GetMass();
01484   static const G4double mProt= G4QPDGCode(2212).GetMass();
01485   static const G4double mLamb= G4QPDGCode(3122).GetMass();
01486   static const G4double mSigZ= G4QPDGCode(3212).GetMass();
01487   static const G4double mSigM= G4QPDGCode(3112).GetMass();
01488   static const G4double mSigP= G4QPDGCode(3222).GetMass();
01489   //static const G4double mAlph = G4QPDGCode(2112).GetNuclMass(2,2,0);
01490   static const G4double eps=.003;
01491   G4int nQuasmons = theQuasmons.size();
01492 #ifdef chdebug
01493   G4int finCharge=theEnvironment.GetCharge();
01494   G4int finBaryoN=theEnvironment.GetA();
01495   G4int nHad=theQHadrons.size();
01496   if(nHad) for(G4int ih=0; ih<nHad; ih++)
01497   {
01498     finCharge+=theQHadrons[ih]->GetCharge();
01499     finBaryoN+=theQHadrons[ih]->GetBaryonNumber();
01500   }
01501   //G4int nQuas=theQuasmons.size();
01502   if(nQuasmons)for(G4int iq=0; iq<nQuasmons; iq++)
01503   {
01504     finCharge+=theQuasmons[iq]->GetCharge();
01505     finBaryoN+=theQuasmons[iq]->GetBaryonNumber();
01506   }
01507   if(finCharge!=totCharge || finBaryoN!=totBaryoN)
01508   {
01509     G4cout<<"*::*G4QE::HQ:T(1) tC="<<totCharge<<",C="<<finCharge<<",tB="<<totBaryoN
01510           <<",B="<<finBaryoN<<",E="<<theEnvironment<<G4endl;
01511     if(nHad) for(G4int h=0; h<nHad; h++)
01512     {
01513       G4QHadron* cH = theQHadrons[h];
01514       G4cout<<"*::*G4QE::HQ:h#"<<h<<",QC="<<cH->GetQC()<<",PDG="<<cH->GetPDGCode()<<G4endl;
01515     }
01516     if(nQuasmons) for(G4int q=0; q<nQuasmons; q++)
01517     {
01518       G4Quasmon* cQ = theQuasmons[q];
01519       G4cout<<"*::*G4QE::HQ:q#"<<q<<",C="<<cQ->GetCharge()<<",QCont="<<cQ->GetQC()<<G4endl;
01520     }
01521   }
01522 #endif
01523 #ifdef debug
01524   G4cout<<"G4QE::HQE:*HADRONIZE Q-ENVIRONMENT="<<theEnvironment<<",nQ="<<nQuasmons<<G4endl;
01525 #endif
01526   if(nQuasmons<1)                            // "No Quasmons" case -> Fill QEnviron
01527   {
01528     G4int nPDG = theEnvironment.GetPDG();    // PDG code of the residual Nucl.Environ.
01529 #ifdef debug
01530     G4cout<<"G4QE::HQE:***NO QUASMONS***Env="<<nPDG<<theEnvironment.Get4Momentum()<<G4endl;
01531 #endif
01532     if(nPDG==90000000) return theQHadrons;
01533     if(nPDG>80000000)
01534     {
01535       G4QHadron* rNucleus = new G4QHadron(theEnvironment); // Create HadronEnvironment
01536       theQHadrons.push_back(rNucleus);       // Fill GS - no further decay (del. equiv.)
01537 #ifdef fdebug
01538       G4cout<<"G4QEnv::HadrQE: ---->> Fill Environment="<<theEnvironment<<G4endl;
01539 #endif
01540     }
01541     return theQHadrons;
01542   }
01543   if(theEnvironment.GetPDG()==NUCPDG)        // ==> "Environment is Vacuum" case
01544   {
01545 #ifdef rdebug
01546     G4cout<<"G4QEnv::HadrQE: ***Vacuum*** #ofQ="<<nQuasmons<<G4endl;
01547     G4int totInC=0;
01548     G4LorentzVector totIn4M(0.,0.,0.,0.);
01549     for (G4int is=0; is<nQuasmons; is++)     // Sum4mom's of Quasmons for the comparison
01550     {
01551       G4Quasmon*      pQ = theQuasmons[is];
01552       G4LorentzVector Q4M= pQ->Get4Momentum();
01553       totIn4M           += Q4M;
01554       totInC            += pQ->GetQC().GetCharge();
01555     } // End of TotInitial4Momentum summation LOOP over Quasmons
01556     G4int nsHadr  = theQHadrons.size();      // Update the value of OUTPUT entries
01557     if(nsHadr) for(G4int jso=0; jso<nsHadr; jso++)// LOOP over output hadrons 
01558     {
01559       G4int hsNF  = theQHadrons[jso]->GetNFragments(); // A#of secondary fragments
01560       if(!hsNF)                                        // Add only final hadrons
01561       {
01562         G4LorentzVector hs4Mom = theQHadrons[jso]->Get4Momentum();
01563         totIn4M          += hs4Mom;
01564         totInC           += theQHadrons[jso]->GetCharge();
01565       }
01566     }
01567 #endif
01568     G4QNucleus vE(90000000);
01569     G4int     nlq = 0;                       // Prototype of a#of Living Quasmons
01570     if(nQuasmons) for(G4int lq=0; lq<nQuasmons; lq++)if(theQuasmons[lq]->GetStatus())nlq++;
01571     if(nQuasmons) for(G4int iq=0; iq<nQuasmons; iq++)
01572     {
01573 #ifdef chdebug
01574       G4int f1Charge=theEnvironment.GetCharge();
01575       G4int f1BaryoN=theEnvironment.GetA();
01576       G4int nHad=theQHadrons.size();
01577       if(nHad) for(G4int ih=0; ih<nHad; ih++)
01578       {
01579         f1Charge+=theQHadrons[ih]->GetCharge();
01580         f1BaryoN+=theQHadrons[ih]->GetBaryonNumber();
01581       }
01582       G4int nQuas=theQuasmons.size();
01583       if(nQuas)for(G4int iqs=0; iqs<nQuas; iqs++)
01584       {
01585         f1Charge+=theQuasmons[iqs]->GetCharge();
01586         f1BaryoN+=theQuasmons[iqs]->GetBaryonNumber();
01587       }
01588       if(f1Charge!=totCharge || f1BaryoN!=totBaryoN)
01589       {
01590         G4cout<<"*::*G4QE::HQ:(2)q#"<<iq<<",tC="<<totCharge<<",C="<<f1Charge<<",tB="
01591               <<totBaryoN<<",B="<<f1BaryoN<<",E="<<theEnvironment<<G4endl;
01592         if(nHad) for(G4int h=0; h<nHad; h++)
01593         {
01594           G4QHadron* cH = theQHadrons[h];
01595           G4cout<<"*:*G4QE::HQ:#"<<h<<",QC="<<cH->GetQC()<<",P="<<cH->GetPDGCode()<<G4endl;
01596         }
01597         if(nQuas) for(G4int q=0; q<nQuas; q++)
01598         {
01599           G4Quasmon* cQ = theQuasmons[q];
01600           G4cout<<"*:*G4QE::HQ:q#"<<q<<",C="<<cQ->GetCharge()<<",QC="<<cQ->GetQC()<<G4endl;
01601         }
01602       }
01603 #endif
01604       G4int ist=theQuasmons[iq]->GetStatus();// Status of the Quasmon before fragmentation
01605       if(ist)
01606       {
01607         G4QHadronVector* output=theQuasmons[iq]->Fragment(vE,1);
01608         G4int ast=theQuasmons[iq]->GetStatus();  // Quasmon's Status after fragmentation  ^
01609         if(!ast) nlq--;                          // Reduce nlq if Quasmon decayed         ^
01610         G4int nHadrons = output->size();         // A#of output Hadrons in the Quasmon    ^
01611 #ifdef debug
01612         G4cout<<"G4QEnv::HadrQE: ***Vacuum*** Q#"<<iq<<", nHadr="<<nHadrons<<G4endl; //   ^
01613 #endif
01614         if(nHadrons>0)                           // Copy QHadrons-Quasmon to Output       ^
01615         {
01616           for (G4int ih=0; ih<nHadrons; ih++)    // LOOP over QHadrons of the Quasmon     ^
01617           {
01618             //G4QHadron* curH=new G4QHadron(output->operator[](ih));// (Del 7 lines below)^
01619             G4QHadron* curH = new G4QHadron((*output)[ih]); // (Deleted 7 lines below)    ^
01620 #ifdef debug
01621             G4cout<<"G4QEnv::HadrQE:Vacuum, H#"<<ih<<", QPDG="<<curH->GetQPDG() //        ^
01622                   <<",4M="<<curH->Get4Momentum()<<G4endl; //                              ^
01623 #endif
01624             theQHadrons.push_back(curH);         // Fill hadron-copy (delete equivalent)  ^
01625           }
01626         }                                        //                                       ^
01627         else                                     // => "Quasmon can't decay" case         ^
01628         {                                        //                                       ^
01629           G4QContent totQC=theQuasmons[iq]->GetQC();//                                    ^
01630           G4int     tQBN=totQC.GetBaryonNumber();// Baryon Number of not decayed Quasmon  ^
01631           G4QNucleus     tqN(totQC);             // Define the quasmon as a nucleus       ^
01632           G4double   gsM=tqN.GetMZNS();          // GS Mass                               ^
01633           G4LorentzVector tot4M=theQuasmons[iq]->Get4Momentum();
01634           G4double totQM=tot4M.m();              // Real Mass of Quasmon                  ^
01635           if(tQBN>0&&totQM>gsM)                  // => "Try Quasmon evaporation" case     ^
01636           {                                      //                                       ^
01637             G4QHadron* nuclQ = new G4QHadron(totQC,tot4M); //                             ^
01638 #ifdef fdebug
01639             G4cout<<"G4QEnv::HadrQE:Vac,tQC"<<totQC<<",t4M="<<tot4M<<G4endl; //           ^
01640 #endif
01641             EvaporateResidual(nuclQ);            // Evaporate ResNuc (del.equiv)          ^
01642             theQuasmons[iq]->KillQuasmon();      // Kill evaporated Quasmon               ^
01643             nlq--;                               //                                       ^
01644           }
01645           else if(iq+1<nQuasmons&&nlq>1)         // => "Try to merge with next" case      ^
01646           {
01647             G4int s_value=theQuasmons[iq+1]->GetStatus();//Status of the next Quasmon     ^
01648             theQuasmons[iq+1]->IncreaseBy(theQuasmons[iq]);// Merge with the next Quasmon ^
01649             theQuasmons[iq]->KillQuasmon();      // Kill the week Quasmon                 ^
01650             if(s_value) nlq--;                   // Reduce a number of "living Quasmons"  ^
01651           }
01652           else if(iq+1==nQuasmons&&iq&&nlq>1)    // => "Quasmon stack is exhosted" case   ^
01653           {
01654             G4int s_value=theQuasmons[0]->GetStatus(); // Status of the first Quasmon     ^
01655             theQuasmons[0]->IncreaseBy(theQuasmons[iq]);// Merge with the first Quasmon   ^
01656             theQuasmons[iq]->KillQuasmon();      // Kill the week Quasmon                 ^
01657             if(s_value) nlq--;                   // Reduce a number of "living Quasmons"  ^
01658           }
01659           else                                   // "Have a chance to recover" case       ^
01660           {                                      //                                       ^
01661 #ifdef debug
01662             G4cout<<"***G4QE::HQE:"<<iq<<",n="<<nHadrons<<",Tot="<<totQC<<totQM<<G4endl;//^
01663             for (G4int kq=0; kq<nQuasmons; kq++) // LOOP over Quasmons for DEBUG PRINTING ^
01664               G4cout<<kq<<",St/QC="<<theQuasmons[kq]->GetStatus()<<theQuasmons[kq] //     ^
01665                     ->GetQC()<<",M="<<theQuasmons[kq]->Get4Momentum().m()<<G4endl; //     ^
01666 #endif
01667             G4int nOfOUT = theQHadrons.size();   // Total #of QHadrons at this point      ^
01668             G4double  dM = totQM-gsM;            // Excitation of the Quasmon             ^
01669             G4bool corrf = true;                 // False when corrected & needs to quit  ^
01670             while(nOfOUT && corrf)               // LOOP over all existing QHadrons       ^
01671             {                                    //                                       ^
01672               G4QHadron*     theLast = theQHadrons[nOfOUT-1];     //  Remember            ^
01673               G4LorentzVector last4M = theLast->Get4Momentum();   //  all                 ^
01674               G4QContent      lastQC = theLast->GetQC();          //  content             ^
01675               G4int           lastS  = lastQC.GetStrangeness();   //  of    // Only       ^
01676               G4int           totS   = totQC.GetStrangeness();    //  the   // for        ^
01677               G4int           nFr    = theLast->GetNFragments();  //  Last  // if()       ^
01678               G4int           gam    = theLast->GetPDGCode();     //        //            ^
01679               if(gam!=22&&!nFr&&lastS<0&&lastS+totS<0&&nOfOUT>1)//=> Skip K,gam & decayed ^
01680               {                                  //                                       ^
01681                 G4QHadron* thePrev = theQHadrons[nOfOUT-2];// Kill Prev & make Last->Prev ^
01682                 theQHadrons.pop_back();          // theLastQHadron is excluded from OUTPUT^
01683                 theQHadrons.pop_back();          // thePrevQHadron is excluded from OUTPUT^
01684                 theQHadrons.push_back(thePrev);  // thePrev becomes theLast as an object  ^
01685                 delete     theLast;              // the Last QHadron is destructed        ^
01686                 theLast = thePrev;               // Update parameters (thePrev*->theLast*)^
01687                 last4M = theLast->Get4Momentum();// 4Mom of the previouse Quasmon         ^
01688                 lastQC = theLast->GetQC();       // Quark Content of the previouse Quasmon^
01689               }                                  //                                       ^
01690               else                               // Just Clear and destroy theLast        ^
01691               {                                  //                                       ^
01692                 theQHadrons.pop_back();          // theLastQHadron is excluded from OUTPUT^
01693                 delete         theLast;          // theLastQHadron is deleated as instance^
01694               }                                  //                                       ^
01695               totQC+=lastQC;                     // Update (increase) the total QC        ^
01696               tot4M+=last4M;                     // Update (increase) the total 4-momentum^
01697               totQM=tot4M.m();                   // Calculate new real total mass         ^
01698               G4QNucleus nN(totQC);              // Define the Quasmon as a nucleus       ^
01699               gsM=nN.GetMZNS();                  // Calculate the new GS Mass             ^
01700               dM = totQM-gsM;                    // Escitation energy for the Quasmon     ^
01701               if(dM>0)                           // "Mass of Q is big enough" case        ^
01702               {                                  //                                       ^
01703                 theQuasmons[iq]->InitQuasmon(totQC,tot4M);// Update the week Quasmon      ^
01704                 G4QHadronVector* curout=theQuasmons[iq]->Fragment(vE,1);
01705                 ast=theQuasmons[iq]->GetStatus();// Status of the Quasmon               ^ ^
01706                 if(!ast) nlq--;                  // Reduce nlq if Quasmon decayed       ^ ^
01707                 nHadrons=curout->size();         // A#of outputQHadrons in theDecayedQ  ^ ^
01708 #ifdef debug
01709                 G4cout<<"G4QEnv::HadrQE:VacuumRecoverQ#"<<iq<<",n="<<nHadrons<<G4endl;//^ ^
01710 #endif
01711                 if(nHadrons>0)                   // => "QHadrons from Quasmon to Output"^ ^
01712                 {                                //                                     ^ ^
01713                   for (G4int ih=0; ih<nHadrons; ih++) // LOOP over Hadrons of theQuasmon^ ^
01714                   {                              //                                     ^ ^
01715                     //G4QHadron* curH = new G4QHadron(curout->operator[](ih)); //       ^ ^
01716                     G4QHadron* curH = new G4QHadron((*curout)[ih]); //                  ^ ^
01717 #ifdef debug
01718                     G4cout<<"G4QEnv::HadrQE:Recovered, H#"<<ih<<", QPDG=" //            ^ ^
01719                           <<curH->GetQPDG()<<",4M="<<curH->Get4Momentum()<<G4endl;  //  ^ ^
01720 #endif
01721                     totQC-=curH->GetQC();        // totQC recalculation                 ^ ^
01722                     tot4M-=curH->Get4Momentum(); // tot4M recalculation                 ^ ^
01723                     theQHadrons.push_back(curH); // Fill hadron-copy (delete equivalent)^ ^
01724                     //delete curout->operator[](ih);//>-Necessary to delete instances*>-^ ^
01725                     delete (*curout)[ih];        // >-*Necessary to delete instances*>--^ ^
01726                   } // End of LOOP over Hadrons of the Quasmon                          ^ ^
01727                   curout->clear();               //                                     ^ ^
01728                   delete curout;                 //>*Necessary to delete VectPointers*>=^ ^
01729                   corrf = false;                 // Corrected: go out of the while loop ^ ^
01730                   //break;                       // @@ ??                               ^ ^
01731                 } // End of check for existing output Hadrons in the Quasmon            ^ ^
01732                 else                             //                                     ^ ^
01733                 {                                //                                     ^ ^
01734                   for_each(curout->begin(), curout->end(), DeleteQHadron()); // >-------^ ^
01735                   curout->clear();               //                                     ^ ^
01736                   delete curout;                 //>*Necessary to delete VectPointers>--^ ^
01737                 }                                //                                       ^
01738               }                                  //                                       ^
01739               nOfOUT  = theQHadrons.size();      // Update the value of OUTPUT entries    ^
01740 #ifdef rdebug
01741               G4int tC=totInC;                   // Vacuum: No ResidualEnvironCharge      ^
01742               G4LorentzVector t4M=totIn4M;       // Vacuum: No ResidualEnvironment 4-Mom  ^
01743               for (G4int js=0; js<nQuasmons; js++) // Subtract 4mom's of Quasmons from dif^
01744               {                                  //                                       ^
01745                 G4Quasmon*      pQ = theQuasmons[js]; //                                  ^
01746                 if(pQ->GetStatus())              // Subtract only if Quasmon is alive     ^
01747                 {                                //                                       ^
01748                   G4LorentzVector Q4M= pQ->Get4Momentum(); //                             ^
01749                   t4M               -= Q4M;                //                             ^
01750                   tC                -= pQ->GetQC().GetCharge(); //                        ^
01751                 }                                //                                       ^
01752                 else G4cout<<"G4QE::HQ:SUM-4-Mom s("<<js<<")="<<pQ->GetStatus()<<G4endl;//^
01753               } // End of Quasmons4Momentum subtractions                                  ^
01754               if(nOfOUT) for(G4int jpo=0; jpo<nOfOUT; jpo++)// LOOP over output hadrons   ^
01755               {                                  //                                       ^
01756                 G4int hsNF  = theQHadrons[jpo]->GetNFragments();//A#of secondary fragments^
01757                 if(!hsNF)                                   // Subtract only final hadrons^
01758                 {
01759                   G4LorentzVector hs4Mom = theQHadrons[jpo]->Get4Momentum(); //           ^
01760                   t4M                   -= hs4Mom;                           //           ^
01761                   tC                    -= theQHadrons[jpo]->GetCharge();    //           ^
01762                 }                                //                                       ^
01763               }                                  //                                       ^
01764               G4cout<<"G4QE::HQ:|||Vacuum|||4-MomCHECK|||d4M="<<t4M<<",dC="<<tC<<G4endl;//^
01765 #endif
01766             }                                    // End of the WHILE LOOP                 ^
01767             //if(!nOfOUT&&nQuasmons==1)          // TRY TO EVAPORATE THE TOTAL SYSTEM     ^
01768             if((!nOfOUT&&nQuasmons==1)||theEnvironment.GetPDGCode()==NUCPDG)//EvaporTotal ^
01769             {                                    //                                       ^
01770               G4int totS=totQC.GetStrangeness(); //  Total Strangeness                    ^
01771               //G4int totBN=totQC.GetBaryonNumber();// Total Baryon Number                ^
01772               G4int totPDG=totQC.GetZNSPDGCode();// Convert QC to PDGCOde for the nucleus ^
01773               if(totS) totPDG-=totS*999999;      // @@ ??                                 ^
01774 #ifdef fdebug
01775               G4cout<<"G4QE::HQE: totPDG="<<totPDG<<",totM="<<totQM<<G4endl; //           ^
01776 #endif
01777               G4QHadron* evH = new G4QHadron(totQC,tot4M); // Create a Hadron-ResidualNucl^
01778               CleanUp();                         //                                       ^
01779               EvaporateResidual(evH);            // Evaporate ResNuc (del.equiv)          ^
01780               for_each(output->begin(), output->end(), DeleteQHadron());// >------------->+
01781               output->clear();                   //                                       ^
01782               delete output;                     // >--------------->-------------------->+
01783               return theQHadrons;                //                                       ^
01784             }                                    //                                       ^
01785             else if(!nOfOUT)                     // Still remain not used Quasmons        ^
01786             {                                    //                                       ^
01787               G4ExceptionDescription ed;         //                                       ^
01788               ed <<"Can't decay Quasmon: T="<< tot4M << totQC << ",M=" << totQM        // ^
01789                  <<" < gsM="<< gsM <<", d="<< dM <<",Env="<< theEnvironment << G4endl; // ^
01790               G4Exception("G4QEnvironment::HadronizeQEnvironment()", "HAD_CHPS_0000",  // ^
01791                           FatalException, ed);                                         // ^
01792             }                                    //                                       ^
01793           } // End of PANIC treatment                                                     ^
01794         } // End of trouble handling with Quasmon decay in Vacuum                         ^
01795         for_each(output->begin(), output->end(), DeleteQHadron());  // >----------------->+
01796         output->clear();                         //                                       ^
01797         delete output;                           // >----------------->------------------>+
01798       } // End of check for the already decayed Quasmon
01799     } // End of the LOOP over Quasmons
01800   }
01801   else                                           // ==> "Nuclear environment" case
01802   {
01803 #ifdef rdebug
01804     G4cout<<"G4QEnv::HadrQE:FRAGMENTATION IN NUCLEAR ENVIRONMENT nQ="<<nQuasmons<<G4endl;
01805     G4int totInC=theEnvironment.GetZ();
01806     G4LorentzVector totIn4M=theEnvironment.Get4Momentum();
01807     for (G4int is=0; is<nQuasmons; is++) // Sum 4mom's of Quasmons for comparison
01808     {
01809       G4Quasmon*      pQ = theQuasmons[is];
01810       G4LorentzVector Q4M= pQ->Get4Momentum();
01811       totIn4M           += Q4M;
01812       totInC            += pQ->GetQC().GetCharge();
01813     } // End of TotInitial4Momentum summation LOOP over Quasmons
01814     G4int nsHadr  = theQHadrons.size();        // Update the value of #of OUTPUT entries
01815     if(nsHadr) for(G4int jso=0; jso<nsHadr; jso++)// LOOP over output hadrons 
01816     {
01817       G4int hsNF  = theQHadrons[jso]->GetNFragments(); // A#of secondary fragments
01818       if(!hsNF)                                        // Add only final hadrons
01819       {
01820         G4LorentzVector hs4Mom = theQHadrons[jso]->Get4Momentum();
01821         totIn4M          += hs4Mom;
01822         totInC           += theQHadrons[jso]->GetCharge();
01823       }
01824     }
01825 #endif
01826     // @@ Experimental calculations
01827     G4QContent totInQC=theEnvironment.GetQCZNS();
01828     G4LorentzVector totIn4M=theEnvironment.Get4Momentum();
01829     for (G4int is=0; is<nQuasmons; is++) // Sum 4mom's of Quasmons for comparison
01830     {
01831       G4Quasmon*      pQ = theQuasmons[is];
01832       totIn4M           += pQ->Get4Momentum();
01833       totInQC           += pQ->GetQC();
01834     } // End of TotInitial4Momentum/QC summation LOOP over Quasmons
01835     G4double totMass=totIn4M.m();
01836     G4QNucleus totN(totInQC);
01837     G4double totM=totN.GetMZNS();
01838     G4double excE = totMass-totM;
01839     // @@ End of experimental calculations
01840     G4int   envA=theEnvironment.GetA();
01841     //G4int   c3Max = 27;                   // Big number (and any #0) slowes dow a lot
01842     //G4int   c3Max = 9;                    // Max#of "no hadrons" steps (reduced below?)
01844     G4int   c3Max = 1;
01845     if(excE > fPi0) c3Max=(G4int)(excE/mPi0); // Try more for big excess
01846     //G4int   c3Max = 1;
01847     //if(excE > dPi0) c3Max=(G4int)(excE/mPi0); // Try more for big excess
01848     //G4int   c3Max = 0;
01849     //if(excE > mPi0) c3Max=(G4int)(excE/mPi0); // Try more for big excess
01850     //G4int   c3Max = 0;                    // It closes the force decay of Quasmon at all!
01851     //
01852     //G4int   premC = 27;
01853     //G4int   premC = 3;
01854     G4int   premC = 1;
01855     //if(envA>1&&envA<13) premC = 24/envA;
01856     if(envA>1&&envA<19) premC = 36/envA;
01857     //if(envA>1&&envA<31) premC = 60/envA;
01858     //if(envA>1&&envA<61) premC = 120/envA;
01859     G4int  sumstat= 2;                     // Sum of statuses of all Quasmons
01860     G4bool force  = false;                 // Prototype of the Force Major Flag
01861     G4int cbR     =0;                      // Counter of the "Stoped by Coulomb Barrier"
01862     //
01863     //G4int cbRM    =0;                      // * MaxCounter of "StopedByCoulombBarrier" *
01864     //G4int cbRM    =1;                      // MaxCounter of the "StopedByCoulombBarrier"
01865     //G4int cbRM    =3;                      // MaxCounter of the "StopedByCoulombBarrier"
01866     //G4int cbRM    =9;                      // MaxCounter of the "Stoped byCoulombBarrier"
01867     G4int cbRM    = c3Max;                 // MaxCounter of the "StopedByCoulombBarrier"
01868     G4int totC    = 0;                     // Counter to break the "infinit" loop
01869     //G4int totCM   = 227;                   // Limit for the "infinit" loop counter
01870     G4int totCM   = envA;                   // Limit for the "infinit" loop counter
01871     //G4int totCM   = 27;                    // Limit for this counter
01872     //G4int nCnMax = 1;                      // MaxCounterOfHadrFolts for shortCutSolutions
01873     //G4int nCnMax = 3;                      // MaxCounterOfHadrFolts for shortCutSolutions
01874     //G4int nCnMax = 9;                      // MaxCounterOfHadrFolts for shortCutSolutions
01875     G4int nCnMax = c3Max;                  // MaxCounterOfHadrFolts for shortCutSolutions
01876     G4bool first=true;                     // Flag of the first interaction (only NucMedia)
01877     G4int cAN=0;                           // Counter of the nucleon absorptions
01878     //G4int mcAN=27;                         // Max for the counter of nucleon absorptions
01880     //G4int mcAN=3;                          // Max for the counter of nucleon absorptions
01881     G4int mcAN=1;                          // Max for the counter of nucleon absorptions
01882     G4double proNorm=.001;                 // Rescattering parameter mb^-1 
01883     //G4double proNorm=.0027;                // Rescattering parameter mb^-1
01884     while (sumstat||totC<totCM)            // ===***=== The MAIN "FOREVER" LOOP ===***===
01885     {
01886 #ifdef chdebug
01887       G4int f2Charge=0;
01888       G4int f2BaryoN=0;
01889       if(theEnvironment.GetMass()>0.)
01890       {
01891         f2Charge=theEnvironment.GetCharge();
01892         f2BaryoN=theEnvironment.GetA();
01893       }
01894       G4int nHad=theQHadrons.size();
01895       if(nHad) for(G4int ih=0; ih<nHad; ih++)
01896       {
01897         f2Charge+=theQHadrons[ih]->GetCharge();
01898         f2BaryoN+=theQHadrons[ih]->GetBaryonNumber();
01899       }
01900       G4int nQuas=theQuasmons.size();
01901       if(nQuas)for(G4int iqs=0; iqs<nQuas; iqs++)
01902       {
01903         f2Charge+=theQuasmons[iqs]->GetCharge();
01904         f2BaryoN+=theQuasmons[iqs]->GetBaryonNumber();
01905       }
01906       if(f2Charge!=totCharge || f2BaryoN!=totBaryoN)
01907       {
01908         G4cout<<"*::*G4QE::HQ:(3)(NucEnv)i#"<<totC<<",tC="<<totCharge<<",C="<<f2Charge
01909               <<",tB="<<totBaryoN<<",B="<<f2BaryoN<<",E="<<theEnvironment<<G4endl;
01910         if(nHad) for(G4int h=0; h<nHad; h++)
01911         {
01912           G4QHadron* cH = theQHadrons[h];
01913           G4cout<<"*:*G4QE::HQ:#"<<h<<",QC="<<cH->GetQC()<<",P="<<cH->GetPDGCode()<<G4endl;
01914         }
01915         if(nQuas) for(G4int q=0; q<nQuas; q++)
01916         {
01917           G4Quasmon* cQ = theQuasmons[q];
01918           G4cout<<"*:*G4QE::HQ:q#"<<q<<",C="<<cQ->GetCharge()<<",QC="<<cQ->GetQC()<<G4endl;
01919         }
01920       }
01921 #endif
01922       totC++;
01923       if( nQuasmons==1 && sumstat==3 ) cbR++;    // Counter of dead solutions for nQ=1
01924       else cbR=0;
01925       G4QContent envQC=theEnvironment.GetQCZNS();// QuarkCont of current NuclearEnvironment
01926       G4QContent totQC=envQC;                    // Total QuarkContent in the system
01927       G4double   envM =theEnvironment.GetMass(); // mass of NuclEnvironment (@@GetMZNS())
01928       G4double   sumM =envM;                     // Sum of all residual masses in theSystem
01929       G4LorentzVector env4M=theEnvironment.Get4Momentum();      
01930       G4LorentzVector tot4M=env4M;               // 4-momentum of the Total System
01931       sumstat         =0;
01932       G4int     nCount=0;                        // Counter of notsuccessful fragmentations
01933       G4int     fCount=0;                        // Counter of successful(notFinal) fragm's
01934       G4int     eCount=0;                        // Counter of not yet decayed Quasmons
01935       for (G4int iq=0; iq<nQuasmons; iq++)       // Sum up Quasmons for making a decision
01936       {
01937         G4Quasmon*      pQ = theQuasmons[iq];
01938         G4QContent      QQC= pQ->GetQC();
01939         totQC             += QQC;
01940         G4LorentzVector Q4M= pQ->Get4Momentum();
01941         tot4M             += Q4M;
01942         G4double        QM = Q4M.m();
01943         sumM              += QM;
01944         G4int           Qst= pQ->GetStatus();
01945         sumstat           += Qst;
01946 #ifdef debug
01947         G4cout<<"G4QEnv::HadrQE:#"<<iq<<", Qst="<<Qst<<", Q="<<Q4M<<Q4M.m()<<QQC<<", Env="
01948               <<theEnvironment<<",nQ="<<nQuasmons<<G4endl;
01949 #endif
01950         if(nQuasmons>1 && iq+1==nQuasmons && !Qst && Q4M==zeroLV)
01951         {
01952           theQuasmons.pop_back();                // Exclude the zero-Quasmon
01953           delete pQ;                             // and delet it
01954           nQuasmons--;
01955         }
01956         if(Qst==1||Qst==3||Qst==4)
01957         {
01958           fCount++;                              // Incr. counterSuccessfulFragmentations
01959           nCount=0;                             // SetCounterNotSuccessfulFragmentations
01960         }
01961         if(Qst>0)                  eCount++;     // Incr. counter of existing Quasmons 
01962       } // End of summation LOOP over Quasmons
01963       G4int      totS  =totQC.GetStrangeness();  // Total Strangeness of the Total System
01964       G4int      totBN =totQC.GetBaryonNumber(); // Total Baryon Number of the Total System
01965       G4int      totPDG=0;                       // Total PDG Code for the Current compound
01966       totM  =0.;                                 // min(GroundSt)Mass of theResidualSystem
01967       if(totBN < 2)                              // Solution for the light nucleus  
01968       {
01969         totPDG=totQC.GetSPDGCode();              // Min totPDGCode for theCurrentCompound
01970         if(totPDG) totM=G4QPDGCode(totPDG).GetMass(); // min Mass of the Residual System
01971         else
01972         {
01973           // throw G4QException("G4QEnv::HadrQEnv: Impossible PDG for B=1");
01974           G4Exception("G4QEnvironment::HadronizeQEnvironment()", "HAD_CHPS_0001",
01975                       FatalException, "Impossible PDG for B=1");
01976         }
01977       }
01978       else
01979       {
01980         G4QNucleus totN_temporary(totQC,tot4M);  // Excited nucleus for theResidualSystem
01981         totN=totN_temporary;
01982         totM=totN.GetMZNS();                     // min(GroundSt)Mass of theResidualSystem
01983         totPDG=totN.GetPDG();                    // Total PDG Code for the Current compound
01984       }
01985 #ifdef fdebug
01986       G4cout<<"G4QEnv::HadrQE:totC="<<totC<<"<totCM="<<totCM<<",ss="<<sumstat<<G4endl;
01987 #endif
01988       if ( totC >= totCM || cbR > cbRM)
01989       {
01990         CleanUp();
01991         G4QHadron* evH = new G4QHadron(totQC,tot4M);// Create a Hadron for ResidualNucl
01992         EvaporateResidual(evH);             // Try to evaporate residual (del. equiv.)
01993         return theQHadrons;
01994       }
01995       // === Now we should be prepared for evaporation ===
01996       G4int      totChg=totQC.GetCharge();    // Total Electric Charge of the Total System
01997 #ifdef debug
01998       if(totPDG==90999999||totPDG==90999000||totPDG==90000999||totPDG==89999001)
01999       G4cout<<"***G4QEnv::HadrQEnv: Meson (1) PDG="<<totPDG<<", M="<<tot4M.m()<<G4endl;
02000       G4int           nOH=theQHadrons.size(); // A#of output hadrons
02001       G4LorentzVector s4M=tot4M;              // Total 4-momentum (@@ only for checking)
02002       if(nOH) for(G4int ih=0; ih<nOH; ih++) s4M+=theQHadrons[ih]->Get4Momentum();     
02003       G4cout<<"G4QEnv::HadrQE:tBN="<<totBN<<",s="<<sumstat<<",fC="<<fCount<<",eC="<<eCount
02004             <<",En="<<theEnvironment<<",nH="<<nOH<<",tLV="<<s4M<<totQC<<nCount<<G4endl;
02005 #endif
02006       if(totBN<2)                             // => "Baryons or Mesons" case (@@antiBaryon)
02007       {
02008         totPDG =totQC.GetSPDGCode();
02009         if(totPDG && totPDG!=10 && totPDG!=1114 && totPDG!=2224)
02010                                                          totM=G4QPDGCode(totPDG).GetMass();
02011         else if(totPDG==1114) totM=mNeut+mPi;
02012         else if(totPDG==2224) totM=mProt+mPi;
02013         else if(totPDG==10)
02014         {
02015           G4QChipolino totChip(totQC);        // define the residual as a Chipolino
02016           totM  =totChip.GetQPDG1().GetMass()+totChip.GetQPDG2().GetMass();
02017         }
02018         else
02019         {
02020           G4ExceptionDescription ed;
02021           ed << "Impossible Hadron in CHIPS: totPDG=" << totPDG << ", totQC="
02022              << totQC << G4endl;
02023           G4Exception("G4QEnvironment::HadronizeQEnvironment()", "HAD_CHPS_0002",
02024                       FatalException, ed); 
02025         }
02026       }
02027       totMass = tot4M.m();                        // Total effective Mass
02028       G4bool   Premium = eCount && premC && envM; // Premium condition
02029       G4int    count3  = 0;
02030       if(sumstat && (fCount||Premium) && !force && count3<c3Max)//=>"Force Quasmons decay"
02031       {
02032         if(!fCount) premC--;                  // Reduce premium efforts counter
02033         if(nQuasmons) for (G4int jq=0; jq<nQuasmons; jq++)//FragmentationLOOP over Quasmons
02034         {
02035           G4Quasmon* pQ     = theQuasmons[jq];// Pointer to the CurrentQuasmon <--<--<--+
02036           G4int      status = pQ->GetStatus();// Old status of the Quasmon              ^
02037 #ifdef debug
02038           G4cout<<"G4QE::HQE:Status of Q#"<<jq<<" (before Fragment)="<<status<<G4endl;//^
02039 #endif
02040           if(status)                          // Skip dead Quasmons                     ^
02041           {                                   //                                        ^
02042             G4int nQuas=eCount;               //                                        ^
02043             if(nQuas==1&&first) nQuas=-nQuas; //                                        ^
02044             G4QHadronVector* output=pQ->Fragment(theEnvironment,nQuas);//<DESTRUCT<--<--^-+
02045 #ifdef debug
02046             G4cout<<"G4QE::HQE:Q#"<<jq<<",*afterFragm* Env="<<theEnvironment<<G4endl;// ^ ^
02047 #endif
02048             envM =theEnvironment.GetMass();   // new mass of Nuclear Environment        ^ ^
02049             status = pQ->GetStatus();         // NewStatus after FragmentationAttempt   ^ ^
02050             if(!status) eCount--;             // Dec. ExistingQuasmonsCounter for Q=0   ^ ^
02051             G4int nHadrons = output->size();  //                                        ^ ^
02052 #ifdef rdebug
02053             G4cout<<"G4QE::HQE:**AfterFragmAttempt**#"<<jq<<",stat="<<status<<", Q4M="//^ ^
02054                   <<pQ->Get4Momentum()<<", Env="<<theEnvironment<<",nH="<<nHadrons //   ^ ^
02055                   <<",c3="<<count3<<" < "<<c3Max<<",eC="<<eCount<<G4endl;          //   ^ ^
02056             G4int tC=totInC-theEnvironment.GetZ(); // Subtract theResidualEnvironCharge ^ ^
02057             G4LorentzVector t4M=totIn4M;      // Compare with the total                 ^ ^
02058             G4LorentzVector theEnv4m=theEnvironment.Get4Momentum(); // Environment 4Mom ^ ^
02059             t4M-=theEnv4m;                    // Subtract the Environment 4-momentum    ^ ^
02060             G4cout<<"G4QEnv::HadrQE:SUM-4Mom e4M="<<theEnv4m<<theEnvironment<<G4endl;// ^ ^
02061             for (G4int js=0; js<nQuasmons; ++js)// Subtract 4mom's of Quasmons (compare)^ ^
02062             {                                 //                                        ^ ^
02063               G4Quasmon*      prQ = theQuasmons[js];//                                  ^ ^
02064               if(prQ->GetStatus())            // Subtract only if Quasmon is alive      ^ ^
02065               {                               //                                        ^ ^
02066                 G4LorentzVector Q4M= prQ->Get4Momentum(); //                            ^ ^
02067                 G4QContent qQC= prQ->GetQC(); //                                        ^ ^
02068                 G4cout<<"G4QE::HQE:SUM-4Mom q("<<js<<")4M="<<Q4M<<",QC="<<qQC<<G4endl;//^ ^
02069                 t4M          -= Q4M;          //                                        ^ ^
02070                 tC           -= prQ->GetQC().GetCharge(); //                            ^ ^
02071               }                               //                                        ^ ^
02072               else G4cout<<"G4QE::HQE:SUM-4M,st("<<js<<")="<<prQ->GetStatus()<<G4endl;//^ ^
02073             } // End of Quasmons4Momentum subtractions                                  ^ ^
02074             G4int nsbHadr=theQHadrons.size(); // Update the value of OUTPUT entries     ^ ^
02075             if(nsbHadr) for(G4int jpo=0; jpo<nsbHadr; jpo++)// LOOP over output hadrons ^ ^
02076             {                                 //                                        ^ ^
02077               G4int hsNF  = theQHadrons[jpo]->GetNFragments();// A#of out fragments     ^ ^
02078               if(!hsNF)                       // Subtract only final hadrons            ^ ^
02079               {                               //                                        ^ ^
02080                 G4LorentzVector hs4Mom = theQHadrons[jpo]->Get4Momentum(); //           ^ ^
02081                 G4int hPDG = theQHadrons[jpo]->GetPDGCode(); //                         ^ ^
02082                 G4cout<<"G4QE::HQE:SUM-4-Mom eh("<<jpo<<")4M="<<hs4Mom<<hPDG<<G4endl;// ^ ^
02083                 t4M          -= hs4Mom;       //                                        ^ ^
02084                 tC           -= theQHadrons[jpo]->GetCharge(); //                       ^ ^
02085               }                               // End of the "FinalHadron" IF            ^ ^
02086             }                                 // End of the LOOP over output hadrons    ^ ^
02087             if(nHadrons) for(G4int kpo=0; kpo<nHadrons; ++kpo)//LOOP over out QHadrons  ^ ^
02088             {                                 //                                        ^ ^
02089               //G4QHadron* insH =output->operator[](kpo);// Pointer to theOutputQHadron ^ ^
02090               G4QHadron* insH = (*output)[kpo];// Pointer to the Output QHadron         ^ ^
02091               G4int qhsNF  = insH->GetNFragments(); // A#of secondary fragments         ^ ^
02092               if(!qhsNF) // Should never be here // Subtract -> only final hadrons      ^ ^
02093               {                               //                                        ^ ^
02094                 G4LorentzVector qhs4Mom = insH->Get4Momentum();// 4M of theOutputHadron ^ ^
02095                 G4int hPDG = insH->GetPDGCode(); //  PDG Code of the Q-output Hadron    ^ ^
02096                 G4cout<<"G4QE::HQE:SUM-4-Mom qh("<<kpo<<")4M="<<qhs4Mom<<hPDG<<G4endl;//^ ^
02097                 t4M          -= qhs4Mom;      //                                        ^ ^
02098                 tC           -= insH->GetCharge(); //                                   ^ ^
02099               }                               //                                        ^ ^
02100             }                                 // End of the LOOP over output QHadrons   ^ ^
02101             G4cout<<"G4QEnv::HadrQE:|||||4-MomCHECK||||d4M="<<t4M<<",dC="<<tC<<G4endl;//^ ^
02102 #endif
02103             if(!status||status==1||nHadrons)  //OutHadronVector was filled in G4Q::Frag ^ ^
02104             {                                 //                                        ^ ^
02105               nCount=0;                       // Reset the NotSuccessfulFragmCounter    ^ ^
02106               if(nHadrons>0)                  // Transfer QHadrons from Quasm to Output ^ ^
02107               {                               //                                        ^ ^
02108                 for (G4int ih=0; ih<nHadrons; ++ih) // LOOP over Q-output QHadrons      ^ ^
02109                 {                             //                                        ^ ^
02110                   G4QHadron* inpH = (*output)[ih]; //                                   ^ ^
02111                   G4int hC=inpH->GetCharge(); // Charge of the Hadron                   ^ ^
02112                   G4int hF=inpH->GetNFragments();// Number of fragments                 ^ ^
02113                   G4double hCB=0.;            // Coulomb Barrier prototype              ^ ^
02114                   G4double hKE=0.;            // Kinetic Energy of the Hadron prototype ^ ^
02115                   G4LorentzVector hLV=inpH->Get4Momentum(); //                          ^ ^
02116 #ifdef debug
02117                   G4cout<<"->G4QEnv::HadrQE:H#"<<ih<<", hC="<<hC<<",hF="<<hF<<",4M=" // ^ ^
02118                         <<hLV<<inpH->GetPDGCode()<<G4endl;  //                          ^ ^
02119 #endif
02120                   G4bool can = hC && !hF;     // Charged and not yet decayed hadron     ^ ^
02121                   if(can)                     //                                        ^ ^
02122                   {                           //                                        ^ ^
02123                     G4int hB=inpH->GetBaryonNumber(); //                                ^ ^
02124                     hCB=theEnvironment.CoulombBarrier(hC,hB); // Coulomb barrier        ^ ^
02125                     hKE=hLV.e()-hLV.m();      // Kinetic energy of the QHadron          ^ ^
02126                   }                           //                                        ^ ^
02127                   if(can && hKE < hCB)        // => "Suck Hadron into Quas or Env" case ^ ^
02128                   {                           //                                        ^ ^
02129                     if(status)                // => "Suck into existing Quasmon" case   ^ ^
02130                     {                         //                                        ^ ^
02131                       G4QContent tQC=inpH->GetQC()+pQ->GetQC();  //                     ^ ^
02132                       G4LorentzVector tLV=hLV+pQ->Get4Momentum();//                     ^ ^
02133                       pQ->InitQuasmon(tQC,tLV); // Reinitialize the current Quasmon     ^ ^
02134 #ifdef debug
02135                       G4cout<<"G4QE::HQE:Medium, H#"<<ih<<", QPDG="<<inpH->GetQPDG() // ^ ^
02136                             <<",4M="<<inpH->Get4Momentum()<<" is suckedInQ"<<G4endl; // ^ ^
02137 #endif
02138                     }                         //                                        ^ ^
02139                     else                      // => "Suck in the Environment" case      ^ ^
02140                     {                         //                                        ^ ^
02141                       G4QContent tQC=inpH->GetQC()+theEnvironment.GetQCZNS();//         ^ ^
02142                       G4LorentzVector tLV=hLV+theEnvironment.Get4Momentum(); //         ^ ^
02143                       theEnvironment=G4QNucleus(tQC,tLV); // Reinit currentEnvironment  ^ ^
02144 #ifdef debug
02145                       G4cout<<"G4QE::HQE:Med,H#"<<ih<<",PDG="<<inpH->GetQPDG()<<",4M="//^ ^
02146                             <<inpH->Get4Momentum()<<" is suckedInEnvironment"<<G4endl;//^ ^
02147 #endif
02148                     }                         // End of the STATUS IF                   ^ ^
02149                   }                           // End of the E/Q suck Hdron IF           ^ ^
02150                   else if(!hF)                // => "Hadron can go out" case, skip dec  ^ ^
02151                   {                           //                                        ^ ^
02152                     G4QHadron* curH = new G4QHadron(inpH); //                           ^ ^
02153 #ifdef debug
02154                     G4LorentzVector ph4M=curH->Get4Momentum(); // 4-mom of the hadron   ^ ^
02155                     G4double phX=ph4M.x();    // p_x of the hadron                      ^ ^
02156                     G4double phY=ph4M.y();    // p_y of the hadron                      ^ ^
02157                     G4double phZ=ph4M.z();    // p_x of the hadron                      ^ ^
02158                     G4double phCost=phZ/sqrt(phX*phX+phY*phY+phZ*phZ);// Hadr cos(theta)^ ^
02159                     G4cout<<"G4QEnv::HadrQE:Medium, H#"<<ih<<",QPDG="<<curH->GetQPDG()//^ ^
02160                           <<", 4M="<<ph4M<<", ct="<<phCost<<G4endl; //                  ^ ^
02161 #endif
02162                     G4QContent qhdQC=curH->GetQC(); // QuarkCont of current QHadron     ^ ^
02163                     G4LorentzVector qhd4M=curH->Get4Momentum(); // 4Mom of currQHadron  ^ ^
02164                     // ... Here the rescattering starts ...                             ^ ^
02165                     G4int qhdBN=curH->GetBaryonNumber();// Baryon number of the hadron  ^ ^
02166                     G4bool scat= false;                 // Scattering happened Flag     ^ ^
02167                     G4int EnvZ = theEnvironment.GetZ(); // Z of the ResidualEnvironment ^ ^
02168                     G4int EnvN = theEnvironment.GetN(); // N of the ResidualEnvironment ^ ^
02169                     G4int EnvS = theEnvironment.GetS(); // S of the ResidualEnvironment ^ ^
02170                     G4int EnvA = EnvZ + EnvN + EnvS;    // A of the ResidualEnvironment ^ ^
02171                     G4double EnvM = theEnvironment.GetMZNS(); // ResidualEnvironmentMass   ^ ^
02172                     G4LorentzVector Env4M= theEnvironment.Get4Momentum(); //            ^ ^
02173 #ifdef debug
02174                     G4cout<<"=*=>G4QE::HQEnv: Env4M="<<Env4M<<",Z="<<EnvZ<<",N="<<EnvN//^ ^
02175                           <<",S="<<EnvS<<G4endl;                          //            ^ ^
02176 #endif
02177                     G4int hPDG = curH->GetPDGCode();      //                            ^ ^
02178                     G4LorentzVector h4M = curH->Get4Momentum(); //                      ^ ^
02179                     if(EnvA>1 && qhdBN>-1 && qhdBN<2 && h4M.vect().mag() > 0.000001 && hPDG>111 && //^ ^
02180                        hPDG!=222 && hPDG!=333)//** Quasi-free interaction is possible **^ ^
02181                     { //                                                                ^ ^
02182                       --EnvA;                             //                            ^ ^
02183                       G4double hM2 = h4M.m2();            //                            ^ ^
02184                       G4double hP  = h4M.rho();           //                            ^ ^
02185                       G4int pi0F=0;                       // Pi0 flag                   ^ ^
02186                       if(hPDG==111 || hPDG==222 || hPDG==333) pi0F=hPDG; //             ^ ^
02187                       if(pi0F) hPDG=211;                  //                            ^ ^
02188                       pair<G4double,G4double> Xp=theQFScat->FetchElTot(hP,hPDG,false);//^ ^
02189                       if(pi0F)                            // Get Pi+ and make the mean//^ ^
02190                       { //                                                              ^ ^
02191                         hPDG=-211;                        //                            ^ ^
02192                         pair<G4double,G4double>Y=theQFScat->FetchElTot(hP,hPDG,false);//^ ^
02193                         G4double fst=(Xp.first+Y.first)/2;//                            ^ ^
02194                         G4double snd=(Xp.second+Y.second)/2;//                          ^ ^
02195                         Xp.first  = fst;                  //                            ^ ^
02196                         Xp.second = snd;                  //                            ^ ^
02197                         hPDG=211;                         //                            ^ ^
02198                       } //                                                              ^ ^
02199                       G4double XSp = Xp.second;           // TotXS hp                   ^ ^
02200                       pair<G4double,G4double> Xn=theQFScat->FetchElTot(hP,hPDG,true);// ^ ^
02201                       if(pi0F)                            // Get Pi+ and make the mean//^ ^
02202                       { //                                                              ^ ^
02203                         hPDG=-211;                        //                            ^ ^
02204                         pair<G4double,G4double> Y=theQFScat->FetchElTot(hP,hPDG,true);//^ ^
02205                         G4double fst=(Xn.first+Y.first)/2;//                            ^ ^
02206                         G4double snd=(Xn.second+Y.second)/2;//                          ^ ^
02207                         Xn.first  = fst;                  //                            ^ ^
02208                         Xn.second = snd;                  //                            ^ ^
02209                         hPDG=pi0F;                        //                            ^ ^
02210                         pi0F=0;                           //                            ^ ^
02211                       } //                                                              ^ ^
02212                       G4double XSn = Xn.second;           // TotXS hn                   ^ ^
02213                       G4double XSZ = XSp * EnvZ;          //                            ^ ^
02214                       G4double XSN = XSn * EnvN;          //                            ^ ^
02215                       G4double XSA = XSZ + XSN;           //                            ^ ^
02216                       if(hM2 > 10000. && XSA > 0.)        // One can try to scatter     ^ ^
02217                       { //                                                              ^ ^
02218                         G4double Prob=XSA*sqrt(hM2)*G4QThd(EnvA)*proNorm/h4M.e()/EnvA;//^ ^
02219                         if(G4UniformRand() < Prob)        // Scattering                 ^ ^
02220                         { //                                                            ^ ^
02221                           G4double XEp = Xp.first;        // ElXS hp                    ^ ^
02222                           G4double XEn = Xn.first;        // ElXS hn                    ^ ^
02223                           G4double XEZ = XEp * EnvZ;      //                            ^ ^
02224                           G4double XEN = XEn * EnvN;      //                            ^ ^
02225                           G4double XEA = XEZ + XEN;       //                            ^ ^
02226                           G4int NPDG=2112;                // Quasi-Elastic on Neutron   ^ ^
02227                           G4bool flN=true;                //                            ^ ^
02228                           G4QNucleus newE(1,0);           // Fake Proto                 ^ ^
02229                           G4LorentzVector N4M(0.,0.,0.,0.); // Fake Proto               ^ ^
02230                           if(G4UniformRand() < XEA/XSA)   // Quasi-Elastic              ^ ^
02231                           { //                                                          ^ ^
02232                             if(G4UniformRand() < XEZ/XEA) // Quasi-Elastic on Proton    ^ ^
02233                             { //                                                        ^ ^
02234                               NPDG= 2212;                 //                            ^ ^
02235                               flN = false;                //                            ^ ^
02236                             } //                                                        ^ ^
02237                             if(flN) newE=G4QNucleus(EnvZ, EnvN-1, EnvS); // QF n        ^ ^
02238                             else    newE=G4QNucleus(EnvZ-1, EnvN, EnvS); // QF p        ^ ^
02239                             G4double mT=EnvM - newE.GetMZNS(); // Virtual mass          ^ ^
02240                             N4M = (mT/EnvM)*Env4M;        //                            ^ ^
02241                             newE.Set4Momentum(Env4M-N4M); //                            ^ ^
02242 #ifdef debug
02243                             G4cout<<"==>G4QE::HQE:QEl,NPDG=="<<NPDG<<",N4M="<<N4M    // ^ ^
02244                                   <<",hPDG="<<hPDG<<",h4M="<<h4M<<G4endl;            // ^ ^
02245 #endif
02246                             pair<G4LorentzVector,G4LorentzVector> RS =  //              ^ ^
02247                               theQFScat->Scatter(NPDG, N4M, hPDG, h4M); //              ^ ^
02248 #ifdef debug
02249                             G4cout<<"**>G4QE::HQE:QEl,N4M="<<RS.first<<",h4M=" //       ^ ^
02250                                <<RS.second<<",d="<<N4M+h4M-RS.first-RS.second<<G4endl;//^ ^
02251 #endif
02252                             if((RS.first).e() > 0.) // The Elastic Scattering is made //^ ^
02253                             { //                                                        ^ ^
02254                                       curH->Set4Momentum(RS.second);// justUpdate, NO scat=true ^ ^
02255                               G4QHadron* qfN = new G4QHadron(NPDG, RS.first); //        ^ ^
02256                               theQHadrons.push_back(qfN);// Fill QFN(delete equivalent) ^ ^
02257                               theEnvironment=newE;       // *** change Environment ***  ^ ^
02258 #ifdef debug
02259                               G4cout<<"*>G4QE::HQE:QE,PDG="<<NPDG<<",4M=" //            ^ ^
02260                                     <<RS.first<<",***newEnv***: "<<newE<<G4endl;//      ^ ^
02261 #endif
02262                               // The totQC & tot4M must be reduced by the qfN           ^ ^
02263                               tot4M-=RS.first;            // current tot4M is reduced   ^ ^
02264                               if     (NPDG==2212) totQC-=protQC; // sub n               ^ ^
02265                               else if(NPDG==2112) totQC-=neutQC; // sub p               ^ ^
02266                               else G4cout<<"*W*>G4QE::HQE:QE,Bad PDG="<<NPDG<<G4endl;// ^ ^
02267                             } //                                                        ^ ^
02268                           } //                                                          ^ ^
02269                           else                            // Quasi-Inelastic            ^ ^
02270                           { //                                                          ^ ^
02271                             if(G4UniformRand() < (XSZ-XEZ)/(XSA-XEA))// QInEl on Proton ^ ^
02272                             { //                                                        ^ ^
02273                               NPDG= 2212;                 //                            ^ ^
02274                               flN = false;                //                            ^ ^
02275                             } //                                                        ^ ^
02276                             if(flN) newE=G4QNucleus(EnvZ, EnvN-1, EnvS); // QF n        ^ ^
02277                             else    newE=G4QNucleus(EnvZ-1, EnvN, EnvS); // QF p        ^ ^
02278                             G4double mT=EnvM - newE.GetMZNS(); // Virtual mass          ^ ^
02279                             N4M = (mT/EnvM)*Env4M;        //                            ^ ^
02280                             newE.Set4Momentum(Env4M-N4M); //                            ^ ^
02281 #ifdef debug
02282                             G4cout<<"==>G4QE::HQE:QInEl,NPDG=="<<NPDG<<",N4M="<<N4M  // ^ ^
02283                                   <<",hPDG="<<hPDG<<",h4M="<<h4M<<G4endl;            // ^ ^
02284 #endif
02285                             G4QHadronVector* Q=theQFScat->InElF(NPDG, N4M, hPDG, h4M);//^ ^
02286                             if(Q) // Inelastic reaction succeeded                       ^ ^
02287                             { //                                                        ^ ^
02288                               theQHadrons.push_back((*Q)[0]); // Fill 1st (del. equiv.) ^ ^
02289                               theQHadrons.push_back((*Q)[1]); // Fill 2nd (del. equiv.) ^ ^
02290                               theQHadrons.push_back((*Q)[2]); // Fill 3d  (del. equiv.) ^ ^
02291                               theEnvironment=newE;            // *** change Environ *** ^ ^
02292 #ifdef debug
02293                               G4cout<<"*>G4QE::HQE:QIE,PDG1="<<(*Q)[0]->GetPDGCode() // ^ ^
02294                                     <<",4M1="<<(*Q)[0]->Get4Momentum()<<G4endl;      // ^ ^
02295                               G4cout<<"*>G4QE::HQE:QIE,PDG2="<<(*Q)[1]->GetPDGCode() // ^ ^
02296                                     <<",4M1="<<(*Q)[1]->Get4Momentum()<<G4endl;      // ^ ^
02297                               G4cout<<"*>G4QE::HQE:QIE,PDG3="<<(*Q)[2]->GetPDGCode() // ^ ^
02298                                     <<",4M1="<<(*Q)[2]->Get4Momentum()<<G4endl;      // ^ ^
02299                               G4cout<<"*>G4QE::HQE:QIE,***NewEnv***: "<<newE<<G4endl;// ^ ^
02300 #endif
02301                               scat=true;                      // Don't fill the Primary ^ ^
02302                               delete Q;
02303                             } //                                                        ^ ^
02304                           } //                                                          ^ ^
02305                         } //                                                            ^ ^
02306                       } //                                                              ^ ^
02307                     } //                                                                ^ ^
02308                     if(!scat) //                                                        ^ ^
02309                     // ... Rescattering END ........................                    ^ ^
02310                     theQHadrons.push_back(curH); // Fill hadronCopy (delete equivalent) ^ ^
02311                     totQC-=qhdQC;             //  Update QC of Env + Quasmons           ^ ^
02312                     tot4M-=qhd4M;             //  Update 4Mom of Env + Quasmons         ^ ^
02313                   }                           //                                        ^ ^
02314                 }                             // ==> End of the LOOP over outQHadrons   ^ ^
02315                 pQ->ClearOutput();            // Hadrons are filled, Clear Frag-out <-<-^ ^
02316                 count3=0;                     // Reset counter of empty hadronizations    ^
02317                 //c3Max=1;                    // Reduce repetition Max to accelerate      ^
02318                 first=false;                  // First hadronization is for sure is over  ^
02319               }                               //                                          ^
02320               else count3++;                  // Increment counter of empty hadronizations^
02321             }                                 //                                          ^
02322             else if(status<0||status==2)      // => "PANIC or NOTHING was done" case      ^
02323             {                                 //                                          ^
02324 #ifdef debug
02325               G4cout<<"G4QE::HQE:***PANIC***,status="<<status<<",nC="<<nCount<<G4endl; // ^
02326 #endif
02327               ++nCount;                       //                                          ^
02328               if(eCount==1 && status<0 && CheckGroundState(pQ,true))// Correct & Finish   ^
02329               {                               //                                          ^
02330                 for_each(output->begin(), output->end(), DeleteQHadron()); // ->->->----->^
02331                 output->clear();              //                                          ^
02332                 delete output;                // >----------------->--------------------->^
02333                 pQ->KillQuasmon();            // If BackFusion succeeded, kill the Quasmon^
02334                 delete pQ;
02335                 eCount--;                     // Reduce the number of the living Quasmons ^
02336                 return theQHadrons;           //                                          ^
02337               }                               //                                          ^
02338               else if(status<0&&nHadrons)     // This is just a confusion in the status...^
02339               {                               //                                          ^
02340                 G4cerr<<"***G4QEnv::HadrQE: nH="<<nHadrons<<"< status="<<status<<G4endl;//^
02341                 for_each(output->begin(), output->end(), DeleteQHadron()); // -->-->-->---^
02342                 output->clear();              //                                          ^
02343                 delete output;                // >------------------->------------------->^
02344                 G4Exception("G4QEnvironment::HadronizeQEnvironment()",      //            ^
02345                             "HAD_CHPS_0003", JustWarning, "Do Nothing Er"); //            ^
02346               }                               //                                          ^
02347               else if(status==2 && eCount==1 && cAN<mcAN && envM>500.)// Add N from E to Q^
02348               {                               //                                          ^
02349 #ifdef debug
02350                     G4cout<<"G4QE::HQE:E="<<theEnvironment<<",M="<<envM<<",c="<<cAN<<G4endl;//^
02351 #endif
02352                 cAN++;                        // Increment the counter of absorptions     ^
02353                 G4int envPDG = theEnvironment.GetPDG(); // PDGCode of the NuclQEnvironment^
02354                 env4M=theEnvironment.Get4Momentum();    // 4mom of the NucEnv             ^
02355                 G4int envN=theEnvironment.GetN();                    // N of Env          ^
02356                 G4int envZ=theEnvironment.GetZ();                    // Z of Env          ^
02357                 G4int resPDG=envPDG-1;        // Residual for the neutron (prototype)     ^
02358                 G4QContent nucQC=neutQC;      // Nucleon Quark Content                    ^
02359                 if ( envN && (envN+envZ)*G4UniformRand() > envZ ) // Change to a proton   ^
02360                 {                             //                                          ^
02361                   resPDG=envPDG-1000;         // new PDG for the Environment              ^
02362                   nucQC=protQC;               // proton QContent                          ^
02363                 }                             //                                          ^
02364 #ifdef debug
02365                     G4cout<<"G4QE::HQE:P,eZ="<<envZ<<",eN="<<envN<<",rPDG="<<resPDG<<G4endl;//^
02366 #endif
02367                 G4QNucleus resNuc(resPDG);    // Create the residual nucleus (future Env) ^
02368                 G4double resM=resNuc.GetGSMass();       // Mass of the residual nucleus   ^
02369                 G4double eM=theEnvironment.GetGSMass(); // Mass of the current environment^
02370                 G4double nucM=eM-resM;                  // Effective mass of theNucleon   ^
02371                 G4LorentzVector res4M(0.,0.,0.,resM);   // Prototype of newEnv4M (at rest)^
02372                 G4LorentzVector nuc4M(0.,0.,0.,nucM);   // Prototype of newEnv4M (at rest)^
02373                 if(std::fabs(env4M.e()-eM) > 0.001)     // the Environment is not at rest ^
02374                 {                                       //                                ^
02375                   res4M=(resM/eM)*env4M;                // Proportional 4M for residEnv   ^
02376                   nuc4M=(nucM/eM)*env4M;                // Proportional 4M for effNucleon ^
02377                 }                                       //                                ^
02378                 theEnvironment=G4QNucleus(res4M,resPDG);// Update the Environment         ^
02379                 theQuasmons[0]->IncreaseBy(nucQC,nuc4M);// Update the Only Quasmon        ^
02380 #ifdef debug
02381                     G4cout<<"G4QE::HQE:P,Q="<<nucQC<<nuc4M<<",env="<<theEnvironment<<G4endl;//^
02382 #endif
02383               }                                         //                                ^
02384               else if(status==2&&nCount>nCnMax)// Treat PANIC for stat=2 (NothingWasDone) ^
02385               {                               //                                          ^
02386 #ifdef debug
02387                     G4cout<<"G4QE::HQE:PANIC,nC="<<nCount<<">"<<nCnMax<<G4endl; //            ^
02388 #endif
02389                 G4QContent qQC=pQ->GetQC();   // QuarkContent of the Quasmon              ^
02390                 G4int      pqC=qQC.GetCharge(); // Charge (nP) of the Current Quasmon     ^
02391                 G4int      pqS=qQC.GetStrangeness(); // Strangeness (nL) of theCurrQuasmon^
02392                 G4int      pqB=qQC.GetBaryonNumber(); // BaryNumber of the CurrentQuasmon ^
02393                 G4LorentzVector cq4M=pQ->Get4Momentum(); // 4Mom of the Current Quasmon   ^
02394                 G4double cqMass=cq4M.m();     // Real Mass of the current Quasmon         ^
02395                 G4double fqMass=G4QPDGCode(22).GetNuclMass(pqC,pqB-pqC-pqS,pqS);//CQ FreeM^
02396 #ifdef edebug
02397                 G4cout<<"G4QEnv::HQE:M="<<cqMass<<">fM="<<fqMass<<",S="<<pqS<<",C="<<pqC//^
02398                       <<",ePDG="<<theEnvironment.GetPDG()<<",qQC="<<qQC<<",eC="<<eCount //^
02399                       <<G4endl;                                                     //    ^
02400 #endif
02401                 if(pqB>0&&pqS<0&&cqMass>fqMass)// "AntiStrangeNucleus-Chipolino" case     ^
02402                 {                             //                                          ^
02403                   G4QHadron* nuclQ = new G4QHadron(qQC,cq4M);// Hadron for AntiStrangeNuc.^
02404                   theEnvironment.DecayAntiStrange(nuclQ,&theQHadrons);// AntiStrange(D.E.)^
02405                   pQ->KillQuasmon();          // If BackFusion succeeded, kill theQuasmon ^
02406 #ifdef edebug
02407                   G4cout<<"G4QEnv::HQE:Status after kill (#"<<jq<<")="<<pQ->GetStatus()// ^
02408                         <<", nH="<<theQHadrons.size()<<G4endl;                         // ^
02409 #endif
02410                   tot4M-=cq4M;                // Update TotalResidNucleus for hadronizPro.^
02411                   totQC-=qQC;                 // Update total QC for the HadronizationPro.^
02412                   eCount--;                   // Reduce the number of the living Quasmons ^
02413                 }                             //                                          ^
02414                 else if(theEnvironment.GetPDG()!=NUCPDG) // ==> "NuclearEnvironment" case ^
02415                 {                             //                                          ^
02416                   if(eCount>1)                //                                          ^
02417                   {                           //                                          ^
02418 #ifdef fdebug
02419                     G4cout<<"G4QE::HQE:TOTEVAP tPDG="<<totPDG<<",t4M="<<tot4M<<G4endl; // ^
02420 #endif
02421                     G4QHadron* evH = new G4QHadron(totQC,tot4M); // Create Hadron-ResidNuc^
02422                     CleanUp();                //                                          ^
02423                     EvaporateResidual(evH);   // Evaporate ResNuc (delete equivalemt)     ^
02424                     for_each(output->begin(), output->end(), DeleteQHadron());// >--------^
02425                     output->clear();          //                                          ^
02426                     delete output;            // >---------->----------->---------------->^
02427                     return theQHadrons;       //                                          ^
02428                   }                           //                                          ^
02429                   G4LorentzVector t4M=cq4M+theEnvironment.Get4Momentum(); // Q+E tot4Mom  ^
02430                   G4double      tM=t4M.m();   // Real total (Quasmon+Environment) mass    ^
02431                   envQC=theEnvironment.GetQCZNS(); // QuarkCont of NucEnviron             ^
02432                   G4QContent curQC=envQC+qQC; // Total Quark Content                      ^
02433                   G4QNucleus curE(curQC);     // Pseudo nucleus for the Total System      ^
02434                   G4double   curM=curE.GetGSMass();// min mass of the Total System        ^
02435 #ifdef edebug
02436                   G4cout<<"G4QEnv::HQE:Q#"<<jq<<",tM="<<tM<<">gsM="<<curM<<curE<<G4endl;//^
02437 #endif
02438                   if(tM<curM)                 //                                          ^
02439                   {
02440                     G4int qPDG=qQC.GetZNSPDGCode();// PDG Code of the Quasmon             ^
02441                     G4double qMass=G4QPDGCode(qPDG).GetMass(); // GroundStM of theQuasmon ^
02442 #ifdef edebug
02443                     G4cout<<"G4QE::HQE:nQ="<<nQuasmons<<",eC="<<eCount<<",qPDG="<<qPDG // ^
02444                           <<",qM="<<qMass<<",eM="<<envM<<",tM="<<tM<<",Q+E="<<qMass+envM//^
02445                           <<G4endl;           //                                          ^
02446 #endif
02447                     if(eCount==1&&qPDG&&qMass&&tM>qMass+envM)//==> Q+E decay for one Quasm^
02448                     //if(nQuasmons==1 && qPDG && qMass && tM>qMass+envM) // ==> Q+E decay ^
02449                     {                         //                                          ^
02450                       G4int envPDG = theEnvironment.GetPDG(); // PDGCode of the NuclQEnv. ^
02451 #ifdef edebug
02452                       G4cout<<"G4QEnv::HadrQEnv: Q+E decay, nQ=1, qPDG=="<<qPDG<<G4endl;//^
02453 #endif
02454                       // => "Quasmon-Chipolino or Environment-Dibaryon" case              ^
02455                       if(qPDG==10 || qPDG==92000000 || qPDG==90002000 || qPDG==90000002)//^
02456                       {                          //                                       ^
02457                         G4QPDGCode h1QPDG=nQPDG; // QPDG of the first hadron              ^
02458                         G4double   h1M   =mNeut; // Mass of the first hadron              ^
02459                         G4QPDGCode h2QPDG=h1QPDG;// QPDG of the second hadron             ^
02460                         G4double   h2M   =mNeut; // Mass of the second hadron             ^
02461                         if(qPDG==10)             // CHIPOLINO decay case                  ^
02462                         {                     //                                          ^
02463                           G4QChipolino QChip(qQC);// define the Quasmon as a Chipolino    ^
02464                           h1QPDG=QChip.GetQPDG1();// QPDG of the first hadron             ^
02465                           h1M   =h1QPDG.GetMass();// Mass of the first hadron             ^
02466                           h2QPDG=QChip.GetQPDG2();// QPDG of the second hadron            ^
02467                           h2M   =h2QPDG.GetMass();// Mass of the second hadron            ^
02468                         }                     //                                          ^
02469                         else if(qPDG==90002000) // DiProton decay case                    ^
02470                         {                     //                                          ^
02471                           h1QPDG=pQPDG;       // QPDG of the first hadron                 ^
02472                           h1M   =mProt;       // Mass of the first hadron                 ^
02473                           h2QPDG=h1QPDG;      // QPDG of the second hadron                ^
02474                           h2M   =mProt;       // Mass of the second hadron                ^
02475                         }                     //                                          ^
02476                         else if(qPDG==92000000) // Two lambdas case                       ^
02477                         {                     //                                          ^
02478                           h1QPDG=lQPDG;       // QPDG of the first hadron                 ^
02479                           h1M   =mLamb;       // Mass of the first hadron                 ^
02480                           h2QPDG=h1QPDG;      // QPDG of the second hadron                ^
02481                           h2M   =mLamb;       // Mass of the second hadron                ^
02482                           G4double ddMass=totMass-envM; // Free CM energy                 ^
02483                           if(ddMass>mSigZ+mSigZ) // Sigma0+Sigma0 is possible             ^
02484                           {                   // @@ Only two particles PS is used         ^
02485                             G4double dd2=ddMass*ddMass; // Squared free energy            ^
02486                             G4double sma=mLamb+mLamb; // Lambda+Lambda sum                ^
02487                             G4double pr1=0.;          // Prototype to avoid sqrt(-)       ^
02488                             if(ddMass>sma) pr1=sqrt((dd2-sma*sma)*dd2); // Lamb+Lamb PS   ^
02489                             sma=mLamb+mSigZ;          // Lambda+Sigma0 sum                ^
02490                             G4double smi=mSigZ-mLamb; // Sigma0-Lambda difference         ^
02491                             G4double pr2=pr1;         // Prototype of +L+S0 PS            ^
02492                             if(ddMass>sma&&ddMass>smi) //                                 ^
02493                               pr2+=sqrt((dd2-sma*sma)*(dd2-smi*smi)); //                  ^
02494                             sma=mSigZ+mSigZ;          // Sigma0+Sigma0 sum                ^
02495                             G4double pr3=pr2;         // Prototype of +Sigma0+Sigma0 PS   ^
02496                             if(ddMass>sma) pr3+=sqrt((dd2-sma*sma)*dd2); //               ^
02497                             G4double hhRND=pr3*G4UniformRand(); // Randomize PS           ^
02498                             if(hhRND>pr2)     // --> "ENnv+Sigma0+Sigma0" case            ^
02499                             {                 //                                          ^
02500                               h1QPDG=s0QPDG;  // QPDG of the first hadron                 ^
02501                               h1M   =mSigZ;   // Mass of the first hadron                 ^
02502                               h2QPDG=h1QPDG;  // QPDG of the second hadron                ^
02503                               h2M   =mSigZ;   // Mass of the second hadron                ^
02504                             }                 //                                          ^
02505                             else if(hhRND>pr1)// --> "ENnv+Sigma0+Lambda" case            ^
02506                             {                 //                                          ^
02507                               h1QPDG=s0QPDG;  // QPDG of the first hadron                 ^
02508                               h1M   =mSigZ;   // Mass of the first hadron                 ^
02509                             }                 //                                          ^
02510                           }                   //                                          ^
02511                           else if(ddMass>mSigZ+mLamb) // Lambda+Sigma0 is possible        ^
02512                           {                   // @@ Only two particles PS is used         ^
02513                             G4double dd2=ddMass*ddMass; // Squared free energy            ^
02514                             G4double sma=mLamb+mLamb; // Lambda+Lambda sum                ^
02515                             G4double pr1=0.;          // Prototype to avoid sqrt(-)       ^
02516                             if(ddMass>sma) pr1=sqrt((dd2-sma*sma)*dd2); // Lamb+Lamb PS   ^
02517                             sma=mLamb+mSigZ;          // Lambda+Sigma0 sum                ^
02518                             G4double smi=mSigZ-mLamb; // Sigma0-Lambda difference         ^
02519                             G4double pr2=pr1;         //+L+S0 PS                          ^
02520                             if(ddMass>sma && ddMass>smi) //                               ^
02521                               pr2+=sqrt((dd2-sma*sma)*(dd2-smi*smi)); //                  ^
02522                             if(pr2*G4UniformRand()>pr1) // --> "ENnv+Sigma0+Lambda" case  ^
02523                             {                 //                                          ^
02524                               h1QPDG=s0QPDG;  // QPDG of the first hadron                 ^
02525                               h1M   =mSigZ;   // Mass of the first hadron                 ^
02526                             }                 //                                          ^
02527                           }                   //                                          ^
02528                         }                     //                                          ^
02529                         if(h1M+h2M+envM<totMass) // => "Three particles decay" case       ^
02530                         {                     //                                          ^
02531                           G4LorentzVector h14M(0.,0.,0.,h1M);           //                ^
02532                           G4LorentzVector h24M(0.,0.,0.,h2M);           //                ^
02533                           G4LorentzVector e4M(0.,0.,0.,envM);           //                ^
02534                           if(!G4QHadron(tot4M).DecayIn3(h14M,h24M,e4M)) //                ^
02535                           {                   //                                          ^
02536                             G4ExceptionDescription ed;                  //                ^
02537                             ed << "QChip+E DecIn3 error: (0)tM=" << tot4M.m() //          ^
02538                                << "->h1=" << h1QPDG << "(" << h1M << ")+h2="  //          ^
02539                                << h1QPDG << "(" << h2M << ")+envM=" << envM   //          ^
02540                                << "==" << h1M+h2M+envM << G4endl;             //          ^
02541                             G4Exception("G4QEnvironment::HadronizeQEnvironment()",  //    ^
02542                                         "HAD_CHPS_0004", FatalException, ed);       //    ^
02543                           }                   //                                          ^
02544                           G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M); //    ^
02545                           theQHadrons.push_back(h1H);        // (delete equivalent)       ^
02546 #ifdef debug
02547                           G4cout<<"G4QE::HQE:(1) H1="<<h1QPDG<<h14M<<G4endl;        //    ^
02548 #endif
02549                           G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M); //    ^
02550                           theQHadrons.push_back(h2H);        // (delete equivalent)       ^
02551 #ifdef debug
02552                           G4cout<<"G4QE::HQE:(1) H2="<<h2QPDG<<h24M<<G4endl;        //    ^
02553 #endif
02554                           G4QHadron* qeH = new G4QHadron(envPDG,e4M);               //    ^
02555                           theQHadrons.push_back(qeH);        // (delete equivalent)       ^
02556 #ifdef debug
02557                           G4cout<<"G4QE::HQE:(1) QEnv="<<envPDG<<e4M<<G4endl;       //    ^
02558 #endif
02559                         }                     //                                          ^
02560                         else                  // Try to recover                           ^
02561                         {                     //                                          ^
02562                           //if(eCount==1&&CheckGroundState(pQ,true)) // @@ BackFusion     ^
02563                           if(eCount==1&&CheckGroundState(pQ))// BackFusion attempt        ^
02564                           {                   //                                          ^
02565                             pQ->KillQuasmon();// ??                                       ^
02566                             eCount--;         // Reduce a#of theLivingQuasmons            ^
02567                             for_each(output->begin(),output->end(),DeleteQHadron()); //   ^
02568                             output->clear();  // -->-->-->-->-->-->-->-->-->-->-->-->-->--+
02569                             delete output;    // >---------------->---------------------->+
02570                             return theQHadrons; //                                        ^
02571                           }                   //                                          ^
02572                           for_each(output->begin(),output->end(),DeleteQHadron()); //-->--+
02573                           output->clear();    // -->-->-->-->-->-->-->-->-->-->-->-->-->--+
02574                           delete output;      // >---------------->------------->-------->+
02575 #ifdef fdebug
02576                           G4cout<<"--Warning--G4QE::HQE:tM="<<tot4M.m()<<"< h1="<<h1QPDG//^
02577                                 <<"(M="<<h1M<<")+h2="<<h1QPDG<<"(M="<<h2M<<")+EM="<<envM//^
02578                                 <<"="<<h1M+h2M+envM<<G4endl; //                           ^
02579                           //throw G4QException("G4QEnv::HQE:(0)Chi+Env mass > totMass");//^
02580 #endif
02581                           CleanUp();          //                                          ^
02582                           G4QHadron* evH = new G4QHadron(totQC,tot4M);// ResidualNuclHadr ^
02583                           EvaporateResidual(evH);  // Evaporate residual (del. equiv.)    ^
02584                           return theQHadrons; //                                          ^
02585                         }                     //                                          ^
02586                       }                       //                                          ^
02587                       else                    // => "Two particles decay" case            ^
02588                       {                       //                                          ^
02589                         G4LorentzVector fq4M(0.,0.,0.,qMass); //                          ^
02590                         G4LorentzVector qe4M(0.,0.,0.,envM);  //                          ^
02591                         if(!G4QHadron(tot4M).RelDecayIn2(fq4M,qe4M,cq4M,1.,1.))//Q ch.dir.^
02592                         {                     //                                          ^
02593                           G4cerr<<"***G4QEnv::HadQE:(0)tM="<<tot4M.m()<<"-> qPDG="<<qPDG//^
02594                                 <<"(M="<<qMass<<") + envM="<<envM<<")"<<G4endl;         //^
02595                           for_each(output->begin(),output->end(),DeleteQHadron()); //-->->+
02596                           output->clear();    // -->-->-->-->-->-->-->-->-->-->-->-->-->->+
02597                           delete output;      // >----------------->--------------------->+
02598                           // throw G4QException("***G4QEnv::HadrQEnv: Q+Env DecIn2 error");//^
02599                           G4Exception("G4QEnvironment::HadronizeQEnvironment()",
02600                                       "HAD_CHPS_0005", FatalException,
02601                                       "Q+Env DecIn2 error");
02602                         }                     //                                          ^
02603                         G4QHadron* qH = new G4QHadron(qPDG,fq4M);// the out going Quasmon ^
02604                         theQHadrons.push_back(qH); // (delete equivalent)                 ^
02605 #ifdef debug
02606                         G4cout<<"G4QE::HQE:QuasmH="<<qPDG<<fq4M<<G4endl;         //       ^
02607 #endif
02608                         G4QHadron* qeH = new G4QHadron(envPDG,qe4M);//theRecoilEnvironment^
02609 #ifdef debug
02610                         G4cout<<"G4QE::HQE:EnvironH="<<envPDG<<qe4M<<G4endl;     //       ^
02611 #endif
02612                         if(envPDG==92000000||envPDG==90002000||envPDG==90000002) //       ^
02613                           theEnvironment.DecayDibaryon(qeH,&theQHadrons);        //       ^
02614                         else theQHadrons.push_back(qeH);// (del.equiv.) *** this too ***  ^
02615                       }                       //                                          ^
02616                       for_each(output->begin(),output->end(),DeleteQHadron());//--->-->-->+
02617                       output->clear();        //                                          ^
02618                       delete output;          // >--------------->----------------->----->+
02619                       CleanUp();              // Clean up Environ and Quasmon             ^
02620                       return theQHadrons;     // Finish the hadronization process         ^
02621                     }                         //                                          ^
02622                     else status=-1;           // Q+E && totM below MassShell - PANIC      ^
02623                   }                           //                                          ^
02624                   else if(eCount>1&&(nCount>nCnMax||theEnvironment.GetA()<2))// 2Quasmons ^
02625                   {                                  //                                   ^
02626                     theEnvironment.InitByPDG(NUCPDG);// KillEnvironment(@@ Q's? CleanUp)) ^
02627 #ifdef fdebug
02628                     G4cout<<"G4QEnv::HQE:Evaporate Env+Quasm Env="<<curE<<G4endl;//       ^
02629 #endif
02630                     G4QHadron* nucQE = new G4QHadron(curQC,t4M);// Hadron for Quasm+Envir.^
02631                     EvaporateResidual(nucQE); // Evaporate residual Quasm+Env(del.equiv.) ^
02632                     pQ->KillQuasmon();        // If BackFusion succeeded, kill theQuasmon ^
02633 #ifdef edebug
02634                     G4cout<<"G4QEnv::HQE:StatusAfterKill (#"<<jq<<")="<<pQ->GetStatus()// ^
02635                           <<", nH="<<theQHadrons.size()<<G4endl;                       // ^
02636 #endif
02637                     tot4M-=t4M;               // Update TotalResidNucleus for hadronizPro.^
02638                     totQC-=curQC;             // Update total QC for the HadronizationPro.^
02639                     eCount--;                 // Reduce the number of the living Quasmons ^
02640                   }                           //                                          ^
02641                   if(eCount==1 && tM>=curM)   //==>for one Quasmon evaporate ResTotN      ^
02642                   {                           //                                          ^
02643                     theEnvironment.InitByPDG(NUCPDG);// Cancele the Environment           ^
02644                     G4int ttPDG=totQC.GetSPDGCode(); // Total PDG Code (10 - Chipolino)   ^
02645 #ifdef pcdebug
02646                     G4cout<<"G4QE::HQE:BefEv 4M="<<tot4M<<",QC="<<totQC<<ttPDG<<G4endl;// ^
02647 #endif
02648                     for_each(output->begin(),output->end(),DeleteQHadron()); //-->-->-->->+
02649                     output->clear();          //                                          ^
02650                     delete output;            // >------------>-------------------------->+
02651                     CleanUp();                // Clean up the Environ and Quasmons        ^
02652                     G4int ttBN=totQC.GetBaryonNumber(); //                                ^
02653                     if(ttPDG==10&&ttBN<2)     // Chipolino case                           ^
02654                     {                         //                                          ^
02655                       G4QChipolino QCh(totQC);// define the TotalResidual as a Chipolino  ^
02656                       G4QPDGCode   h1QPDG=QCh.GetQPDG1();  // QPDG of the first hadron    ^
02657                       G4double     h1M   =h1QPDG.GetMass();// Mass of the first hadron    ^
02658                       G4QPDGCode   h2QPDG=QCh.GetQPDG2();  // QPDG of the second hadron   ^
02659                       G4double     h2M   =h2QPDG.GetMass();// Mass of the second hadron   ^
02660                       G4double ttM=tot4M.m(); // Mass of the Chipolino                    ^
02661                       if(h1M+h2M<ttM)         // Two particles decay of Chipolino is pos. ^
02662                       {                       //                                          ^
02663                         G4LorentzVector h14M(0.,0.,0.,h1M);       //                      ^
02664                         G4LorentzVector h24M(0.,0.,0.,h2M);       //                      ^
02665                         if(!G4QHadron(tot4M).DecayIn2(h14M,h24M)) //                      ^
02666                         {                                         //                      ^
02667                           G4ExceptionDescription ed;              //                      ^
02668                           ed << "QChip (1) DecIn2 error: tM=" << ttM << "->h1="      //   ^
02669                              << h1QPDG << "(" << h1M << ")+h2=" << h1QPDG            //   ^
02670                              << "(" << h2M << ")=" << h1M+h2M << G4endl;             //   ^
02671                           G4Exception("G4QEnvironment::HadronizeQEnvironment()",     //   ^
02672                                       "HAD_CHPS_0006", FatalException, ed);          //   ^
02673                         }                     //                                          ^
02674                         G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);    //   ^
02675                         theQHadrons.push_back(h1H);               // (delete equivalent)  ^
02676 #ifdef debug
02677                         G4cout<<"G4QE::HQE: QCip-> H1="<<h1QPDG<<h14M<<G4endl;       //   ^
02678 #endif
02679                         G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);    //   ^
02680                         theQHadrons.push_back(h2H);               // (delete equivalent)  ^
02681 #ifdef debug
02682                         G4cout<<"G4QE::HQE: QChip->H2="<<h2QPDG<<h24M<<G4endl;       //   ^
02683 #endif
02684                       }                       //                                          ^
02685                       else                    //                                          ^
02686                       {                       //                                          ^
02687                         G4ExceptionDescription ed;                              //        ^
02688                         ed << " QChip (2) DecIn2 error: tM=" << ttM << totQC << "->h1=" //^
02689                            << h1QPDG << "(" << h2M << "=" << h1M+h2M << G4endl; //        ^
02690                         G4Exception("G4QEnvironment::HadronizeQEnvironment()",  //        ^
02691                                     "HAD_CHPS_0007", FatalException, ed);       //        ^
02692                       }                       //                                          ^
02693                     }                         //                                          ^
02694                     else                      //                                          ^
02695                     {                         //                                          ^
02696 #ifdef edebug
02697                       if(ttPDG<80000000&&ttBN<1) //                                       ^
02698                         G4cout<<"---Warning---G4QE::HQE: NotNuc, tPDG="<<ttPDG<<G4endl;// ^
02699 #endif
02700                       G4QHadron* evH = new G4QHadron(totQC,tot4M);// Hadron for ResidNucl ^
02701                       EvaporateResidual(evH); // Evaporate residual (del.equiv.)          ^
02702                     }                         //                                          ^
02703                     return theQHadrons;       //                                          ^
02704                   }                           //                                          ^
02705                   else if(eCount==1 && CheckGroundState(pQ,true)) // Correct and Finish   ^
02706                   {                           //                                          ^
02707                     for_each(output->begin(), output->end(), DeleteQHadron()); // -->-->->+
02708                     output->clear();          //                                          ^
02709                     delete output;            // >------------------->---------------->-->+
02710                     pQ->KillQuasmon();        // If BackFusion succeeded, kill Quasm      ^
02711                     delete pQ;
02712                     eCount--;                 // Reduce a#of the living Quasmons          ^
02713                     return theQHadrons;       //                                          ^
02714                   }                           //                                          ^
02715                 }                             //                                          ^
02716                 else                          // "Vacuum" case                            ^
02717                 {                             //                                          ^
02718                   G4QPDGCode QPDGQ=pQ->GetQPDG(); // QPDG Code for the Quasmon            ^
02719                   G4int PDGQ=QPDGQ.GetPDGCode();  // PDG Code of the QUASMON              ^
02720 #ifdef edebug
02721                   G4cout<<"G4QEnv::HadrQEnv: vacuum PDGQ="<<PDGQ<<G4endl; //              ^
02722 #endif
02723                   if(!PDGQ) status=-1;        // Unknown Quasmon in Vaquum - PANIC        ^
02724                   // @@ There still can be a case for 2pSigma+ or 2nSigma- (PDGCode?)     ^
02725                   else if(PDGQ==3112||PDGQ==3222||PDGQ==90999001||PDGQ==91000999)// S+/S- ^
02726                   {                           //                                          ^
02727 #ifdef edebug
02728                     G4cout<<"G4QEnv::HadrQEnv:Sigma Mass="<<cqMass<<G4endl;      //       ^
02729 #endif
02730                     G4double hyM=mNeut;       // Prototype of the hyperon mass            ^
02731                     G4int    hyPDG=2112;      // Prototype of the hyperon PDG Code        ^
02732                     G4double pigM=mPi;        // Prototype of the gamma/pion mass         ^
02733                     G4int    pigPDG=-211;     // Prototype of the gamma/pion PDG Code     ^
02734                     if(PDGQ==3112||PDGQ==90999001) // --> "Sigma-" case                   ^
02735                     { //                                                                  ^
02736                       if(cqMass>mPi+mLamb)    // "Lambda + Pi- is possible" case          ^
02737                       { //                                                                ^
02738                         hyM   = mLamb;        // Lambda mass                              ^
02739                         hyPDG = 3122;         // Lambda PDG Code                          ^
02740                       } //                                                                ^
02741                       else if(cqMass>mSigM)   // "Sigma- gamma decay" case                ^
02742                       { //                                                                ^
02743                         hyM=mSigM;            // Sigma- mass                              ^
02744                         hyPDG=3112;           // Sigma- PDG Code                          ^
02745                         pigM=0.;              // Gamma mass                               ^
02746                         pigPDG=22;            // Gamma PDG Code                           ^
02747                       } //                                                                ^
02748                     } //                                                                  ^
02749                     else if(PDGQ==3222||PDGQ==91000999) // --> "Sigma+" case              ^
02750                     { //                                                                  ^
02751                       pigPDG= 211;            // Pi+ PDG Code                             ^
02752                       if(cqMass>mPi+mLamb)    // --- "Lambda + Pi+ is possible" case      ^
02753                       { //                                                                ^
02754                         hyM   = mLamb;        // Lambda mass                              ^
02755                         hyPDG = 3122;         // Lambda PDG Code                          ^
02756                         pigM  = mPi;          // Pi+ mass                                 ^
02757                         pigPDG= 211;          // Pi+ PDG Code                             ^
02758                       } //                                                                ^
02759                       else if(cqMass>mSigP)   // "Sigma- gamma decay" case                ^
02760                       { //                                                                ^
02761                         hyM=mSigP;            // Sigma+ mass                              ^
02762                         hyPDG=3222;           // Sigma+ PDG Code                          ^
02763                         pigM=0.;              // Gamma mass                               ^
02764                         pigPDG=22;            // Gamma PDG Code                           ^
02765                       } //                                                                ^
02766                       else if(cqMass>mPi0+mProt&&G4UniformRand()>.5) // "P + Pi0" case    ^
02767                       { //                                                                ^
02768                         hyM   = mProt;        // Proton mass                              ^
02769                         hyPDG = 2212;         // Proton PDG Code                          ^
02770                         pigM  = mPi0;         // Pi0 mass                                 ^
02771                         pigPDG= 111;          // Pi0 PDG Code                             ^
02772                       } //                                                                ^
02773                       else if(cqMass<mPi+mNeut)// "P+gamma" case as "N+Pi+" is impossible ^
02774                       { //                                                                ^
02775                         hyM   = mProt;        // Proton mass                              ^
02776                         hyPDG = 2212;         // Proton PDG Code                          ^
02777                         pigM=0.;              // Gamma mass                               ^
02778                         pigPDG=22;            // Gamma PDG Code                           ^
02779                       } //                                                                ^
02780                       // othing should be done for "N + P+" case                          ^
02781                     } //                                                                  ^
02782                     G4LorentzVector b4Mom(0.,0.,0.,hyM); // Hyperon mass                  ^
02783                     G4LorentzVector m4Mom(0.,0.,0.,pigM);// pion/gamma mass               ^
02784                     if(!G4QHadron(cq4M).DecayIn2(b4Mom, m4Mom)) // "DecayIn2 failed" case ^
02785                     { //                                                                  ^
02786                       G4cout<<"---Warning---G4QE::HQE:H="<<hyPDG<<"(m="<<hyM<<")+G/Pi=" //^
02787                             <<pigPDG<<"(m="<<pigM<<")="<<hyM+pigM<<">"<<cqMass<<G4endl; //^
02788                       G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC             ^
02789                       CleanUp();              //                                          ^
02790                       if(!CheckGroundState(quasH,true)) // Last posibility to correct     ^
02791                       { //                                                                ^
02792                         G4QHadron* hadr = new G4QHadron(totQC,tot4M); //                  ^
02793                         theQHadrons.push_back(hadr);    // Cor or fill as It Is           ^
02794 #ifdef debug
02795                         G4cout<<"-Warn-G4QE::HQE:Sig,QC="<<totQC<<",4M="<<tot4M<<G4endl;//^
02796 #endif
02797                         //throw G4QException("G4QEnvironment::HadronizeQEnv:Sig error");//^
02798                       } //                                                                ^
02799                       delete quasH;          // Delete the temporary fake Quasmon         ^
02800                       return theQHadrons;    //                                           ^
02801                     } //                                                                  ^
02802 #ifdef debug
02803                     G4cout<<"G4QEnv::HadronizeQEnv: Sigma="<<PDGQ<<cq4M<<" -> Hyperon="// ^
02804                           <<hyPDG<<b4Mom<<" + Gamma/Pi="<<pigPDG<<m4Mom<<G4endl; //       ^
02805 #endif
02806                     G4QHadron* curBar = new G4QHadron(hyPDG,b4Mom); //                    ^
02807                     theQHadrons.push_back(curBar); // Fill the Hyperon (delete equivalent)^
02808                     G4QHadron* curMes = new G4QHadron(pigPDG,m4Mom);  //                  ^
02809                     theQHadrons.push_back(curMes); // Fill the gam/pi (delete equivalent) ^
02810                     pQ->KillQuasmon();        // Make done the current Quasmon            ^
02811                     tot4M-=cq4M;              // Update theTotalResidNucl of HadrPr.      ^
02812                     totQC-=qQC;               // Update total residual QC of HadrPr.      ^
02813                     eCount--;                 // Reduce a#of the living Quasmons          ^
02814                   }                           //                                          ^
02815                   else if(PDGQ==90999002||PDGQ==91001999) // pS+/nS-                      ^
02816                   {                           //                                          ^
02817 #ifdef edebug
02818                     G4cout<<"G4QEnv::HadrQEnv: Nucleon+Sigma Mass="<<cqMass<<G4endl; //   ^
02819 #endif
02820                     G4bool dinFlag = false;   // Di-nucleon flag                          ^
02821                     G4double hyM=mSigM;       // Prototype of the hyperon mass (n+Sigma-) ^
02822                     G4int    hyPDG=3112;      // Prototype of the hyperon PDG Code        ^
02823                     G4double pigM=mNeut;      // Prototype of the nucleon mass            ^
02824                     G4int    pigPDG=2112;     // Prototype of the nucleon PDG Code        ^
02825                     if     (PDGQ==90999002)   // --> "n+Sigma-" case                      ^
02826                     {                         //                                          ^
02827                       if(cqMass<mNeut+mSigM)  // ----> "DiNeutron+Pi-" case               ^
02828                       { //                                                                ^
02829                         dinFlag = true;       // For the final decay                      ^
02830                         hyM=mNeut+mNeut;      // Di-neutron                               ^
02831                         hyPDG=2112;           // Neutron PDG Code                         ^
02832                         pigM=mPi;             // Pi- mass                                 ^
02833                         pigPDG=-211;          // Pi- PDG Code                             ^
02834                       } //                                                                ^
02835                     } //                                                                  ^
02836                     else if(PDGQ==91001999)   // --> "p+Sigma+" case                      ^
02837                     { //                                                                  ^
02838                       hyM=mSigP;              // Sigma+                                   ^
02839                       hyPDG=3222;             // PDG Code of Sigma+                       ^
02840                       pigM=mProt;             // Proton mass                              ^
02841                       pigPDG=2212;            // PDG Code of proton                       ^
02842                       if(cqMass<mProt+mSigP)  // ----> "Proton+Proton" case               ^
02843                       { //                                                                ^
02844                         hyM=mProt;            // Proton mass                              ^
02845                         hyPDG=2212;           // Proton PDG Code                          ^
02846                         pigM=mProt;           // Proton mass                              ^
02847                         pigPDG=2212;          // Proton PDG Code                          ^
02848                       } //                                                                ^
02849                     } //                                                                  ^
02850                     G4LorentzVector b4Mom(0.,0.,0.,hyM); // Hyperon (di-nucleon) mass     ^
02851                     G4LorentzVector m4Mom(0.,0.,0.,pigM);// Nucleon (pion) mass           ^
02852                     if(!G4QHadron(cq4M).DecayIn2(b4Mom, m4Mom)) // "DecayIn2 failed" case ^
02853                     { //                                                                  ^
02854                       G4cout<<"--Warning--G4QE::HQE:S/D="<<hyPDG<<"(m="<<hyM<<")+N/Pi=" //^
02855                             <<pigPDG<<"(m="<<pigM<<")="<<hyM+pigM<<">"<<cqMass<<G4endl; //^
02856                       G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC             ^
02857                       CleanUp();              //                                          ^
02858                       if(!CheckGroundState(quasH,true)) // Last posibility to correct     ^
02859                       { //                                                                ^
02860                         G4QHadron* hadr = new G4QHadron(totQC,tot4M); //                  ^
02861                         theQHadrons.push_back(hadr);    // Cor or fill as It Is           ^
02862 #ifdef debug
02863                         G4cout<<"-Warn-G4QE::HQE:Sig,QC="<<totQC<<",4M="<<tot4M<<G4endl;//^
02864 #endif
02865                         //throw G4QException("G4QEnvironment::HadronizeQEnv:Sig error");//^
02866                       } //                                                                ^
02867                       delete quasH;          // Delete the temporary fake Quasmon         ^
02868                       return theQHadrons;    //                                           ^
02869                     } //                                                                  ^
02870 #ifdef debug
02871                     G4cout<<"G4QEnv::HadronizeQEnv: NSigma="<<PDGQ<<cq4M<<"-> Sigma/dN="//^
02872                           <<hyPDG<<b4Mom<<" + N/Pi="<<pigPDG<<m4Mom<<G4endl; //           ^
02873 #endif
02874                     if(dinFlag) b4Mom/=2.;    // Split the 4-mom for the dinucleon        ^
02875                     G4QHadron* curBar = new G4QHadron(hyPDG,b4Mom); //                    ^
02876                     theQHadrons.push_back(curBar); // Fill the Hyperon (delete equivalent)^
02877                     if(dinFlag)               //                                          ^
02878                     {                         //                                          ^
02879                       G4QHadron* secBar = new G4QHadron(hyPDG,b4Mom);// Cre. 2-nd nucleon ^
02880                       theQHadrons.push_back(secBar);// Fill 2-nd nucleon (delete equiv.)  ^
02881                     }                         //                                          ^
02882                     G4QHadron* curMes = new G4QHadron(pigPDG,m4Mom);  //                  ^
02883                     theQHadrons.push_back(curMes); // Fill the gam/pi (delete equivalent) ^
02884                     pQ->KillQuasmon();        // Make done the current Quasmon            ^
02885                     tot4M-=cq4M;              // Update theTotalResidNucl of HadrPr.      ^
02886                     totQC-=qQC;               // Update total residual QC of HadrPr.      ^
02887                     eCount--;                 // Reduce a#of the living Quasmons          ^
02888                   }                           //                                          ^
02889                   else if(PDGQ==90999003||PDGQ==91002999) // ppS+/nnS-                    ^
02890                   {                           //                                          ^
02891 #ifdef edebug
02892                     G4cout<<"G4QEnv::HadrQEnv: DiNucleon+Sigma Mass="<<cqMass<<G4endl; // ^
02893 #endif
02894                     G4bool dinFlag = false;   // Di-nucleon flag                          ^
02895                     G4double hyM=mSigM;       // Prototype of the hyperon mass (n+Sigma-) ^
02896                     G4int    hyPDG=3112;      // Prototype of the hyperon PDG Code        ^
02897                     G4double pigM=mNeut+mNeut;// Prototype of the di-nucleon mass         ^
02898                     G4int    pigPDG=2112;     // Prototype of the nucleon PDG Code        ^
02899                     if     (PDGQ==90999003)   // --> "n+Sigma-" case                      ^
02900                     {                         //                                          ^
02901                       if(cqMass<pigM+mSigM)   // ----> "DiNeutron+Pi-" case               ^
02902                       { //                                                                ^
02903                         dinFlag = true;       // For the final decay                      ^
02904                         pigM=mNeut+mNeut+mNeut;// Tri-neutron                             ^
02905                         pigPDG=2112;          // Neutron PDG Code                         ^
02906                         hyM=mPi;              // Pi- mass                                 ^
02907                         hyPDG=-211;           // Pi- PDG Code                             ^
02908                       } //                                                                ^
02909                     } //                                                                  ^
02910                     else if(PDGQ==91002999)   // --> "p+Sigma+" case                      ^
02911                     { //                                                                  ^
02912                       hyM=mSigP;              // Sigma+                                   ^
02913                       hyPDG=3222;             // PDG Code of Sigma+                       ^
02914                       pigM=mProt+mProt;       // Di-Proton mass                           ^
02915                       pigPDG=2212;            // PDG Code of proton                       ^
02916                       if(cqMass<pigM+mSigP)   // ----> "DiProton+Pi+" case                ^
02917                       { //                                                                ^
02918                         dinFlag = true;       // For the final decay                      ^
02919                         pigM=mProt+mProt+mProt;// Tri-proton                              ^
02920                         pigPDG=2212;          // Neutron PDG Code                         ^
02921                         hyM=mPi;             // Pi+ mass                                  ^
02922                         hyPDG=211;           // Pi+ PDG Code                              ^
02923                       } //                                                                ^
02924                     } //                                                                  ^
02925                     G4LorentzVector b4Mom(0.,0.,0.,hyM); // Hyperon (di-nucleon) mass     ^
02926                     G4LorentzVector m4Mom(0.,0.,0.,pigM);// Nucleon (pion) mass           ^
02927                     if(!G4QHadron(cq4M).DecayIn2(b4Mom, m4Mom)) // "DecayIn2 failed" case ^
02928                     { //                                                                  ^
02929                       G4cout<<"--Warning--G4QE::HQE:S/Pi="<<hyPDG<<"(m="<<hyM<<")+D/T=" //^
02930                             <<pigPDG<<"(m="<<pigM<<")="<<hyM+pigM<<">"<<cqMass<<G4endl; //^
02931                       G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC             ^
02932                       CleanUp();              //                                          ^
02933                       if(!CheckGroundState(quasH,true)) // Last posibility to correct     ^
02934                       { //                                                                ^
02935                         G4QHadron* hadr = new G4QHadron(totQC,tot4M); //                  ^
02936                         theQHadrons.push_back(hadr);    // Cor or fill as It Is           ^
02937 #ifdef debug
02938                         G4cout<<"-Warn-G4QE::HQE:Sig,QC="<<totQC<<",4M="<<tot4M<<G4endl;//^
02939 #endif
02940                         //throw G4QException("G4QEnvironment::HadronizeQEnv:Sig error");//^
02941                       } //                                                                ^
02942                       delete quasH;          // Delete the temporary fake Quasmon         ^
02943                       return theQHadrons;    //                                           ^
02944                     } //                                                                  ^
02945 #ifdef debug
02946                     G4cout<<"G4QEnv::HadronizeQEnv:2NSigma="<<PDGQ<<cq4M<<"-> Sigma/Pi="//^
02947                           <<hyPDG<<b4Mom<<" + 2N/3N="<<pigPDG<<m4Mom<<dinFlag<<G4endl; // ^
02948 #endif
02949                     G4QHadron* curBar = new G4QHadron(hyPDG,b4Mom); //                    ^
02950                     theQHadrons.push_back(curBar); // Fill the Hyperon (delete equivalent)^
02951                     if(dinFlag) m4Mom/=3.;   // Split the 4-mom for the dinucleon in 3    ^
02952                     else m4Mom/=2.;          // Split the 4-mom for the dinucleon in 2    ^
02953                     G4QHadron* curMes = new G4QHadron(pigPDG,m4Mom);  //                  ^
02954                     theQHadrons.push_back(curMes); // Fill the gam/pi (delete equivalent) ^
02955                     G4QHadron* secBar = new G4QHadron(pigPDG,m4Mom);  //                  ^
02956                     theQHadrons.push_back(secBar); // Fill the gam/pi (delete equivalent) ^
02957                     if(dinFlag)               //                                          ^
02958                     {                         //                                          ^
02959                       G4QHadron* triBar = new G4QHadron(pigPDG,m4Mom);// Cre. 3-d nucleon ^
02960                       theQHadrons.push_back(triBar);// Fill 3-d nucleon (delete equival.) ^
02961                     }                         //                                          ^
02962                     pQ->KillQuasmon();        // Make done the current Quasmon            ^
02963                     tot4M-=cq4M;              // Update theTotalResidNucl of HadrPr.      ^
02964                     totQC-=qQC;               // Update total residual QC of HadrPr.      ^
02965                     eCount--;                 // Reduce a#of the living Quasmons          ^
02966                   }                           //                                          ^
02967                   else if (PDGQ!=10)          // @@ Chipolino can wait @@                 ^
02968                   {                           //                                          ^
02969                     G4double qM =cq4M.m();    // Real mass of the Quasmon                 ^
02970                     G4double gsM=QPDGQ.GetMass(); // GSmass of the Quasmon                ^
02971 #ifdef edebug
02972                     G4cout<<"G4QEnv::HadrQEnv:#"<<jq<<",qM="<<qM<<">gsM="<<gsM<<G4endl;// ^
02973 #endif
02974                     if(fabs(qM-gsM)<0.0001)   // "Fill & Kill" Case                       ^
02975                     {                         //                                          ^
02976                       G4QHadron* resQ = new G4QHadron(PDGQ,cq4M); // GSM hadron for CurQ  ^
02977 #ifdef debug
02978                       G4cout<<"G4QEnv::HadrQEnv:ResQ="<<PDGQ<<cq4M<<G4endl;         //    ^
02979 #endif
02980                       theQHadrons.push_back(resQ); // @@ Check Dibarions @@ (del.equiv.)  ^
02981                       pQ->KillQuasmon();      // Make done the current Quasmon            ^
02982                       tot4M-=cq4M;            // Update theTotalResidNucl of HadrPr.      ^
02983                       totQC-=qQC;             // Update total residual QC of HadrPr.      ^
02984                       eCount--;               // Reduce a#of the living Quasmons          ^
02985                     }                         //                                          ^
02986                     else if(eCount==1 && qM<gsM && CheckGroundState(pQ,true))// Cor.& Fin.^
02987                     {                         //                                          ^
02988 #ifdef edebug
02989                       G4cout<<"G4QEnv::HadrQEnv:**>>** CGS Correction **>>**"<<G4endl; // ^
02990 #endif
02991                       for_each(output->begin(), output->end(), DeleteQHadron()); //-->-->-^
02992                       output->clear();        //                                          ^
02993                       delete output;          // >--------------->--------------->------->+
02994                       pQ->KillQuasmon();      // If BackFusion -> kill theQuasmon         ^
02995                       eCount--;               // Reduce a#of the living Quasmons          ^
02996                       return theQHadrons;     //                                          ^
02997                     }                         //                                          ^
02998                     else if(qM<gsM&&(pQ->GetQC().GetSPDGCode()==1114     //               ^
02999                                      || pQ->GetQC().GetSPDGCode()==2224) //               ^
03000                           &&qM>theWorld->GetQParticle(QPDGQ)->MinMassOfFragm())//Del&Kill ^
03001                     {                         //                                          ^
03002 #ifdef edebug
03003                       G4cout<<"G4QEnv::HadrQEnv:**||** Copy&Decay **||**"<<G4endl; //     ^
03004 #endif
03005                       G4QHadronVector* decHV=pQ->DecayQuasmon();//Dec.Quasm & fill decHV=*^
03006                       CopyAndDeleteHadronVector(decHV);// Copy output to QHadrV of G4Env  ^
03007                       tot4M-=pQ->Get4Momentum(); // tot4M recalculation                   ^
03008                       totQC-=pQ->GetQC();     // totQC recalculation                      ^
03009                       pQ->KillQuasmon();      // Make done the current Quasmon            ^
03010                       eCount--;               // Reduce a#of the living Quasmons          ^
03011                     }                         //                                          ^
03012                   }                           //                                          ^
03013                 }                             // End of the Medium/Vacuum IF              ^
03014               }                               // End of the status ELSE IF                ^
03015               else if(status==3) count3++;    //                                          ^
03016               if(status<0)                    // Panic: Quasmon is below theMassShell     ^
03017               {                               //                                          ^
03018                 //if(eCount==1 && DecayInEnvQ(pQ)) //                                     ^
03019                 //{                             //                                        ^
03020                 //  for_each(output->begin(), output->end(), DeleteQHadron());//--->-->-->+
03021                 //  output->clear();            //                                        ^
03022                 //  delete output;              // >----------------->---------------->-->+
03023                 //  eCount--;                   // Reduce a#of the living Quasmons        ^
03024                 //  pQ->KillQuasmon();          //                                        ^
03025                 //  return theQHadrons;         //                                        ^
03026                 //}                             //                                        ^
03027                 G4int    ppm=jq;                // Initialized by PANIC Quasmon pointer   ^
03028                 G4int    nRQ=0;                 // Prot. of a#of additionalRealQuasmons   ^
03029 #ifdef edebug
03030                 G4cout<<"G4QEnv::HadrQEnv: ***PANIC*** for jq="<<jq<<G4endl; //           ^
03031 #endif
03032                 G4ThreeVector vp= pQ->Get4Momentum().vect(); // PANICQuasmon momentum     ^
03033                 G4double dpm=1.e+30;            // Big number (dot product of momenta)    ^
03034                 if(nQuasmons>1) for(G4int ir=0; ir<nQuasmons; ir++)// Search for partner  ^
03035                 {                               //                                        ^
03036                   if(ir!=jq)                    // Skip the current (PANIC) Quasmon itself^
03037                   {                             //                                        ^
03038                     G4Quasmon* rQ = theQuasmons[ir]; //                                   ^
03039                     G4int Qst = rQ->GetStatus();// Status of a Quasmon                    ^
03040 #ifdef edebug
03041                     G4cout<<"G4QEnv::HadrQEnv: ir="<<ir<<",Qstatus="<<Qst<<G4endl; //     ^
03042 #endif
03043                     if(Qst>0)                   // Skip the dead Quasmon                  ^
03044                     {
03045                       nRQ++;                    // Increment real-Quasmon-counter         ^
03046                       G4double dp=vp.dot(rQ->Get4Momentum().vect()); //                   ^
03047                       if(dp<dpm)                // Search for the "moving in thesameDir"  ^
03048                       {                         //                                        ^
03049                         ppm=ir;                 // Remember the index of MinProj Quasmon  ^
03050                         dpm=dp;                 // Remember the value of theMinProjection ^
03051                       }                         //                                        ^
03052                     }                           //                                        ^
03053                   } // End of the Quasmon LOOP 
03054                 } // End of the partner-search-for-the-PANIC-Quasmon LOOP                 ^
03055                 if(nRQ)                         // Merge with theBestPartnerQuasmonCandid ^
03056                 {                               //                                        ^
03057                   G4Quasmon*      rQ = theQuasmons[ppm];   //                             ^
03058                   G4QContent      rQC= rQ->GetQC();        //                             ^
03059                   G4LorentzVector r4M= rQ->Get4Momentum(); //                             ^
03060                   rQC               += pQ->GetQC();        //                             ^
03061                   r4M               += pQ->Get4Momentum(); //                             ^
03062                   rQ->InitQuasmon(rQC, r4M);    // Make new Quasmon                       ^
03063 #ifdef edebug
03064                   G4cout<<"G4QE::HQE:"<<pQ->GetQC()<<"+"<<rQ->GetQC()<<"="<<rQC<<G4endl;//^
03065 #endif
03066                   pQ->KillQuasmon();            // Delete old Quasmon                     ^
03067                   eCount--;                     // Decrement counter of living Quasmons   ^
03068                 }                               //                                        ^
03069                 else // No candidate to resolve PANIC was found                           ^
03070                 {                               //                                        ^
03071 #ifdef edebug
03072                   G4cout<<"G4QEnv::HQE: No Q-cand. nRQ="<<nRQ<<",eC="<<eCount<<G4endl; // ^
03073 #endif
03074                   //if(eCount==1 && CheckGroundState(pQ,true)) //  BackFusion attempt     ^
03075                   if(CheckGroundState(pQ,true)) //  The only Q: BackFusion attempt        ^
03076                   {
03077                     for_each(output->begin(), output->end(), DeleteQHadron()); //-->-->-->+
03078                     output->clear();            //                                        ^
03079                     delete output;              // >-------------->---------------->----->+
03080                     pQ->KillQuasmon();          //                                        ^
03081                     eCount--;                   // Reduce a#of the living Quasmons        ^
03082                     return theQHadrons;         //                                        ^
03083                   }                             //                                        ^
03084 #ifdef fdebug
03085                   G4cout<<"G4QEnv::HadrQEnv:NO PANICsolution,t="<<tot4M<<totQC<<G4endl;// ^
03086 #endif
03087                   totQC=theEnvironment.GetQC(); //                                        ^
03088                   tot4M=theEnvironment.Get4Momentum(); //                                 ^
03089                   if(nQuasmons) for(G4int jr=0; jr<nQuasmons; jr++) // Search for partner ^
03090                   {                             //                                        ^
03091                     G4Quasmon* rQ = theQuasmons[jr]; // Pointer to the Quasmon            ^
03092                     G4int Qst = rQ->GetStatus();// Status of a Quasmon                    ^
03093                     if(jr==jq)                  //                                        ^
03094                     {                           //                                        ^
03095                       totQC+=rQ->GetQC();       // QuarkContent of the Quasmon            ^
03096                       tot4M+=rQ->Get4Momentum();// QuarkContent of the Quasmon            ^
03097                     }                           //                                        ^
03098                     else if(Qst)                // Skip dead Quasmons                     ^
03099                     {                           //                                        ^
03100                       totQC+=rQ->GetQC();       // QuarkContent of the Quasmon            ^
03101                       tot4M+=rQ->Get4Momentum();// QuarkContent of the Quasmon            ^
03102                     }                           //                                        ^
03103                   } // End of the "No candidate to resolve PANIC" ELSE                    ^
03104                   pQ->KillQuasmon();            // Kill the only Quasmon                  ^
03105                   eCount--;                     // Reduce a#of the living Quasmons        ^
03106                   CleanUp();                    // Clean up THIS Quasmon and Environment  ^
03107                   G4QHadron* evH = new G4QHadron(totQC,tot4M); // Create ResidNuclHadron  ^
03108                   EvaporateResidual(evH);       // Try to evaporate residual (del.equiv.) ^
03109                   for_each(output->begin(), output->end(), DeleteQHadron()); //-->-->-->->+
03110                   output->clear();              //                                        ^
03111                   delete output;                // >------------------>--------------->-->+
03112                   force=true;                   // Make the force decision                ^
03113                   break;                        // Out of the fragmentation loop >->+     ^
03114                 }                               //                                  |     ^
03115               }                                 //                                  |     ^
03116             }                                   //                                  |     ^
03117             for_each(output->begin(), output->end(), DeleteQHadron()); // ->-->-->--|---->+
03118             output->clear();                    //                                  |     ^
03119             delete output;                      // >----------------->--------------|-->->+
03120           } // End of skip of the dead Quasmons                                     |
03121 #ifdef debug
03122           G4cout<<"G4QE::HQE:QStat("<<jq<<"="<<status<<pQ->Get4Momentum()<<G4endl;//|
03123 #endif
03124         } // End of fragmentation LOOP over Quasmons (jq) <--------<----------<-----+
03125         cAN=0;
03126       }
03127       else if(totMass>totM+.001)                // ==> "Try Evaporate or decay" case
03128       {
03129 #ifdef edebug
03130         G4cout<<"G4QEnv::HadrQE: NQ="<<nQuasmons<<",tM="<<totMass<<",tPDG="<<totPDG<<",tB="
03131               <<totBN<<",GSM="<<totM<<",dM="<<totMass-totM<<",totQC="<<totQC<<G4endl;
03132 #endif
03133         //if(nQuasmons==1)
03134         if(2>3)                                 // ** closed, because doesn't make a diff
03135         {
03136           G4QContent quasQC=totQC-envQC;        // Total QuarkContent of the Only Quasmon
03137           G4int resQPDG=quasQC.GetSPDGCode();   // GS mass for the Only Quasmon-hadron
03138           G4int resQB=quasQC.GetBaryonNumber(); // Baryon number of the Only Quasmon
03139           G4int resQCh=quasQC.GetCharge();      // Charge of the Only Quasmon
03140           //G4int resQS=quasQC.GetStrangeness();  // Strangeness of the Only Quasmon
03141           if((resQPDG==0 || resQPDG==10) && resQB>0) resQPDG=quasQC.GetZNSPDGCode();
03142           G4double resQM=G4QPDGCode(resQPDG).GetMass();// GS Mass of the Only Quasmon
03143           G4double qCB=theEnvironment.CoulombBarrier(resQCh,resQB); // CoulombBarrier
03144           G4double de=totMass-envM-resQM-qCB;
03145 #ifdef debug
03146           G4cout<<"G4QEnv::HadrQE:NQ==1,tM="<<totMass<<",qM="<<resQM<<",eM="<<envM<<",CB="
03147                 <<qCB<<",dE="<<totMass-envM-resQM-qCB<<G4endl;
03148 #endif
03149           if(de>0.)                             // Make DecayIn2 conserving Q-direction
03150           {
03151             G4LorentzVector fq4M=G4LorentzVector(0.,0.,0.,resQM); // Prot. for outQuasmon
03152             G4LorentzVector fe4M=env4M;         // Prototype for outEnvironment
03153             G4LorentzVector dir4M=tot4M-env4M;  // Internall quasmon 4-momentum
03154             if(!G4QHadron(tot4M).RelDecayIn2(fe4M,fq4M,dir4M,1.,1.))
03155             {
03156               G4ExceptionDescription ed;
03157               ed << "Can't decay Q+E: t4M=" << tot4M << ",d=" << de << G4endl;
03158               G4Exception("G4QEnvironment::HadronizeQEnvironment()", "HAD_CHPS_0008",
03159                           FatalException, ed); 
03160             }
03161               G4QHadron* hQua = new G4QHadron(resQPDG,fq4M);
03162               theQHadrons.push_back(hQua);      // Fill the hadron-quasmon (delete equiv.)
03163               G4int envPDG=theEnvironment.GetPDGCode();
03164               G4QHadron* hEnv = new G4QHadron(envPDG,fe4M);
03165               theQHadrons.push_back(hEnv);      // Fill the hadron-environ (delete equiv.)
03166 #ifdef debug
03167               G4cout<<"G4QEnv::HadrQEnv:fQ="<<resQPDG<<fq4M<<", fE="<<envPDG<<fe4M<<G4endl;
03168 #endif
03169               return theQHadrons;
03170           }
03171         }
03172 #ifdef debug
03173         G4cout<<"G4QEnv::HadrQE: M="<<totMass<<",PDG="<<totPDG<<",B="<<totBN<<",GSM="<<totM
03174               <<",dM="<<totMass-totM<<",totQC="<<totQC<<G4endl;
03175 #endif
03176         if(totBN<2)                             // ==> "Baryon/Meson residual Quasmon" case
03177         {
03178           if(totPDG==90999999||totPDG==90999000||totPDG==90000999||totPDG==89999001)//"M"ca
03179           {
03180             G4cout<<"---Warning---G4QE::HQE:Meson(2) PDG="<<totPDG<<",M="<<totMass<<G4endl;
03181           }
03182           else if(totPDG==1114||totPDG==2224)   //==> "DELTA- or DELTA++" case (?antiDELTA)
03183           {
03184             G4double   mBar=mProt;
03185             G4int      bPDG=2212;
03186             G4double   mMes=mPi;
03187             G4int      mPDG=211;
03188             if(totPDG==1114)                    // "DELTA-" case
03189             {
03190               mBar=mNeut;
03191               bPDG=2112;
03192               mPDG=-211;
03193             }
03194             if(totMass<mBar+mMes)
03195             {
03196               G4cout<<"--Warning--G4QE::HQE:tM="<<totMass<<"<GSM+mPi0="<<totM+mPi0<<G4endl;
03197               G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03198               CleanUp();
03199               if(!CheckGroundState(quasH,true))
03200               {
03201                 G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03202                 theQHadrons.push_back(hadr);   // Cor or fill as It Is
03203 #ifdef debug
03204                 G4cout<<"***G4QE::HQE:FillAsIs(-4),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03205 #endif
03206                 //throw G4QException("G4QEnvironment::HadronizeQEnvironment:(1)DecayQEnv");
03207               }
03208               delete quasH;  
03209               return theQHadrons;
03210             }
03211             else
03212             {
03213               //G4QHadron* delta = new G4QHadron(totQC,tot4M);
03214               //delta->SetNFragments(2);           // Put a#of Fragments=2
03215               //theQHadrons.push_back(delta);      // Fill the residual DELTA (del.Eq.)
03216               // Instead
03217               //delete delta;
03218               //
03219               G4LorentzVector b4Mom(0.,0.,0.,mBar);
03220               G4LorentzVector m4Mom(0.,0.,0.,mMes);
03221               if(!G4QHadron(tot4M).DecayIn2(b4Mom, m4Mom))
03222               {
03223                 G4cout<<"---Warning---G4QEnv::HadronizeQE:B="<<bPDG<<"(m="<<mBar<<") + M="
03224                       <<mPDG<<"(m="<<mMes<<")="<<mBar+mMes<<" > mDel="<<totMass<<G4endl;
03225                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03226                 CleanUp();
03227                 if(!CheckGroundState(quasH,true))
03228                 {
03229                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03230                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03231 #ifdef debug
03232                   G4cout<<"***G4QE::HQE:FillAsIs(-3),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03233 #endif
03234                   //throw G4QException("G4QEnvironment::HadronizeQEnv:Del->Bar+Mes error");
03235                 }
03236                 delete quasH;  
03237                 return theQHadrons;
03238               }
03239 #ifdef debug
03240               G4cout<<"G4QEnv::HadronizeQEnv: DELTA="<<totPDG<<tot4M<<" -> Bar="
03241                     <<bPDG<<b4Mom<<" + Mes="<<mPDG<<m4Mom<<G4endl;
03242 #endif
03243               G4QHadron* curBar = new G4QHadron(bPDG,b4Mom);
03244               theQHadrons.push_back(curBar);     // Fill the baryon (delete equivalent)
03245 #ifdef edebug
03246               G4cout<<"G4QEnv::HadrQEnv:BaryonH="<<bPDG<<b4Mom<<G4endl;
03247 #endif
03248               G4QHadron* curMes = new G4QHadron(mPDG,m4Mom);
03249               theQHadrons.push_back(curMes);     // Fill the meson (delete equivalent)
03250 #ifdef edebug
03251               G4cout<<"G4QEnv::HadrQEnv:MesonH="<<mPDG<<m4Mom<<G4endl;
03252 #endif
03253               return theQHadrons;
03254             }
03255           }
03256           else if(totPDG==10)                    // ==> "Chipolino" case
03257           {
03258             G4QChipolino resChip(totQC);         // define Residual as Chipolino
03259             G4QPDGCode h1QPDG=resChip.GetQPDG1();// QPDG of the first hadron
03260             G4int      h1PDG=h1QPDG.GetPDGCode();// PDG code of the first hadron
03261             G4double   h1M  =h1QPDG.GetMass();   // Mass of the first hadron
03262             G4QPDGCode h2QPDG=resChip.GetQPDG2();// QPDG of the second hadron
03263             G4int      h2PDG=h2QPDG.GetPDGCode();// PDG code of the second hadron
03264             G4double   h2M  =h2QPDG.GetMass();   // Mass of the second hadron
03265             G4LorentzVector h14Mom(0.,0.,0.,h1M);
03266             G4LorentzVector h24Mom(0.,0.,0.,h2M);
03267             if(!G4QHadron(tot4M).DecayIn2(h14Mom, h24Mom))
03268             {
03269               G4cout<<"---Warning---G4QEnv::HadronizeQE:h1="<<h1PDG<<"(m="<<h1M<<") + h2="
03270                     <<h2PDG<<"(m="<<h2M<<")="<<h1M+h2M<<" > mChipo="<<totMass<<G4endl;
03271               G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03272               CleanUp();
03273               if(!CheckGroundState(quasH,true))
03274               {
03275                 G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03276                 theQHadrons.push_back(hadr);   // Cor or fill as It Is
03277 #ifdef debug
03278                 G4cout<<"***G4QE::HQE:FillAsIs(-2),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03279 #endif
03280                 //throw G4QException("G4QEnvironment::HadrQEnv: Chipo->1+2 decay failed");
03281               }
03282               delete quasH;  
03283               return theQHadrons;
03284             }
03285 #ifdef debug
03286             G4cout<<"G4QEnv::HadronizeQEnv: Chipo="<<tot4M<<" -> h1="
03287                   <<h1PDG<<h14Mom<<" + Mes="<<h2PDG<<h24Mom<<G4endl;
03288 #endif
03289             G4QHadron* curH1 = new G4QHadron(h1PDG,h14Mom);
03290             theQHadrons.push_back(curH1);        // Fill the curH1 (delete equivalent)
03291 #ifdef edebug
03292             G4cout<<"G4QEnv::HadrQEnv:HadronH="<<h1PDG<<h14Mom<<G4endl;
03293 #endif
03294             G4QHadron* curH2 = new G4QHadron(h2PDG,h24Mom);
03295             theQHadrons.push_back(curH2);        // Fill the curH2 (delete equivalent)
03296 #ifdef edebug
03297             G4cout<<"G4QEnv::HadrQEnv:MesAsHadrPartnerH="<<h2PDG<<h24Mom<<G4endl;
03298 #endif
03299             return theQHadrons;
03300           }
03301           else if(totBN<2&&totPDG&&totMass<totM+mPi0+.001)// ==> "Meson/Baryon+gamma" case
03302           {
03303             G4LorentzVector h4Mom(0.,0.,0.,totM);
03304             G4LorentzVector g4Mom(0.,0.,0.,0.);
03305             if(!G4QHadron(tot4M).DecayIn2(h4Mom, g4Mom))
03306             {
03307               G4cout<<"---Warning---G4QEnv::HadronizeQEnv: h="<<totPDG<<"(m="<<totM
03308                     <<") + gamma > mTot="<<totMass<<G4endl;
03309               G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03310               CleanUp();
03311               if(!CheckGroundState(quasH,true))
03312               {
03313                 G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03314                 theQHadrons.push_back(hadr);   // Cor or fill as It Is
03315 #ifdef debug
03316                 G4cout<<"***G4QE::HQE:FillAsIs(-1),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03317 #endif
03318                 //throw G4QException("G4QEnvironment::HadronizeQEnv:Gamma Decay failed");
03319               }
03320               delete quasH;  
03321               return theQHadrons;
03322             }
03323 #ifdef debug
03324             G4cout<<"G4QE::HQE:"<<tot4M<<"->h="<<totPDG<<h4Mom<<" + gamma="<<g4Mom<<G4endl;
03325 #endif
03326             G4QHadron* curG = new G4QHadron(22,g4Mom);
03327             theQHadrons.push_back(curG);         // Fill the gamma (delete equivalent)
03328 #ifdef edebug
03329             G4cout<<"G4QEnv::HadrQEnv:PhotonH="<<g4Mom<<G4endl;
03330 #endif
03331             G4QHadron* curH = new G4QHadron(totPDG,h4Mom);
03332 #ifdef edebug
03333             G4cout<<"G4QEnv::HadrQEnv:GamPartnerH="<<totPDG<<h4Mom<<G4endl;
03334 #endif
03335             if(totPDG==92000000||totPDG==90002000||totPDG==90000002)
03336               theEnvironment.DecayDibaryon(curH,&theQHadrons);
03337             else theQHadrons.push_back(curH);    // Fill the baryon (delete equivalent)
03338             return theQHadrons;
03339           }
03340           else if(totBN<2&&totPDG)               // ==> "Meson/Baryon+pi" case
03341           {
03342             G4int piPDG=111;
03343             G4double mpi=mPi0;
03344             G4int mbPDG=totPDG;
03345             G4double mbm=totM;
03346             if(totPDG==1114)
03347             {
03348               piPDG=-211;
03349               mpi=mPi;
03350               mbPDG=2112;
03351               mbm=mNeut;
03352             }
03353             else if(totPDG==2224)
03354             {
03355               piPDG=211;
03356               mpi=mPi;
03357               mbPDG=2212;
03358               mbm=mProt;
03359             }
03360             else if(totPDG==113)
03361             {
03362               piPDG=-211;
03363               mpi=mPi;
03364               mbPDG=211;
03365               mbm=mPi;
03366             }
03367             G4LorentzVector h4Mom(0.,0.,0.,mbm);
03368             G4LorentzVector g4Mom(0.,0.,0.,mpi);
03369             if(!G4QHadron(tot4M).DecayIn2(h4Mom, g4Mom))
03370             {
03371               G4cout<<"---Warning---G4QEnv::HadronizeQEnv: h="<<mbPDG<<"(m="<<mbm
03372                     <<") + pi(m="<<mpi<<")="<<mbm+mpi<<" > mTot="<<totMass<<G4endl;
03373               G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03374               CleanUp();
03375               if(!CheckGroundState(quasH,true))
03376               {
03377                 G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03378                 theQHadrons.push_back(hadr);   // Cor or fill as It Is
03379 #ifdef debug
03380                 G4cout<<"***G4QE::HQE:FillAsIs(0),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03381 #endif
03382                 //throw G4QException("G4QEnvironment::HadronizeQE: DecIn2 mB+nPi failed");
03383               }
03384               delete quasH;  
03385               return theQHadrons;
03386             }
03387 #ifdef debug
03388             G4cout<<"G4QE::HQE:"<<tot4M<<"->h="<<mbPDG<<h4Mom<<"+p="<<piPDG<<g4Mom<<G4endl;
03389 #endif
03390             G4QHadron* curH = new G4QHadron(mbPDG,h4Mom);
03391             if(totPDG==92000000||totPDG==90002000||totPDG==90000002)
03392               theEnvironment.DecayDibaryon(curH,&theQHadrons);
03393             else theQHadrons.push_back(curH);    // Fill the baryon (delete equivalent)
03394             G4QHadron* curG = new G4QHadron(piPDG,g4Mom);
03395 #ifdef edebug
03396             G4cout<<"G4QEnv::HadrQEnv:Gamma/Pi0H="<<piPDG<<g4Mom<<G4endl;
03397 #endif
03398             theQHadrons.push_back(curG);         // Fill the pi0 (delete equivalent)
03399             return theQHadrons;
03400           }
03401           else                                   // ==> "|B|<2 new Quasmon" case
03402           {
03403             G4Quasmon* resid = new G4Quasmon(totQC,tot4M); // delete is 3 lines below <-+
03404             G4QNucleus vacuum_value(90000000);         //                                     ^
03405             G4QHadronVector* curout=resid->Fragment(vacuum_value,1);// **!!DESTROY!!**<-<-+   ^
03406             G4int rest = resid->GetStatus();     // New status after fragm attempt  ^   ^
03407             if(!rest) eCount--;                  // Dec ExistingQuasmonsCounter     ^   ^
03408             delete resid;                        //_________________________________^___^
03409             G4int nHadrons = curout->size();     // a#of Hadrons in the outHV       ^
03410             if(nHadrons>0)                       // Transfer QHadrons to Output     ^
03411             {
03412               for (G4int ih=0; ih<nHadrons; ih++)// LOOP over output QHadrons       ^
03413               {                                  //                                 ^
03414 #ifdef debug
03415                 G4cout<<"G4QEnv::HadrQE:NewB<2, H#"<<ih //                          ^
03416                       <<", QPDG="<<(*curout)[ih]->GetQPDG() //                      ^
03417                       <<", 4M="<<(*curout)[ih]->Get4Momentum()<<G4endl; //          ^
03418 #endif
03419                 //theQHadrons.push_back(curout->operator[](ih));//(delete equ.) <-<-^
03420                 theQHadrons.push_back((*curout)[ih]);          // (delete equ.) <-<-^
03421               }                                  //                                 ^
03422             }                                    //                                 ^
03423             else                                 //                                 ^
03424             {                                    //                                 ^
03425               G4ExceptionDescription ed;         //                                 ^
03426               ed << " Quasmon decay? : MQ=" << tot4M.m() << ",QC=" << totQC //      ^
03427                  << G4endl;
03428               G4Exception("G4QEnvironment::HadronizeQEnvironment()", "HAD_CHPS_0009",
03429                           FatalException, ed);
03430             }                                    // *** Do not destroy instances ***^
03431             curout->clear();                     // The instances are filled above  ^
03432             delete curout;                       // >-------------->--------------->+
03433             return theQHadrons;
03434           }
03435         }
03436         else
03437         {
03438           G4QContent tQC    =totQC;              // Not subtracted copy for error prints
03439           G4int      NSi    =0;                  // a#of additional Sigma
03440           G4int      SiPDG  =0;                  // PDG of additional Sigma
03441           G4double   MSi    =0.;                 // TotalMass of additional Sigma
03442           G4int      NaK    =0;                  // a#of additional Kaons/anti-Kaons
03443           G4int      aKPDG  =0;                  // PDG of additional Kaons/anti-Kaons
03444           G4double   MaK    =0.;                 // TotalMass of additionalKaons/anti-Kaons
03445           G4int      NPi    =0;                  // a#of additional pions
03446           G4int      PiPDG  =0;                  // PDG of additional pions
03447           G4double   MPi    =0.;                 // Total Mass of additional pions
03448           if    (totBN>0&&totS<0&&totChg+totChg>=totBN)// => "additional K+" case
03449           {
03450             aKPDG=321;
03451             NaK=-totS;
03452             MaK=mK*NaK;
03453             tQC+=totS*KpQC;
03454             totChg+=totS;                        // Charge reduction (totS<0!)
03455             totS=0;                              // Anti-strangness goes to anti-Kaons
03456           }
03457           else if (totBN>0&&totS<0)              // => "additional aK0" case
03458           {
03459             aKPDG=311;
03460             NaK=-totS;
03461             MaK=mK0*NaK;
03462             tQC+=totS*K0QC;
03463             totS=0;                              // Anti-strangness goes to anti-Kaons
03464           }
03465           else if (totBN>1&&totS>0&&(totChg<0||totChg>totBN-totS))//=>"additional Sigma"
03466           {
03467             NSi=totS;                            // Prototype of a#of Sigmas
03468             if(totChg<0)                         // Negative Sigmas
03469             {
03470               SiPDG=3112;
03471               if(-totChg<NSi) NSi=-totChg;       // A#of Sigma- is restricted by charge
03472               MSi=mSigM*NSi;                     // Total mass of Sigma-'s
03473               tQC-=NSi*SiMQC;                    // Subtract QC of Sigma-'s from totQC
03474               totChg+=NSi;                       // Increase the TotalResidualCharge
03475             }
03476             else
03477             {
03478               SiPDG=3222;                        // Positive Sigmas
03479               G4int exChg=totChg-totBN+totS;     // Excesive positive charge
03480               if(exChg<NSi) NSi=exChg;           // A#of Sigma+ is restricted by charge
03481               MSi=mSigP*NSi;                     // Total mass of Sigma+'s
03482               tQC-=NSi*SiPQC;                    // Subtract QC of Sigma-'s from totQC
03483               totChg-=NSi;                       // Reduce the TotalResidualCharge
03484             }
03485             totS-=NSi;                           // Reduce the TotalResidualStrangeness
03486             totBN-=NSi;                          // A#of excessive pions is added below
03487           }
03488           else if (totBN>0&&totS>totBN&&totBN<totS+totChg)// => "additional K0" case
03489           {// @@ Here Ksi0 check should be added totS=2>totBN=1&&totBN=1<totS=2+totChg=0
03490             aKPDG=-311;
03491             NaK=totS-totBN;
03492             MaK=mK0*NaK;
03493             tQC+=NaK*K0QC;
03494             totS-=NaK;                           // Reduce residualstrangeness
03495           }
03496           else if (totBN>0&&totS>totBN&&totChg<0)// => "additional K-" case
03497           {// @@ Here Ksi- check should be added totS=2>totBN=1&&totChg=-1<0
03498             aKPDG=-321;
03499             NaK=totS-totBN;
03500             MaK=mK0*NaK;
03501             tQC+=NaK*KpQC;
03502             totChg+=NaK;                         // Increase residual charge
03503             totS-=NaK;                           // Reduce residual strangeness
03504           }
03505           // === Now residual DELTAS should be subtracted === 
03506           if      (totBN>0&&totChg>totBN-totS)   // => "additional PI+" case
03507           {// @@ Here Sigma+ check should be added totChg=1>totBn=1-totS=1
03508             PiPDG=211;
03509             NPi=totChg-totBN+totS;
03510             MPi=mPi*NPi;
03511             tQC-=NPi*PiQC;
03512             totChg-=NPi;
03513           }
03514           else if (totBN>0&&totChg<0)            // => "additional PI-" case
03515           {// @@ Here Sigma- check should be added totChg<0
03516             PiPDG=-211;
03517             NPi=-totChg;
03518             MPi=mPi*NPi;
03519             tQC+=NPi*PiQC;                       // Now anti-Pions must be subtracted
03520             totChg+=NPi;
03521           }
03522           else if (!totBN&&totChg>1-totS)        // => "additional PI+" case
03523           {// @@ Here Sigma+ check should be added totChg=1>totBn=1-totS=1
03524             PiPDG=211;
03525             NPi=totChg+totS-1;
03526             MPi=mPi*NPi;
03527             tQC-=NPi*PiQC;
03528             totChg-=NPi;
03529           }
03530           else if (!totBN&&totChg<-1-totS)       // => "additional PI-" case
03531           {// @@ Here Sigma- check should be added totChg<0
03532             PiPDG=-211;
03533             NPi-=totChg+totS+1;
03534             MPi=mPi*NPi;
03535             tQC+=NPi*PiQC;                       // Now anti-Pions must be subtracted
03536             totChg+=NPi;
03537           }
03538           G4double      totRM=0.;                // min (GS) Mass of the Residual System
03539           if(totBN<2)                            // Calculate totPDG & totRM
03540           {
03541             totPDG=tQC.GetSPDGCode();            // MinPDGCode for the Residual compound
03542             if(totPDG==10&&tQC.GetBaryonNumber()>0) totPDG=tQC.GetZNSPDGCode();
03543             if(totPDG) totRM=G4QPDGCode(totPDG).GetMass(); // minMass of theResidualSystem
03544             else
03545             {
03546               // G4cerr<<"***G4QEnvironment::HadronizeQEnv: totPDG=0"<<G4endl;
03547               // throw G4QException("G4QEnv::HadrQEnv: Impossible PDG for B=1");
03548               G4ExceptionDescription ed;
03549               ed << "Impossible PDG for B=1: totPDG=0" << G4endl;
03550               G4Exception("G4QEnvironment::HadronizeQEnvironment()",
03551                           "HAD_CHPS_0010", FatalException, ed);
03552             }
03553           }
03554           else
03555           {
03556             G4QNucleus totN_temporary(tQC,tot4M);// Excited nucleus for the Residual System
03557             totN=totN_temporary;
03558             totRM=totN.GetMZNS();                // min (GS) Mass of the Residual System
03559             totPDG=totN.GetPDG();                // Total PDG Code for the Current compound
03560           }
03561           if(NaK)                                // ==> "Decay in K0 or K+ + NPi" case
03562           {//@@ Can (must) be moved to EvaporateResidual ??
03563             if(!NPi)                             // ==> "Only anti-strange K" case
03564             {
03565               G4LorentzVector m4Mom(0.,0.,0.,MaK);
03566               G4LorentzVector n4Mom(0.,0.,0.,totRM);
03567               G4double sum=MaK+totRM;
03568               if(fabs(totMass-sum)<eps)
03569               {
03570                 m4Mom=tot4M*(MaK/sum);
03571                 n4Mom=tot4M*(totRM/sum);
03572               }
03573               else if(totMass<sum || !G4QHadron(tot4M).DecayIn2(m4Mom, n4Mom))
03574               {
03575 #ifdef edebug
03576                 G4cout<<"***G4QE::HadronizeQE:M="<<aKPDG<<"(m="<<MaK<<")+N="<<totPDG<<"(m="
03577                       <<totRM<<")="<<sum<<" > mSN="<<totMass<<",d="<<sum-totMass<<G4endl;
03578 #endif
03579                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03580                 CleanUp();
03581                 if(!CheckGroundState(quasH,true))
03582                 {
03583                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03584                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03585 #ifdef debug
03586                   G4cout<<"***G4QEnv::HQE:FillAsItIs(1),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03587 #endif
03588                   //throw G4QException("G4QEnvironment::HadronizeQEnv:AntiS-Nuc error");
03589                 }
03590                 delete quasH;  
03591                 return theQHadrons;
03592               }
03593 #ifdef debug
03594               G4cout<<"G4QEnv::HadronizeQEnv: SN="<<tot4M<<" -> M="
03595                     <<aKPDG<<m4Mom<<" + N="<<totPDG<<n4Mom<<totQC<<G4endl;
03596 #endif
03597               G4LorentzVector oneK=m4Mom;        // 4-mom of only kaon  
03598               if(NaK>1) oneK = m4Mom/NaK;        // 4-mom of one kaon  
03599               for (G4int jp=0; jp<NaK; jp++)
03600               {
03601                 G4QHadron* curK = new G4QHadron(aKPDG,oneK);
03602                 theQHadrons.push_back(curK);     // Fill the curK (delete equivalent)
03603               }
03604               G4QHadron* curN = new G4QHadron(totPDG,n4Mom); // @@ Use DecayDib then Evap
03605               EvaporateResidual(curN);           // Try to evaporate residual (del.eq.)
03606             }
03607             else                                 // ==> "Anti-strange K's + DELTA's" case
03608             {
03609               G4LorentzVector m4Mom(0.,0.,0.,MPi);
03610               G4LorentzVector k4Mom(0.,0.,0.,MaK);
03611               G4LorentzVector n4Mom(0.,0.,0.,totRM);
03612               if(!G4QHadron(tot4M).DecayIn3(m4Mom, k4Mom, n4Mom))
03613               {
03614                 G4cout<<"---Warning---G4QE::HadronQE:K="<<aKPDG<<"(m="<<MaK<<")+PI="<<PiPDG
03615                       <<"(m="<<MPi<<")+N="<<totPDG<<"(m="<<totRM<<")>tM="<<totMass<<G4endl;
03616                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03617                 CleanUp();
03618                 if(!CheckGroundState(quasH,true))
03619                 {
03620                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03621                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03622 #ifdef debug
03623                   G4cout<<"***G4QEnv::HQE:FillAsItIs(2),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03624 #endif
03625                   //throw G4QException("G4QEnvironment::HadronizeQE:2AntiS-Nucl(1) error");
03626                 }
03627                 delete quasH;  
03628                 return theQHadrons;
03629               }
03630 #ifdef fdebug
03631               G4cout<<"G4QEnv::HadronizeQEnv: SN="<<tot4M<<" -> nK="<<aKPDG<<k4Mom
03632                     <<" + nPi="<<PiPDG<<m4Mom<<" + N="<<totPDG<<n4Mom<<G4endl;
03633 #endif
03634               G4LorentzVector onePi=m4Mom;       // 4-mom of only pion  
03635               if(NPi>1) onePi = m4Mom/NPi;       // 4-mom of one pion  
03636               for (G4int ip=0; ip<NPi; ip++)
03637               {
03638                 G4QHadron* curP = new G4QHadron(PiPDG,onePi);
03639 #ifdef debug
03640                 G4cout<<"G4QEnv::HadrQEnv:SPion#"<<ip<<",H="<<PiPDG<<onePi<<G4endl;
03641 #endif
03642                 theQHadrons.push_back(curP);     // Fill the curM (delete equivalent)
03643               }
03644               G4LorentzVector oneK=k4Mom;        // 4-mom of one kaon  
03645               if(NaK>1) oneK = k4Mom/NaK;        // 4-mom of one kaon  
03646               for (G4int jp=0; jp<NaK; jp++)
03647               {
03648                 G4QHadron* curP = new G4QHadron(aKPDG,oneK);
03649 #ifdef debug
03650                 G4cout<<"G4QEnv::HadrQEnv:Kaon#"<<jp<<",H="<<aKPDG<<oneK<<G4endl;
03651 #endif
03652                 theQHadrons.push_back(curP);     // Fill the curM (delete equivalent)
03653               }
03654               G4QHadron* curN = new G4QHadron(totPDG,n4Mom);
03655               EvaporateResidual(curN);           // Try to evaporate residual (del.equiv.)
03656             }
03657             return theQHadrons;
03658           }
03659           else if(NSi)                           // ==> "Decay in Sig+ or Sig- + NPi" case
03660           {//@@ Can (must) be moved to EvaporateResidual ??
03661             if(!NPi)                             // ==> "Only Sigma's" case
03662             {
03663               G4LorentzVector m4Mom(0.,0.,0.,MSi);
03664               G4LorentzVector n4Mom(0.,0.,0.,totRM);
03665               G4double sum=MSi+totRM;
03666               if(fabs(totMass-sum)<eps)
03667               {
03668                 m4Mom=tot4M*(MSi/sum);
03669                 n4Mom=tot4M*(totRM/sum);
03670               }
03671               else if(totMass<sum || !G4QHadron(tot4M).DecayIn2(m4Mom, n4Mom))
03672               {
03673 #ifdef edebug
03674                 G4cout<<"***G4QE::HadronizeQE:M="<<aKPDG<<"(s="<<MSi<<")+N="<<totPDG<<"(m="
03675                       <<totRM<<")="<<sum<<" > mSN="<<totMass<<",d="<<sum-totMass<<G4endl;
03676 #endif
03677                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03678                 CleanUp();
03679                 if(!CheckGroundState(quasH,true))
03680                 {
03681                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03682                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03683 #ifdef debug
03684                   G4cout<<"***G4QEnv::HQE:FillAsItIs(2),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03685 #endif
03686                   //throw G4QException("G4QEnvironment::HadronizeQEnv:Sigma-Nuc error");
03687                 }
03688                 delete quasH;  
03689                 return theQHadrons;
03690               }
03691 #ifdef debug
03692               G4cout<<"G4QEnv::HadronizeQEnv: SN="<<tot4M<<" -> Sig="
03693                     <<SiPDG<<m4Mom<<" + N="<<totPDG<<n4Mom<<totQC<<G4endl;
03694 #endif
03695               G4LorentzVector oneS=m4Mom;        // 4-mom of the only sigma  
03696               if(NSi>1) oneS = m4Mom/NSi;        // 4-mom of one sigma  
03697               for (G4int jp=0; jp<NSi; jp++)
03698               {
03699                 G4QHadron* curS = new G4QHadron(SiPDG,oneS);
03700                 theQHadrons.push_back(curS);     // Fill the curS (delete equivalent)
03701               }
03702               G4QHadron* curN = new G4QHadron(totPDG,n4Mom); // @@ Use DecayDib then Evap
03703               EvaporateResidual(curN);           // Try to evaporate residual (del.eq.)
03704             }
03705             else                                 // ==> "Sigma's + DELTA's" case
03706             {
03707               G4LorentzVector m4Mom(0.,0.,0.,MPi);
03708               G4LorentzVector k4Mom(0.,0.,0.,MSi);
03709               G4LorentzVector n4Mom(0.,0.,0.,totRM);
03710               if(!G4QHadron(tot4M).DecayIn3(m4Mom, k4Mom, n4Mom))
03711               {
03712                 G4cout<<"---Warning---G4QE::HadronQE:S="<<SiPDG<<"(m="<<MSi<<")+PI="<<PiPDG
03713                       <<"(m="<<MPi<<")+N="<<totPDG<<"(m="<<totRM<<")>tM="<<totMass<<G4endl;
03714                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03715                 CleanUp();
03716                 if(!CheckGroundState(quasH,true))
03717                 {
03718                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03719                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03720 #ifdef debug
03721                   G4cout<<"***G4QEnv::HQE:FillAsItIs(3),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03722 #endif
03723                   //throw G4QException("G4QEnvironment::HadronizeQE:2Sigma-Nucl(1) error");
03724                 }
03725                 delete quasH;  
03726                 return theQHadrons;
03727               }
03728 #ifdef fdebug
03729               G4cout<<"G4QEnv::HadronizeQEnv: SN="<<tot4M<<" -> nS="<<SiPDG<<k4Mom
03730                     <<" + nPi="<<PiPDG<<m4Mom<<" + N="<<totPDG<<n4Mom<<G4endl;
03731 #endif
03732               G4LorentzVector onePi=m4Mom;       // 4-mom of the only pion  
03733               if(NPi>1) onePi = m4Mom/NPi;       // 4-mom of one pion  
03734               for (G4int ip=0; ip<NPi; ip++)
03735               {
03736                 G4QHadron* curP = new G4QHadron(PiPDG,onePi);
03737 #ifdef debug
03738                 G4cout<<"G4QEnv::HadrQEnv:SPion#"<<ip<<",H="<<PiPDG<<onePi<<G4endl;
03739 #endif
03740                 theQHadrons.push_back(curP);     // Fill the curM (delete equivalent)
03741               }
03742               G4LorentzVector oneS=k4Mom;        // 4-mom of the only kaon  
03743               if(NSi>1) oneS = k4Mom/NSi;        // 4-mom of one kaon  
03744               for (G4int jp=0; jp<NSi; jp++)
03745               {
03746                 G4QHadron* curP = new G4QHadron(SiPDG,oneS);
03747 #ifdef debug
03748                 G4cout<<"G4QEnv::HadrQEnv:Sigma#"<<jp<<",H="<<SiPDG<<oneS<<G4endl;
03749 #endif
03750                 theQHadrons.push_back(curP);     // Fill the curM (delete equivalent)
03751               }
03752               G4QHadron* curN = new G4QHadron(totPDG,n4Mom);
03753               EvaporateResidual(curN);           // Try to evaporate residual (del.equiv.)
03754             }
03755             return theQHadrons;
03756           }
03757           else if(NPi)                           // ==> "Decay in Pi+ or Pi-" case
03758           {
03759             if(NPi==1)                           // ==> "One isobar" case
03760             {
03761               G4LorentzVector m4Mom(0.,0.,0.,MPi);
03762               G4LorentzVector n4Mom(0.,0.,0.,totRM);
03763               if(!G4QHadron(tot4M).DecayIn2(m4Mom, n4Mom))
03764               {
03765                 G4cout<<"---Warning---G4QEnv::HadronizeQEnv:M="<<PiPDG<<"(m="<<MPi<<")+N="
03766                       <<totPDG<<"(m="<<totRM<<")="<<MPi+totRM<<" > mSN="<<totMass<<G4endl;
03767                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03768                 CleanUp();
03769                 if(!CheckGroundState(quasH,true))
03770                 {
03771                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03772                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03773 #ifdef debug
03774                   G4cout<<"***G4QEnv::HQE:FillAsItIs(5),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03775 #endif
03776                   //throw G4QException("G4QEnvironment::HadronizeQEnv:Iso-Nucleus error");
03777                 }
03778                 delete quasH;  
03779                 return theQHadrons;
03780               }
03781 #ifdef debug
03782               G4cout<<"G4QEnv::HadronizeQEnv: SN="<<tot4M<<" -> M="<<PiPDG<<m4Mom<<" + N="
03783                     <<totPDG<<n4Mom<<totQC<<G4endl;
03784 #endif
03785               G4QHadron* curK = new G4QHadron(PiPDG,m4Mom);
03786               theQHadrons.push_back(curK);       // Fill the curK (delete equivalent)
03787               G4QHadron* curN = new G4QHadron(totPDG,n4Mom);
03788               EvaporateResidual(curN);           // Evaporate residual (delete equivalent)
03789             }
03790             else                                 // ==> "Many Isobars" case
03791             {
03792               G4int N1Pi = NPi/2;                // First pion cluster
03793               G4int N2Pi = NPi-N1Pi;             // Second pion cluster
03794               G4double mM  = MPi/NPi;            // Mass of Pi
03795               G4double m1M = mM*N1Pi;            // Mass of the first Pi-cluster
03796               G4double m2M = mM*N2Pi;            // Mass of the second Pi-cluster
03797               G4LorentzVector m4Mom(0.,0.,0.,m1M);
03798               G4LorentzVector k4Mom(0.,0.,0.,m2M);
03799               G4LorentzVector n4Mom(0.,0.,0.,totRM);
03800               if(!G4QHadron(tot4M).DecayIn3(m4Mom, k4Mom, n4Mom))
03801               {
03802                 G4cout<<"---Warning---G4QEnv::HadronizeQE:N*Pi="<<PiPDG<<"(m="<<mM<<")+N="
03803                       <<totPDG<<"(m="<<totRM<<") >(?)SN="<<totMass<<G4endl;
03804                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03805                 CleanUp();
03806                 if(!CheckGroundState(quasH,true))
03807                 {
03808                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03809                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03810 #ifdef debug
03811                   G4cout<<"***G4QEnv::HQE:FillAsItIs(5),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03812 #endif
03813                   //throw G4QException("G4QEnvironment::HadronizeQE:ManyIsoNucleus error");
03814                 }
03815                 delete quasH;  
03816                 return theQHadrons;
03817               }
03818 #ifdef debug
03819               G4cout<<"G4QEnv::HadronizeQEnv: SN="<<tot4M<<" -> N*PI="<<PiPDG
03820                     <<" (4M1="<<m4Mom<<" + 4M2="<<k4Mom<<") + N="<<totPDG<<n4Mom<<G4endl;
03821 #endif
03822               G4LorentzVector one1=m4Mom;        // 4-mom of the 1st cluster only pion  
03823               if(N1Pi>1) one1=m4Mom/N1Pi;        // 4-mom of the 1st cluster one pion  
03824               for (G4int ip=0; ip<N1Pi; ip++)
03825               {
03826                 G4QHadron* curP = new G4QHadron(PiPDG,one1);
03827                 theQHadrons.push_back(curP);     // Fill the curP (delete equivalent)
03828               }
03829               G4LorentzVector one2=k4Mom;        // 4-mom of the 2nd cluster only pion  
03830               if(N2Pi>1) one2=k4Mom/N2Pi;        // 4-mom of the 2nd cluster one pion  
03831               for (G4int jp=0; jp<N2Pi; jp++)
03832               {
03833                 G4QHadron* curP = new G4QHadron(PiPDG,one2);
03834                 theQHadrons.push_back(curP);     // Fill the curP (delete equivalent)
03835               }
03836               G4QHadron* curN = new G4QHadron(totPDG,n4Mom);
03837               EvaporateResidual(curN);           // Try to evaporate residual (del.equiv.)
03838             }
03839             return theQHadrons;
03840           }
03841         }
03842 #ifdef fdebug
03843         G4cout<<"G4QE::HadrQEnv: Try FinalEvaporation t4M="<<tot4M<<",tQC="<<totQC<<G4endl;
03844 #endif
03845         CleanUp();
03846         G4QHadron* evH = new G4QHadron(totQC,tot4M); // Create a Hadron for theResidualNucl
03847         EvaporateResidual(evH);                  // Try to evaporate residual (del.equiv.)
03848         return theQHadrons;
03849       }
03850       else                                       // ==> "Only with GSEnvironment" case
03851       { 
03852         if(totPDG==90000000 || fabs(totMass)<0.000001)
03853         {
03854           CleanUp();
03855           return theQHadrons;
03856         }
03857         G4double dM=totMass-totM;
03858 #ifdef debug
03859         G4cout<<"G4QEnv::HadrQEnv:GroundState tM-GSM="<<dM<<",GSM="<<totM<<",tPDG="<<totPDG
03860               <<",nQ="<<nQuasmons<<G4endl;
03861 #endif
03862         G4Quasmon*       pQ = theQuasmons[0];    // Pointer to the first Quasmon          
03863         G4QPDGCode    QQPDG = pQ->GetQPDG();     // QPDG of the first Quasmon
03864         G4int          QPDG = QQPDG.GetPDGCode();
03865         G4QNucleus    totRN(totQC,tot4M);        // Nucleus for theTotalResidualNuclearComp
03866         G4int          spbRN=totRN.SplitBaryon();// PossibilityToSplit baryon from Residual
03867         if(dM>-0.001)
03868         {
03869 #ifdef fdebug
03870           G4cout<<"G4QE::HadrQE:ExcitedNucleus, dM="<<dM<<">0,tBN="<<totBN<<",nQ="<<G4endl;
03871 #endif
03872           CleanUp();
03873           G4QHadron* evH = new G4QHadron(totQC,tot4M);// Create a Hadron for ResidualNucl
03874           EvaporateResidual(evH);                // Try to evaporate residual (del. equiv.)
03875         }
03876         else if(nQuasmons==1&&QPDG!=22&&QPDG!=111)// => "Decay Quasmon or Q+Environ" case
03877         {
03878           G4int envPDG = theEnvironment.GetPDG();// PDGCode of the NuclQEnvironment
03879 #ifdef debug
03880           G4cout<<"G4QEnv::HadrQEnv: nQ=1, QPDG=="<<QPDG<<G4endl;
03881 #endif
03882           if(!QPDG)
03883           {
03884             G4ExceptionDescription ed;
03885             ed <<"(2)Can't Decay QEnv: Quasmon is an unknown QHadron: PDG="<< QPDG<<G4endl;
03886             G4Exception("G4QEnvironment::HadronizeQEnvironmen()", "HAD_CHPS_0011",
03887                         FatalException, ed);
03888           }
03889           // => "Quasmon-Chipolino or Environment-Dibaryon" case
03890           else if(QPDG==10||QPDG==92000000||QPDG==90002000||QPDG==90000002)
03891           {
03892             G4QContent QQC = pQ->GetQC();        // Quark Content of the Quasmon
03893             G4QPDGCode h1QPDG=nQPDG;             // QPDG of the first hadron
03894             G4double   h1M   =mNeut;             // Mass of the first hadron
03895             G4QPDGCode h2QPDG=h1QPDG;            // QPDG of the second hadron
03896             G4double   h2M   =mNeut;             // Mass of the second hadron
03897             if(QPDG==10)
03898             {
03899               G4QChipolino QChip(QQC);           // define the Quasmon as a Chipolino
03900               h1QPDG=QChip.GetQPDG1();           // QPDG of the first hadron
03901               h1M   =h1QPDG.GetMass();           // Mass of the first hadron
03902               h2QPDG=QChip.GetQPDG2();           // QPDG of the second hadron
03903               h2M   =h2QPDG.GetMass();           // Mass of the second hadron
03904             }
03905             else if(QPDG==90002000)
03906             {
03907               h1QPDG=pQPDG;                      // QPDG of the first hadron
03908               h1M   =mProt;                      // Mass of the first hadron
03909               h2QPDG=h1QPDG;                     // QPDG of the second hadron
03910               h2M   =mProt;                      // Mass of the second hadron
03911             }
03912             else if(QPDG==92000000)
03913             {
03914               h1QPDG=lQPDG;                      // QPDG of the first hadron
03915               h1M   =mLamb;                      // Mass of the first hadron
03916               h2QPDG=h1QPDG;                     // QPDG of the second hadron
03917               h2M   =mLamb;                      // Mass of the second hadron
03918               G4double ddMass=totMass-envM;      // Free CM energy
03919               if(ddMass>mSigZ+mSigZ)             // Sigma0+Sigma0 is possible
03920               {                                  // @@ Only two particles PS is used
03921                 G4double dd2=ddMass*ddMass;      // Squared free energy
03922                 G4double sma=mLamb+mLamb;        // Lambda+Lambda sum
03923                 G4double pr1=0.;                 // Prototype to avoid sqrt(-)
03924                 if(ddMass>sma) pr1=sqrt((dd2-sma*sma)*dd2); // Lamb+Lamb PS
03925                 sma=mLamb+mSigZ;                 // Lambda+Sigma0 sum
03926                 G4double smi=mSigZ-mLamb;        // Sigma0-Lambda difference
03927                 G4double pr2=pr1;                // Prototype of +L+S0 PS
03928                 if(ddMass>sma && ddMass>smi) pr2+=sqrt((dd2-sma*sma)*(dd2-smi*smi));
03929                 sma=mSigZ+mSigZ;                 // Sigma0+Sigma0 sum
03930                 G4double pr3=pr2;                // Prototype of +Sigma0+Sigma0 PS
03931                 if(ddMass>sma) pr3+=sqrt((dd2-sma*sma)*dd2);
03932                 G4double hhRND=pr3*G4UniformRand(); // Randomize PS
03933                 if(hhRND>pr2)                    // --> "ENnv+Sigma0+Sigma0" case
03934                 {                                //
03935                   h1QPDG=s0QPDG;                 // QPDG of the first hadron
03936                   h1M   =mSigZ;                  // Mass of the first hadron
03937                   h2QPDG=h1QPDG;                 // QPDG of the second hadron
03938                   h2M   =mSigZ;                  // Mass of the second hadron
03939                 }                                //
03940                 else if(hhRND>pr1)               // --> "ENnv+Sigma0+Lambda" case
03941                 {                                //
03942                   h1QPDG=s0QPDG;                 // QPDG of the first hadron
03943                   h1M   =mSigZ;                  // Mass of the first hadron
03944                 }                                //
03945               }                                  //
03946               else if(ddMass>mSigZ+mLamb)        // Lambda+Sigma0 is possible
03947               {                                  // @@ Only two particles PS is used
03948                 G4double dd2=ddMass*ddMass;      // Squared free energy
03949                 G4double sma=mLamb+mLamb;        // Lambda+Lambda sum
03950                 G4double pr1=0.;                 // Prototype to avoid sqrt(-)
03951                 if(ddMass>sma) pr1=sqrt((dd2-sma*sma)*dd2); // Lamb+Lamb PS
03952                 sma=mLamb+mSigZ;                 // Lambda+Sigma0 sum
03953                 G4double smi=mSigZ-mLamb;        // Sigma0-Lambda difference
03954                 G4double pr2=pr1;                // Prototype of +L+S0 PS
03955                 if(ddMass>sma && ddMass>smi) pr2+=sqrt((dd2-sma*sma)*(dd2-smi*smi));
03956                 if(pr2*G4UniformRand()>pr1)      // --> "ENnv+Sigma0+Lambda" case
03957                 {                                //
03958                   h1QPDG=s0QPDG;                 // QPDG of the first hadron
03959                   h1M   =mSigZ;                  // Mass of the first hadron
03960                 }                                //
03961               }                                  //
03962             }                                    //
03963             if(h1M+h2M+envM<totMass)             // => "Three parts decay" case
03964             {
03965               G4LorentzVector h14M(0.,0.,0.,h1M);
03966               G4LorentzVector h24M(0.,0.,0.,h2M);
03967               G4LorentzVector e4M(0.,0.,0.,envM);
03968               if(!G4QHadron(tot4M).DecayIn3(h14M,h24M,e4M))
03969               {
03970                 G4cout<<"Warning->G4QE::HQE:M="<<tot4M.m()<<","<<totMass<<"->"<<h1QPDG<<"("
03971                       <<h1M<<")+"<<h1QPDG<<"("<<h2M<<")+"<<envM<<"="<<h1M+h2M+envM<<G4endl;
03972                 G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
03973                 CleanUp();
03974                 if(!CheckGroundState(quasH,true))
03975                 {
03976                   G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
03977                   theQHadrons.push_back(hadr);   // Cor or fill as It Is
03978 #ifdef debug
03979                   G4cout<<"***G4QEnv::HQE:FillAsItIs(6),QC="<<totQC<<",4M="<<tot4M<<G4endl;
03980 #endif
03981                   //throw G4QException("G4QEnv::HadrQEnv:QChipo+Environment DecIn3 Error");
03982                 }
03983                 delete quasH;  
03984                 return theQHadrons;
03985 
03986               }
03987               G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
03988               theQHadrons.push_back(h1H);        // (delete equivalent)
03989 #ifdef debug
03990               G4cout<<"G4QE::HQE:(2) H1="<<h1QPDG<<h14M<<G4endl;
03991 #endif
03992               G4QHadron* h2H = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
03993               theQHadrons.push_back(h2H);        // (delete equivalent)
03994 #ifdef debug
03995               G4cout<<"G4QE::HQE:(2) H2-"<<h2QPDG<<h24M<<G4endl;
03996 #endif
03997               G4QHadron* qeH = new G4QHadron(envPDG,e4M);
03998               theQHadrons.push_back(qeH);        // (delete equivalent)
03999 #ifdef debug
04000               G4cout<<"G4QE::HQE:(2) QEenv="<<envPDG<<e4M<<G4endl;
04001 #endif
04002             }
04003 #ifdef fdebug
04004             G4cout<<"***G4QEnv::HadQEnv:tM="<<tot4M.m()<<totQC<<"< h1="<<h1QPDG<<"(M="<<h1M
04005                   <<")+h2="<<h1QPDG<<"(M="<<h2M<<")+eM="<<envM<<"="<<h1M+h2M+envM<<G4endl;
04006             //throw G4QException("G4QEnv::HadrQEnv:QChipo+Env mass > than decaying mass");
04007 #endif
04008             CleanUp();
04009             G4QHadron* evH = new G4QHadron(totQC,tot4M);// Create a Hadron for ResidualNucl
04010             EvaporateResidual(evH);              // Try to evaporate residual (del. equiv.)
04011             return theQHadrons;
04012           }
04013           else                                   // No environment
04014           {
04015             G4int nHadrs=theQHadrons.size();     // #of available hadrons
04016             for(G4int ih=0; ih<nHadrs; ++ih)
04017             {
04018               G4QHadron* ch=theQHadrons[ih];
04019               G4LorentzVector ch4M=ch->Get4Momentum();
04020               G4double chM=ch4M.m();
04021               G4LorentzVector tch4M=ch4M+tot4M;
04022               if(tch4M.m() > chM + totM)         // Can be corrected
04023               {
04024                 G4LorentzVector h14M(0.,0.,0.,chM);
04025                 G4LorentzVector h24M(0.,0.,0.,totM);
04026                 if(!G4QHadron(tch4M).DecayIn2(h14M,h24M))
04027                 {
04028                   G4cout<<"-Warning->G4QE::HQE:M="<<tch4M.m()<<"->"<<chM<<"+"<<totM<<"="
04029                         <<chM+totM<<G4endl;
04030                 }
04031                 else
04032                 {
04033                   tot4M=h24M;                    // Change the residual 4M
04034                   ch->Set4Momentum(h14M);        // Change 4M of the current hadron
04035                   break;                         // Quit the loop
04036                 }
04037               }
04038             }
04039             G4QHadron* rH = new G4QHadron(totQC,tot4M);// Create a Hadron for ResidualNucl
04040             theQHadrons.push_back(rH);
04041           }
04042         }
04043         else if(spbRN)// => "Join all quasmons to the residual compound and evaporate" case
04044         {
04045 #ifdef fdebug
04046           G4cout<<"***G4QEnv::HadQEnv: Evaporate the total residual tRN="<<totRN<<G4endl;
04047 #endif
04048           CleanUp();
04049           G4QHadron* evH = new G4QHadron(totQC,tot4M);// Create Hadron for theResidNucleus
04050           EvaporateResidual(evH);               // Try to evaporate residual (del.equiv.)
04051           return theQHadrons;
04052         }
04053         //else if(nQuasmons<3||theQHadrons.size()<12)//"Try to correct" case (change cond)
04054         else if(2>3)  // "Try to correct" case (change condition)
04055         {
04056 #ifdef debug
04057           G4cout<<"***G4QEnv::HadrQE: M="<<totMass<<",dM="<<dM<<",nQ="<<nQuasmons<<G4endl;
04058 #endif
04059           G4int          nOfOUT  = theQHadrons.size();
04060           while(nOfOUT)
04061           {
04062             G4QHadron*     theLast = theQHadrons[nOfOUT-1];
04063             G4LorentzVector last4M = theLast->Get4Momentum();
04064             G4QContent      lastQC = theLast->GetQC();
04065             G4int           lastS  = lastQC.GetStrangeness();
04066             totS                   = totQC.GetStrangeness();
04067             G4int           nFr    = theLast->GetNFragments();
04068             G4int           gam    = theLast->GetPDGCode();
04069             if(gam!=22&&!nFr&&lastS<0&&lastS+totS<0&&nOfOUT>1) // => "Skip K,gam & decayed"
04070             {
04071               G4QHadron* thePrev = theQHadrons[nOfOUT-2];
04072               theQHadrons.pop_back();         // the last QHadron is excluded from OUTPUT
04073               theQHadrons.pop_back();         // the prev QHadron is excluded from OUTPUT
04074               theQHadrons.push_back(thePrev); // thePast becomes theLast as an instance
04075               delete    theLast;              // theLast QHadron is deleated as an instance
04076               theLast = thePrev;              // Update parameters(thePrev becomes theLast)
04077               last4M = theLast->Get4Momentum();
04078               lastQC = theLast->GetQC();
04079             }
04080             else
04081             {
04082               theQHadrons.pop_back();         // the last QHadron is excluded from OUTPUT 
04083               delete         theLast;         // theLastQHadron is deleated as an instance
04084             }
04085             totQC+=lastQC;                    // Update (increase) the total QC
04086             tot4M+=last4M;                    // Update (increase) the total 4-momentum
04087             totMass=tot4M.m();                // Calculate new real total mass
04088             G4int bn=totQC.GetBaryonNumber(); // The BaryNum after addition
04089             totPDG=totQC.GetSPDGCode();
04090             if(totPDG==10&&totQC.GetBaryonNumber()>0) totPDG=totQC.GetZNSPDGCode();
04091             if(bn>1)
04092             {
04093               totS  =totQC.GetStrangeness();  // Total Strangeness of this System
04094               if(totS>=0)                     // => "This is a normal nucleus" case
04095               {
04096                 G4QNucleus newN(totQC,tot4M);
04097                 totPDG=newN.GetPDG();
04098                 totM  =newN.GetMZNS();           // Calculate new minimum (GS) mass
04099               }
04100               else if(totS==-1)                  // => "Try to decay in K+/aK0 and finish"
04101               {
04102                 G4double m1=mK;         
04103                 G4int  PDG1=321;
04104                 G4QNucleus  newNp(totQC-KpQC);
04105                 G4int  PDG2=newNp.GetPDG();
04106                 G4double m2_value=newNp.GetMZNS();
04107                 G4QNucleus  newN0(totQC-K0QC);
04108                 G4double m3_value=newN0.GetMZNS();
04109                 if (m3_value+mK0<m2_value+mK)                // => "aK0+ResA is better" case
04110                 {
04111                   m1  =mK0;
04112                   PDG1=311;
04113                   m2_value  =m3_value;
04114                   PDG2=newN0.GetPDG();
04115                 }
04116                 if(totMass>m1+m2_value)                // => "can decay" case
04117                 {
04118                   G4LorentzVector fq4M(0.,0.,0.,m1);
04119                   G4LorentzVector qe4M(0.,0.,0.,m2_value);
04120                   if(!G4QHadron(tot4M).DecayIn2(fq4M,qe4M))
04121                   {
04122                     G4cout<<"---Warning---G4QE::HadQE:tM="<<tot4M.m()<<"->aK="<<PDG1<<"(M="
04123                           <<m1<<")+ResA="<<PDG2<<"(M="<<m2_value<<")="<<m1+m2_value<<G4endl;
04124                     G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
04125                     CleanUp();
04126                     if(!CheckGroundState(quasH,true))
04127                     {
04128                       G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
04129                       theQHadrons.push_back(hadr);   // Cor or fill as It Is
04130 #ifdef debug
04131                       G4cout<<"***G4QE::HQE:FillAsIs(7),QC="<<totQC<<",4M="<<tot4M<<G4endl;
04132 #endif
04133                       //throw G4QException("G4QEnv::HadrQEnv: aK+ResA DecayIn2 error");
04134                     }
04135                     delete quasH;  
04136                     return theQHadrons;
04137                   }
04138                   G4QHadron* H1 = new G4QHadron(PDG1,fq4M);
04139 #ifdef debug
04140                   G4cout<<"G4QE::HQE:Kaon(Env)="<<PDG1<<fq4M<<G4endl;
04141 #endif
04142                   theQHadrons.push_back(H1);     // (delete equivalent)
04143                   G4QHadron* H2 = new G4QHadron(PDG2,qe4M);
04144 #ifdef debug
04145                   G4cout<<"G4QE::HQE:ResidEnv="<<PDG2<<qe4M<<G4endl;
04146 #endif
04147                   theQHadrons.push_back(H2);     // (delete equivalent)
04148                   break;
04149                 }
04150                 else totM=250000.;               // => "Continue reversion" case
04151               }
04152               else if(totS==-2)                  //=>"Try to decay in 2(K+/aK0) and finish"
04153               {
04154                 G4double m1=mK;         
04155                 G4int  PDG1=321;
04156                 G4double m2_value=mK0;         
04157                 G4int  PDG2=311;
04158                 G4QNucleus  newNp0(totQC-KpQC-K0QC);
04159                 G4int  PDG3=newNp0.GetPDG();
04160                 G4double m3_value=newNp0.GetMZNS();    // M-K^0-K^+
04161                 G4QNucleus  newN00(totQC-K0QC-K0QC);
04162                 G4double m4=newN00.GetMZNS();    // M-2*K^0
04163                 G4QNucleus  newNpp(totQC-KpQC-KpQC);
04164                 G4double m5=newNpp.GetMZNS();    // M-2*K^+
04165                 if (m4+mK0+mK0<m3_value+mK+mK0 && m4+mK0+mK0<=m5+mK+mK) //=>"2K0+ResA is theBest"
04166                 {
04167                   m1  =mK0;
04168                   PDG1=311;
04169                   m3_value  =m4;
04170                   PDG3=newN00.GetPDG();
04171                 }
04172                 else if(m5+mK+mK<m3_value+mK+mK0 && m5+mK+mK<=m4+mK0+mK0)//=>"2Kp+ResA isTheBest"
04173                 {
04174                   m2_value  =mK;
04175                   PDG1=321;
04176                   m3_value  =m5;
04177                   PDG3=newNpp.GetPDG();
04178                 }
04179                 if(totMass>m1+m2_value+m3_value)             // => "can decay" case
04180                 {
04181                   G4LorentzVector k14M(0.,0.,0.,m1);
04182                   G4LorentzVector k24M(0.,0.,0.,m2_value);
04183                   G4LorentzVector ra4M(0.,0.,0.,m3_value);
04184                   if(!G4QHadron(tot4M).DecayIn3(k14M,k24M,ra4M))
04185                   {
04186                     G4cout<<"--Warning--G4QE::HQE:tM="<<tot4M.m()<<"->aK="<<PDG1<<"(M="<<m1
04187                           <<")+K2="<<PDG2<<"(M="<<m2_value<<")+A="<<PDG3<<"(M="<<m3_value<<")"<<G4endl;
04188                     G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
04189                     CleanUp();
04190                     if(!CheckGroundState(quasH,true))
04191                     {
04192                       G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
04193                       theQHadrons.push_back(hadr);   // Cor or fill as It Is
04194 #ifdef debug
04195                       G4cout<<"***G4QE::HQE:FillAsIs(8),QC="<<totQC<<",4M="<<tot4M<<G4endl;
04196 #endif
04197                       //throw G4QException("G4QEnv::HadrQE:2K+ResidNucleus DecIn3 Error");
04198                     }
04199                     delete quasH;  
04200                     return theQHadrons;
04201                   }
04202                   G4QHadron* H1 = new G4QHadron(PDG1,k14M);
04203                   theQHadrons.push_back(H1);     // (delete equivalent)
04204 #ifdef debug
04205                   G4cout<<"G4QE::HQE:K1(Env)="<<PDG1<<k14M<<G4endl;
04206 #endif
04207                   G4QHadron* H2 = new G4QHadron(PDG2,k24M);
04208                   theQHadrons.push_back(H2);     // (delete equivalent)
04209 #ifdef debug
04210                   G4cout<<"G4QE::HQE:K2(Env)="<<PDG2<<k24M<<G4endl;
04211 #endif
04212                   G4QHadron* H3 = new G4QHadron(PDG3,ra4M);
04213                   theQHadrons.push_back(H3);     // (delete equivalent)
04214 #ifdef debug
04215                   G4cout<<"G4QE::HQE:ResKKEnv="<<PDG3<<ra4M<<G4endl;
04216 #endif
04217                   break;
04218                 }
04219                 else totM=270000.;               // => "Continue reversion" case
04220               }
04221               else totM=300000.;                 // => "Continue reversion" case
04222             }
04223             else
04224             {
04225               if     (totPDG==1114||totPDG==2224||totPDG==10) // Decay right now and finish
04226               {
04227                 G4double m1=mNeut;
04228                 G4int  PDG1=2112;
04229                 G4double m2_value=mPi;
04230                 G4int  PDG2=-211;
04231                 if(totPDG==2224)
04232                 {
04233                   m1=mProt;
04234                   PDG1=2212;
04235                   m2_value=mPi;
04236                   PDG2=211;
04237                 }
04238                 else if(totPDG==10)              // "Chipolino" case
04239                 {
04240                   G4QChipolino resChip(totQC);   // define the residual as a Chipolino
04241                   G4QPDGCode h1=resChip.GetQPDG1();
04242                   PDG1=h1.GetPDGCode();          // PDG code of the first hadron
04243                   m1  =h1.GetMass();             // Mass of the first hadron
04244                   G4QPDGCode h2=resChip.GetQPDG2();
04245                   PDG2=h2.GetPDGCode();          // PDG code of the second hadron
04246                   m2_value  =h2.GetMass();       // Mass of the second hadron
04247                 }
04248                 if(totMass>m1+m2)
04249                 {
04250                   G4LorentzVector fq4M(0.,0.,0.,m1);
04251                   G4LorentzVector qe4M(0.,0.,0.,m2_value);
04252                   if(!G4QHadron(tot4M).DecayIn2(fq4M,qe4M))
04253                   {
04254                     G4cout<<"---Warning---G4QE::HaQE:tM="<<tot4M.m()<<"-> h1="<<PDG1<<"(M="
04255                           <<m1<<") + h2="<<PDG2<<"(M="<<m2_value<<")="<<m1+m2_value<<G4endl;
04256                     G4Quasmon* quasH = new G4Quasmon(totQC,tot4M); // totQC not tQC!
04257                     CleanUp();
04258                     if(!CheckGroundState(quasH,true))
04259                     {
04260                       G4QHadron* hadr = new G4QHadron(totQC,tot4M); // totQC not tQC!
04261                       theQHadrons.push_back(hadr);   // Cor or fill as It Is
04262 #ifdef debug
04263                       G4cout<<"***G4QE::HQE:FillAsIs(9),QC="<<totQC<<",4M="<<tot4M<<G4endl;
04264 #endif
04265                       //throw G4QException("G4QEnv::HadrQEnv: h1+h2 DecayIn2 Error");
04266                     }
04267                     delete quasH;  
04268                     return theQHadrons;
04269                   }
04270                   G4QHadron* H1 = new G4QHadron(PDG1,fq4M);
04271                   theQHadrons.push_back(H1);     // (delete equivalent)
04272 #ifdef debug
04273                   G4cout<<"G4QE::HQE:h1="<<PDG1<<fq4M<<G4endl;
04274 #endif
04275                   G4QHadron* H2 = new G4QHadron(PDG2,qe4M);
04276 #ifdef debug
04277                   G4cout<<"G4QE::HQE:h2="<<PDG2<<qe4M<<G4endl;
04278 #endif
04279                   theQHadrons.push_back(H2);     // (delete equivalent)
04280                   break;
04281                 }
04282                 else totM=350000.;
04283               }
04284               else if(totPDG) totM=G4QPDGCode(totPDG).GetMass();
04285               else totM=400000.;
04286             }
04287             totBN=totQC.GetBaryonNumber();      // The BaryNum after addition
04288             totS=totQC.GetStrangeness();        // The Strangeness after addition
04289             dM=totMass-totM;
04290 #ifdef fdebug
04291             G4cout<<"G4QEnv::HadrQE: Add H="<<last4M<<lastQC<<",tM="<<tot4M<<totM<<totQC
04292                   <<",dM="<<dM<<", tB="<<totBN<<", tS="<<totS<<G4endl;
04293 #endif
04294             if(dM>-0.001&&totPDG)
04295             {
04296               CleanUp();
04297               G4QHadron* evH = new G4QHadron(totPDG,tot4M);//Create Hadron for ResidNucleus
04298               EvaporateResidual(evH);           // Evaporate ResNuc (del.equiv)
04299               break;
04300             }
04301             nOfOUT  = theQHadrons.size();       // Update the value of OUTPUT entries
04302           } // End of WHILE(nOfOUT)
04303           nOfOUT  = theQHadrons.size();         // Update the value of OUTPUT entries
04304           if(!nOfOUT)
04305           {
04306             G4cout<<"---Warning---G4QEnv::HadrQE:M="<<totMass<<"<gsM="<<totM<<",dM="<<dM
04307                   <<", tPDG="<<totPDG<<", t4M="<<tot4M<<G4endl;
04308             // throw G4QException("G4QEnvironment::HadronizeQEnv:Can't decayExhostedQEnv");
04309             CleanUp();
04310             G4QHadron* evH = new G4QHadron(totPDG,tot4M);// Create Hadron for ResidNucleus
04311             EvaporateResidual(evH);             // Evaporate ResidNucl (del.equiv)
04312           }
04313         }
04314         else                                    // "Last decay was fatal" case @@ buggy ?MK
04315         {
04316 #ifdef debug
04317           G4cout<<"***G4QEnv::HadrQE: M="<<totMass<<",dM="<<dM<<",nQ="<<nQuasmons<<G4endl;
04318 #endif
04319           G4Quasmon* quasH = new G4Quasmon(totQC,tot4M);
04320           CleanUp();
04321           if(!CheckGroundState(quasH,true))
04322           {
04323             G4QHadron* hadr = new G4QHadron(totQC,tot4M);
04324 #ifdef debug
04325             G4cout<<"G4QE::HQE:CheckGS failed H="<<totQC<<tot4M<<G4endl;
04326 #endif
04327             theQHadrons.push_back(hadr); // Cor or fill asItIs
04328           }
04329           delete quasH;  
04330         }
04331         CleanUp();
04332       }
04333     } // End of "infinit" WHILE LOOP
04334   } // End of the "Nuclear Environment" case
04335   return theQHadrons;
04336 } // End of the main member function HadronizeQEnvironment
04337 
04338 // Clean up the QEnvironment to Zero
04339 void G4QEnvironment::CleanUp()
04340 {
04341   static const G4QNucleus vacuum(90000000);
04342   theEnvironment=vacuum;
04343   G4int nQuasmons = theQuasmons.size();
04344   if (nQuasmons) for (G4int iq=0; iq<nQuasmons; iq++)theQuasmons[iq]->KillQuasmon();
04345 } // End of CleanUp
04346 
04347 //Evaporate Residual Nucleus
04348 void G4QEnvironment::EvaporateResidual(G4QHadron* qH,  G4bool fCGS)
04349 {
04350   static const G4double mAlph = G4QPDGCode(2112).GetNuclMass(2,2,0);
04351   static const G4double mDeut = G4QPDGCode(2112).GetNuclMass(1,1,0);
04352   static const G4double mNeut = G4QPDGCode(2112).GetMass();
04353   static const G4double mProt = G4QPDGCode(2212).GetMass();
04354   static const G4double mAlPr = mAlph+mProt;
04355   static const G4double mAlNt = mAlph+mNeut;
04356   static const G4double dProt = mProt+mProt;
04357   static const G4double dNeut = mNeut+mNeut;
04358   static const G4double dAlph = mAlph+mAlph;
04359   static const G4double eps=.003;
04360   G4int thePDG = qH->GetPDGCode();           // Get PDG code of the Residual Nucleus
04361   G4int theBN  = qH->GetBaryonNumber();      // A (Baryon number of the nucleus)
04362   G4QContent  theQC  = qH->GetQC();          // Quark Content of the hadron
04363   G4int theS=theQC.GetStrangeness();         // S (Strangeness of the nucleus)
04364 #ifdef debug
04365   G4cout<<"G4QE::EvaporateRes:Called for PDG="<<thePDG<<",4M="<<qH->Get4Momentum()<<G4endl;
04366 #endif
04367   if(thePDG==10)
04368   {
04369     G4QContent   chQC=qH->GetQC();           // Quark content of the Hadron-Chipolino
04370     G4QChipolino QCh(chQC);                  // Define a Chipolino instance for the Hadron
04371     G4LorentzVector ch4M=qH->Get4Momentum(); // 4Mom of the Hadron-Chipolino
04372     G4QPDGCode h1QPDG=QCh.GetQPDG1();        // QPDG of the first hadron
04373     G4double   h1M   =h1QPDG.GetMass();      // Mass of the first hadron
04374     G4QPDGCode h2QPDG=QCh.GetQPDG2();        // QPDG of the second hadron
04375     G4double   h2M   =h2QPDG.GetMass();      // Mass of the second hadron
04376     G4double   chM2  =ch4M.m2();             // Squared Mass of the Chipolino
04377     if( sqr(h1M+h2M) < chM2 )                // Decay is possible
04378     {
04379       G4LorentzVector h14M(0.,0.,0.,h1M);
04380       G4LorentzVector h24M(0.,0.,0.,h2M);
04381       if(!G4QHadron(ch4M).DecayIn2(h14M,h24M))
04382       {
04383         G4ExceptionDescription ed;
04384         ed << "QChipolino DecIn2 error: CM=" << std::sqrt(chM2) << " -> h1="
04385            << h1QPDG << "(" << h1M << ") + h2=" << h1QPDG << "(" << h2M
04386            << ") = " << h1M+h2M << " **Failed**" << G4endl;
04387         G4Exception("G4QEnvironment::EvaporateResidual()", "HAD_CHPS_0000",
04388                     FatalException, ed);
04389       }
04390       delete qH;                             // Kill the primary Chipolino
04391       G4QHadron* h1H = new G4QHadron(h1QPDG.GetPDGCode(),h14M);
04392       theQHadrons.push_back(h1H);            // (delete equivalent)
04393 #ifdef debug
04394       G4cout<<"G4QE::EvaporateResidual: Chipolino -> H1="<<h1QPDG<<h14M<<G4endl;
04395 #endif
04396       qH = new G4QHadron(h2QPDG.GetPDGCode(),h24M);
04397       theQHadrons.push_back(qH);             // (delete equivalent)
04398 #ifdef debug
04399       G4cout<<"G4QE::EvaporateResidual: Chipolino -> H2="<<h2QPDG<<h24M<<G4endl;
04400 #endif
04401     }
04402     else
04403     {
04404       // G4cerr<<"***G4QEnv::EvaporateResid: ChipoMeson="<<qH->GetQC()<<qH->Get4Momentum()
04405       //       <<", chipoM="<<std::sqrt(chM2)<<" < m1="<<h1M<<"("<<h1QPDG<<") + m2="<<h2M
04406       //       <<"("<<h2QPDG<<") = "<<h1M+h2M<<G4endl;
04407       // throw G4QException("G4QEnvironment::EvaporateResidual: LowMassChipolino in Input");
04408       G4ExceptionDescription ed;
04409       ed << "LowMassChipolino in Input: ChipoMeson=" << qH->GetQC()
04410          << qH->Get4Momentum() << ", chipoM=" << std::sqrt(chM2) << " < m1="
04411          << h1M << "(" << h1QPDG << ") + m2=" << h2M << "(" << h2QPDG << ") = "
04412          << h1M+h2M << G4endl;
04413       G4Exception("G4QEnvironment::EvaporateResidual()", "HAD_CHPS_0001",
04414                   FatalException, ed);
04415     }
04416     return;
04417   }
04418   else if(theS<0)                            // Antistrange nucleus
04419   {
04420 #ifdef debug
04421     G4cout<<"G4QE::EvaporateRes: AntistrangeNucleus="<<thePDG<<qH->Get4Momentum()<<G4endl;
04422 #endif
04423     DecayAntistrange(qH, &theQHadrons);      // (delete equivalent)
04424     return;
04425   }
04426   else if(theBN==1)
04427   {
04428 #ifdef debug
04429     G4cout<<"G4QE::EvaporateRes: Baryon="<<thePDG<<qH->Get4Momentum()<<G4endl;
04430 #endif
04431     DecayBaryon(qH, &theQHadrons);           // (delete equivalent)
04432     return;
04433   }
04434   else if(!theBN) // @@ In future it is usefull to add the MesonExcitationDecay (?!)
04435   {
04436 #ifdef debug
04437     G4LorentzVector mesLV=qH->Get4Momentum();
04438     G4cout<<"G4QE::EvaporateRes:(!)Meson(!) PDG="<<thePDG<<",4M="<<mesLV<<mesLV.m()
04439           <<",QC="<<qH->GetQC()<<",MPDG="<<G4QPDGCode(thePDG).GetMass()<<G4endl;
04440 #endif
04441     DecayMeson(qH, &theQHadrons);            // (delete equivalent)
04442     //theQHadrons.push_back(qH);             // Old solution
04443     return;
04444   }
04445   G4int theC=theQC.GetCharge();              // P
04446   if(!thePDG) thePDG = theQC.GetSPDGCode();  // If there is no PDG code, get it from QC
04447   if(thePDG==10 && theBN>0) thePDG=theQC.GetZNSPDGCode();
04448   if(theS>0) thePDG-=theS*999999;            // @@ May hide hypernuclear problems (G4) ! @@
04449   G4double totGSM = G4QNucleus(thePDG).GetGSMass();// TheGroundStMass of theTotalResNucleus
04450   if(theBN==2)
04451   {
04452     if(!theC)        totGSM=dNeut;           // nn, nL, LL
04453     else if(theC==2) totGSM=dProt;           // pp
04454     else             totGSM=mDeut;           // np, Lp
04455   }
04456   else if(theBN==5)
04457   {
04458     if     (theC==3) totGSM=mAlPr;           // effective "Alph+p"
04459     else if(theC==2) totGSM=mAlNt;           // effective "Alph+n"
04460   }
04461   else if(theBN==8)   totGSM=dAlph;          // effective "Be8"
04462   // @@ Should be more (else if) for bigger A=theBN
04463   G4LorentzVector q4M = qH->Get4Momentum();  // Get 4-momentum of theTotalResidNucleus
04464   G4double    totMass = q4M.m();             // Get theRealMass of theTotalResidNucleus
04465   if(fabs(totMass-totGSM)<eps)
04466   {
04467     theQHadrons.push_back(qH);               // fill As It Is
04468   }
04469   else if(totMass>totGSM)
04470   {
04471     theEnvironment.EvaporateNucleus(qH,&theQHadrons);
04472 #ifdef qdebug
04473     qH=0;
04474 #endif
04475   }
04476   else                                       // Correction must be done
04477   {
04478 #ifdef debug
04479     G4cout<<"G4QE::EvaRes: *Correct* "<<theQC<<q4M<<totMass<<"<"<<totGSM<<G4endl;
04480 #endif
04481     G4Quasmon* quasH = new G4Quasmon(theQC,q4M);
04482     if(fCGS && !CheckGroundState(quasH, true) )
04483     {
04484 #ifdef debug
04485       G4cout<<"***G4QE::EvaporResid:GSCorFailed.FillAsItIs,n="<<theQHadrons.size()<<G4endl;
04486 #endif
04487       theQHadrons.push_back(qH);             // Correction failed: fill as it is
04488 #ifdef qdebug
04489       qH=0;
04490 #endif
04491     }
04492     else
04493     {
04494       delete qH;
04495 #ifdef qdebug
04496       qH=0;
04497 #endif
04498     }
04499     delete quasH;
04500   }
04501 #ifdef qdebug
04502   if (qH)
04503   {
04504     G4cout<<"G4QEnvironment::EvaporateResidual:EndDeleted, PDG="<<qH->GetPDGCode()<<G4endl;
04505     delete qH;
04506   }
04507 #endif
04508   return;
04509 } // End of EvaporateResidual
04510 
04511 //Public Hadronisation function with Exception treatment (del is responsibility of User!)
04512 G4QHadronVector* G4QEnvironment::Fragment()
04513 {
04514 #ifdef chdebug
04515   G4int fCharge=theEnvironment.GetCharge();
04516   G4int fBaryoN=theEnvironment.GetA();
04517   G4int nHad=theQHadrons.size();
04518   if(nHad) for(G4int ih=0; ih<nHad; ih++)
04519   {
04520     fCharge+=theQHadrons[ih]->GetCharge();
04521     fBaryoN+=theQHadrons[ih]->GetBaryonNumber();
04522   }
04523   G4int nQuas=theQuasmons.size();
04524   if(nQuas)for(G4int iqs=0; iqs<nQuas; iqs++)
04525   {
04526     fCharge+=theQuasmons[iqs]->GetCharge();
04527     fBaryoN+=theQuasmons[iqs]->GetBaryonNumber();
04528   }
04529   if(fCharge!=totCharge || fBaryoN!=totBaryoN)
04530   {
04531     G4cout<<"*::*G4QE::Frag:(4) tC="<<totCharge<<",C="<<fCharge<<",tB="<<totBaryoN
04532           <<",B="<<fBaryoN<<",E="<<theEnvironment<<G4endl;
04533     if(nHad) for(G4int h=0; h<nHad; h++)
04534     {
04535       G4QHadron* cH = theQHadrons[h];
04536       G4cout<<"*::*G4QE::HQ:h#"<<h<<",QC="<<cH->GetQC()<<",PDG="<<cH->GetPDGCode()<<G4endl;
04537     }
04538     if(nQuas) for(G4int q=0; q<nQuas; q++)
04539     {
04540       G4Quasmon* cQ = theQuasmons[q];
04541       G4cout<<"*::*G4QE::HQ:q#"<<q<<",C="<<cQ->GetCharge()<<",QCont="<<cQ->GetQC()<<G4endl;
04542     }
04543   }
04544 #endif
04545   G4QHadronVector dummy;       // Prototype of the output G4QHadronVector to avoid warnings
04546   G4QHadronVector* theFragments = &dummy; // Prototype of the output G4QHadronVector
04547   G4int ExCount =0;                       // Counter of the repetitions
04548   G4int MaxExCnt=1;                       // A#of of repetitions + 1 (1 for no repetitions)
04549   G4bool RepFlag=true;                    // To come inside the while
04550   // For the purpose of the recalculation the Quasmons, Hadrons, Environment must be stored
04551   G4QuasmonVector* reQuasmons = new G4QuasmonVector; // deleted after the "while LOOP"
04552   G4int nQ = theQuasmons.size();
04553   if(nQ)
04554   {
04555     for(G4int iq=0; iq<nQ; iq++)
04556     {
04557       G4Quasmon* curQ     = new G4Quasmon(theQuasmons[iq]);
04558       reQuasmons->push_back(curQ);                  // deleted after the "while LOOP"
04559     }
04560   }
04561   G4QHadronVector* reQHadrons = new G4QHadronVector; // deleted after the "while LOOP"
04562   G4int nH = theQHadrons.size();
04563   if(nH)
04564   {
04565     for(G4int ih=0; ih<nH; ih++)
04566     {
04567       G4QHadron* curH     = new G4QHadron(theQHadrons[ih]);
04568       reQHadrons->push_back(curH);                 // deleted after the "while LOOP"
04569     }
04570   }
04571   G4QNucleus reEnvironment=theEnvironment;
04572   G4LorentzVector rem4M=tot4Mom;
04573   while (RepFlag && ExCount<MaxExCnt)
04574   {
04575     try
04576     {
04577       RepFlag=false;                      // If OK - go out of the while
04578       theFragments = FSInteraction();     // InterClass creation. User must delet QHadrons.
04579     }
04580     catch (G4QException& error)
04581     {
04582       G4cout<<"***G4QEnvironment::Fragment: Exception is catched"<<G4endl;
04583       RepFlag=true;                       // For the Exception - repete
04584       ExCount++;                          // Increment the repetition counter
04585       G4cout<<"***G4QEnv::Fragment:Exception #"<<ExCount<<": "<<error.GetMessage()<<G4endl;
04586       G4LorentzVector dif=rem4M-theEnvironment.Get4Momentum(); // CHECK difference
04587       G4int nHp=theQHadrons.size();
04588       G4int nQp = theQuasmons.size();
04589       G4cout<<"***G4QEnvir::Fragment:nH="<<nHp<<",nQ="<<nQp<<",E="<<theEnvironment<<G4endl;
04590       for(G4int ph=0; ph<nHp; ph++)
04591       {
04592         G4QHadron* cH = theQHadrons[ph];
04593         dif-=cH->Get4Momentum();
04594         G4cout<<"***G4QEnvir::Fr:H"<<ph<<"="<<cH->Get4Momentum()<<cH->GetPDGCode()<<G4endl;
04595       }
04596       for(G4int pq=0; pq<nQp; pq++)
04597       {
04598         G4Quasmon* cQ = theQuasmons[pq];
04599         dif-=cQ->Get4Momentum();
04600         G4cout<<"***G4QEnvir::Fr:Quasm#"<<pq<<"="<<cQ->Get4Momentum()<<cQ->GetQC()<<G4endl;
04601       }
04602       // *** Cleaning Up of all old output instances for the recalculation purposes ***
04603       for_each(theFragments->begin(), theFragments->end(), DeleteQHadron()); // old Hadrons
04604       theFragments->clear();
04605       for_each(theQHadrons.begin(), theQHadrons.end(), DeleteQHadron()); //internal Hadrons
04606       theQHadrons.clear();
04607       for_each(theQuasmons.begin(), theQuasmons.end(), DeleteQuasmon()); // old Quasmons
04608       theQuasmons.clear();
04609       G4cout<<"***G4QEnv::Fragment: ----------- End of CleaningUp: 4Mdif="<<dif<<G4endl;
04610       // **************** Recover all conditions for the recalculation ********************
04611       theEnvironment=reEnvironment;             // Recover the nuclear environment
04612       tot4Mom=rem4M;                            // Recover the total 4Momentum of the React
04613       G4cout<<"***G4QEnv::Fragment:*Recover*Env="<<theEnvironment<<",4M="<<tot4Mom<<G4endl;
04614       G4int mQ = reQuasmons->size();            // Recover the memorizedQuasmons with print
04615       for(G4int jq=0; jq<mQ; jq++)
04616       {
04617         //G4Quasmon* curQ = new G4Quasmon(reQuasmons->operator[](jq));
04618         G4Quasmon* curQ = new G4Quasmon((*reQuasmons)[jq]);
04619         G4cout<<"***G4QE::Fragm:Q("<<jq<<")="<<curQ->Get4Momentum()<<curQ->GetQC()<<G4endl;
04620         theQuasmons.push_back(curQ);            // (delete equivalent)
04621       }
04622       G4int mH = reQHadrons->size();            // Recover the memorizedQHadrons with print
04623       for(G4int jh=0; jh<mH; jh++)
04624       {
04625         //G4QHadron* curH = new G4QHadron(reQHadrons->operator[](jh));
04626         G4QHadron* curH = new G4QHadron((*reQHadrons)[jh]);
04627         G4cout<<"***G4QE::Fragm:H("<<jh<<")="<<curH->Get4Momentum()<<curH->GetQC()<<G4endl;
04628         theQHadrons.push_back(curH);            // (delete equivalent)
04629       }
04630     }
04631   }
04632   if(reQuasmons->size()) // If something is still in memory then clean it up
04633   {
04634     for_each(reQuasmons->begin(),reQuasmons->end(),DeleteQuasmon()); // CleanUp oldQuasmons
04635     reQuasmons->clear();
04636   }
04637   delete reQuasmons;     // All temporary Quasmons memory is wiped out
04638   if(reQHadrons->size()) // If something is still in memory then clean it up
04639   {
04640     for_each(reQHadrons->begin(),reQHadrons->end(),DeleteQHadron()); //CleanUp old QHadrons
04641     reQHadrons->clear();
04642   }
04643   delete reQHadrons;     // All temporary QHadrons memory is wiped out
04644   if(ExCount>=MaxExCnt)
04645   {
04646     G4int nProj=theProjectiles.size();
04647     G4cerr<<"*G4QEnv::Fragment:Exception.Target="<<theTargetPDG<<". #Proj="<<nProj<<G4endl;
04648     if(nProj) for(G4int ipr=0; ipr<nProj; ipr++)
04649     {
04650       G4QHadron* prH = theProjectiles[ipr];
04651       G4cerr<<"G4QE::F:#"<<ipr<<",PDG/4M="<<prH->GetPDGCode()<<prH->Get4Momentum()<<G4endl;
04652     }
04653     G4Exception("G4QEnvironment::Fragment()", "HAD_CHPS_0000",
04654                 FatalException, "This reaction caused the CHIPSException");
04655   }
04656   // Put the postponed hadrons in the begining of theFragments and clean them up
04657   G4int tmpS=intQHadrons.size();
04658   if(tmpS)
04659   {
04660     //tmpS=theFragments->size();
04661     //intQHadrons.resize(tmpS+intQHadrons.size());
04662     //copy(theFragments->begin(), theFragments->end(), intQHadrons.end()-tmpS);
04663     //tmpS=intQHadrons.size();
04664     //theFragments->resize(tmpS);  // Resize theFragments
04665     //copy(intQHadrons.begin(), intQHadrons.end(), theFragments->begin());
04666     // Can be like this, but by performance it is closer to FNAL (but better than it)
04667     //copy(theFragments->begin(), theFragments->end(), back_inserter(intQHadrons));
04668     //theFragments->resize(intQHadrons.size());  // Resize theFragments
04669     //copy(intQHadrons.begin(), intQHadrons.end(), theFragments->begin());
04670     // The following (istead of all above) has worse performance !
04671     theFragments->insert(theFragments->begin(), intQHadrons.begin(), intQHadrons.end() );
04672     intQHadrons.clear();
04673   }
04674   // No we need to check that all hadrons are on the mass shell
04675   CheckMassShell(theFragments); // @@ the same can be done in the end of G4QFragmentation
04676   return theFragments;
04677 } // End of the Fragmentation member function
04678 
04679 //The Final State Interaction Filter for the resulting output of ::HadronizeQEnvironment()
04680 G4QHadronVector* G4QEnvironment::FSInteraction()
04681 {
04682   static const G4QPDGCode gQPDG(22);
04683   static const G4QPDGCode pizQPDG(111);
04684   static const G4QPDGCode pipQPDG(211);
04685   static const G4QPDGCode pimQPDG(-211);
04686   static const G4QPDGCode nQPDG(2112);
04687   static const G4QPDGCode pQPDG(2212);
04688   static const G4QPDGCode lQPDG(3122);
04689   static const G4QPDGCode s0QPDG(3212);
04690   //static const G4QPDGCode dQPDG(90001001);
04691   static const G4QPDGCode tQPDG(90001002);
04692   static const G4QPDGCode he3QPDG(90002001);
04693   static const G4QPDGCode aQPDG(90002002);
04694   static const G4QPDGCode a6QPDG(90002004);
04695   static const G4QPDGCode be6QPDG(90004002);
04696   //static const G4QPDGCode b7QPDG(90005002);
04697   //static const G4QPDGCode he7QPDG(90002005);
04698   static const G4QPDGCode c8QPDG(90006002);
04699   static const G4QPDGCode a8QPDG(90002006);
04700   static const G4QPDGCode c10QPDG(90006004);
04701   static const G4QPDGCode o14QPDG(90008006);
04702   static const G4QPDGCode o15QPDG(90008007);
04703   static const G4QContent K0QC(1,0,0,0,0,1);
04704   static const G4QContent KpQC(0,1,0,0,0,1);
04705   static const G4double mPi  = G4QPDGCode(211).GetMass();
04706   static const G4double mPi0 = G4QPDGCode(111).GetMass();
04707   static const G4double mK   = G4QPDGCode(321).GetMass();
04708   static const G4double mK0  = G4QPDGCode(311).GetMass();
04709   static const G4double mNeut= G4QPDGCode(2112).GetMass();
04710   static const G4double mProt= G4QPDGCode(2212).GetMass();
04711   static const G4double mLamb= G4QPDGCode(3122).GetMass();
04712   static const G4double mSigZ= G4QPDGCode(3212).GetMass();
04713   static const G4double mSigM= G4QPDGCode(3112).GetMass();
04714   static const G4double mSigP= G4QPDGCode(3222).GetMass();
04715   static const G4double mXiZ = G4QPDGCode(3322).GetMass();
04716   static const G4double mXiM = G4QPDGCode(3312).GetMass();
04717   static const G4double mOmM = G4QPDGCode(3334).GetMass();
04718   static const G4double mDeut= G4QPDGCode(2112).GetNuclMass(1,1,0);
04719   static const G4double mTrit= G4QPDGCode(2112).GetNuclMass(1,2,0);
04720   static const G4double mHe3 = G4QPDGCode(2112).GetNuclMass(2,1,0);
04721   static const G4double mAlph= G4QPDGCode(2112).GetNuclMass(2,2,0);
04722   static const G4double mHe6 = G4QPDGCode(2112).GetNuclMass(2,4,0);
04723   static const G4double mBe6 = G4QPDGCode(2112).GetNuclMass(4,2,0);
04724   //static const G4double mHe7 = G4QPDGCode(2112).GetNuclMass(2,5,0);
04725   //static const G4double mB7  = G4QPDGCode(2112).GetNuclMass(5,2,0);
04726   static const G4double mHe8 = G4QPDGCode(2112).GetNuclMass(2,6,0);
04727   static const G4double mC8  = G4QPDGCode(2112).GetNuclMass(6,2,0);
04728   static const G4double mC10 = G4QPDGCode(2112).GetNuclMass(6,4,0);
04729   static const G4double mO14 = G4QPDGCode(2112).GetNuclMass(8,6,0);
04730   static const G4double mO15 = G4QPDGCode(2112).GetNuclMass(8,7,0);
04731   static const G4double mKmP = mK+mProt;
04732   static const G4double mKmN = mK+mNeut;
04733   static const G4double mK0mP = mK0+mProt;
04734   static const G4double mK0mN = mK0+mNeut;
04735   static const G4QNucleus vacuum(90000000);
04736   static const G4double eps=0.003;
04739   G4int envA=theEnvironment.GetBaryonNumber();
04741 #ifdef rdebug
04742   G4int totInC=theEnvironment.GetZ();
04743   G4LorentzVector totIn4M=theEnvironment.Get4Momentum();
04744   G4cout<<"G4QEnvironment(G4QE)::FSInter(FSI): ***called*** envA="<<envA<<totIn4M<<G4endl;
04745   G4int nQuasmons=theQuasmons.size();
04746   for (G4int is=0; is<nQuasmons; is++) // Sum 4mom's of Quasmons for comparison
04747   {
04748     G4Quasmon*      pQ = theQuasmons[is];
04749     G4LorentzVector Q4M= pQ->Get4Momentum();
04750     G4cout<<"G4QE::FSI: Quasmon ("<<is<<") is added, 4M="<<Q4M<<G4endl;
04751     totIn4M           += Q4M;
04752     totInC            += pQ->GetQC().GetCharge();
04753   } // End of TotInitial4Momentum summation LOOP over Quasmons
04754   G4int nsHadr  = theQHadrons.size();        // Update the value of OUTPUT entries
04755   if(nsHadr) for(G4int jso=0; jso<nsHadr; jso++)// LOOP over output hadrons 
04756   {
04757     G4int hsNF  = theQHadrons[jso]->GetNFragments(); // A#of secondary fragments
04758     if(!hsNF)                                        // Add only final hadrons
04759     {
04760       G4LorentzVector hs4Mom = theQHadrons[jso]->Get4Momentum();
04761       G4cout<<"G4QE::FSI: Hadron ("<<jso<<") is added, 4M="<<hs4Mom<<G4endl;
04762       totIn4M          += hs4Mom;
04763       totInC           += theQHadrons[jso]->GetCharge();
04764     }
04765   }
04766   G4cout<<"G4QE::FSI: The resulting 4Momentum="<<totIn4M<<G4endl;
04767 #endif
04768 #ifdef chdebug
04769   G4int fCharge=theEnvironment.GetCharge();
04770   G4int fBaryoN=theEnvironment.GetA();
04771   G4int nHad=theQHadrons.size();
04772   if(nHad) for(G4int ih=0; ih<nHad; ih++)
04773   {
04774     fCharge+=theQHadrons[ih]->GetCharge();
04775     fBaryoN+=theQHadrons[ih]->GetBaryonNumber();
04776   }
04777   G4int nQuas=theQuasmons.size();
04778   if(nQuas)for(G4int iqs=0; iqs<nQuas; iqs++)
04779   {
04780     fCharge+=theQuasmons[iqs]->GetCharge();
04781     fBaryoN+=theQuasmons[iqs]->GetBaryonNumber();
04782   }
04783   if(fCharge!=totCharge || fBaryoN!=totBaryoN)
04784   {
04785     G4cout<<"*::*G4QE::FSI:(5) tC="<<totCharge<<",C="<<fCharge<<",tB="<<totBaryoN
04786           <<",B="<<fBaryoN<<",E="<<theEnvironment<<G4endl;
04787     if(nHad) for(G4int h=0; h<nHad; h++)
04788     {
04789       G4QHadron* cH = theQHadrons[h];
04790       G4cout<<"*::*G4QE::HQ:h#"<<h<<",QC="<<cH->GetQC()<<",PDG="<<cH->GetPDGCode()<<G4endl;
04791     }
04792     if(nQuas) for(G4int q=0; q<nQuas; q++)
04793     {
04794       G4Quasmon* cQ = theQuasmons[q];
04795       G4cout<<"*::*G4QE::HQ:q#"<<q<<",C="<<cQ->GetCharge()<<",QCont="<<cQ->GetQC()<<G4endl;
04796     }
04797   }
04798 #endif
04799   G4QHadronVector* theFragments = new G4QHadronVector;//Internal creation. User must delete
04800   HadronizeQEnvironment();                // --->> Call the main fragmentation function
04801 #ifdef rdebug
04802   G4int tC=totInC-theEnvironment.GetZ();  // Subtract theResidualEnvironCharge 
04803   G4LorentzVector t4M=totIn4M;            // Compare with the total                 
04804   G4cout<<"G4QEnv::FSI: Initial tot4M="<<t4M<<" to be subtracted"<<G4endl;
04805   G4LorentzVector theEnv4m=theEnvironment.Get4Momentum(); // Environment 4Mom 
04806   t4M-=theEnv4m;                          // Subtract the Environment 4-momentum    
04807   G4cout<<"G4QEnv::FSI: Subtract Environ="<<theEnv4m<<theEnvironment<<G4endl;
04808   for (G4int js=0; js<nQuasmons; js++)    // Subtract 4mom's of Quasmons (compare)
04809   {                                       //                                        
04810     G4Quasmon*      prQ = theQuasmons[js];//                                  
04811     if(prQ->GetStatus())                  // Subtract only if Quasmon is alive      
04812     {                                     //                                        
04813       G4LorentzVector Q4M= prQ->Get4Momentum(); // 4-momentum of the Quasmon
04814       G4QContent qQC= prQ->GetQC();       //                                        
04815       G4cout<<"G4QE::FSI: Subtract Quasmon("<<js<<"),4M="<<Q4M<<",QC="<<qQC<<G4endl;
04816       t4M          -= Q4M;                // Subtract 4-momentum of the Quasmon        
04817       tC           -= prQ->GetQC().GetCharge(); //                            
04818     }                                     //                                        
04819     else G4cout<<"G4QE::FSI:Dead Quasmon("<<js<<")="<<prQ->GetStatus()<<G4endl;
04820   } // End of Quasmons4Momentum subtractions                                  
04821   G4int nsbHadr=theQHadrons.size();       // Update the value of OUTPUT entries     
04822   if(nsbHadr) for(G4int jpo=0; jpo<nsbHadr; jpo++)// LOOP over output hadrons 
04823   {
04824     G4int hsNF  = theQHadrons[jpo]->GetNFragments();// A#of out fragments     
04825     if(!hsNF)                            // Subtract only final hadrons            
04826     {                                    //                                        
04827       G4LorentzVector hs4Mom = theQHadrons[jpo]->Get4Momentum(); // Output hadron
04828       G4int hPDG = theQHadrons[jpo]->GetPDGCode(); // PDG of the Output Hadron
04829       G4cout<<"G4QE::FSI: Subtract Hadron("<<jpo<<"), 4M="<<hs4Mom<<hPDG<<G4endl; 
04830       t4M          -= hs4Mom;           //                                        
04831       tC           -= theQHadrons[jpo]->GetCharge(); // Subtract charge of the OutHadron
04832     }                                   // End of the "FinalHadron" IF            
04833   }                                     // End of the LOOP over output hadrons    
04834   G4cout<<"G4QEnv::FSI:|||||4-MomCHECK||||d4M="<<t4M<<",dCharge="<<tC<<G4endl;
04835 #endif
04836   unsigned nHadr=theQHadrons.size();
04837   if(nHadr<=0)
04838   {
04839     G4cout<<"---Warning---G4QEnvironment::FSInteraction: nHadrons="<<nHadr<<G4endl;
04840     //throw G4QException("G4QEnvironment::FSInteraction: No hadrons in the output");
04841     return theFragments;
04842   }
04843   G4int lHadr=theQHadrons[nHadr-1]->GetBaryonNumber();
04844 #ifdef debug
04845   G4cout<<"G4QE::FSI:after HQE,nH="<<nHadr<<",lHBN="<<lHadr<<",E="<<theEnvironment<<G4endl;
04846 #endif
04847   if(lHadr>1)                          // TheLastHadron is nucleus:try to decay/evap/cor it
04848   {
04849     G4QHadron* theLast = theQHadrons[nHadr-1];
04850     G4QHadron* curHadr = new G4QHadron(theLast);
04851     G4LorentzVector lh4M=curHadr->Get4Momentum(); // Actual mass of the last fragment
04852     G4double lhM=lh4M.m();             // Actual mass of the last fragment
04853     G4int lhPDG=curHadr->GetPDGCode();            // PDG code of the last fragment
04854     G4double lhGSM=G4QPDGCode(lhPDG).GetMass();   // GroundStateMass of the last fragment
04855 #ifdef debug
04856     G4cout<<"G4QE::FSI:lastHadr 4M/M="<<lh4M<<lhM<<",GSM="<<lhGSM<<",PDG="<<lhPDG<<G4endl;
04857 #endif
04858     if(lhM>lhGSM+eps)                  // ==> Try to evaporate the residual nucleus
04859     {
04860       theQHadrons.pop_back();          // the last QHadron-Nucleus is excluded from OUTPUT
04861       delete theLast;// *!!When kill,DON'T forget to delete theLastQHadron as an instance!*
04862       EvaporateResidual(curHadr);      // Try to evaporate Hadr-Nucl (@@DecDib)(delete eq.)
04863       nHadr=theQHadrons.size();
04864 #ifdef debug
04865       G4cout<<"G4QE::FSI:After nH="<<nHadr<<",PDG="<<curHadr->GetPDGCode()<<G4endl;
04866 #endif
04867     }
04868     else if(lhM<lhGSM-eps)             // ==> Try to make the HadronicSteck FSI correction
04869     {
04870       theQHadrons.pop_back();          //exclude LastHadronPointer from OUTPUT
04871       delete theLast;      // *!! When killing, DON'T forget to delete the last QHadron !!*
04872       G4Quasmon* quasH = new G4Quasmon(curHadr->GetQC(),lh4M); // Fake Quasmon ctreation
04873       if(!CheckGroundState(quasH,true))// Try to correct with other hadrons
04874       {
04875 #ifdef debug
04876         // M.K. Fake complain in the low energy nHe/pHe reactions, while everything is OK
04877         G4cout<<"---Warning---G4QEnv::FSI:Correction error LeaveAsItIs h4m="<<lh4M<<G4endl;
04878 #endif
04879         theQHadrons.push_back(curHadr);// Fill theResidualNucleus asItIs(delete equivalent)
04880         //throw G4QException("G4QEnv::FSI: STOP at Correction Error");
04881       }
04882       else
04883       {
04884         delete curHadr;              // The intermediate curHadr isn't necessary any more
04885         nHadr=theQHadrons.size();      // Update nHadr after successful correction
04886       }
04887       delete quasH;                    // Delete the temporary fake Quasmon
04888     }
04889     else delete curHadr;               // ==> Leave the nucleus as it is (close to the GSM)
04890   }
04891 #ifdef debug
04892   G4LorentzVector ccs4M(0.,0.,0.,0.);  // CurrentControlSum of outgoing Hadrons
04893 #endif
04894   // *** Initial Charge Control Sum Calculation ***
04895   G4int chContSum=0;                   // ChargeControlSum to keepTrack FSI transformations
04896   G4int bnContSum=0;                   // BaryoNControlSum to keepTrack FSI transformations
04897   if(nHadr)for(unsigned ich=0; ich<nHadr; ich++) if(!(theQHadrons[ich]->GetNFragments()))
04898   {
04899     chContSum+=theQHadrons[ich]->GetCharge();
04900     bnContSum+=theQHadrons[ich]->GetBaryonNumber();
04901   }
04902 #ifdef chdebug
04903   if(chContSum!=totCharge || bnContSum!=totBaryoN)
04904   {
04905     G4cout<<"*::*G4QE::Fr:(6)tC="<<totCharge<<",C="<<chContSum<<",tB="<<totBaryoN
04906           <<",B="<<bnContSum<<",E="<<theEnvironment<<G4endl;
04907     if(nHadr) for(unsigned h=0; h<nHadr; h++)
04908     {
04909       G4QHadron* cH = theQHadrons[h];
04910       G4cout<<"*::*G4QE::HQ:h#"<<h<<",QC="<<cH->GetQC()<<",PDG="<<cH->GetPDGCode()<<G4endl;
04911     }
04912     if(nQuas) for(G4int q=0; q<nQuas; q++)
04913     {
04914       G4Quasmon* cQ = theQuasmons[q];
04915       G4cout<<"*::*G4QE::HQ:q#"<<q<<",C="<<cQ->GetCharge()<<",QCont="<<cQ->GetQC()<<G4endl;
04916     }
04917   }
04918 #endif
04919   // ***
04920   if(nHadr)for(unsigned ipo=0; ipo<theQHadrons.size(); ipo++)//FindBigestNuclFragm & DecayA
04921   {
04922     unsigned jpo=ipo;
04923     nHadr=theQHadrons.size();
04924     lHadr=theQHadrons[nHadr-1]->GetBaryonNumber();
04925     G4QHadron* theCurr = theQHadrons[ipo];    // Pointer to the Current Hadron
04926     G4int hBN  = theCurr->GetBaryonNumber();
04927     G4int sBN  = theCurr->GetStrangeness();
04928     G4int cBN  = theCurr->GetCharge();
04929     G4int hPDG = theCurr->GetPDGCode();
04930     G4LorentzVector h4Mom = theCurr->Get4Momentum();
04931 #ifdef debug
04932     G4int hNF  = theCurr->GetNFragments();
04933     G4cout<<"G4QE::FSI:h#"<<ipo<<",PDG="<<hPDG<<h4Mom<<",mGS="<<G4QPDGCode(hPDG).GetMass()
04934           <<",F="<<hNF<<",nH="<<theQHadrons.size()<<G4endl;
04935 #endif
04936     if(hBN>lHadr && ipo+1<theQHadrons.size()) // CurrHadron=BiggestFragment -> Swap w/ Last
04937     {
04938       G4QHadron* curHadr = new G4QHadron(theCurr);// Remember CurHadron for evaporation
04939       G4QHadron* theLast = theQHadrons[theQHadrons.size()-1]; // theLastHadron (Cur<Last)
04940       G4QPDGCode lQP=theLast->GetQPDG();      // The QPDG of the last
04941       if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of LastHadr
04942       else theCurr->SetQC(theLast->GetQC());  // CurHadrPDG instead of LastHadrPDG
04943       theCurr->Set4Momentum(theLast->Get4Momentum()); // ... continue substitution
04944       h4Mom = theCurr->Get4Momentum();
04945       hBN  = theCurr->GetBaryonNumber();
04946       cBN  = theCurr->GetCharge();
04947       sBN  = theCurr->GetStrangeness();
04948       hPDG = theCurr->GetPDGCode();
04949       theQHadrons.pop_back();         // pointer to theLastHadron is excluded from OUTPUT
04950       delete theLast;// *!!When kill,DON'T forget to delete theLastQHadron asAnInstance !!*
04951       theQHadrons.push_back(curHadr);
04952       nHadr=theQHadrons.size();
04953     }
04954     if(hPDG==89002000||hPDG==89001001||hPDG==89000002)// 2pt dec. of anti-strange (3pt dec)
04955     {
04956 #ifdef debug
04957       G4cout<<"G4QE::FSI:***ANTISTRANGE*** i="<<ipo<<",PDG="<<hPDG<<",BaryN="<<hBN<<G4endl;
04958 #endif
04959       G4double hM=h4Mom.m(); // 89002000
04960       G4double hMi=hM+eps;
04961       G4QPDGCode fQPDG = pQPDG;
04962       G4double fM = mProt;
04963       G4int  sPDG = 321;
04964       G4double sM = mK;
04965       G4int  tPDG = 0;
04966       G4double tM = 0.;
04967       if(hPDG==89002000)                     // Use the prototypes above
04968       {
04969         if(hMi<mKmP)
04970         {
04971           if(hMi>mProt+mPi+mPi0)
04972           {
04973             sPDG=211;
04974             sM  =mPi;
04975             tPDG=111;
04976             tM  =mPi0;
04977           }
04978           else if(hMi>mProt+mPi) // @@ Does not conserve strangeness (Week decay)
04979           {
04980 #ifdef debug
04981             G4cout<<"**G4QE::FSI:ANTISTRANGE*++*STRANGENESS,PDG="<<hPDG<<",M="<<hM<<G4endl;
04982 #endif
04983             sPDG=211;
04984             sM  =mPi;
04985           }
04986           else sPDG=0;
04987         }
04988       }
04989       else if(hPDG==89001001)
04990       {
04991         fQPDG= nQPDG;
04992         fM   = mNeut;
04993         sPDG = 321;
04994         sM   = mK;
04995         if(hMi>mK0mP&&G4UniformRand()>.5)
04996         {
04997           fQPDG= pQPDG;
04998           fM   = mProt;
04999           sPDG = 311;
05000           sM   = mK0;
05001         }
05002         else if(hMi<mKmN)
05003         {
05004           if(hMi>mProt+mPi0+mPi0)
05005           {
05006             fQPDG= pQPDG;
05007             fM   = mProt;
05008             sPDG = 111;
05009             sM   = mPi0;
05010             tPDG = 111;
05011             tM   = mPi0;
05012             if(hMi>mNeut+mPi+mPi0&&G4UniformRand()>.67)
05013             {
05014               fQPDG= nQPDG;
05015               fM   = mNeut;
05016               tPDG = 211;
05017               tM   = mPi;
05018             }
05019             if(hMi>mProt+mPi+mPi&&G4UniformRand()>.5)
05020             {
05021               sPDG = 211;
05022               sM   = mPi;
05023               tPDG =-211;
05024               tM   = mPi;
05025             }
05026           }
05027           else if(hMi>mProt+mPi0) // @@ Does not conserve strangeness (Week decay)
05028           {
05029 #ifdef debug
05030             G4cout<<"**G4QE::FSI:*ANTISTRANGE*+*STRANGENESS*PDG="<<hPDG<<",M="<<hM<<G4endl;
05031 #endif
05032             fQPDG= pQPDG;
05033             fM   = mProt;
05034             sPDG = 111;
05035             sM   = mPi0;
05036           }
05037           else sPDG=0;      // @@ Still can try to decay in gamma+neutron (electromagnetic)
05038         }
05039       }
05040       else if(hPDG==89000002)
05041       {
05042         fQPDG= nQPDG;
05043         fM   = mNeut;
05044         sPDG = 311;
05045         sM   = mK0;
05046         if(hMi<mK0mN)
05047         {
05048           if(hMi>mNeut+mPi+mPi)
05049           {
05050             sPDG = 211;
05051             sM   = mPi;
05052             tPDG =-211;
05053             tM   = mPi;
05054           }
05055           if(hMi>mProt+mPi+mPi0)
05056           {
05057             fQPDG= pQPDG;
05058             fM   = mProt;
05059             sPDG = 111;
05060             sM   = mPi0;
05061             tPDG =-211;
05062             tM   = mPi;
05063           }
05064           else if(hMi>mProt+mPi) // @@ Does not conserve strangeness (Week decay)
05065           {
05066 #ifdef debug
05067             G4cout<<"**G4QE::FSI:**ANTISTRANGE*0*STRANGENE**PDG="<<hPDG<<",M="<<hM<<G4endl;
05068 #endif
05069             fQPDG= pQPDG;
05070             fM   = mProt;
05071             sPDG =-211;
05072             sM   = mPi;
05073           }
05074           else sPDG=0;      // @@ Still can try to decay in gamma+neutron (electromagnetic)
05075         }
05076       }
05077       if(!sPDG)
05078       {
05079 #ifdef debug
05080         G4cout<<"***G4QE::FSI:***ANTISTRANGE***CANN'T DECAY,PDG="<<hPDG<<",M="<<hM<<G4endl;
05081 #endif
05082       }
05083       else if(!tPDG)           // 2 particle decay
05084       {
05085         G4bool fOK=true;
05086         G4LorentzVector f4M(0.,0.,0.,fM);
05087         G4LorentzVector s4M(0.,0.,0.,sM);
05088         G4double sum=fM+sM;
05089         if(fabs(hM-sum)<=eps)
05090         {
05091           f4M=h4Mom*(fM/sum);
05092           s4M=h4Mom*(sM/sum);
05093         }
05094         else if(hM<sum || !G4QHadron(h4Mom).DecayIn2(f4M,s4M))
05095         {
05096           G4cout<<"---Warning---G4QE::FSI: Still try(2),M="<<hM<<"->"<<fM<<"("<<fQPDG<<")+"
05097                 <<sM<<"("<<sPDG<<")="<<sum<<G4endl;
05098           // Tipical scenario of recovery:
05099           //             1. Check that the Environment is vacuum (must be), 
05100           //if(theEnvironment==vacuum)
05101           if(!theEnvironment.GetA())
05102           {
05103             //           2. Extract and put in qH, substitute by the Last and make quasH,
05104             G4QHadron* theLast = theCurr;       // Prototype of thePointer to theLastHadron
05105             G4QHadron* qH = new G4QHadron(theCurr); // Copy of the Current Hadron
05106             if(ipo+1<theQHadrons.size())            // If ipo<Last, swap CurHadr & LastHadr
05107             {
05108               theLast = theQHadrons[theQHadrons.size()-1];//PointerTo theLastHadr(ipo<Last)
05109               G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
05110               if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of LastHadr
05111               else theCurr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
05112               theCurr->Set4Momentum(theLast->Get4Momentum()); // ... 4Momentum substitution
05113             }                                       //ELSE: it's already theLast -> no swap
05114             theQHadrons.pop_back();                 //exclude LastHadronPointer from OUTPUT
05115             delete theLast;// *!! When killing, DON'T forget to delete the last QHadron !!*
05116             G4Quasmon* quasH = new G4Quasmon(qH->GetQC(),qH->Get4Momentum());//Fake Quasmon
05117             //           3. Try to use other hadrons to recover this one (under Mass Shell)
05118             if(!CheckGroundState(quasH,true))       // Try to correct with other hadrons
05119             {
05120               G4cout<<"---Warning---G4QEnv::FSI:Failed (2) LeaveAsItIs 4m="<<h4Mom<<G4endl;
05121               theQHadrons.push_back(qH);            // Fill as it is (delete equivalent)
05122             }
05123             else
05124             {
05125               delete qH;
05126               //         4. Decrement jpo index (copy of ipo) to find theBiggestNuclearFrag
05127               jpo--;
05128               //         5. Recheck the probuct, which replaced the Last and check others
05129               nHadr=theQHadrons.size();
05130             }
05131             //           6. Delete the intermediate quasmon  
05132             delete quasH;
05133             //           7. Forbid the decay
05134             fOK=false;
05135           }
05136           else
05137           {
05138             // G4cerr<<"***G4QEnv::FSI: No recovery (1) Env="<<theEnvironment<<G4endl;
05139             // throw G4QException("G4QEnv::FSI:ANTISTRANGE DecayIn2 did not succeed");
05140             G4ExceptionDescription ed;
05141             ed << "FSI:ANTISTRANGE DecayIn2 did not succeed: FSI: No recovery (1) Env="
05142                << theEnvironment << G4endl;
05143             G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0000",
05144                         FatalException, ed);
05145           }
05146         }
05147         if(fOK)
05148         {
05149           theQHadrons[ipo]->SetQPDG(fQPDG);
05150           theQHadrons[ipo]->Set4Momentum(f4M);
05151           G4QHadron* sH = new G4QHadron(sPDG,s4M);
05152           theQHadrons.push_back(sH);               // (delete equivalent)
05153         }
05154       }
05155       else
05156       {
05157         G4bool fOK=true;
05158         G4LorentzVector f4M(0.,0.,0.,fM);
05159         G4LorentzVector s4M(0.,0.,0.,sM);
05160         G4LorentzVector t4M(0.,0.,0.,tM);
05161         G4double sum=fM+sM+tM;
05162         if(fabs(hM-sum)<=eps)
05163         {
05164           f4M=h4Mom*(fM/sum);
05165           s4M=h4Mom*(sM/sum);
05166           t4M=h4Mom*(tM/sum);
05167         }
05168         else if(hM<sum || !G4QHadron(h4Mom).DecayIn3(f4M,s4M,t4M))
05169         {
05170           G4cout<<"---Warning---G4QE::FSI: Still try(3), M"<<hM<<"->"<<fM<<"("<<fQPDG<<")+"
05171                 <<sM<<"("<<sPDG<<")+"<<tM<<"("<<tPDG<<")="<<sum<<G4endl;
05172           //if(theEnvironment==vacuum)
05173           if(!theEnvironment.GetA())
05174           {
05175             G4QHadron* theLast = theCurr;    // Prototype of the pointer to the Last Hadron
05176             G4QHadron* qH = new G4QHadron(theCurr); // Copy of the Current Hadron
05177             if(ipo+1<theQHadrons.size())       // If ipo<Last, swap CurHadr and theLastHadr
05178             {
05179               theLast = theQHadrons[theQHadrons.size()-1];//Pointer to LastHadron(ipo<Last)
05180               G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
05181               if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of LastHadr
05182               else theCurr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
05183               theCurr->Set4Momentum(theLast->Get4Momentum()); // ... 4Momentum substitution
05184             }
05185             theQHadrons.pop_back();        // exclude theLastHadron pointer from the OUTPUT
05186             delete theLast;// *!! When killing, DON'T forget to delete the last QHadron !!*
05187             G4Quasmon* quasH = new G4Quasmon(qH->GetQC(),qH->Get4Momentum());//Fake Quasmon
05188             if(!CheckGroundState(quasH,true))         // Try to correct by other hadrons
05189             {
05190               G4cout<<"---Warning---G4QEnv::FSI:Failed (3) LeaveAsItIs,4M="<<h4Mom<<G4endl;
05191               theQHadrons.push_back(qH);              // Fill as it is (delete equivalent)
05192             }
05193             else
05194             {
05195               delete qH;
05196               jpo--;
05197               nHadr=theQHadrons.size();
05198             }
05199             delete quasH;
05200             fOK=false;
05201           }
05202           else
05203           {
05204             // G4cout<<"***G4QEnv::FSI: No recovery (2) Env="<<theEnvironment<<G4endl;
05205             // throw G4QException("G4QEnv::FSI:ANTISTRANGE DecayIn3 did not succeed");
05206             G4ExceptionDescription ed;
05207             ed << "ANTISTRANGE DecayIn3 did not succeed: No recovery (2) Env="
05208                << theEnvironment << G4endl;
05209             G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0001",
05210                         FatalException, ed);
05211           }
05212         }
05213         if(fOK)
05214         {
05215           theQHadrons[ipo]->SetQPDG(fQPDG);
05216           theQHadrons[ipo]->Set4Momentum(f4M);
05217           G4QHadron* sH = new G4QHadron(sPDG,s4M);
05218           theQHadrons.push_back(sH);               // (delete equivalent)
05219           G4QHadron* tH = new G4QHadron(tPDG,t4M);
05220           theQHadrons.push_back(tH);               // (delete equivalent)
05221         }
05222       }
05223       nHadr=theQHadrons.size();
05224     }
05225     else if(hPDG==89999003||hPDG==90002999||hPDG==90000003||hPDG==90003000||
05226             hPDG==90999002||hPDG==91001999) // "3-particles decays of dibaryons and 3N"
05227     {
05228 #ifdef debug
05229       G4cout<<"G4QE::FSI:***nD-/pD++/nnn/ppp***i="<<ipo<<",PDG="<<hPDG<<",A="<<hBN<<G4endl;
05230 #endif
05231       G4double hM=h4Mom.m();
05232       G4QPDGCode nuQPDG=nQPDG; // n,n,pi-
05233       G4double nucM = mNeut;
05234       G4int  barPDG = 2112;
05235       G4double barM = mNeut;
05236       G4int   tPDG  = -211;
05237       G4double tM   = mPi;
05238       if(hPDG==90002999)       // p,p,pi+
05239       {
05240         nuQPDG = pQPDG;        // Substitute p for the first n
05241         nucM   = mProt;
05242         barPDG = 2212;         // Substitute p for the second n
05243         barM   = mProt;
05244         tPDG   = 211;          // Substitute pi+ for the first pi-
05245       }
05246       else if(hPDG==90003000)  // 3p
05247       {
05248         nuQPDG = pQPDG;        // Substitute p for the first n
05249         nucM   = mProt;
05250         barPDG = 2212;         // Substitute p for the second n
05251         barM   = mProt;
05252         tPDG   = 2212;         // Substitute p for pi-
05253         tM     = mProt;
05254       }
05255       else if(hPDG==90999002)  // n,Lambda,pi-/n,Sigma0,pi-/n,Sigma-,gamma(@@)
05256       {
05257         if(hM>mSigZ+mNeut+mPi)
05258         {
05259           G4double ddMass=hM-mPi;          // Free CM energy
05260           G4double dd2=ddMass*ddMass;      // Squared free energy
05261           G4double sma=mLamb+mNeut;        // Neutron+Lambda sum
05262           G4double pr1=0.;                 // Prototype to avoid sqrt(-)
05263           if(ddMass>sma) pr1=sqrt((dd2-sma*sma)*dd2); // Neut+Lamb PS
05264           sma=mNeut+mSigZ;                 // Neutron+Sigma0 sum
05265           G4double smi=mSigZ-mNeut;        // Sigma0-Neutron difference
05266           G4double pr2=pr1;                // Prototype of +N+S0 PS
05267           if(ddMass>sma && ddMass>smi) pr2+=sqrt((dd2-sma*sma)*(dd2-smi*smi));
05268           if(pr2*G4UniformRand()>pr1)      // --> "ENnv+Sigma0+Lambda" case
05269           {
05270             barPDG = 3212;     // Substitute Sigma0 for the second n
05271             barM   = mSigZ;
05272           }
05273           else
05274           {
05275             barPDG = 3122;     // Substitute Lambda for the second n
05276             barM   = mLamb;
05277           }
05278         }
05279         else if(hM>mLamb+mNeut+mPi)
05280         {
05281           barPDG = 3122;       // Substitute Lambda for the second n
05282           barM   = mLamb;
05283         }
05284         else if(hM>mSigM+mNeut)// @@ Decay in 2
05285         {
05286           barPDG = 3112;       // Substitute Sigma- for the second n
05287           barM   = mSigM;
05288           tPDG   = 22;
05289           tM     = 0;
05290         }
05291       }
05292       else if(hPDG==91001999)  // p,Lambda,pi+/p,Sigma0,pi+/p,Sigma+,gamma(@@)
05293       {
05294         nuQPDG = pQPDG;        // Substitute p for the first n
05295         nucM   = mProt;
05296         tPDG   = 211;          // Substitute pi+ for the first pi-
05297         if(hM>mSigZ+mProt+mPi)
05298         {
05299           G4double ddMass=hM-mPi;          // Free CM energy
05300           G4double dd2=ddMass*ddMass;      // Squared free energy
05301           G4double sma=mLamb+mProt;        // Lambda+Proton sum
05302           G4double pr1=0.;                 // Prototype to avoid sqrt(-)
05303           if(ddMass>sma) pr1=sqrt((dd2-sma*sma)*dd2); // Lamb+Prot PS
05304           sma=mProt+mSigZ;                 // Proton+Sigma0 sum
05305           G4double smi=mSigZ-mProt;        // Sigma0-Proton difference
05306           G4double pr2=pr1;                // Prototype of +P+S0 PS
05307           if(ddMass>sma && ddMass>smi) pr2+=sqrt((dd2-sma*sma)*(dd2-smi*smi));
05308           if(pr2*G4UniformRand()>pr1)      // --> "ENnv+Sigma0+Lambda" case
05309           {
05310             barPDG = 3212;     // Substitute Sigma0 for the second n
05311             barM   = mSigZ;
05312           }
05313           else
05314           {
05315             barPDG = 3122;     // Substitute Lambda for the second n
05316             barM   = mLamb;
05317           }
05318         }
05319         if(hM>mLamb+mProt+mPi)
05320         {
05321           barPDG = 3122;         // Substitute Lambda for the second n
05322           barM   = mLamb;
05323         }
05324         else if(hM>mSigP+mProt)  // @@ Decay in 2
05325         {
05326           barPDG = 3222;         // Substitute Sigma- for the second n
05327           barM   = mSigP;
05328           tPDG   = 22;
05329           tM     = 0;
05330         }
05331       }
05332       else if(hPDG==90000003)  // 3n
05333       {
05334         tPDG   = 2112;         // Substitute n for pi-
05335         tM     = mNeut;
05336       }
05337       G4bool fOK=true;
05338       G4LorentzVector nu4M(0.,0.,0.,nucM);
05339       G4LorentzVector ba4M(0.,0.,0.,barM);
05340       G4LorentzVector pi4M(0.,0.,0.,tM);
05341       G4double sum=nucM+barM+tM;
05342       if(fabs(hM-sum)<=eps)
05343       {
05344         nu4M=h4Mom*(nucM/sum);
05345         ba4M=h4Mom*(barM/sum);
05346         pi4M=h4Mom*(tM/sum);
05347       }
05348       if(hM<sum || !G4QHadron(h4Mom).DecayIn3(nu4M,ba4M,pi4M))
05349       {
05350 #ifdef debug
05351         G4int eA=theEnvironment.GetA();
05352         G4cout<<"***G4QEnv::FSI:T="<<hPDG<<"("<<hM<<")-> N="<<nuQPDG<<"(M="<<nucM<<") + B="
05353               <<barPDG<<"("<<barM<<")+N/pi="<<tPDG<<"("<<tM<<")="<<sum<<", A="<<eA<<G4endl;
05354 #endif
05355         //if(!eA)
05356         //{
05357           G4QHadron* theLast = theCurr;        // Prototype of the pointer to theLastHadron
05358           G4QHadron* qH = new G4QHadron(theCurr); // Copy of the Current Hadron
05359 #ifdef debug
05360           G4cout<<"***G4QE::FSI:#"<<ipo<<",4MQC="<<qH->Get4Momentum()<<qH->GetQC()<<G4endl;
05361 #endif
05362           if(ipo+1<theQHadrons.size())         // If ipo<Last, swap CurHadr and theLastHadr
05363           {
05364             G4int nhd1=theQHadrons.size()-1;
05365             theLast = theQHadrons[nhd1];// Pointer to theLastHadron (ipo<L)
05366             G4LorentzVector l4M=theLast->Get4Momentum();
05367             G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
05368             if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of LastHadr
05369             else theCurr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
05370 #ifdef debug
05371             G4cout<<"---Warning---G4QE::FSI:l#"<<nhd1<<",4M="<<l4M<<",PDG="<<lQP<<G4endl;
05372 #endif
05373             theCurr->Set4Momentum(theLast->Get4Momentum()); // ... 4Momentum substitution
05374           }
05375           theQHadrons.pop_back();              // exclude theLastHadron pointer from OUTPUT
05376           delete theLast;  // *!! When killing, DON'T forget to delete the last QHadron !!*
05377           G4QContent cqQC=qH->GetQC();
05378           G4LorentzVector tqLV=qH->Get4Momentum();
05379           G4Quasmon* quasH = new G4Quasmon(cqQC,tqLV);//Create fakeQuasm
05380           if(!CheckGroundState(quasH,true))         // Try to correct by other hadrons
05381           {
05382 #ifdef chdebug
05383             G4cout<<":W:G4QE::FSI:E="<<theEnvironment<<",Q="<<cqQC<<tqLV<<tqLV.m()<<G4endl;
05384 #endif
05385             theQHadrons.push_back(qH);              // Fill as it is (delete equivalent)
05386           }
05387           else
05388           {
05389             delete qH;
05390             jpo--;
05391             nHadr=theQHadrons.size();
05392           }
05393           delete quasH;
05394           fOK=false;
05395         //}
05396         //else
05397         //{
05398         //  G4cerr<<"***G4QEnv::FSI:NoRec(3)E="<<theEnvironment<<eA<<",PDG="<<hPDG<<G4endl;
05399         //  throw G4QException("G4QEnv::FSI:ISO-dibaryon or 3n/3p DecayIn3 error");
05400       //}
05401       }
05402       if(fOK)
05403       {
05404         theQHadrons[ipo]->SetQPDG(nuQPDG);
05405         theQHadrons[ipo]->Set4Momentum(nu4M);
05406         G4QHadron* baH = new G4QHadron(barPDG,ba4M);
05407         theQHadrons.push_back(baH);               // (delete equivalent)
05408         G4QHadron* piH = new G4QHadron(tPDG,pi4M);
05409         theQHadrons.push_back(piH);               // (delete equivalent)
05410         nHadr=theQHadrons.size();
05411       }
05412     }
05413     else if(hBN>1 && !sBN && (cBN<0 || cBN>hBN)) // "nN+mD- or nP+mD++ decay"
05414     {
05415 #ifdef debug
05416       G4cout<<"G4QE::FSI:nNmD-/nPmD++ #"<<ipo<<",P="<<hPDG<<",B="<<hBN<<",C="<<cBN<<G4endl;
05417 #endif
05418       G4double hM=h4Mom.m();
05419       G4QPDGCode nuQPDG=nQPDG; // "(n+m)*N,m*pi-" case === Default
05420       G4double nucM = mNeut;
05421       G4int  barPDG = 2112;
05422       G4double barM = mNeut;
05423       G4int    nN   = hBN-1;   // a#of baryons - 1
05424       G4int   tPDG  = -211;
05425       G4double tM   = mPi;
05426       G4int    nPi  = -cBN;    // a#of Pi-'s
05427       if( cBN>hBN)             // reinitialization for the "(n+m)*P,m*pi+" case
05428       {
05429         nuQPDG = pQPDG;        // Substitute p for the first n
05430         nucM   = mProt;
05431         barPDG = 2212;         // Substitute p for the second n
05432         barM   = mProt;
05433         tPDG   = 211;          // Substitute pi+ for the first pi-
05434         nPi    = cBN-hBN;      // a#0f Pi+'s
05435       }
05436       if(nPi>1)   tM*=nPi;
05437       if(nN >1) barM*=nN;
05438       G4bool fOK=true;
05439       G4LorentzVector nu4M(0.,0.,0.,nucM);
05440       G4LorentzVector ba4M(0.,0.,0.,barM);
05441       G4LorentzVector pi4M(0.,0.,0.,tM);
05442       G4double sum=nucM+barM+tM;
05443       if(fabs(hM-sum)<=eps)
05444       {
05445         nu4M=h4Mom*(nucM/sum);
05446         ba4M=h4Mom*(barM/sum);
05447         pi4M=h4Mom*(tM/sum);
05448       }
05449       if(hM<sum || !G4QHadron(h4Mom).DecayIn3(nu4M,ba4M,pi4M))
05450       {
05451 #ifdef debug
05452         G4cout<<"***G4QEnv::FSI:IsN M="<<hM<<","<<hPDG<<"->N="<<nuQPDG<<"(M="<<nucM<<")+"
05453               <<nN<<"*B="<<barPDG<<"(M="<<barM<<")+"<<nPi<<"*pi="<<tPDG<<"(M="<<tM<<")="
05454               <<nucM+barM+tM<<G4endl;
05455         G4cout<<"***G4QEnv::FSI:IsN BaryN="<<hBN<<",Charge="<<cBN<<",Stran="<<sBN<<G4endl;
05456 #endif
05457         if(!theEnvironment.GetA())           // Emergency recovery
05458         {
05459           G4QHadron* theLast = theCurr;      // Prototype of the pointer to the Last Hadron
05460           G4QHadron* qH = new G4QHadron(theCurr); // Copy of the Current Hadron
05461           if(ipo+1<theQHadrons.size())       // If ipo<Last, swap CurHadr and theLastHadr
05462           {
05463             theLast = theQHadrons[theQHadrons.size()-1];// Ptr to theLastHadron (ipo<Last)
05464             G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
05465             if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of LastHadr
05466             else theCurr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
05467             theCurr->Set4Momentum(theLast->Get4Momentum()); // ... 4Momentum substitution
05468           }
05469           theQHadrons.pop_back();            // exclude theLastHadron pointer from OUTPUT
05470           delete theLast;  // *!! When killing, DON'T forget to delete the last QHadron !!*
05471           G4QContent cqQC=qH->GetQC();
05472           G4LorentzVector cq4M=qH->Get4Momentum();
05473           G4Quasmon* quasH = new G4Quasmon(cqQC,cq4M);// Create fakeQuasmon for the Last
05474           if(!CheckGroundState(quasH,true))         // Try to correct by other hadrons
05475           {
05476             G4cout<<"---Warning---G4QEnv::FSI:IN Failed, FillAsItIs: "<<cqQC<<cq4M<<G4endl;
05477             theQHadrons.push_back(qH);              // Fill as it is (delete equivalent)
05478           }
05479           else
05480           {
05481             delete qH;
05482             jpo--;
05483             nHadr=theQHadrons.size();
05484           }
05485           delete quasH;
05486           fOK=false;
05487         }
05488         else
05489         {
05490           G4ExceptionDescription ed;
05491           ed << "IN Multy ISO-dibaryon DecayIn3 did not succeed: IN,NoRec(4) Env="
05492              << theEnvironment << ",PDG=" << hPDG << G4endl;
05493           G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0002",
05494                       FatalException, ed);
05495         }
05496       }
05497       if(fOK)
05498       {
05499         theQHadrons[ipo]->SetQPDG(nuQPDG);
05500         theQHadrons[ipo]->Set4Momentum(nu4M);
05501         if(nN>1) ba4M=ba4M/nN;
05502         for(G4int ib=0; ib<nN; ib++)
05503         {
05504           G4QHadron* baH = new G4QHadron(barPDG,ba4M);
05505           theQHadrons.push_back(baH);               // (delete equivalent)
05506         }
05507         if(nPi>1) pi4M=pi4M/nPi;
05508         for(G4int im=0; im<nPi; im++)
05509         {
05510           G4QHadron* piH = new G4QHadron(tPDG,pi4M);
05511           theQHadrons.push_back(piH);               // (delete equivalent)
05512         }
05513         nHadr=theQHadrons.size();
05514       }
05515     }
05516 #ifdef debug
05517     G4int           hNFrag= theQHadrons[ipo]->GetNFragments(); //Recover after swapping
05518     G4QContent      hQC   = theQHadrons[ipo]->GetQC();         // ...
05519     hPDG                  = theQHadrons[ipo]->GetPDGCode();    // ...
05520     h4Mom                 = theQHadrons[ipo]->Get4Momentum();  // ...
05521     ccs4M+=h4Mom;                                              // Calculate CurSum of Hadrs
05522     G4cout<<"G4QE::FSI:#"<<ipo<<": h="<<hPDG<<hQC<<",h4M="<<h4Mom<<h4Mom.m()<<",hNF="
05523           <<hNFrag<<G4endl;
05524 #endif
05525     ipo=jpo;            // Take into account the roll back in case of the Last substitution
05526   }
05527 #ifdef debug
05528   G4cout<<"G4QE::FSI: --->>CurrentControlSumOf4MomOfHadrons="<<ccs4M<<G4endl;
05529 #endif
05530   nHadr=theQHadrons.size();
05531 #ifdef chdebug
05532   // *** (1) Charge Control Sum Calculation for the Charge Conservation Check ***
05533   G4int ccContSum=0;                   // Intermediate ChargeControlSum 
05534   G4int cbContSum=0;                   // Intermediate BaryonNumberControlSum 
05535   if(nHadr)for(unsigned ic1=0; ic1<nHadr; ic1++) if(!(theQHadrons[ic1]->GetNFragments()))
05536   {
05537     ccContSum+=theQHadrons[ic1]->GetCharge();
05538     cbContSum+=theQHadrons[ic1]->GetBaryonNumber();
05539   }
05540   if(ccContSum-chContSum || cbContSum-bnContSum)
05541   {
05542     G4cout<<"*::*G4QE::FSI:(7)dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
05543           <<G4endl;
05544     //throw G4QException("G4QEnvironment::FSInteract: (1) Charge is not conserved");
05545   }
05546   // ***
05547 #endif
05548   G4double p2cut=250000.;        // 250000=(2*p_Ferm)**2
05549   if(envA>0) p2cut/=envA*envA;
05550   //G4double p2cut2=0.;          //cut for the alpha creation
05551   //
05552   G4int bfCountM=3;
05553   if(envA>10) bfCountM*=(envA-1)/3;
05554   G4bool bfAct = true;
05555   G4int bfCount= 0;
05556   G4LorentzVector tmp4Mom=tot4Mom;
05557   G4LorentzVector postp4M(0.,0.,0.,0.);
05558   G4int nPost=intQHadrons.size();
05559   if(nPost) for(G4int psp=0; psp<nPost; psp++)
05560     if(!(intQHadrons[psp]->GetNFragments())) postp4M+=intQHadrons[psp]->Get4Momentum();
05561   while(bfAct&&bfCount<bfCountM) // "Infinite" LOOP of the ThermoNuclearBackFusion
05562   {
05563     tot4Mom=tmp4Mom-postp4M;     // Prepare tot4Mom for the "En/Mom conservation" reduction
05564     bfAct=false;
05565     bfCount++;
05566     nHadr=theQHadrons.size();
05567     if(nHadr) for(unsigned hadron=0; hadron<theQHadrons.size(); hadron++)// BackFusion LOOP
05568     {
05569       G4QHadron* curHadr = theQHadrons[hadron]; // Get a pointer to the current Hadron
05570       G4int         hPDG = curHadr->GetPDGCode();
05571       G4QPDGCode    hQPDG(hPDG);
05572       G4double      hGSM = hQPDG.GetMass();     // Ground State Mass of the first fragment
05573 #ifdef debug
05574       G4cout<<"G4QE::FSI:LOOP START,h#"<<hadron<<curHadr->Get4Momentum()<<hPDG<<G4endl;
05575 #endif
05576       if(hPDG==89999003||hPDG==90002999)
05577       {
05578         G4cout<<"---WARNING---G4QE::FSI:**nD-/pD++**(3),PDG="<<hPDG<<" CORRECTION"<<G4endl;
05579         G4LorentzVector h4Mom=curHadr->Get4Momentum();
05580         G4double      hM=h4Mom.m();
05581         G4QPDGCode fQPDG=nQPDG;
05582         G4double     fM =mNeut;
05583         G4int      sPDG =2112;
05584         G4double     sM =mNeut;
05585         G4int      tPDG =-211;
05586         G4double     tM =mPi;
05587         if(hPDG==90002999)
05588         {
05589           fQPDG=pQPDG;
05590           fM   =mProt;
05591           sPDG =2212;
05592           sM   =mProt;
05593           tPDG =211;
05594         }
05595         G4bool fOK=true;
05596         G4LorentzVector f4M(0.,0.,0.,fM);
05597         G4LorentzVector s4M(0.,0.,0.,sM);
05598         G4LorentzVector t4M(0.,0.,0.,tM);
05599         G4double sum=fM+sM+tM;
05600         if(fabs(hM-sum)<=eps)
05601         {
05602           f4M=h4Mom*(fM/sum);
05603           s4M=h4Mom*(sM/sum);
05604           t4M=h4Mom*(tM/sum);
05605         }
05606         else if(hM<sum || !G4QHadron(h4Mom).DecayIn3(f4M,s4M,t4M))
05607         {
05608           G4cout<<"---WARNING---G4QE::FSI: Still trying, NDM="<<hM<<"->"<<fM<<"("<<fQPDG
05609                 <<")+"<<sM<<"("<<sPDG<<")+"<<tM<<"("<<tPDG<<")="<<sum<<G4endl;
05610           if(!theEnvironment.GetA())
05611           {
05612             G4QHadron* theLast = curHadr;          // Prototype of Pointer to theLastHadron
05613             G4QHadron* qH = new G4QHadron(curHadr);// Copy of the Current Hadron
05614             if(hadron+1<theQHadrons.size())        // If hadr<Last,swap CurHadr & LastHadr
05615             {
05616               theLast = theQHadrons[theQHadrons.size()-1]; // Pointer to LastHadr (nh<Last)
05617               G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
05618               if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
05619               else curHadr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
05620               curHadr->Set4Momentum(theLast->Get4Momentum()); // ... 4Momentum substitution
05621             }
05622             theQHadrons.pop_back();        // exclude theLastHadron pointer from the OUTPUT
05623             delete theLast;// *!! When killing, DON'T forget to delete the last QHadron !!*
05624             G4Quasmon* quasH = new G4Quasmon(qH->GetQC(),qH->Get4Momentum());//Fake Quasmon
05625             if(!CheckGroundState(quasH,true))      // Try to correct by other hadrons
05626             {
05627               G4cout<<"---Warning---G4QE::FSI:NDel Failed LeaveAsItIs, 4m="<<h4Mom<<G4endl;
05628               theQHadrons.push_back(qH);           // Leave as it is (delete equivalent)
05629             }
05630             else
05631             {
05632               delete qH;
05633               nHadr=theQHadrons.size();
05634             }
05635             delete quasH;
05636             fOK=false;
05637           }
05638           else
05639           {
05640             // G4cout<<"***G4QEnv::FSI: No ND recovery Env="<<theEnvironment<<G4endl;
05641             // throw G4QException("G4QEnv::FSI:ND DecayIn3 did not succeed");
05642             G4ExceptionDescription ed;
05643             ed << "ND DecayIn3 did not succeed: No ND recovery Env="
05644                << theEnvironment << G4endl;
05645             G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0003",
05646                         FatalException, ed);
05647           }
05648         }
05649         if(fOK)
05650         {
05651           curHadr->SetQPDG(fQPDG);
05652           curHadr->Set4Momentum(f4M);
05653           G4QHadron* sH = new G4QHadron(sPDG,s4M);
05654           theQHadrons.push_back(sH);               // (delete equivalent)
05655           G4QHadron* tH = new G4QHadron(tPDG,t4M);
05656           theQHadrons.push_back(tH);               // (delete equivalent)
05657         }
05658         hPDG = curHadr->GetPDGCode();            // Change PDG Code of theFirstFragment
05659         hQPDG= G4QPDGCode(hPDG);
05660         hGSM = hQPDG.GetMass();                  // Change GroundStateMass of theFirstFragm
05661       }
05662       nHadr=theQHadrons.size();
05663       if(hPDG==89001001||hPDG==89002000||hPDG==89000002)
05664       {
05665         G4cout<<"---WARNING---G4QE::FSI:***(K+N)*** (2),PDG="<<hPDG<<" CORRECTION"<<G4endl;
05666         G4LorentzVector h4Mom=curHadr->Get4Momentum();
05667         G4double      hM=h4Mom.m();
05668         G4QPDGCode fQPDG=nQPDG;
05669         G4double     fM =mNeut;
05670         G4int      sPDG =311;
05671         G4double     sM =mK0;
05672         if(hPDG==89000002)
05673         {
05674           fQPDG=pQPDG;
05675           fM   =mProt;
05676           sPDG =321;
05677           sM   =mK;
05678         }
05679         if(hPDG==89001001)
05680         {
05681           if(hM<mK0+mProt || G4UniformRand()>.5)
05682           {
05683             sPDG =321;
05684             sM   =mK;
05685           }
05686           else
05687           {
05688             fQPDG=pQPDG;
05689             fM   =mProt;
05690           }
05691         }
05692         G4bool fOK=true;
05693         G4LorentzVector f4M(0.,0.,0.,fM);
05694         G4LorentzVector s4M(0.,0.,0.,sM);
05695         G4double sum=fM+sM;
05696         if(fabs(hM-sum)<=eps)
05697         {
05698           f4M=h4Mom*(fM/sum);
05699           s4M=h4Mom*(sM/sum);
05700         }
05701         else if(hM<sum || !G4QHadron(h4Mom).DecayIn2(f4M,s4M))
05702         {
05703           G4cout<<"---WARNING---G4QE::FSI: Still trying (2),NDM="<<hM<<"->"<<fM<<"("<<fQPDG
05704                 <<")+"<<sM<<"("<<sPDG<<")="<<sum<<G4endl;
05705           if(!theEnvironment.GetA())
05706           {
05707             G4QHadron* theLast = curHadr;          // Prototype of Pointer to theLastHadron
05708             G4QHadron* qH = new G4QHadron(curHadr);// Copy of the Current Hadron
05709             if(hadron+1<theQHadrons.size())        // If hadr<Last, swap CurHadr & LastHadr
05710             {
05711               theLast = theQHadrons[theQHadrons.size()-1]; // Pointer to LastHadr (nh<Last)
05712               G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
05713               if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
05714               else curHadr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
05715               curHadr->Set4Momentum(theLast->Get4Momentum()); // ... 4Momentum substitution
05716             }
05717             theQHadrons.pop_back();        // exclude theLastHadron pointer from the OUTPUT
05718             delete theLast;// *!! When killing, DON'T forget to delete the last QHadron !!*
05719             G4Quasmon* quasH = new G4Quasmon(qH->GetQC(),qH->Get4Momentum());//Fake Quasmon
05720             if(!CheckGroundState(quasH,true))      // Try to correct by other hadrons
05721             {
05722               G4cout<<"---Warning---G4QE::FSI:KN Failed LeaveAsItIs 4m="<<h4Mom<<G4endl;
05723               theQHadrons.push_back(qH);           // Leave as it is (delete equivalent)
05724             }
05725             else
05726             {
05727               delete qH;
05728               nHadr=theQHadrons.size();
05729             }
05730             delete quasH;
05731             fOK=false;
05732           }
05733           else
05734           {
05735             // G4cerr<<"***G4QEnv::FSI: No KN recovery Env="<<theEnvironment<<G4endl;
05736             // throw G4QException("G4QEnv::FSI:KN DecayIn2 did not succeed");
05737             G4ExceptionDescription ed;
05738             ed << "KN DecayIn2 did not succeed: No KN recovery Env="
05739                << theEnvironment << G4endl;
05740             G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0004",
05741                         FatalException, ed);
05742           }
05743         }
05744         if(fOK)
05745         {
05746           curHadr->SetQPDG(fQPDG);
05747           curHadr->Set4Momentum(f4M);
05748           G4QHadron* sH = new G4QHadron(sPDG,s4M);
05749           theQHadrons.push_back(sH);               // (delete equivalent)
05750         }
05751         hPDG = curHadr->GetPDGCode();            // Change PDG Code of theFirstFragment
05752         hQPDG= G4QPDGCode(hPDG);
05753         hGSM = hQPDG.GetMass();                  // Change GroundStateMass of theFirstFragm
05754       }
05755       nHadr=theQHadrons.size();
05756       G4int           hS = curHadr->GetStrangeness();
05757       G4int           hF = curHadr->GetNFragments();
05758       G4LorentzVector h4m= curHadr->Get4Momentum();
05759       G4double hM        = h4m.m();             // Real Mass of the first fragment
05760       G4int hB           = curHadr->GetBaryonNumber();
05762 #ifdef debug
05763       if(!hF && ( (hPDG>80000000 && hPDG<90000000) || hPDG==90000000 ||
05764                   (hPDG>90000000 && (hPDG%1000000>200000 || hPDG%1000>300) ) ) )
05765         G4cout<<"**G4QEnv::FSInteraction: PDG("<<hadron<<")="<<hPDG<<", M="<<hM<<G4endl;
05766 #endif
05767 #ifdef debug
05768       G4cout<<"G4QE::FSI:h="<<hPDG<<",S="<<hS<<",B="<<hB<<",#"<<hadron<<"<"<<nHadr<<G4endl;
05769 #endif
05770       //if(hadron&&!hF&&hB>0&&!hS&&(nHadr>3||hB<2)) // ThermoBackFus (VIMP for gamA TotCS)
05771       //if(hadron&&!hF&&hB>0&&!hS&&(nHadr>2||hB<4)) // ThermoBackFus (VIMP for gamA TotCS)
05772       if(hadron&&!hF&&hB>0&&!hS) // ThermoBackFusion cond. (VIMP for gamA TotCS)
05773       //if(hadron&&!hF&&hB>0&&hB<4&&!hS) // ThermoBackFusion cond. (VIMP for gamA TotCS)
05774       //if(hadron&&!hF&&hB>0&&!hS&&nHadr>2)//ThermoBackFusion MAX condition (VIMP for gamA)
05775       //if(2>3)                         // Close the ThermoBackFusion (VIMP for gamA TotCS)
05776       {
05777 #ifdef debug
05778         //if(nHadr==3)
05779           G4cout<<"G4QE::FSI: h="<<hPDG<<",B="<<hB<<",h#"<<hadron<<" < nH="<<nHadr<<G4endl;
05780 #endif
05781         G4QContent hQC = curHadr->GetQC();
05782         if(hadron&&!hF&&hB>0) for(unsigned pt=0; pt<hadron; pt++)
05783         {
05784           G4QHadron* backH = theQHadrons[pt];   // Get pointer to one of thePreviousHadrons
05785           G4int   bF = backH->GetNFragments();
05786           G4LorentzVector b4m= backH->Get4Momentum();
05787           G4double bM= b4m.m();                 // Real Mass of the second fragment
05788           G4QContent bQC = backH->GetQC();
05789           G4int bPDG=bQC.GetZNSPDGCode();
05790           G4QPDGCode bQPDG(bPDG);
05791           G4double bGSM=bQPDG.GetMass();        // Ground State Mass of the second fragment
05792           G4int   bB = backH->GetBaryonNumber();
05793 
05795           G4QContent sQC=bQC+hQC;
05796           G4int sPDG=sQC.GetZNSPDGCode();
05797           G4QPDGCode sQPDG(sPDG);
05798           G4double tM=sQPDG.GetMass();
05799           G4LorentzVector s4M=h4m+b4m;
05800           G4double sM2=s4M.m2();
05801           G4double sM=sqrt(sM2);
05802           G4double dsM2=sM2+sM2;
05803           G4double rm=bM-hM;
05804           G4double sm=bM+hM;
05805           G4double pCM2=(sM2-rm*rm)*(sM2-sm*sm)/(dsM2+dsM2);
05806           G4int   bS = backH->GetStrangeness();
05807 #ifdef debug
05808           //if(nHadr==3)
05809           G4cout<<"G4QE::FSI:"<<pt<<",B="<<bB<<",S="<<bS<<",p="<<pCM2<<"<"<<p2cut<<",hB="
05810                 <<hB<<",bM+hM="<<bM+hM<<">tM="<<tM<<",tQC="<<sQC<<G4endl;
05811 #endif
05812           //if(!bF&&(bB==1||hB==1)&&bM+hM>tM+.001&&pCM2<p2cut)      // Only baryons == pcut
05813           //if(!bF&&!bS&&(bB==1&&hB>0||hB==1&&bB>0)&&bM+hM>tM+.00001
05814           //   && (pCM2<p2cut&&nHadr>3||pCM2<p2cut2&&nHadr==3))
05815           //if(!bF&&(bB==1||hB==1)&&bM+hM>tM+.001&&(pCM2<p2cut&&nHadr>3 ||
05816           //   pCM2<p2cut2&&nHadr==3&&bPDG>90000000))
05817           //if(!bF&&bB<4&&bM+hM>tM+.001&&pCM2<p2cut)
05818           if(!bF&&!bS&&bB>0&&bM+hM>tM+.001&&pCM2<p2cut)
05819           //if(!bF&&bB<4&&bM+hM>tM+.001&&(pCM2<p2cut || bB+hB==4&&pCM2<p2cut2))
05820           //if(!bF&&(bB==1||hB==1)&&(nHadr>3||bPDG>90000000)&&bM+hM>tM+.001&&pCM2<p2cut)
05821           //if(!bF&&(bB==1&&!bC||hB==1&&!hC)&&bM+hM>tM+.001&&pCM2<p2cut)// Only n == pcut
05822           //if(!bF&&(bB==1||hB==1)&&bM+hM>tM+.001&&sM-bM-hM<cut)  // Only baryons == ecut
05823           //if(!bF&&bB&&bB<fL&&bM+hM>tM+.001&&sM-bM-hM<cut)    // Light fragments == ecut
05824           {
05825 #ifdef fdebug
05826             G4int bPDG = backH->GetPDGCode();
05827             if(sPDG==89999003||sPDG==90002999||sPDG==89999002||sPDG==90001999)
05828               G4cout<<"G4QE::FSI:**nD-/pD++**,h="<<hPDG<<",hB="<<hB<<",b="<<bPDG<<",bB="
05829                     <<bB<<G4endl;
05830             //if(nHadr==3)
05831             G4cout<<"G4QE::FSI:*FUSION*#"<<hadron<<"["<<hPDG<<"]"<<hM<<"+#"<<pt<<"["<<bPDG
05832                   <<"]"<<bM<<"="<<bM+hM<<", sM="<<sM<<">["<<sPDG<<"]"<<tM<<",p2="<<pCM2
05833                   <<"<"<<p2cut<<G4endl;
05834 #endif
05835             bfAct=true;
05836             //@@Temporary decay in gamma
05837             G4bool three=false;
05838             G4QPDGCode fQPDG=sQPDG;
05839             G4QPDGCode rQPDG=gQPDG;
05840             hQPDG=gQPDG;
05841             G4LorentzVector f4Mom(0.,0.,0.,tM);
05842             G4LorentzVector g4Mom(0.,0.,0.,0.);
05843             G4LorentzVector t4Mom(0.,0.,0.,0.);
05844             if(sPDG==89999002)                               // A=1
05845             {
05846               fQPDG=nQPDG;
05847               rQPDG=pimQPDG;
05848               f4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05849               g4Mom=G4LorentzVector(0.,0.,0.,mPi);
05850             }
05851             else if(sPDG==90001999)
05852             {
05853               fQPDG=pQPDG;
05854               rQPDG=pipQPDG;
05855               f4Mom=G4LorentzVector(0.,0.,0.,mProt);
05856               g4Mom=G4LorentzVector(0.,0.,0.,mPi);
05857             }
05858             else if(sPDG==90000002)                        // A=2
05859             {
05860               fQPDG=nQPDG;
05861               rQPDG=nQPDG;
05862               f4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05863               g4Mom=f4Mom;
05864             }
05865             else if(sPDG==90002000)
05866             {
05867               fQPDG=pQPDG;
05868               rQPDG=pQPDG;
05869               f4Mom=G4LorentzVector(0.,0.,0.,mProt);
05870               g4Mom=f4Mom;
05871             }
05872             else if(sPDG==92000000)
05873             {
05874               fQPDG=lQPDG;
05875               rQPDG=lQPDG;
05876               f4Mom=G4LorentzVector(0.,0.,0.,mLamb);
05877               g4Mom=f4Mom;
05878               if(sM>mSigZ+mSigZ)             // Sigma0+Sigma0 is possible
05879               {                                  // @@ Only two particles PS is used
05880                 G4double sma=mLamb+mLamb;        // Lambda+Lambda sum
05881                 G4double pr1=0.;                 // Prototype to avoid sqrt(-)
05882                 if(sM>sma) pr1=sqrt((sM2-sma*sma)*sM2); // Lamb+Lamb PS
05883                 sma=mLamb+mSigZ;                 // Lambda+Sigma0 sum
05884                 G4double smi=mSigZ-mLamb;        // Sigma0-Lambda difference
05885                 G4double pr2=pr1;                // Prototype of +L +S0 PS
05886                 if(sM>sma && sM>smi) pr2+=sqrt((sM2-sma*sma)*(sM2-smi*smi));
05887                 sma=mSigZ+mSigZ;                 // Sigma0+Sigma0 sum
05888                 G4double pr3=pr2;                // Prototype of +Sigma0+Sigma0 PS
05889                 if(sM>sma) pr3+=sqrt((sM2-sma*sma)*sM2);
05890                 G4double hhRND=pr3*G4UniformRand(); // Randomize PS
05891                 if(hhRND>pr2)                    // --> "ENnv+Sigma0+Sigma0" case
05892                 {                                //
05893                   fQPDG=s0QPDG;
05894                   f4Mom=G4LorentzVector(0.,0.,0.,mSigZ);
05895                   rQPDG=s0QPDG;
05896                   g4Mom=f4Mom;
05897                 }                                //
05898                 else if(hhRND>pr1)               // --> "ENnv+Sigma0+Lambda" case
05899                 {                                //
05900                   fQPDG=s0QPDG;
05901                   f4Mom=G4LorentzVector(0.,0.,0.,mSigZ);
05902                 }                                //
05903               }
05904               else if(sM>mSigZ+mLamb)            // Lambda+Sigma0 is possible
05905               {                                  // @@ Only two particles PS is used
05906                 G4double sma=mLamb+mLamb;        // Lambda+Lambda sum
05907                 G4double pr1=0.;                 // Prototype to avoid sqrt(-)
05908                 if(sM>sma) pr1=sqrt((sM2-sma*sma)*sM2); // Lamb+Lamb PS
05909                 sma=mLamb+mSigZ;                 // Lambda+Sigma0 sum
05910                 G4double smi=mSigZ-mLamb;        // Sigma0-Lambda difference
05911                 G4double pr2=pr1;                // Prototype of +L +S0 PS
05912                 if(sM>sma && sM>smi) pr2+=sqrt((sM2-sma*sma)*(sM2-smi*smi));
05913                 if(pr2*G4UniformRand()>pr1)      // --> "ENnv+Sigma0+Lambda" case
05914                 {                                //
05915                   fQPDG=s0QPDG;
05916                   f4Mom=G4LorentzVector(0.,0.,0.,mSigZ);
05917                 }                                //
05918               }                                  //
05919             }
05920             else if(sPDG==89999003)                       // A=2
05921             {
05922               hQPDG=nQPDG;
05923               rQPDG=nQPDG;
05924               fQPDG=pimQPDG;
05925               t4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05926               g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05927               f4Mom=G4LorentzVector(0.,0.,0.,mPi);
05928               three=true;
05929             }
05930             else if(sPDG==90002999)
05931             {
05932               hQPDG=pQPDG;
05933               rQPDG=pQPDG;
05934               fQPDG=pipQPDG;
05935               t4Mom=G4LorentzVector(0.,0.,0.,mProt);
05936               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
05937               f4Mom=G4LorentzVector(0.,0.,0.,mPi);
05938               three=true;
05939             }
05940             else if(sPDG==90000003)                        // A=3
05941             {
05942               hQPDG=nQPDG;
05943               rQPDG=nQPDG;
05944               fQPDG=nQPDG;
05945               t4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05946               g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05947               f4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05948               three=true;
05949             }
05950             else if(sPDG==90003000)
05951             {
05952               hQPDG=pQPDG;
05953               rQPDG=pQPDG;
05954               fQPDG=pQPDG;
05955               t4Mom=G4LorentzVector(0.,0.,0.,mProt);
05956               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
05957               f4Mom=G4LorentzVector(0.,0.,0.,mProt);
05958               three=true;
05959             }
05960             else if(sPDG==90001003)                     // A=4
05961             {
05962               rQPDG=nQPDG;
05963               fQPDG=tQPDG;
05964               g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05965               f4Mom=G4LorentzVector(0.,0.,0.,mTrit);
05966             }
05967             else if(sPDG==90003001)
05968             {
05969               rQPDG=pQPDG;
05970               fQPDG=he3QPDG;
05971               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
05972               f4Mom=G4LorentzVector(0.,0.,0.,mHe3);
05973             }
05974             else if(sPDG==90002003)                         // A=5
05975             {
05976               rQPDG=nQPDG;
05977               fQPDG=aQPDG;
05978               g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
05979               f4Mom=G4LorentzVector(0.,0.,0.,mAlph);
05980             }
05981             else if(sPDG==90003002)
05982             {
05983               rQPDG=pQPDG;
05984               fQPDG=aQPDG;
05985               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
05986               f4Mom=G4LorentzVector(0.,0.,0.,mAlph);
05987             }
05988             else if(sPDG==90004002)                          // A=6
05989             {
05990               hQPDG=pQPDG;
05991               rQPDG=pQPDG;
05992               fQPDG=aQPDG;
05993               t4Mom=G4LorentzVector(0.,0.,0.,mProt);
05994               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
05995               f4Mom=G4LorentzVector(0.,0.,0.,mAlph);
05996               three=true;
05997             }
05998             else if(sPDG==90002005)                        // A=7
05999             {
06000               rQPDG=nQPDG;
06001               fQPDG=a6QPDG;
06002               g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
06003               f4Mom=G4LorentzVector(0.,0.,0.,mHe6);
06004             }
06005             else if(sPDG==90005002)
06006             {
06007               rQPDG=pQPDG;
06008               fQPDG=be6QPDG;
06009               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06010               f4Mom=G4LorentzVector(0.,0.,0.,mBe6);
06011             }
06012             else if(sPDG==90004004)                        // A=8
06013             {
06014               fQPDG=aQPDG;
06015               rQPDG=aQPDG;
06016               f4Mom=G4LorentzVector(0.,0.,0.,mAlph);
06017               g4Mom=f4Mom;
06018             }
06019             //else if(sPDG==90006002)
06020             //{
06021             //  hQPDG=pQPDG;
06022             //  rQPDG=pQPDG;
06023             //  fQPDG=be6QPDG;
06024             //  t4Mom=G4LorentzVector(0.,0.,0.,mProt);
06025             //  g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06026             //  f4Mom=G4LorentzVector(0.,0.,0.,mBe6);
06027             //  three=true;
06028             //}
06029             //else if(sPDG==90002006)
06030             //{
06031             //  hQPDG=nQPDG;
06032             //  rQPDG=nQPDG;
06033             //  fQPDG=a6QPDG;
06034             //  t4Mom=G4LorentzVector(0.,0.,0.,mNeut);
06035             //  g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
06036             //  f4Mom=G4LorentzVector(0.,0.,0.,mHe6);
06037             //  three=true;
06038             //}
06039             else if(sPDG==90002007)                      // A=9
06040             {
06041               rQPDG=nQPDG;
06042               fQPDG=a8QPDG;
06043               g4Mom=G4LorentzVector(0.,0.,0.,mNeut);
06044               f4Mom=G4LorentzVector(0.,0.,0.,mHe8);
06045             }
06046             else if(sPDG==90005004)                      // A=9
06047             {
06048               rQPDG=pQPDG;
06049               fQPDG=aQPDG;
06050               hQPDG=aQPDG;
06051               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06052               f4Mom=G4LorentzVector(0.,0.,0.,mAlph);
06053               t4Mom=G4LorentzVector(0.,0.,0.,mAlph);
06054               three=true;
06055             }
06056             else if(sPDG==90007002)                      // A=9
06057             {
06058               rQPDG=pQPDG;
06059               fQPDG=c8QPDG;
06060               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06061               f4Mom=G4LorentzVector(0.,0.,0.,mC8);
06062             }
06063             else if(sPDG==90008004)                      // A=12
06064             {
06065               hQPDG=pQPDG;
06066               rQPDG=pQPDG;
06067               fQPDG=c10QPDG;
06068               t4Mom=G4LorentzVector(0.,0.,0.,mProt);
06069               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06070               f4Mom=G4LorentzVector(0.,0.,0.,mC10);
06071               three=true;
06072             }
06073             else if(sPDG==90009006)                     // A=15
06074             {
06075               rQPDG=pQPDG;
06076               fQPDG=o14QPDG;
06077               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06078               f4Mom=G4LorentzVector(0.,0.,0.,mO14);
06079             }
06080             else if(sPDG==90009007)                     // A=16
06081             {
06082               rQPDG=pQPDG;
06083               fQPDG=o15QPDG;
06084               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06085               f4Mom=G4LorentzVector(0.,0.,0.,mO15);
06086             }
06087             else if(sPDG==90010006)                     // A=16
06088             {
06089               hQPDG=pQPDG;
06090               rQPDG=pQPDG;
06091               fQPDG=o14QPDG;
06092               t4Mom=G4LorentzVector(0.,0.,0.,mProt);
06093               g4Mom=G4LorentzVector(0.,0.,0.,mProt);
06094               f4Mom=G4LorentzVector(0.,0.,0.,mO14);
06095               three=true;
06096             }
06097 #ifdef debug
06098             G4cout<<"G4QE::FSI: "<<three<<",r="<<rQPDG<<",f="<<fQPDG<<",t="<<hQPDG<<G4endl;
06099 #endif
06100             if(!three)
06101             {
06102               if(!G4QHadron(s4M).DecayIn2(f4Mom,g4Mom))
06103               {
06104                 G4ExceptionDescription ed;
06105                 ed << "Fusion (1) DecIn2 error: (2)*FUSION*,tM[" << sPDG << "]="
06106                    << tM << ">sM=" << sM << " of " << h4m << hM << hQC << hGSM
06107                    << " & " << b4m << bM << bQC << bGSM << G4endl;
06108                 G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0005",
06109                             FatalException, ed);
06110               }
06111               else
06112               {
06113 #ifdef debug
06114                 G4cout<<"G4QE::FSI:*FUSION IS DONE*,fPDG="<<sPDG<<",PDG1="<<hPDG<<",PDG2="
06115                       <<bPDG<<G4endl;
06116 #endif
06117                 curHadr->SetQPDG(fQPDG);
06118                 curHadr->Set4Momentum(f4Mom);
06119                 backH->SetQPDG(rQPDG);
06120                 backH->Set4Momentum(g4Mom);
06121 #ifdef debug
06122                 G4cout<<"G4QE::FSI:h="<<h4m<<",b="<<b4m<<",s="<<s4M<<G4endl;
06123                 G4cout<<"G4QE::FSI:f="<<f4Mom<<",g="<<g4Mom<<",s="<<f4Mom+g4Mom<<G4endl;
06124 #endif
06125               }
06126             }
06127             else
06128             {
06129               if(!G4QHadron(s4M).DecayIn3(f4Mom,g4Mom,t4Mom))
06130               {
06131                 G4ExceptionDescription ed;
06132                 ed << "Fusion(2) DecayIn3 error: (3)*FUSION*,tM[" << sPDG
06133                    << "]=" << tM << ">sM=" << sM << " of " << h4m << hM << hQC
06134                    << hGSM << " & " << b4m << bM << bQC << bGSM << G4endl;
06135                 G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0006",
06136                             FatalException, ed);
06137               }
06138               else
06139               {
06140 #ifdef debug
06141                 G4cout<<"G4QE::FSI:DONE,n="<<nHadr<<",PDG="<<sPDG<<",1="<<hPDG<<",2="<<bPDG
06142                       <<G4endl;
06143 #endif
06144                 curHadr->SetQPDG(fQPDG);
06145                 curHadr->Set4Momentum(f4Mom);
06146                 backH->SetQPDG(rQPDG);
06147                 backH->Set4Momentum(g4Mom);
06148                 G4QHadron* newH = new G4QHadron(hQPDG.GetPDGCode(),t4Mom);
06149                 theQHadrons.push_back(newH);      // (delete equivalent for newH)
06150                 nHadr=theQHadrons.size();
06151 #ifdef debug
06152                 G4cout<<"G4QE::FSI:h="<<h4m<<",b="<<b4m<<G4endl;
06153                 G4cout<<"G4QE::FSI:s="<<s4M<<" = Sum"<<f4Mom+g4Mom+t4Mom<<G4endl;
06154                 G4cout<<"G4QE::FSI:*Products*,nH="<<nHadr<<",f="<<fQPDG<<f4Mom<<",b="
06155                       <<rQPDG<<g4Mom<<",new="<<hQPDG<<t4Mom<<",nH="<<nHadr<<",nD="
06156                       <<theQHadrons.size()<<G4endl;
06157 #endif
06158               }
06159             }
06160             tot4Mom+=b4m;                       // Instead of the fused hadron
06161             tot4Mom-=g4Mom;                     // subtract from the total the new hadron
06163             // Instead the curHadr parameters should be updated ______
06164             hQPDG=fQPDG;
06165             hPDG=hQPDG.GetPDGCode();
06166             hQC=fQPDG.GetQuarkContent();
06167             hS=hQC.GetStrangeness();
06168             hB=hQC.GetBaryonNumber();
06169             hGSM = hQPDG.GetMass();
06170             h4m=f4Mom;
06171             hM=h4m.m();
06172             // End of Instead ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
06173 #ifdef debug
06174             G4cout<<"G4QE::FSI:cH4M="<<curHadr->Get4Momentum()<<G4endl;
06175 #endif
06176           } // End of the fusion check
06177         } // End of the LOOP over previous hadrons
06178       } // End of the FUSION check
06179 #ifdef chdebug
06180       // *** (2) Charge Control Sum Calculation for the Charge Conservation Check ***
06181       ccContSum=0;                   // Intermediate ChargeControlSum 
06182       cbContSum=0;                   // Intermediate BaryonNumberControlSum 
06183       if(nHadr)for(unsigned ic2=0;ic2<nHadr;ic2++) if(!(theQHadrons[ic2]->GetNFragments()))
06184       {
06185         ccContSum+=theQHadrons[ic2]->GetCharge();
06186         cbContSum+=theQHadrons[ic2]->GetBaryonNumber();
06187       }
06188       unsigned pHadr=intQHadrons.size();
06189       if(pHadr)for(unsigned ic3=0;ic3<pHadr;ic3++) if(!(intQHadrons[ic3]->GetNFragments()))
06190       {
06191         ccContSum+=intQHadrons[ic3]->GetCharge();
06192         cbContSum+=intQHadrons[ic3]->GetBaryonNumber();
06193       }
06194       if(ccContSum-chContSum || cbContSum-bnContSum)
06195       {
06196         G4cout<<"*::*G4QE::FSI:(8) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
06197               <<G4endl;
06198         //throw G4QException("G4QEnvironment::FSInteract: (2) Charge is not conserved");
06199       }
06200       // ***
06201 #endif
06202       G4LorentzVector cH4Mom = curHadr->Get4Momentum(); // 4-mom of the current hadron
06203       tot4Mom-=cH4Mom;                          // Reduce theTotal 4mom by theCurrent 4mom
06204       totCharge-=curHadr->GetCharge();          // @!@
06205       totBaryoN-=curHadr->GetBaryonNumber();    // @!@
06206 #ifdef pdebug
06207         G4cout<<"G4QE::FSI:Cur4M="<<tot4Mom<<",tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;
06208 #endif
06209       if(hadron+1==nHadr)                       // The Last Hadron in the set
06210       {
06211 #ifdef pdebug
06212         G4cout<<"G4QE::FSI:Last4M="<<tot4Mom<<",tC="<<totCharge<<",tB="<<totBaryoN<<G4endl;
06213 #endif
06214         G4double misM=0.;                       // @!@
06215         G4int mPDG=0;                           // @!@
06216         if(totCharge>=0 && totBaryoN > 0)       // @!@
06217         {                                       // @!@
06218           mPDG=90000000+999*totCharge+totBaryoN;// @!@
06219           misM=G4QPDGCode(mPDG).GetMass();      // @!@
06220         }                                       // @!@
06221         G4double re =tot4Mom.e();
06222         G4double rpx=tot4Mom.px();
06223         G4double rpy=tot4Mom.py();
06224         G4double rpz=tot4Mom.pz();
06225         G4double re2=re*re;                     // @!@
06226         G4double dmo=rpx*rpx+rpy*rpy+rpz*rpz;
06227         G4double dem=re2+dmo;
06228         G4double dm2=re2-dmo;                   // @!@
06229         G4double sdm=0.;                        // @!@
06230         if(dm2>0.) sdm=std::sqrt(dm2);          // @!@
06231 #ifdef debug
06232         G4cout<<"G4QE::FSI: Is En&Mom conserved? t4M="<<tot4Mom<<",dM="<<sdm<<", mM="<<misM
06233               <<",mPDG="<<mPDG<<",dCH="<<totCharge<<",dBN="<<totBaryoN<<G4endl;
06234 #endif
06235         G4LorentzVector cor4M(0.,0.,0.,0.);     // Prototype for the missing particle
06236         if(dem>0.1)                             // Energy or momentum is not conserved
06237         {
06238           G4bool corf=false;
06239 #ifdef pdebug
06240           G4cout<<"--Warning--G4QE::FSI:dE/Mc4M="<<tot4Mom<<sdm<<". Correct it!"<<G4endl;
06241 #endif
06242             if(sdm < .01 || (re2 > 0. && !totCharge && !totBaryoN && sdm/re2 < .0001)) // @!@
06243           {
06244 #ifdef pdebug
06245             G4cout<<"...G4QE::FSI:E/M conservation is corrected by a photon"<<G4endl;
06246 #endif
06247             cor4M=tot4Mom;                                 // Complete correction
06248             G4QHadron* theH = new G4QHadron(22,tot4Mom);
06249             theQHadrons.push_back(theH);    // (delete equivalent for the proton)
06250             corf=true;
06251           }
06252           else                                             // @!@
06253           {
06254             if(dmo<0.0001 && re>900.)               // MomentumIsConserved - recoverMissing
06255             {
06256               if(fabs(re-mNeut)<.01)
06257               {
06258 #ifdef pdebug
06259                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by neutron"<<G4endl;
06260 #endif
06261                 cor4M=G4LorentzVector(0.,0.,0.,mNeut);
06262                 G4QHadron* theH = new G4QHadron(90000001,G4LorentzVector(0.,0.,0.,mNeut));
06263                 theQHadrons.push_back(theH);  // (delete equivalent for the proton)
06264                 corf=true;
06265               }
06266               else if(fabs(re-mProt)<.01)
06267               {
06268 #ifdef pdebug
06269                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by proton"<<G4endl;
06270 #endif
06271                 cor4M=G4LorentzVector(0.,0.,0.,mProt);
06272                 G4QHadron* theH = new G4QHadron(90001000,G4LorentzVector(0.,0.,0.,mProt));
06273                 theQHadrons.push_back(theH);  // (delete equivalent for the proton)
06274                 corf=true;
06275               }
06276               else if(fabs(re-mDeut)<.01)
06277               {
06278 #ifdef pdebug
06279                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by deuteron"<<G4endl;
06280 #endif
06281                 cor4M=G4LorentzVector(0.,0.,0.,mDeut);
06282                 G4QHadron* theH = new G4QHadron(90001001,G4LorentzVector(0.,0.,0.,mDeut));
06283                 theQHadrons.push_back(theH);  // (delete equivalent for the proton)
06284                 corf=true;
06285               }
06286               else if(fabs(re-mTrit)<.01)
06287               {
06288 #ifdef pdebug
06289                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by tritium"<<G4endl;
06290 #endif
06291                 cor4M=G4LorentzVector(0.,0.,0.,mTrit);
06292                 G4QHadron* theH = new G4QHadron(90001002,G4LorentzVector(0.,0.,0.,mTrit));
06293                 theQHadrons.push_back(theH);  // (delete equivalent for the proton)
06294                 corf=true;
06295               }
06296               else if(fabs(re-mHe3)<.01)
06297               {
06298 #ifdef pdebug
06299                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by He3"<<G4endl;
06300 #endif
06301                 cor4M=G4LorentzVector(0.,0.,0.,mHe3);
06302                 G4QHadron* theH = new G4QHadron(90002001,G4LorentzVector(0.,0.,0.,mHe3));
06303                 theQHadrons.push_back(theH);  // (delete equivalent for the proton)
06304                 corf=true;
06305               }
06306               else if(fabs(re-mAlph)<.01)
06307               {
06308 #ifdef pdebug
06309                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by alpha"<<G4endl;
06310 #endif
06311                 cor4M=G4LorentzVector(0.,0.,0.,mAlph);
06312                 G4QHadron* theH = new G4QHadron(90002002,G4LorentzVector(0.,0.,0.,mAlph));
06313                 theQHadrons.push_back(theH);  // (delete equivalent for the proton)
06314                 corf=true;
06315               }
06316               else if(fabs(re-mNeut-mNeut)<.01)
06317               {
06318                 cor4M=G4LorentzVector(0.,0.,0.,mNeut+mNeut);
06319 #ifdef pdebug
06320                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by 2 neutrons"<<G4endl;
06321 #endif
06322                 G4QHadron* theH1 = new G4QHadron(90000001,G4LorentzVector(0.,0.,0.,mNeut));
06323                 theQHadrons.push_back(theH1); // (delete equivalent for the proton)
06324                 G4QHadron* theH2 = new G4QHadron(90000001,G4LorentzVector(0.,0.,0.,mNeut));
06325                 theQHadrons.push_back(theH2); // (delete equivalent for the proton)
06326                 corf=true;
06327               }
06328               else if(fabs(re-mProt-mProt)<.01)
06329               {
06330 #ifdef pdebug
06331                 G4cout<<"...G4QE::FSI:E/M conservation is corrected by 2 protons"<<G4endl;
06332 #endif
06333                 cor4M=G4LorentzVector(0.,0.,0.,mProt+mProt);
06334                 G4QHadron* theH1 = new G4QHadron(90001000,G4LorentzVector(0.,0.,0.,mProt));
06335                 theQHadrons.push_back(theH1); // (delete equivalent for the proton)
06336                 G4QHadron* theH2 = new G4QHadron(90001000,G4LorentzVector(0.,0.,0.,mProt));
06337                 theQHadrons.push_back(theH2); // (delete equivalent for the proton)
06338                 corf=true;
06339               }
06340               else G4Exception("G4QEnvironment::FSInteract()", "HAD_CHPS_0007",
06341                                JustWarning, "Try heavier nuclei at rest");
06342             }
06343             else if(std::abs(sdm-misM) < 0.01)        // on flight correction @!@
06344             {
06345 #ifdef pdebug
06346               G4cout<<"...G4QE::FSI:E/M conservation is corrected by ResidualNucl"<<G4endl;
06347 #endif
06348               if(!misM) mPDG=22;
06349               G4QHadron* theH = new G4QHadron(mPDG,tot4Mom); // Create Residual Nucleus
06350               cor4M=tot4Mom;                  // Complete correction
06351               if(std::fabs(sdm-misM) <= 0.01) theQHadrons.push_back(theH); // As is
06352               else EvaporateResidual(theH);   // Evaporate Residual Nucleus
06353               corf=true;
06354             }
06355             else if(tot4Mom.e() > 0 && cH4Mom.e() > 0 && nHadr > 1) // TeV error check
06356             {
06357               G4QHadron* prevHadr = theQHadrons[nHadr-2]; // GetPointer to Prev to theLast
06358               G4LorentzVector pH4Mom = prevHadr->Get4Momentum(); // 4mom of thePrevHadron
06359               G4double cHM = curHadr->GetMass();  // Mass of the current hadron
06360               G4double pHM = prevHadr->GetMass(); // Mass of the previous hadron
06361 #ifdef pdebug
06362                   G4cout<<"G4QE::FSI:Bt4M="<<tot4Mom<<",c4M="<<cH4Mom<<",p4M="<<pH4Mom<<G4endl;
06363 #endif
06364               G4LorentzVector tt4Mom=tot4Mom+cH4Mom+pH4Mom;
06365               G4double totRM=tt4Mom.m();
06366 #ifdef pdebug
06367                   G4cout<<"G4QE::FS:"<<tt4Mom<<",tM="<<totRM<<",cM="<<cHM<<",pM="<<pHM<<G4endl;
06368 #endif
06369               if(cHM+pHM<=totRM)                  // *** Make the final correction ***
06370                 {
06371                 if(!G4QHadron(tt4Mom).DecayIn2(pH4Mom,cH4Mom))
06372                 {
06373                   G4cout<<"***G4QE::FSI:**Correction**tot4M="<<tt4Mom<<totRM<<">sM="
06374                         <<cHM+cHM<<G4endl;
06375 #ifdef pdebug
06376                   G4ExceptionDescription ed;
06377                   ed << "CORRECT DecIn2 error: **Correction**tot4M=" << tt4Mom
06378                      << totRM << ">sM=" << cHM+cHM << G4endl;
06379                   G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0007",
06380                               JustWarning, ed);
06381 #endif
06382                 }
06383 #ifdef chdebug
06384                 G4cout<<"-:-Warning-:-G4QE::FSI:***CORRECTION IS DONE*** d="<<dem<<G4endl;
06385 #endif
06386                 cor4M=tot4Mom;                                 // Complete correction
06387                 curHadr->Set4Momentum(cH4Mom);
06388                 prevHadr->Set4Momentum(pH4Mom);
06389                 corf=true;
06390               }
06391               else
06392               {
06393 #ifdef pdebug
06394                 G4cerr<<"*!*G4QE::FSI: "<<cHM<<"+"<<pHM<<"="<<cHM+pHM<<">"<<totRM<<G4endl;
06395                 G4ExceptionDescription ed;
06396                 ed <<"TEMPORARY EXCEPTION: "<<cHM<<"+"<<pHM<<" = "<<cHM+pHM<<" > "<<totRM
06397                    <<", tot4M="<<tot4Mom<<", c4M="<<cH4Mom<<", p4M="<<pH4Mom<< G4endl;
06398                 G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0008", 
06399                             JustWarning, ed);
06400 #endif 
06401               }
06402             }
06403             else
06404             {
06405               G4cerr<<"*!*G4QE::FSI: tE="<<tot4Mom.e()<<", nHadr="<<nHadr<<G4endl;
06406               G4ExceptionDescription ed;
06407               ed << "TEMPORARY EXCEPTION: *check energy!* tot4M=" << tot4Mom << ", c4M="
06408                  << cH4Mom << ", nHadr="<< nHadr << " > 1 ?" << G4endl;
06409               G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0009", 
06410                           JustWarning, ed);
06411             }
06412             tot4Mom=tot4Mom-cor4M;
06413 #ifdef pdebug
06414             G4cout<<"---Warning---G4QE::FSI:En/MomCons.Error is corrected:"<<cor4M<<G4endl;
06415 #endif
06416           }
06417           if(nHadr>2 && !corf)
06418           {
06419             G4double cHM = curHadr->GetMass();  // Mass of the current hadron
06420             G4int ch=0;
06421             for(ch=nHadr-3; ch>-1; --ch)
06422             {
06423               G4QHadron* prevHadr = theQHadrons[ch]; // GetPointer to Hadr prev to theLast
06424               G4LorentzVector pH4Mom = prevHadr->Get4Momentum();// 4M of thePreviousHadron
06425               G4double pHM = prevHadr->GetMass(); // Mass of the current hadron
06426               tot4Mom+=cH4Mom+pH4Mom;
06427               G4double totRM=tot4Mom.m();
06428               if(cHM+pHM<=totRM)                  // *** Make the final correction ***
06429               {
06430                 if(!G4QHadron(tot4Mom).DecayIn2(pH4Mom,cH4Mom))
06431                 {
06432                   G4cout<<"***G4QEnv::FSI:**Correction**,tot4M="<<tot4Mom<<totRM<<" > sM="
06433                         <<cHM+cHM<<G4endl;
06434 #ifdef debug
06435                   G4ExceptionDescription ed;
06436                   ed << "CORRECTION DecIn2Error: **Correction**,tot4M=" << tot4Mom
06437                      << totRM << " > sM=" << cHM+cHM << G4endl;
06438                   G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0010",
06439                               FatalException, ed);
06440 #endif
06441                 }
06442 #ifdef chdebug
06443                 G4cout<<"-:-!!!-:-G4QE::FSI:***CORRECTION IS DONE*** d="<<dem<<G4endl;
06444 #endif
06445                 curHadr->Set4Momentum(cH4Mom);
06446                 prevHadr->Set4Momentum(pH4Mom);
06447                 break;                            // Get out of the correction LOOP
06448               }
06449               else tot4Mom-=cH4Mom+pH4Mom;
06450             }
06451 #ifdef ppdebug
06452             if(ch<0)
06453             {
06454               G4ExceptionDescription ed;
06455               ed << "EnMomCorrectionFailed: EnergyMomentumCorrection FAILED "
06456                  << G4endl;
06457               G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0011",
06458                           FatalException, ed);
06459             }
06460 #endif
06461           } // End of additional attempt to correct EM by other hadrons
06462         }
06463 #ifdef debug
06464         else  G4cout<<"...G4QE::FSI:E/M conservation is good enough"<<G4endl;
06465         G4cout<<"G4QE::FSI:EMCorrection by "<<theQHadrons.size()-nHadr<<" hadrons"<<G4endl;
06466 #endif
06467         break;
06468       }
06469     } // End of the Back fusion LOOP
06470     // >| 2     | 2  | 2     | 2     | 2      | 2 - old    | 1. If gamma: add to sum4Mom
06471     //  |>0->sum| 3  | 3     | 3     | 3      | 3 - old    | 2. Compare BN with the Last
06472     //  | 5     |>5  | 4     | 4     | 4      | 4 - old    | 3. Swap if larger, del theLast
06473     //  | 0     | 0  |>0->sum| 5<-sum| 5->evap| 2 - new    | 4. If the Last: add the sum
06474     //  | 4     | 4  | 5     | ex    |        |(0 - gamma?)| 5. Decay/Eporate the Last
06475     //  | 3     | ex |                        | 3 - new
06476 #ifdef chdebug
06477     // *** (3) Charge Control Sum Calculation for the Charge Conservation Check ***
06478     ccContSum=0;                              // Intermediate ChargeControlSum 
06479     cbContSum=0;                              // Intermediate BaryonNumberControlSum 
06480     if(nHadr)for(unsigned ic3=0; ic3<nHadr; ic3++) if(!(theQHadrons[ic3]->GetNFragments()))
06481     {
06482       ccContSum+=theQHadrons[ic3]->GetCharge();
06483       cbContSum+=theQHadrons[ic3]->GetBaryonNumber();
06484     }
06485     if(ccContSum-chContSum || cbContSum-bnContSum)
06486     {
06487       G4cout<<"*::*G4QE::FSI:(9) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
06488             <<G4endl;
06489       //throw G4QException("G4QEnvironment::FSInteract: (3) Charge is not conserved");
06490     }
06491     // ***
06492 #endif
06493     G4LorentzVector sum(0.,0.,0.,0.);
06494     G4int gamCount=0;
06495     nHadr=theQHadrons.size();
06496     G4bool frag=false;
06497     if(nHadr>2)for(unsigned f=0; f<theQHadrons.size(); f++) //Check that there's a fragment
06498     {
06499       G4int fBN=theQHadrons[f]->GetBaryonNumber(); // Baryon number of the fragment
06500 #ifdef debug
06501       G4int fPDG=theQHadrons[f]->GetPDGCode();     // PDG code of the fragment
06502       G4LorentzVector fLV=theQHadrons[f]->Get4Momentum(); // 4Mom of the fragment
06503       G4cout<<"G4QE::FSI:"<<f<<",PDG="<<fPDG<<",fBN="<<fBN<<",f4M="<<fLV<<G4endl;
06504 #endif
06505       if(fBN>1)                                    // At least one fragment (A>1) is found
06506       {
06507         frag=true;
06508         break;
06509       }
06510     }
06511 #ifdef debug
06512     G4cout<<"G4QE::FSI:===Before Gamma Compression===, nH="<<nHadr<<",frag="<<frag<<G4endl;
06513 #endif
06514     if(nHadr>2 && frag) for(G4int h=nHadr-1; h>=0; h--)//Collect gammas & kill DecayedHadrs
06515     {
06516       G4QHadron* curHadr = theQHadrons[h];    // Get a pointer to the current Hadron
06517       G4int   hF = curHadr->GetNFragments();
06518       G4int hPDG = curHadr->GetPDGCode();
06519       if(hPDG==89999003||hPDG==90002999)
06520         G4cout<<"---Warning---G4QEnv::FSI:nD-/pD++(1)="<<hPDG<<G4endl;
06521 #ifdef debug
06522       G4cout<<"G4QE::FSI: h#"<<h<<", hPDG="<<hPDG<<", hNFrag="<<hF<<G4endl;
06523 #endif
06524       if(hF||hPDG==22)                        // It should be compressed
06525       {
06526         G4QHadron* theLast = theQHadrons[theQHadrons.size()-1];//Get Ptr to the Last Hadron
06527         if(hPDG==22)
06528         {
06529           G4LorentzVector g4M=curHadr->Get4Momentum();
06530           sum+=g4M;                           // Add 4Mom of gamma to the "sum"
06531           gamCount++;
06532 #ifdef debug
06533           G4cout<<"G4QE::FSI: gam4M="<<g4M<<" is added to s4M="<<sum<<G4endl;
06534 #endif
06535         }
06536         nHadr = theQHadrons.size()-1;
06537         if(h < static_cast<G4int>(nHadr))     // Need swap with the Last
06538         {
06539           curHadr->SetNFragments(0);
06540           curHadr->Set4Momentum(theLast->Get4Momentum());
06541           G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
06542           if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
06543           else curHadr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
06544 #ifdef debug
06545           G4cout<<"G4QE::FSI: Exchange with the last is done"<<G4endl;
06546 #endif
06547         }
06548         theQHadrons.pop_back();               // theLastQHadron is excluded from QHadrons
06549         delete theLast;
06550 #ifdef debug
06551         G4cout<<"G4QE::FSI: The last is compessed"<<G4endl;
06552 #endif
06553       }
06554     }
06555 #ifdef debug
06556     G4cout<<"G4QE::FSI: nH="<<nHadr<<"="<<theQHadrons.size()<<", sum="<<sum<<G4endl;
06557 #endif
06558 #ifdef chdebug
06559     // *** (4) Charge Control Sum Calculation for the Charge Conservation Check ***
06560     ccContSum=0;                   // Intermediate ChargeControlSum 
06561     cbContSum=0;                   // Intermediate BaryonNumberControlSum 
06562     if(nHadr)for(unsigned ic4=0; ic4<nHadr; ic4++) if(!(theQHadrons[ic4]->GetNFragments()))
06563     {
06564         ccContSum+=theQHadrons[ic4]->GetCharge();
06565         cbContSum+=theQHadrons[ic4]->GetBaryonNumber();
06566     }
06567     if(ccContSum-chContSum || cbContSum-bnContSum)
06568     {
06569       G4cout<<"*::*G4QE::FSI:(A) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
06570             <<G4endl;
06571       //throw G4QException("G4QEnvironment::FSInteract: (4) Charge is not conserved");
06572     }
06573     // ***
06574 #endif
06575     if(nHadr>1)for(unsigned hdr=0; hdr<theQHadrons.size()-1; hdr++)//Ord:theBigestIsTheLast
06576     {
06577       G4QHadron* curHadr = theQHadrons[hdr];  // Get a pointer to the current Hadron
06578 #ifdef debug
06579       G4cout<<"G4QE::FSI:ORD,h="<<hdr<<"<"<<nHadr<<",hPDG="<<curHadr->GetPDGCode()<<G4endl;
06580 #endif
06581       G4QHadron* theLast = theQHadrons[theQHadrons.size()-1]; //Get Ptr to the Last Hadron
06582       G4int hB           = curHadr->GetBaryonNumber();
06583       G4int lB           = theLast->GetBaryonNumber();
06584 #ifdef debug
06585       G4cout<<"G4QE::FSI:hBN="<<hB<<"<lBN="<<lB<<",lstPDG="<<theLast->GetPDGCode()<<G4endl;
06586 #endif
06587       if(lB<hB)                               // Must be swapped
06588       {
06589         G4QPDGCode   hQPDG = curHadr->GetQPDG();
06590         G4LorentzVector h4m= curHadr->Get4Momentum();
06591         curHadr->Set4Momentum(theLast->Get4Momentum());
06592         G4QPDGCode lQP=theLast->GetQPDG();    // The QPDG of the last
06593         if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of LastHadr
06594         else curHadr->SetQC(theLast->GetQC());// CurHadrPDG instead of LastHadrPDG
06595         theLast->Set4Momentum(h4m);
06596         theLast->SetQPDG(hQPDG);
06597       }
06598     }
06599     nHadr=theQHadrons.size();
06600 #ifdef chdebug
06601     // *** (5) Charge Control Sum Calculation for the Charge Conservation Check ***
06602     ccContSum=0;                              // Intermediate ChargeControlSum 
06603     cbContSum=0;                              // Intermediate BaryonNumberControlSum 
06604     if(nHadr)for(unsigned ic5=0; ic5<nHadr; ic5++) if(!(theQHadrons[ic5]->GetNFragments()))
06605     {
06606       ccContSum+=theQHadrons[ic5]->GetCharge();
06607       cbContSum+=theQHadrons[ic5]->GetBaryonNumber();
06608     }
06609     if(ccContSum-chContSum || cbContSum-bnContSum)
06610     {
06611       G4cout<<"*::*G4QE::FSI:(B) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
06612             <<G4endl;
06613       //throw G4QException("G4QEnvironment::FSInteract: (5) Charge is not conserved");
06614     }
06615     // ***
06616 #endif
06617     if(gamCount)
06618     {
06619       G4QHadron* theLast = theQHadrons[nHadr-1];// Get a pointer to the Last Hadron
06620       if(theLast->GetBaryonNumber()>0)        // "Absorb photons & evaporate/decay" case
06621       {
06622         G4QHadron* theNew  = new G4QHadron(theLast); // Make New Hadron of the Last Hadron
06623 #ifdef ffdebug
06624         G4cout<<"G4QE::FSI:BeforeLastSub,n="<<nHadr<<",PDG="<<theNew->GetPDGCode()<<G4endl;
06625 #endif
06626         theQHadrons.pop_back();               // the last QHadron is excluded from OUTPUT
06627         delete theLast;// *!When kill,DON'T forget to delete theLastQHadron as anInstance!*
06628         nHadr--;                              // TheLastHadron is only virtually exists now
06629         G4int newPDG=theNew->GetPDGCode();
06630         G4LorentzVector new4M=theNew->Get4Momentum(); // 4-mom of the fragment
06631 #ifdef debug
06632         G4cout<<"G4QE::FSI:gSum4M="<<sum<<" is added to "<<new4M<<", PDG="<<newPDG<<G4endl;
06633 #endif
06634         G4LorentzVector exRes4M=new4M+sum;    //Icrease 4Mom of theLast by "sum of gammas"
06635         G4QNucleus exResidN(exRes4M,newPDG);
06636         //G4double mGamEva=2700.;             // @@Threshold for the evaporation
06637         G4double mGamEva=1700.;               // @@Threshold for the evaporation
06638         if(exResidN.SplitBaryon())
06639         //if(2>3)                             //CloseTheFirstPriorityResN+gamSumEvaporation
06640         {
06641           theNew->Set4Momentum(exRes4M);      // Icrease 4Mom of theLast by "sum" to Evapor
06642 #ifdef ffdebug
06643           G4cout<<"G4QE::FSI:BeforeE(1),n="<<nHadr<<",nPDG="<<theNew->GetPDGCode()<<G4endl;
06644 #endif
06645           EvaporateResidual(theNew);          // Try to evaporate the Nucl.(@@DecDib)(d.e.)
06646         }
06647         else if(theNew->GetPDGCode()==90002002&&exRes4M.m()>mHe3+mNeut&&G4UniformRand()>.5)
06648         {
06649           theNew->Set4Momentum(exRes4M);      // Icrease 4Mom of theLast by "sum" to Evapor
06650           G4LorentzVector n4M(0.,0.,0.,mNeut);
06651           G4LorentzVector h4M(0.,0.,0.,mHe3);
06652           if(!theNew->DecayIn2(n4M,h4M))
06653           {
06654             G4ExceptionDescription ed;
06655             ed << "GamSUPPRES DecIn2(n+He3)error: GamSup, tM=" << exRes4M.m()
06656                << "<n+He3=" << mNeut+mHe3 << G4endl;
06657             G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0012",
06658                         FatalException, ed);
06659           }
06660 #ifdef ffdebug
06661           G4cout<<"G4QE::FSI:Gamma Suppression succided, n="<<n4M<<", He3="<<h4M<<G4endl;
06662 #endif
06663           theNew->Set4Momentum(n4M);
06664           theNew->SetQPDG(nQPDG);             // convert the alpha to the neutron
06665           theQHadrons.push_back(theNew);      // (delete equivalent for theHad=neutron)
06666           G4QHadron* theHe3 = new G4QHadron(90002001,h4M);// Make a New Hadr for the He3
06667           theQHadrons.push_back(theHe3);      // (delete equivalent for the proton)
06668         }
06669         else if(nHadr)                        // Get LastHadrBefResNuc, absorb gam & decay
06670         //else if(2>3)                        // Close the pair absorbtion of gamma
06671         {
06672           if(nHadr>1)for(unsigned sh=0; sh<theQHadrons.size()-1; sh++)//Ord:MinE is TheLast
06673           {
06674             G4QHadron* curHadr = theQHadrons[sh];// Get a pointer to the current Hadron
06675             G4QHadron* thePrev = theQHadrons[theQHadrons.size()-1]; //GetPtr to theLastHadr
06676             G4LorentzVector h4M= curHadr->Get4Momentum();
06677             G4LorentzVector l4M= thePrev->Get4Momentum();
06678 #ifdef ffdebug
06679             G4cout<<"G4QE::FSI:SO,h="<<sh<<"<"<<nHadr<<",PDG/LV="<<curHadr->GetPDGCode()
06680                   <<h4M<<G4endl;
06681 #endif
06682             G4double hM=h4M.m();
06683             G4double hT=h4M.e()-hM;
06684             G4double lT=l4M.e()-l4M.m();
06685 #ifdef ffdebug
06686             G4cout<<"G4QE::FSI:hT="<<hT<<"<T="<<lT<<".PDG="<<thePrev->GetPDGCode()<<G4endl;
06687 #endif
06688             if(hM>mGamEva&&lT>hT)             // Must be swapped as the current is smaller
06689             {
06690               G4QPDGCode   hQPDG = curHadr->GetQPDG();
06691               curHadr->Set4Momentum(l4M);
06692               G4QPDGCode lQP=thePrev->GetQPDG();    // The QPDG of the previous
06693               if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of PrevHadr
06694               else curHadr->SetQC(thePrev->GetQC());// CurHadrPDG instead of PrevHadrPDG
06695               thePrev->Set4Momentum(h4M);
06696               thePrev->SetQPDG(hQPDG);
06697             }
06698           }
06699           nHadr=theQHadrons.size();
06700           G4QHadron* thePrev = theQHadrons[nHadr-1]; // GetPtr to the BeforeResidNuclHadron
06701           if(thePrev->Get4Momentum().m()>mGamEva)
06702           {
06703             G4QHadron* theHad  = new G4QHadron(thePrev);// MakeNewHadr of theBeforeResNuclH
06704 #ifdef ffdebug
06705             G4cout<<"G4QE::FSI:BeforeResidNucHadr nH="<<nHadr<<",hPDG="
06706                   <<theHad->GetPDGCode()<<G4endl;
06707 #endif
06708             theQHadrons.pop_back();           // theLastQHadron excluded from OUTPUT
06709             delete thePrev;// *!When kill,DON'T forget to delete theLastQHadrAsAnInstance!*
06710             G4LorentzVector n4M=theNew->Get4Momentum();// 4Mom of theLast (biggest nucleus)
06711             G4LorentzVector h4M=theHad->Get4Momentum();// 4Mom of the previous Hadron in HV
06712             G4LorentzVector dh4M=exRes4M+h4M; // 4Mom of LH+PH+sum(gam) for theDecay
06713             G4double dhM=dh4M.m();            // M of LH+PH+sum(gammas) for theDecay
06714             if(theHad->GetPDGCode()==90001001&&dhM>n4M.m()+mProt+mNeut&&G4UniformRand()>.5)
06715             //if(2>3)                           // Close Possibility toSplitDeuteron
06716             {
06717               G4double nuM=n4M.m();
06718               h4M=G4LorentzVector(0.,0.,0.,mNeut);
06719               G4LorentzVector p4M(0.,0.,0.,mProt);
06720               G4double sum_value=nuM+mNeut+mProt;
06721               if(fabs(dhM-sum_value)<eps)
06722               {
06723                 n4M=dh4M*(nuM/sum_value);
06724                 h4M=dh4M*(mNeut/sum_value);
06725                 p4M=dh4M*(mProt/sum_value);
06726               }
06727               else if(dhM<sum_value || !G4QHadron(dh4M).DecayIn3(n4M,h4M,p4M))
06728               {
06729                 G4ExceptionDescription ed;
06730                 ed << "Gamma SUPPRESSION by D DecIn3error: GamSupByD,M="
06731                    << dhM << "<A+p+n=" << sum_value << G4endl;
06732                 G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0013",
06733                             FatalException, ed);
06734               }
06735 #ifdef ffdebug
06736               G4cout<<"G4QE::FSI:GamSuppression by d succided,h="<<h4M<<",A="<<n4M<<G4endl;
06737 #endif
06738               theHad->Set4Momentum(h4M);
06739               theHad->SetQPDG(nQPDG);         // convert the deuteron to the neutron
06740               theQHadrons.push_back(theHad);  // (delete equivalent for theHad=neutron)
06741               G4QHadron* theProt = new G4QHadron(90001000,p4M);// Make NewHadr for Proton
06742               theQHadrons.push_back(theProt); // (delete equivalent for the proton)
06743               theNew->Set4Momentum(n4M);
06744               EvaporateResidual(theNew);      // TryToEvaporate theResNuc onceMore(del.eq.)
06745             }
06746             else
06747             {
06748               if(!G4QHadron(dh4M).DecayIn2(n4M,h4M))
06749               {
06750                 G4ExceptionDescription ed;
06751                 ed << "GamSUPPRESSION (3) DecIn2 error: GamSup,M=" << dh4M.m()
06752                    << "<A+h=" << n4M.m()+h4M.m() << G4endl;
06753                 G4Exception("G4QEnvironment::FSInteraction()", "HAD_CHPS_0014",
06754                             FatalException, ed);
06755               }
06756 #ifdef ffdebug
06757               G4cout<<"G4QE::FSI:Gamma Suppression succided, h="<<h4M<<", A="<<n4M<<G4endl;
06758 #endif
06759               theHad->Set4Momentum(h4M);
06760               theQHadrons.push_back(theHad);  // (delete equivalent for theHad)
06761               theNew->Set4Momentum(n4M);
06762               EvaporateResidual(theNew);      // Try to evaporate theResNuc (del.eq.)
06763             }
06764           }
06765           else
06766           {
06767             theNew->Set4Momentum(exRes4M);    // Icrease 4MomOfTheLast by "sum" for Evapor
06768 #ifdef ffdebug
06769             G4cout<<"G4QE::FSI:BeforE(2),n="<<nHadr<<",PDG="<<theNew->GetPDGCode()<<G4endl;
06770 #endif
06771             EvaporateResidual(theNew);  // Try to evaporate the Nucl.(@@DecDib)(delete eq.)
06772           }
06773         }
06774         else                            // Absorb gammas to theResidNucleus and evaporateIt
06775         {
06776           theNew->Set4Momentum(exRes4M);// Icrease 4Mom of the Last by the "sum" for Evap
06777           EvaporateResidual(theNew);    // Try to evaporate the Nucl.(@@DecDib)(delete eq.)
06778 #ifdef ffdebug
06779           G4cout<<"G4QE::FSI:Bef.E(3),n="<<nHadr<<",PDG="<<newPDG<<",4M="<<exRes4M<<G4endl;
06780           unsigned nHN=theQHadrons.size();
06781           G4cout<<"G4QE::FSI:AfterEvaporation: nNew="<<nHN<<G4endl;
06782           if(nHN>nHadr)for(unsigned idp=nHadr; idp<nHN; idp++)
06783           G4cout<<"G4QE::FSI: h#"<<idp<<", PDG="<<theQHadrons[idp]->GetPDGCode()<<G4endl;
06784 #endif
06785         }
06786         //G4int onH=nHadr;
06787         nHadr=theQHadrons.size();
06788         //if(nHadr>onH) bfAct=true;
06789       } // End of "the last is the nucleus" case
06790     } // End of "There are gammas to assimilate"
06791   } // End of the While-LOOOP for the Back Fusion
06792   tot4Mom=tmp4Mom; // Recover tot4Mom after the "En/Mom conservation" reduction
06793   // Final attempt to alpha-decay the residual nucleus, suppressing the gamma ===
06794   G4int gamcnt=0; // Counter of the residual gammas at this level
06795   nHadr=theQHadrons.size();
06796   unsigned maxB=nHadr-1;
06797 #ifdef chdebug
06798   // *** (6) Charge Control Sum Calculation for the Charge Conservation Check ***
06799   ccContSum=0;                   // Intermediate ChargeControlSum 
06800   cbContSum=0;                   // Intermediate BaryonNumberControlSum 
06801   if(nHadr)for(unsigned ic6=0; ic6<nHadr; ic6++) if(!(theQHadrons[ic6]->GetNFragments()))
06802   {
06803     ccContSum+=theQHadrons[ic6]->GetCharge();
06804     cbContSum+=theQHadrons[ic6]->GetBaryonNumber();
06805   }
06806   if(ccContSum-chContSum || cbContSum-bnContSum)
06807   {
06808     G4cout<<"*::*G4QE::FSI:(C) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
06809           <<G4endl;
06810     //throw G4QException("G4QEnvironment::FSInteract: (6) Charge is not conserved");
06811   }
06812   // ***
06813 #endif
06814   lHadr=theQHadrons[maxB]->GetBaryonNumber();
06815   G4int tHadr=lHadr;                             // Total Baryon number
06816   if(nHadr>1)for(unsigned ipo=0; ipo<theQHadrons.size()-1; ipo++) // Find BiggestNuclFragm
06817   {
06818     G4int hPDG = theQHadrons[ipo]->GetPDGCode();
06819     if(hPDG==22) gamcnt++;
06820     else
06821     {
06822       G4int hBN  = theQHadrons[ipo]->GetBaryonNumber();
06823       tHadr+=hBN;
06824 #ifdef debug
06825       G4cout<<"G4QE::FSI:h#"<<ipo<<":hPDG="<<hPDG<<",hBN="<<hBN<<",nH="<<theQHadrons.size()
06826             <<G4endl;
06827 #endif
06828       if(hBN>lHadr)
06829       {
06830         lHadr=hBN;
06831         maxB=ipo;
06832       }                                           // the current biggest nuclear fragment
06833     }
06834   }
06835 #ifdef debug
06836   G4cout<<"G4QE::FSI:max#"<<maxB<<",lB="<<lHadr<<",tBN="<<tHadr<<",gam="<<gamcnt<<G4endl;
06837 #endif
06838   nHadr=theQHadrons.size();
06839 #ifdef chdebug
06840   // *** (7) Charge Control Sum Calculation for the Charge Conservation Check ***
06841   ccContSum=0;                   // Intermediate ChargeControlSum
06842   cbContSum=0;                   // Intermediate BaryonNumberControlSum
06843   if(nHadr)for(unsigned ic7=0; ic7<nHadr; ic7++) if(!(theQHadrons[ic7]->GetNFragments()))
06844   {
06845     ccContSum+=theQHadrons[ic7]->GetCharge();
06846     cbContSum+=theQHadrons[ic7]->GetBaryonNumber();
06847   }
06848   if(ccContSum-chContSum || cbContSum-bnContSum)
06849   {
06850     G4cout<<"*::*G4QE::FSI:(D) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
06851           <<G4endl;
06852     //throw G4QException("G4QEnvironment::FSInteract: (7) Charge is not conserved");
06853   }
06854   // ***
06855 #endif
06856   if(gamcnt&&tHadr>1)                           // Only if there are gammas one should act
06857   {
06858     if(maxB+1<nHadr)                            // If maxB<Last, swap theCurH and theLastH
06859     {
06860       G4QHadron* theCurr = theQHadrons[maxB];   // Pointer to the Current Hadron
06861       G4QHadron* theLast = theQHadrons[nHadr-1];// Pointer to the Last Hadron
06862       G4QHadron* curHadr = new G4QHadron(theCurr);//Remember theCurrentHadron to put on top
06863       G4QPDGCode lQP=theLast->GetQPDG();        // The QPDG of the last
06864       if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of PrevHadr
06865       else theCurr->SetQC(theLast->GetQC());    // CurHadrPDG instead of LastHadrPDG
06866       theCurr->Set4Momentum(theLast->Get4Momentum()); // ... continue substitution
06867       theQHadrons.pop_back();                   // Rnt to theLastHadron is excluded from HV
06868       delete theLast;// *!!When kill,DON'T forget to delete the last QHadron as anInst. !!*
06869       theQHadrons.push_back(curHadr);           // The current Hadron, which is the Biggest
06870     }
06871     nHadr=theQHadrons.size();                   // Must be the same
06872     // Now it is necessary to absorb the photon (photons) and try to radiate alpha or evap.
06873     G4LorentzVector gamSum(0.,0.,0.,0.);
06874     if(nHadr>1)for(unsigned gp=0; gp<nHadr-1; gp++)// Find Gumma, remember and kill
06875     {
06876       G4QHadron* theCurr = theQHadrons[gp];       // Pointer to the Current Hadron
06877       G4int hPDG=theCurr->GetPDGCode();
06878 #ifdef debug
06879       G4cout<<"G4QE::FSI:gp#"<<gp<<", PDG="<<hPDG<<", is found"<<G4endl;
06880 #endif
06881       if(hPDG==22)                                // Photon is foun ond the "gp" position
06882       {
06883         gamSum=gamSum+theCurr->Get4Momentum();    // Accumulate the 4Momenta of the photon
06884 #ifdef debug
06885         G4cout<<"G4QE::FSI:Photon gp#"<<gp<<",nH="<<nHadr<<", update gS="<<gamSum<<G4endl;
06886 #endif
06887         unsigned nLast=nHadr-1;                   // position of theLastHadron (gp<nHadr-1)
06888         G4QHadron* theLast = theQHadrons[nLast];  // Pointer to the Last Hadron
06889 #ifdef debug
06890         G4int wcn=0;
06891 #endif
06892         while(nLast>=gp && theLast->GetPDGCode()==22) // "TheLast is a photon too" LOOP
06893         {
06894 #ifdef debug
06895           ++wcn;
06896 #endif
06897           if(nLast>gp)
06898           {
06899             gamSum=gamSum+theLast->Get4Momentum();// Accumulate 4-momentum of theLastPhoton
06900 #ifdef debug
06901             G4cout<<"G4QE::FSI:TheLastPhotonIsFound #"<<wcn<<",update gS="<<gamSum<<G4endl;
06902 #endif
06903           }
06904           theQHadrons.pop_back();                 // Pnt to theLastHadr.is excluded from HV
06905           delete theLast;// *!!When kill,DON'T forget to delete theLastQHadron as anInst!!*
06906           nHadr=theQHadrons.size();
06907           nLast=nHadr-1;
06908           theLast = theQHadrons[nLast];
06909         }
06910         if(nLast>gp)                              // -> swapping with the last
06911         {
06912           G4QPDGCode lQP=theLast->GetQPDG();      // The QPDG of the last
06913           if(lQP.GetPDGCode()!=10) theCurr->SetQPDG(lQP); //CurHadr instead of PrevHadr
06914           else theCurr->SetQC(theLast->GetQC());  // CurHadrPDG instead of LastHadrPDG
06915           theCurr->Set4Momentum(theLast->Get4Momentum()); // ... continue substitution
06916           theQHadrons.pop_back();                 // Pnt to theLastHadr.is excluded from HV
06917           delete theLast;// *!|When kill,DON'T forget to delete theLastQHadron as anInst!!*
06918           nHadr=theQHadrons.size();
06919 #ifdef debug
06920           G4cout<<"G4QE::FSI:RepBy lPDG="<<lQP<<", nH="<<nHadr<<", gS="<<gamSum<<G4endl;
06921 #endif
06922         }
06923       }
06924     }
06925     // @@ Now it is necessary to try to emit alpha or evaporate the residual nucleus
06926     G4QHadron* theLast = theQHadrons[nHadr-1];   // Pointer to the Last Hadron
06927     if(theLast->GetPDGCode()==22)
06928     {
06929       gamSum=gamSum+theLast->Get4Momentum();     // Accumulate 4-momentum of the LastPhoton
06930       theQHadrons.pop_back();                    // Pnt to theLastHadr.is excluded from HV
06931       delete theLast; // *!!When kill,DON'T forget to delete theLastQHadron as an inst.!!*
06932       nHadr=theQHadrons.size();
06933 #ifdef debug
06934       G4cout<<"-Warning-G4QE::FSI: LastPhotonIsKilled, nH="<<nHadr<<",gS="<<gamSum<<G4endl;
06935 #endif
06936       theLast = theQHadrons[nHadr-1];
06937     }
06938     G4int nEx=nHadr-2;                           // position to be exchanged with theLast
06939     while(theLast->GetBaryonNumber()<1 && nEx>=0)// theLastHadron must be a nucleus (A>0)
06940     {
06941       G4QHadron* theEx=theQHadrons[nEx];         // A hadron to be exchanged with theLast
06942       G4LorentzVector ex4Mom=theEx->Get4Momentum();
06943       G4QPDGCode exQPDG=theEx->GetQPDG();
06944       G4QContent exQC=theEx->GetQC();
06945       G4QPDGCode lQP=theLast->GetQPDG();         // The QPDG of the last
06946       if(lQP.GetPDGCode()!=10) theEx->SetQPDG(lQP); //CurHadr instead of PrevHadr
06947       else theEx->SetQC(theLast->GetQC());       // CurHadrPDG instead of LastHadrPDG
06948       theEx->Set4Momentum(theLast->Get4Momentum());
06949       if(exQPDG.GetPDGCode()!=10) theLast->SetQPDG(exQPDG);
06950       else theLast->SetQC(exQC);                 // CurHadrPDG instead of LastHadrPDG
06951       theLast->Set4Momentum(ex4Mom);
06952       nEx--;
06953     }
06954     G4QHadron* curHadr = new G4QHadron(theLast); // Pnt to theCurrentHadron is theLastCopy
06955     theQHadrons.pop_back();                 // Pnt to theLastHadron is excluded from OUTPUT
06956     delete theLast;// *!!When kill,DON'T forget to delete the LastQHadron as an instance!!*
06957     G4int theLB= curHadr->GetBaryonNumber();
06958     G4LorentzVector tR4M=curHadr->Get4Momentum()+gamSum;
06959     G4double tRM=tR4M.m();                       // TotMass of theResidualNucleus to decay
06960     if(theLB>4)
06961     {
06962       G4QContent lrQC=curHadr->GetQC()-G4QContent(6,6,0,0,0,0);
06963       G4QNucleus lrN(lrQC);
06964       G4double lrM=lrN.GetMZNS();
06965       if(tRM>lrM+mAlph)
06966       {
06967         G4LorentzVector lr4M(0.,0.,0.,lrM);
06968         G4LorentzVector al4M(0.,0.,0.,mAlph);
06969         if(!G4QHadron(tR4M).DecayIn2(lr4M,al4M))
06970         {
06971           curHadr->Set4Momentum(tR4M);
06972           EvaporateResidual(curHadr); // delete equivalent
06973 #ifdef fdebug
06974           G4cout<<"G4QE::FSI: After Evap (1) nH="<<theQHadrons.size()<<G4endl;
06975 #endif
06976         }
06977         else
06978         {
06979           delete curHadr;
06980           G4int APDG=lrN.GetPDG();
06981 #ifdef debug
06982           G4cout<<"G4QE::FSI: Final A+alpha, A="<<APDG<<lr4M<<", a="<<al4M<<G4endl;
06983 #endif
06984           G4QHadron* lrH = new G4QHadron(APDG,lr4M);
06985           theQHadrons.push_back(lrH);      // (delete equivalent for lrH)
06986           G4QHadron* alH = new G4QHadron(90002002,al4M);
06987           theQHadrons.push_back(alH);      // (delete equivalent for alH)
06988         }
06989       }
06990       else
06991       {
06992         curHadr->Set4Momentum(tR4M);
06993         EvaporateResidual(curHadr); // delete equivalent
06994 #ifdef fdebug
06995         G4cout<<"G4QE::FSI: After Evap (2) nH="<<theQHadrons.size()<<G4endl;
06996 #endif
06997       }
06998     }
06999     else
07000     {
07001       curHadr->Set4Momentum(tR4M);
07002       EvaporateResidual(curHadr); // delete equivalent
07003 #ifdef fdebug
07004       G4cout<<"G4QE::FSI: After Evap (5) nH="<<theQHadrons.size()<<G4endl;
07005 #endif
07006     }
07007   }
07008   //Now just fill the output theFravment vector (User is responsible to ClearAndDestroy it)
07009   nHadr=theQHadrons.size();
07010 #ifdef chdebug
07011   // *** (8) Charge Control Sum Calculation for the Charge Conservation Check ***
07012   ccContSum=0;                   // Intermediate ChargeControlSum 
07013   cbContSum=0;                   // Intermediate BaryonNumberControlSum
07014   if(nHadr)for(unsigned ic8=0; ic8<nHadr; ic8++) if(!(theQHadrons[ic8]->GetNFragments()))
07015   {
07016     ccContSum+=theQHadrons[ic8]->GetCharge();
07017     cbContSum+=theQHadrons[ic8]->GetBaryonNumber();
07018   }
07019   if(ccContSum-chContSum || cbContSum-bnContSum)
07020   {
07021     G4cout<<"*::*G4QE::FSI:(E) dC="<<ccContSum-chContSum<<",dB="<<cbContSum-bnContSum
07022           <<G4endl;
07023     //throw G4QException("G4QEnvironment::FSInteract: (8) Charge is not conserved");
07024   }
07025   // ***
07026 #endif
07027   if(nHadr) for(unsigned hd=0; hd<theQHadrons.size(); hd++)
07028   {
07029     //G4QHadron* curHadr = new G4QHadron(theQHadrons[hd]);
07030     G4QHadron* curHadr = theQHadrons[hd];
07031     G4int hPDG=curHadr->GetPDGCode();
07032     if(hPDG==22 && fabs(curHadr->Get4Momentum().e())<.00001) // E=0, gamma in the OUTPUT
07033     {
07034       unsigned lin=theQHadrons.size()-1;
07035       G4QHadron* theLast = theQHadrons[lin];// Pointer to theLastHadron in theQHadrVector
07036       if(lin>hd)
07037       {
07038         G4QPDGCode lQP=theLast->GetQPDG();         // The QPDG of the last
07039         if(lQP.GetPDGCode()!=10) curHadr->SetQPDG(lQP); //CurHadr instead of PrevHadr
07040