G4FTFModel.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 //
00027 // $Id$
00028 // GEANT4 tag $Name:  $
00029 //
00030 
00031 // ------------------------------------------------------------
00032 //      GEANT 4 class implementation file
00033 //
00034 //      ---------------- G4FTFModel ----------------
00035 //             by Gunter Folger, May 1998.
00036 //       class implementing the excitation in the FTF Parton String Model
00037 // ------------------------------------------------------------
00038 
00039 #include <utility> 
00040 
00041 #include "G4FTFModel.hh"
00042 #include "G4ios.hh"
00043 #include "G4PhysicalConstants.hh"
00044 #include "G4SystemOfUnits.hh"
00045 #include "G4FTFParameters.hh"
00046 #include "G4FTFParticipants.hh"
00047 #include "G4DiffractiveSplitableHadron.hh"
00048 #include "G4InteractionContent.hh"
00049 #include "G4LorentzRotation.hh"
00050 #include "G4ParticleDefinition.hh"
00051 #include "G4ParticleTable.hh"
00052 #include "G4IonTable.hh"
00053 
00054 // Class G4FTFModel 
00055 
00056 G4FTFModel::G4FTFModel(const G4String& modelName):G4VPartonStringModel(modelName),
00057                          theExcitation(new G4DiffractiveExcitation()),
00058                          theElastic(new G4ElasticHNScattering()),
00059                          theAnnihilation(new G4FTFAnnihilation())
00060 {
00061         G4VPartonStringModel::SetThisPointer(this);
00062         theParameters=0;
00063         NumberOfInvolvedNucleon=0;
00064         NumberOfInvolvedNucleonOfProjectile=0;
00065     SetEnergyMomentumCheckLevels(2*perCent, 150*MeV);
00066 }
00067 
00068 struct DeleteVSplitableHadron { void operator()(G4VSplitableHadron * aH){ delete aH;} };
00069 
00070 G4FTFModel::~G4FTFModel()
00071 {
00072 // Because FTF model can be called for various particles
00073 // theParameters must be erased at the end of each call.
00074 // Thus the delete is also in G4FTFModel::GetStrings() method
00075    if( theParameters   != 0 ) delete theParameters; 
00076    if( theExcitation   != 0 ) delete theExcitation;
00077    if( theElastic      != 0 ) delete theElastic; 
00078    if( theAnnihilation != 0 ) delete theAnnihilation;
00079 
00080 // Erasing of strings created at annihilation
00081    if(theAdditionalString.size() != 0)
00082    {
00083     std::for_each(theAdditionalString.begin(), theAdditionalString.end(), 
00084                   DeleteVSplitableHadron());
00085    }
00086    theAdditionalString.clear();
00087 
00088 // Erasing of target involved nucleons
00089    if( NumberOfInvolvedNucleon != 0)
00090    {
00091     for(G4int i=0; i < NumberOfInvolvedNucleon; i++)
00092     {
00093      G4VSplitableHadron * aNucleon = TheInvolvedNucleon[i]->GetSplitableHadron();
00094      if(aNucleon) delete aNucleon;
00095     }
00096    }
00097 
00098 // Erasing of projectile involved nucleons
00099 /*
00100    if( NumberOfInvolvedNucleonOfProjectile != 0)
00101    {
00102     for(G4int i=0; i < NumberOfInvolvedNucleonOfProjectile; i++)
00103     {
00104      G4VSplitableHadron * aNucleon = TheInvolvedNucleonOfProjectile[i]->GetSplitableHadron();
00105      if(aNucleon) delete aNucleon;
00106     }
00107    }
00108 */
00109 }
00110 
00111 // ------------------------------------------------------------
00112 void G4FTFModel::Init(const G4Nucleus & aNucleus, const G4DynamicParticle & aProjectile)
00113 {
00114         theProjectile = aProjectile;  
00115 
00116         G4double PlabPerParticle(0.);  // Laboratory momentum Pz per particle/nucleon
00117 
00118 /*
00119 G4cout<<"FTF init Pro Name "<<theProjectile.GetDefinition()->GetParticleName()<<G4endl;
00120 G4cout<<"FTF init Pro Mass "<<theProjectile.GetMass()<<" "<<theProjectile.GetMomentum()<<G4endl;
00121 G4cout<<"FTF init Pro B Q  "<<theProjectile.GetDefinition()->GetBaryonNumber()<<" "<<(G4int) theProjectile.GetDefinition()->GetPDGCharge()<<G4endl; 
00122 G4cout<<"FTF init A Z "<<aNucleus.GetA_asInt()<<" "<<aNucleus.GetZ_asInt()<<G4endl;
00123 G4cout<<"             "<<aNucleus.GetN()<<" "<<aNucleus.GetZ()<<G4endl;
00124 //G4int Uzhi; G4cin>>Uzhi;
00125 */
00126 
00127         theParticipants.SetProjectileNucleus(0);
00128         theParticipants.Init(aNucleus.GetA_asInt(),aNucleus.GetZ_asInt());
00129 
00130         if(std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) <= 1) 
00131         { // Projectile is a hadron
00132          PlabPerParticle=theProjectile.GetMomentum().z();
00133 
00134 //         S = sqr( theProjectile.GetMass() ) + sqr( ProtonMass ) +
00135 //                 2*ProtonMass*theProjectile.GetTotalEnergy();
00136         }
00137 
00138 
00139         if(theProjectile.GetDefinition()->GetBaryonNumber() > 1) 
00140         { // Projectile is a nucleus
00141          theParticipants.InitProjectileNucleus(
00142                       theProjectile.GetDefinition()->GetBaryonNumber(),
00143               (G4int) theProjectile.GetDefinition()->GetPDGCharge()    );
00144 
00145          G4ThreeVector BoostVector=theProjectile.GetMomentum()/theProjectile.GetTotalEnergy();
00146          theParticipants.theProjectileNucleus->DoLorentzBoost(BoostVector);
00147 
00148          PlabPerParticle=theProjectile.GetMomentum().z()/
00149                          theProjectile.GetDefinition()->GetBaryonNumber();
00150 
00151 //         S =         2.*sqr( ProtonMass ) + 2*ProtonMass*
00152 //             theProjectile.GetTotalEnergy()/theProjectile.GetDefinition()->GetBaryonNumber();
00153         }
00154 
00155         if(theProjectile.GetDefinition()->GetBaryonNumber() < -1) 
00156         { // Projectile is an anti-nucleus
00157          theParticipants.InitProjectileNucleus(
00158              std::abs(        theProjectile.GetDefinition()->GetBaryonNumber()),
00159              std::abs((G4int) theProjectile.GetDefinition()->GetPDGCharge())    );
00160 
00161          G4ThreeVector BoostVector=theProjectile.GetMomentum()/theProjectile.GetTotalEnergy();
00162 
00163          theParticipants.theProjectileNucleus->StartLoop();
00164          G4Nucleon * aNucleon;
00165          while ( (aNucleon = theParticipants.theProjectileNucleus->GetNextNucleon()) )
00166          {
00167           if(aNucleon->GetDefinition()->GetPDGEncoding() == 2212) // Proton
00168           {aNucleon->SetParticleType(G4AntiProton::AntiProton());} 
00169 
00170           if(aNucleon->GetDefinition()->GetPDGEncoding() == 2112) // Neutron
00171           {aNucleon->SetParticleType(G4AntiNeutron::AntiNeutron());} 
00172          }   // end of while (theParticipant.theProjectileNucleus->GetNextNucleon())
00173 
00174          theParticipants.theProjectileNucleus->DoLorentzBoost(BoostVector);
00175 
00176          PlabPerParticle=         theProjectile.GetMomentum().z()/
00177                          std::abs(theProjectile.GetDefinition()->GetBaryonNumber());
00178 
00179 //         S =        2.*sqr( ProtonMass ) + 2*ProtonMass*
00180 //                      theProjectile.GetTotalEnergy()/
00181 //             std::abs(theProjectile.GetDefinition()->GetBaryonNumber());
00182         }
00183 
00184 // ------------------------------------------------------------------------
00185       if( theParameters != 0 ) delete theParameters;
00186       theParameters = new G4FTFParameters(theProjectile.GetDefinition(),
00187                                           aNucleus.GetA_asInt(),aNucleus.GetZ_asInt(),
00188                                           PlabPerParticle);
00189 //G4cout<<" End Init "<<theProjectile.GetMomentum()<<G4endl;
00190 // To turn on/off (1/0) elastic scattering close/open ...
00191 //theParameters->SetProbabilityOfElasticScatt(0.); 
00192 //G4cout<<" etProbabilityOfElasticScatt "<<theParameters->GetProbabilityOfElasticScatt()<<G4endl;
00193 //G4cout<<" INIT ";
00194 //G4int Uzhi; G4cin>>Uzhi;
00195 
00196    if(theAdditionalString.size() != 0)
00197    {
00198     std::for_each(theAdditionalString.begin(), theAdditionalString.end(), 
00199                   DeleteVSplitableHadron());
00200    }
00201    theAdditionalString.clear();
00202 //G4cout<<" End Init theProjectile.GetMomentum()"<<theProjectile.GetMomentum()<<G4endl;
00203 }
00204 
00205 // ------------------------------------------------------------
00206 G4ExcitedStringVector * G4FTFModel::GetStrings()
00207 { 
00208         G4ExcitedStringVector * theStrings(0);
00209 
00210         theParticipants.GetList(theProjectile,theParameters);
00211 //        StoreInvolvedNucleon();
00212 //G4cout<<" GetList theProjectile.GetMomentum()  GetBaryonNumber() "<<theProjectile.GetMomentum()<<" "<<theProjectile.GetDefinition()->GetBaryonNumber()<<G4endl;
00213         G4bool Success(true);
00214 
00215         if((std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) <= 1) &&
00216                     (theProjectile.GetDefinition()->GetBaryonNumber() != -1)   )
00217         { // Standard variant of FTF for projectile hadron/nucleon
00218 //G4cout<<"Standard variant of FTF for projectile hadron/nucleon"<<G4endl;
00219          ReggeonCascade(); 
00220 //G4cout<<"Success after Reggeon "<<Success<<" PutOnMasShell"<<G4endl;
00221          Success=PutOnMassShell(); 
00222 //G4cout<<"Success after PutOn "<<Success<<" GetResid"<<G4endl;
00223          GetResidualNucleus();
00224         } 
00225 //G4cout<<"Success after GetN "<<Success<<G4endl;
00226 //G4int Uzhi; G4cin>>Uzhi;
00227         if(theProjectile.GetDefinition()->GetBaryonNumber() > 1)
00228         { // Variant of FTF for projectile nuclei
00229 //G4cout<<"Variant of FTF for projectile nuclei"<<G4endl;
00230          StoreInvolvedNucleon();
00231          ReggeonCascade(); 
00232          Success=PutOnMassShell(); 
00233          GetResidualNucleus();
00234         } 
00235 
00236 //        G4bool LowE_Anti_Ion(false);
00237         if(theProjectile.GetDefinition()->GetBaryonNumber() <= -1) 
00238         { // Projectile is Anti-baryon or Anti-Nucleus
00239 //G4cout<<"Projectile is Anti-baryon or Anti-Nucleus "<<G4endl;
00240 //G4cout<<"Be4 Store"<<G4endl;
00241          StoreInvolvedNucleon();
00242          if(theProjectile.GetTotalMomentum()/
00243             std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) > 5000.*MeV)
00244          {// High energy interaction
00245 //G4cout<<"High energy interaction "<<G4endl;
00246 //G4cout<<"Regeon "<<G4endl;
00247           ReggeonCascade(); 
00248 //G4cout<<"Put on mass "<<G4endl;
00249           Success=PutOnMassShell(); 
00250 //G4cout<<"Residual "<<G4endl;
00251           GetResidualNucleus();
00252          }
00253          else
00254          {
00255 //G4cout<<"Low energy interaction "<<G4endl;
00256 //          LowE_Anti_Ion=true;
00257           Success=true;
00258          }
00259         }
00260 //G4cout<<"Before Excite Success "<<Success<<G4endl;
00261         Success=Success && ExciteParticipants();
00262 //G4cout<<"Success ExciteParticipants()? "<<Success<<G4endl;
00263 //        if(LowE_Anti_Ion) Success=Success && GetResidualNucleusAfterAnnihilation();
00264 
00265         if( Success )
00266         {       
00267           theStrings = BuildStrings();
00268 //G4cout<<"BuildStrings OK"<<G4endl;
00269           if( theParameters != 0 )
00270           {
00271            delete theParameters;
00272            theParameters=0;
00273           }
00274          }
00275 /*
00276         if( Success )
00277         {
00278          if( ExciteParticipants() )
00279          {
00280 //G4cout<<"Excite partic OK"<<G4endl;
00281           theStrings = BuildStrings();
00282 //G4cout<<"Build String OK"<<G4endl;
00283           if(LowE_Anti_Ion) GetResidualNucleusAfterAnnihilation();
00284 
00285           if( theParameters != 0 )
00286           {
00287            delete theParameters;
00288            theParameters=0;
00289           }
00290          } else                      // if( ExciteParticipants() )
00291          {     Success=false;}
00292         } else                       // if( Success )
00293         {      Success=false;}
00294 */
00295         if(!Success)   
00296         {
00297            // -------------- Erase the projectile ----------------
00298 //G4cout<<"Erase Proj"<<G4endl;
00299          std::vector<G4VSplitableHadron *> primaries;
00300 
00301          theParticipants.StartLoop();    // restart a loop 
00302          while ( theParticipants.Next() ) 
00303          {
00304             const G4InteractionContent & interaction=theParticipants.GetInteraction();
00305 
00306                          //  do not allow for duplicates ...
00307             if ( primaries.end() == std::find(primaries.begin(), primaries.end(),
00308                                                    interaction.GetProjectile()) )
00309                 primaries.push_back(interaction.GetProjectile());                
00310          }
00311          std::for_each(primaries.begin(), primaries.end(), DeleteVSplitableHadron());
00312          primaries.clear();
00313         }
00314 // -------------- Cleaning of the memory --------------
00315         G4VSplitableHadron * aNucleon = 0;
00316 // -------------- Erase the projectile nucleon --------
00317 /*
00318         G4VSplitableHadron * aNucleon = 0;
00319         for(G4int i=0; i < NumberOfInvolvedNucleonOfProjectile; i++)
00320         {
00321            aNucleon = TheInvolvedNucleonOfProjectile[i]->GetSplitableHadron();
00322            if(aNucleon) delete aNucleon;
00323         } 
00324 
00325         NumberOfInvolvedNucleonOfProjectile=0;
00326 */  // Maybe it will be needed latter------------------
00327 
00328 // -------------- Erase the target nucleons -----------
00329 //G4cout<<"Erase Target Ninv "<<NumberOfInvolvedNucleon<<G4endl;
00330         for(G4int i=0; i < NumberOfInvolvedNucleon; i++)
00331         {
00332            aNucleon = TheInvolvedNucleon[i]->GetSplitableHadron();
00333            if(aNucleon) delete aNucleon;
00334         } 
00335 
00336         NumberOfInvolvedNucleon=0;
00337 //G4cout<<"Go to fragmentation"<<G4endl;
00338         return theStrings;
00339 
00340 }
00341 
00342 //-------------------------------------------------------------------
00343 void G4FTFModel::StoreInvolvedNucleon()                             
00344 { //--- To store nucleons involved in low energy interaction  -------
00345 if(std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) <= 1)
00346 { // the projectile is a hadron -----------
00347 //G4cout<<"the projectile is a hadron"<<G4endl;
00348         NumberOfInvolvedNucleon=0;
00349 
00350         theParticipants.StartLoop();
00351 
00352         while (theParticipants.Next())
00353         {   
00354 //G4cout<<"theParticipants.Next()"<<G4endl;
00355            const G4InteractionContent & collision=theParticipants.GetInteraction();
00356 //G4cout<<"collision=theParticipants.GetInteraction()"<<G4endl;
00357            G4Nucleon * TargetNucleon=collision.GetTargetNucleon();
00358 //G4cout<<"TargetNucleon=collision.GetTargetNucleon()"<<G4endl;
00359 
00360            TheInvolvedNucleon[NumberOfInvolvedNucleon]=TargetNucleon;
00361            NumberOfInvolvedNucleon++;
00362 //G4cout<<G4endl<<"Prim NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
00363         }      // end of while (theParticipants.Next())
00364 
00365         NumberOfInvolvedTargetNucleon=NumberOfInvolvedNucleon;
00366 // ---------------- Calculation of creation time for each target nucleon -----------
00367 //G4cout<<"theParticipants.StartLoop() "<<G4endl;
00368         theParticipants.StartLoop();    // restart a loop
00369 //G4cout<<"theParticipants.Next();"<<G4endl;
00370         theParticipants.Next();
00371         G4VSplitableHadron * primary = theParticipants.GetInteraction().GetProjectile();
00372 //G4cout<<"primary->Get4Momentum() "<<primary->Get4Momentum()<<G4endl;
00373 //G4cout<<"primary->Get4Momentum().pz() "<<primary->Get4Momentum().pz()<<G4endl;
00374 //G4cout<<"primary->Get4Momentum().e() "<<primary->Get4Momentum().e()<<G4endl;
00375 
00376         G4double betta_z=primary->Get4Momentum().pz()/primary->Get4Momentum().e();
00377 //G4cout<<"betta_z "<<betta_z<<G4endl;
00378         primary->SetTimeOfCreation(0.);
00379 
00380         G4double ZcoordinateOfPreviousCollision(0.);
00381         G4double ZcoordinateOfCurrentInteraction(0.);
00382         G4double TimeOfPreviousCollision(0.);
00383         G4double TimeOfCurrentCollision(0);
00384 
00385         theParticipants.theNucleus->StartLoop();
00386         G4Nucleon * aNucleon;
00387         G4bool theFirstInvolvedNucleon(true);
00388         while ( (aNucleon = theParticipants.theNucleus->GetNextNucleon()) )
00389         {
00390 //G4cout<<"aNucleon->AreYouHit() "<<aNucleon->AreYouHit()<<G4endl;
00391           if(aNucleon->AreYouHit())
00392           {
00393             if(theFirstInvolvedNucleon)
00394             {
00395               ZcoordinateOfPreviousCollision=aNucleon->GetPosition().z();
00396 //G4cout<<"ZcoordinateOfPreviousCollision "<<ZcoordinateOfPreviousCollision/fermi<<G4endl;
00397               theFirstInvolvedNucleon=false;
00398             }
00399 
00400             ZcoordinateOfCurrentInteraction=aNucleon->GetPosition().z();
00401 //G4cout<<"ZcoordinateOfCurrentInteraction "<<ZcoordinateOfCurrentInteraction/fermi<<G4endl;
00402 //G4cout<<"TimeOfPreviousCollision "<<TimeOfPreviousCollision<<G4endl;
00403 
00404             // A.R. 18-Oct-2011 : Protection needed for nuclear capture of
00405             //                    anti-proton at rest.
00406             if ( betta_z > 1.0e-10 ) {
00407               TimeOfCurrentCollision=TimeOfPreviousCollision+ 
00408               (ZcoordinateOfCurrentInteraction-ZcoordinateOfPreviousCollision)/betta_z;
00409             } else {
00410               TimeOfCurrentCollision=TimeOfPreviousCollision;
00411             } 
00412 
00413 //G4cout<<"TimeOfCurrentCollision "<<TimeOfCurrentCollision<<G4endl;
00414 // It is assumed that the nucleons are ordered on increasing z-coordinate ------------
00415             aNucleon->GetSplitableHadron()->SetTimeOfCreation(TimeOfCurrentCollision);
00416 
00417             ZcoordinateOfPreviousCollision=ZcoordinateOfCurrentInteraction;
00418             TimeOfPreviousCollision=TimeOfCurrentCollision;
00419           }  // end of if(aNucleon->AreYouHit())
00420         }   // end of while (theParticipant.theNucleus->GetNextNucleon())
00421 //
00422         return;
00423 } // end of if(std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) <= 1)
00424 
00425 // The projectile is a nucleus or an anti-nucleus
00426 //G4cout<<"FTF The projectile is a nucleus or an anti-nucleus"<<G4endl;
00427         NumberOfInvolvedNucleonOfProjectile=0;
00428 
00429         G4V3DNucleus * ProjectileNucleus =theParticipants.GetProjectileNucleus();
00430         ProjectileNucleus->StartLoop();
00431 
00432         G4Nucleon *    ProjectileNucleon;
00433         while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
00434         {
00435          if ( ProjectileNucleon->AreYouHit() )
00436          {  // Projectile nucleon was involved in the interaction.
00437            TheInvolvedNucleonOfProjectile[NumberOfInvolvedNucleonOfProjectile]=
00438                                     ProjectileNucleon;
00439            NumberOfInvolvedNucleonOfProjectile++;
00440          }
00441         } // End of while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
00442 
00443 //------------------
00444         NumberOfInvolvedNucleon=0;
00445 
00446         G4V3DNucleus * TargetNucleus =theParticipants.GetWoundedNucleus();
00447         TargetNucleus->StartLoop();
00448 
00449         G4Nucleon *    TargetNucleon;
00450         while ( (TargetNucleon=TargetNucleus->GetNextNucleon()) )
00451         {
00452          if ( TargetNucleon->AreYouHit() )
00453          {  // Target nucleon was involved in the interaction.
00454            TheInvolvedNucleon[NumberOfInvolvedNucleon]=TargetNucleon;
00455            NumberOfInvolvedNucleon++;
00456          }
00457         } // End of while ( (TargetNucleon=TargetNucleus->GetNextNucleon()) )
00458 //G4cout<<"Store inv "<<NumberOfInvolvedNucleonOfProjectile<<" "<<NumberOfInvolvedNucleon<<G4endl;
00459 
00460         NumberOfInvolvedTargetNucleon=NumberOfInvolvedNucleon;
00461         return;
00462 }                                                             // Uzhi 10 Feb. 2011
00463 
00464 //-------------------------------------------------------------------
00465 void G4FTFModel::ReggeonCascade()                             
00466 { //--- Implementation of the reggeon theory inspired model-------
00467 //G4cout<<"In reggeon"<<G4endl;
00468 
00469         if(std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) > 1) return;
00470 //      For Nucleus-nucleus or Anti-nucleus - nucleus interactions 
00471 //      the cascading will be implemented latter.
00472 
00473         NumberOfInvolvedNucleon=0;
00474 
00475         theParticipants.StartLoop();
00476         while (theParticipants.Next())
00477         {   
00478            const G4InteractionContent & collision=theParticipants.GetInteraction();
00479 
00480            G4Nucleon * TargetNucleon=collision.GetTargetNucleon();
00481 
00482            TheInvolvedNucleon[NumberOfInvolvedNucleon]=TargetNucleon;
00483            NumberOfInvolvedNucleon++;
00484 //G4cout<<"Prim NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
00485            G4double XofWoundedNucleon = TargetNucleon->GetPosition().x();
00486            G4double YofWoundedNucleon = TargetNucleon->GetPosition().y();
00487 
00488            theParticipants.theNucleus->StartLoop();
00489            G4Nucleon * Neighbour(0);
00490 
00491            while ( (Neighbour = theParticipants.theNucleus->GetNextNucleon()) )
00492            {
00493             if(!Neighbour->AreYouHit())
00494             {
00495              G4double impact2= sqr(XofWoundedNucleon - Neighbour->GetPosition().x()) +
00496                                sqr(YofWoundedNucleon - Neighbour->GetPosition().y());
00497 
00498              if(G4UniformRand() < theParameters->GetCofNuclearDestruction()*
00499                 std::exp(-impact2/theParameters->GetR2ofNuclearDestruction()))  
00500              { // The neighbour nucleon is involved in the reggeon cascade
00501 
00502               TheInvolvedNucleon[NumberOfInvolvedNucleon]=Neighbour;
00503               NumberOfInvolvedNucleon++;
00504 //G4cout<<"Seco NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
00505 
00506               G4VSplitableHadron *targetSplitable; 
00507               targetSplitable = new G4DiffractiveSplitableHadron(*Neighbour); 
00508 
00509               Neighbour->Hit(targetSplitable);
00510               targetSplitable->SetStatus(2);     
00511              }
00512             }  // end of if(!Neighbour->AreYouHit())
00513            }   // end of while (theParticipant.theNucleus->GetNextNucleon())
00514         }      // end of while (theParticipants.Next())
00515 
00516         NumberOfInvolvedTargetNucleon=NumberOfInvolvedNucleon;
00517 
00518 // ---------------- Calculation of creation time for each target nucleon -----------
00519         theParticipants.StartLoop();    // restart a loop
00520         theParticipants.Next();
00521         G4VSplitableHadron * primary = theParticipants.GetInteraction().GetProjectile();
00522         G4double betta_z=primary->Get4Momentum().pz()/primary->Get4Momentum().e();
00523         primary->SetTimeOfCreation(0.);
00524 
00525         G4double ZcoordinateOfPreviousCollision(0.);
00526         G4double ZcoordinateOfCurrentInteraction(0.);
00527         G4double TimeOfPreviousCollision(0.);
00528         G4double TimeOfCurrentCollision(0);
00529 
00530         theParticipants.theNucleus->StartLoop();
00531         G4Nucleon * aNucleon;
00532         G4bool theFirstInvolvedNucleon(true);
00533         while ( (aNucleon = theParticipants.theNucleus->GetNextNucleon()) )
00534         {
00535           if(aNucleon->AreYouHit())
00536           {
00537             if(theFirstInvolvedNucleon)
00538             {
00539               ZcoordinateOfPreviousCollision=aNucleon->GetPosition().z();
00540               theFirstInvolvedNucleon=false;
00541             }
00542 
00543             ZcoordinateOfCurrentInteraction=aNucleon->GetPosition().z();
00544             TimeOfCurrentCollision=TimeOfPreviousCollision+ 
00545             (ZcoordinateOfCurrentInteraction-ZcoordinateOfPreviousCollision)/betta_z; 
00546 // It is assumed that the nucleons are ordered on increasing z-coordinate ------------
00547             aNucleon->GetSplitableHadron()->SetTimeOfCreation(TimeOfCurrentCollision);
00548 
00549             ZcoordinateOfPreviousCollision=ZcoordinateOfCurrentInteraction;
00550             TimeOfPreviousCollision=TimeOfCurrentCollision;
00551           }  // end of if(aNucleon->AreYouHit())
00552         }   // end of while (theParticipant.theNucleus->GetNextNucleon())
00553 //
00554 // The algorithm can be improved, but it will be more complicated, and will require
00555 // changes in G4DiffractiveExcitation.cc and G4ElasticHNScattering.cc
00556 }                                                             // Uzhi 26 July 2009
00557 
00558 // ------------------------------------------------------------
00559 G4bool G4FTFModel::PutOnMassShell()
00560 {
00561 //G4cout<<"PutOnMassShell start "<<G4endl;
00562         if(std::abs(theProjectile.GetDefinition()->GetBaryonNumber()) > 1) // !!!!
00563         { // The projectile is a nucleus or an anti-nucleus
00564 //G4cout<<"PutOnMassShell AA "<<G4endl;
00565          G4LorentzVector P_total(0.,0.,0.,0.);
00566 
00567          G4LorentzVector P_participants(0.,0.,0.,0.);
00568          G4int MultiplicityOfParticipants(0);
00569 
00570          G4V3DNucleus * ProjectileNucleus =theParticipants.GetProjectileNucleus();
00571          ProjectileNucleus->StartLoop();
00572 
00573          G4Nucleon *    ProjectileNucleon;
00574          while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
00575          {
00576           if ( ProjectileNucleon->AreYouHit() )
00577           {  // Projectile nucleon was involved in the interaction.
00578            P_total+=ProjectileNucleon->Get4Momentum();
00579            MultiplicityOfParticipants++;
00580            P_participants+=ProjectileNucleon->Get4Momentum();
00581           }
00582          } // End of while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
00583 //G4cout<<"MultParts mom Pr "<<MultiplicityOfParticipants<<" "<<P_participants<<G4endl;
00584 //------------------
00585          G4int ResidualMassNumber(0);
00586          G4int ResidualCharge(0);
00587          ResidualExcitationEnergy=0.;
00588          G4LorentzVector PnuclearResidual(0.,0.,0.,0.);
00589 
00590          G4double ExcitationEnergyPerWoundedNucleon=
00591                   theParameters->GetExcitationEnergyPerWoundedNucleon();
00592 
00593          G4V3DNucleus * TargetNucleus =theParticipants.GetWoundedNucleus();
00594          TargetNucleus->StartLoop();
00595 
00596          G4Nucleon *    TargetNucleon;
00597          while ( (TargetNucleon=TargetNucleus->GetNextNucleon()) )
00598          {
00599           P_total+=TargetNucleon->Get4Momentum();
00600           if ( TargetNucleon->AreYouHit() )
00601           {  // Target nucleon was involved in the interaction.
00602            MultiplicityOfParticipants++;
00603            P_participants+=TargetNucleon->Get4Momentum();
00604            ResidualExcitationEnergy+=ExcitationEnergyPerWoundedNucleon; 
00605           }
00606           else
00607           {
00608            ResidualMassNumber+=1;
00609            ResidualCharge+=(G4int) TargetNucleon->GetDefinition()->GetPDGCharge();
00610            PnuclearResidual+=TargetNucleon->Get4Momentum();
00611           }
00612          } // End of while ( (TargetNucleon=TargetNucleus->GetNextNucleon()) )
00613 
00614          G4double ResidualMass(0.);
00615          if(ResidualMassNumber == 0)
00616          {
00617           ResidualMass=0.;
00618           ResidualExcitationEnergy=0.;
00619          }
00620          else
00621          {
00622           ResidualMass=G4ParticleTable::GetParticleTable()->GetIonTable()->
00623                               GetIonMass(ResidualCharge ,ResidualMassNumber);
00624           if(ResidualMassNumber == 1) {ResidualExcitationEnergy=0.;}
00625          }
00626 //      ResidualMass +=ResidualExcitationEnergy; // Will be given after checks
00627 
00628 //G4cout<<"MultPars mom+Tr  "<<MultiplicityOfParticipants<<" "<<P_participants<<G4endl;
00629 //G4cout<<"Res              "<<ResidualMassNumber<<" "<<PnuclearResidual<<G4endl;
00630 //G4cout<<"P_total "<<P_total<<G4endl;
00631 
00632 //G4cout<<"Rez A Z M E* "<<ResidualMassNumber<<" "<<ResidualCharge<<" "<<ResidualMass<<" "<<ResidualExcitationEnergy<<G4endl;
00633 //--------------
00634          G4double SqrtS=P_total.mag();
00635          G4double     S=P_total.mag2();
00636 
00637 //         if(theProjectile.GetDefinition()->GetBaryonNumber() > 1)
00638          { // For nucleus-nucleus interactions
00639           G4double MassOfParticipants=P_participants.mag();
00640           G4double MassOfParticipants2=sqr(MassOfParticipants);
00641 
00642 //G4cout<<"ResidualMass + MassOfParticipants "<<ResidualMass + MassOfParticipants<<G4endl;
00643           if(SqrtS < ResidualMass + MassOfParticipants) {return false;}
00644 
00645           if(SqrtS < ResidualMass+ResidualExcitationEnergy + MassOfParticipants)
00646           {ResidualExcitationEnergy=0.;}
00647 
00648           ResidualMass +=ResidualExcitationEnergy; 
00649 //G4cout<<"Rez A Z M E* "<<ResidualMassNumber<<" "<<ResidualCharge<<" "<<ResidualMass<<" "<<ResidualExcitationEnergy<<G4endl;
00650 
00651           G4double ResidualMass2=sqr(ResidualMass);
00652 
00653           G4LorentzRotation toCms(-1*P_total.boostVector());
00654 
00655           G4LorentzVector Pcms=toCms*P_participants;
00656 //G4cout<<"Ppart in CMS "<<Ptmp<<G4endl;
00657 
00658           if ( Pcms.pz() <= 0. )                                
00659           {  // "String" moving backwards in  CMS, abort collision !!
00660            //G4cout << " abort ColliDeleteVSplitableHadronsion!! " << G4endl;
00661            return false; 
00662           }
00663 
00664           toCms.rotateZ(-1*Pcms.phi());              // Uzhi 5.12.09
00665           toCms.rotateY(-1*Pcms.theta());            // Uzhi 5.12.09
00666 
00667 //G4cout<<"Mpa M res "<<ResidualMass<<" "<<MassOfParticipants<<" "<<SqrtS<<G4endl;
00668           G4LorentzRotation toLab(toCms.inverse());
00669 
00670           G4double DecayMomentum2= 
00671                       sqr(S)+sqr(MassOfParticipants2)+ sqr(ResidualMass2) -
00672                           2.*S*MassOfParticipants2 - 2.*S*ResidualMass2 
00673                               -2.*MassOfParticipants2*ResidualMass2;
00674 
00675           if(DecayMomentum2 < 0.) return false;
00676 
00677           DecayMomentum2/=(4.*S);
00678           G4double DecayMomentum = std::sqrt(DecayMomentum2);
00679 //G4cout<<"DecayMomentum "<<DecayMomentum<<G4endl;
00680 
00681           G4LorentzVector New_P_participants(0.,0.,DecayMomentum,
00682                                              std::sqrt(DecayMomentum2+MassOfParticipants2));
00683           G4LorentzVector New_PnuclearResidual(0.,0.,-DecayMomentum,
00684                                              std::sqrt(DecayMomentum2+ResidualMass2));
00685 
00686 //G4cout<<"MultPars mom     "<<MultiplicityOfParticipants<<" "<<New_P_participants<<G4endl;
00687 //G4cout<<"Res              "<<ResidualMassNumber<<" "<<New_PnuclearResidual<<G4endl;
00688           New_P_participants.transform(toLab);
00689           New_PnuclearResidual.transform(toLab);
00690 
00691 //G4cout<<"MultPars mom     "<<MultiplicityOfParticipants<<" "<<New_P_participants<<G4endl;
00692 //G4cout<<"Res              "<<ResidualMassNumber<<" "<<New_PnuclearResidual<<G4endl;
00693 
00694           G4LorentzVector DeltaP_participants=(New_P_participants - P_participants)/
00695                                               ((G4double) MultiplicityOfParticipants);
00696 
00697 //G4cout<<"DeltaP_participants "<<DeltaP_participants<<G4endl;
00698 //-------------
00699           ProjectileNucleus->StartLoop();
00700           while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
00701           {
00702            if ( ProjectileNucleon->AreYouHit() )
00703            {  // Projectile nucleon was involved in the interaction.
00704             G4LorentzVector Ptmp=ProjectileNucleon->Get4Momentum() + DeltaP_participants;
00705             ProjectileNucleon->GetSplitableHadron()->Set4Momentum(Ptmp);
00706             ProjectileNucleon->SetMomentum(Ptmp);
00707            }
00708           } // End of while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
00709 
00710 //-------------
00711           TargetNucleus->StartLoop();
00712           while ( (TargetNucleon=TargetNucleus->GetNextNucleon()) )
00713           {
00714            if ( TargetNucleon->AreYouHit() )
00715            {  // Target nucleon was involved in the interaction.
00716             G4LorentzVector Ptmp=TargetNucleon->Get4Momentum() + DeltaP_participants;
00717             TargetNucleon->GetSplitableHadron()->Set4Momentum(Ptmp);
00718            }
00719           } // End of while ( (TargetNucleon=TargetNucleus->GetNextNucleon()) )
00720 
00721           Residual4Momentum = New_PnuclearResidual;        
00722 //          return true;
00723          } // End of if(theProjectile.GetDefinition()->GetBaryonNumber() > 1)
00724 
00725          return true;
00726         }
00727 //---------------------------------------------------------------------
00728 // -------- The projectile is hadron, or baryon, or anti-baryon -------
00729 // -------------- Properties of the projectile ------------------------
00730         theParticipants.StartLoop();    // restart a loop
00731         theParticipants.Next();
00732         G4VSplitableHadron * primary = theParticipants.GetInteraction().GetProjectile();
00733         G4LorentzVector Pprojectile=primary->Get4Momentum();
00734 
00735 // 13.06.2012 G4bool ProjectileIsAntiBaryon = primary->GetDefinition()->GetBaryonNumber() < 0;
00736 
00737 //G4cout<<"PutOnMass Pprojectile "<<Pprojectile<<G4endl;
00738 // To get original projectile particle
00739 
00740         if(Pprojectile.z() < 0.){return false;}
00741 
00742         G4double Mprojectile  = Pprojectile.mag();
00743         G4double M2projectile = Pprojectile.mag2();
00744 //-------------------------------------------------------------
00745         G4LorentzVector Psum      = Pprojectile;
00746 
00747         G4double        SumMasses = Mprojectile + 20.*MeV; // 13.12.09
00748                                                // Separation energy for projectile
00749 //        if(ProjectileIsAntiBaryon) {SumMasses = Mprojectile;}
00750 //G4cout<<"SumMasses Pr "<<SumMasses<<G4endl;
00751 //--------------- Target nucleus ------------------------------
00752         G4V3DNucleus *theNucleus = GetWoundedNucleus();
00753         G4int ResidualMassNumber=theNucleus->GetMassNumber();
00754         G4int ResidualCharge    =theNucleus->GetCharge();
00755 
00756         ResidualExcitationEnergy=0.;
00757         G4LorentzVector Ptarget(0.,0.,0.,0.);
00758         G4LorentzVector PnuclearResidual(0.,0.,0.,0.); // Uzhi 12.06.2012
00759 
00760         G4double ExcitationEnergyPerWoundedNucleon=
00761                   theParameters->GetExcitationEnergyPerWoundedNucleon();
00762 
00763 //G4cout<<"ExcitationEnergyPerWoundedNucleon "<<ExcitationEnergyPerWoundedNucleon<<G4endl;
00764 
00765         theNucleus->StartLoop();
00766 
00767         while (G4Nucleon * aNucleon = theNucleus->GetNextNucleon())
00768         {
00769          Ptarget+=aNucleon->Get4Momentum();
00770 
00771          if(aNucleon->AreYouHit())
00772          {   // Involved nucleons
00773 //G4cout<<"PutOn Tr "<<aNucleon->Get4Momentum()<<G4endl;
00774 //        Psum += aNucleon->Get4Momentum();                       // Uzhi 20 Sept.
00775 //          if(!ProjectileIsAntiBaryon)                           // Uzhi 13.06.2012
00776 //          {
00777            SumMasses += std::sqrt(sqr(aNucleon->GetDefinition()->GetPDGMass()) //Uzhi 12.06.2012
00778                      +  aNucleon->Get4Momentum().perp2());                     //Uzhi 12.06.2012
00779            SumMasses += 20.*MeV;   // 13.12.09 Separation energy for a nucleon
00780            ResidualExcitationEnergy+=ExcitationEnergyPerWoundedNucleon;
00781 /*                                                                             //Uzhi 13.06.2012
00782           } else 
00783           {
00784            SumMasses += aNucleon->Get4Momentum().mag();           // 4.12.2010
00785            G4LorentzVector tmp=aNucleon->Get4Momentum();
00786            tmp.setE(aNucleon->Get4Momentum().mag());   // It is need to save mass 6.12.2011
00787            aNucleon->SetMomentum(tmp);
00788           }
00789 */                                                                            //Uzhi 13.06.2012
00790 
00791           ResidualMassNumber--;
00792           ResidualCharge-=(G4int) aNucleon->GetDefinition()->GetPDGCharge();
00793          }
00794          else
00795          {   // Spectator nucleons
00796           PnuclearResidual += aNucleon->Get4Momentum();          // Uzhi 12.06.2012
00797          }  // end of if(!aNucleon->AreYouHit())
00798         }   // end of while (theNucleus->GetNextNucleon())
00799 
00800         Psum += Ptarget;   
00801         PnuclearResidual.setPz(0.); PnuclearResidual.setE(0.);   // Uzhi 12.06.2012
00802 //G4cout<<"ResidualCharge ,ResidualMassNumber "<<ResidualCharge<<" "<<ResidualMassNumber<<" "<<Ptarget<<" "<<PnuclearResidual<<G4endl;
00803 
00804         G4double ResidualMass(0.);
00805         if(ResidualMassNumber == 0)
00806         {
00807          ResidualMass=0.;
00808          ResidualExcitationEnergy=0.;
00809         }
00810         else
00811         {
00812          ResidualMass=G4ParticleTable::GetParticleTable()->GetIonTable()->
00813                               GetIonMass(ResidualCharge ,ResidualMassNumber);
00814          if(ResidualMassNumber == 1) {ResidualExcitationEnergy=0.;}
00815         }
00816  
00817 //      ResidualMass +=ResidualExcitationEnergy; // Will be given after checks
00818 //G4cout<<"SumMasses And ResidualMass "<<SumMasses<<" "<<ResidualMass<<G4endl;
00819         SumMasses += std::sqrt(sqr(ResidualMass)+PnuclearResidual.perp2()); // Uzhi 16.05.2013
00820 //G4cout<<"SumMasses + ResM "<<SumMasses<<G4endl;
00821 //G4cout<<"Psum "<<Psum<<G4endl;
00822 //-------------------------------------------------------------
00823 
00824         G4double SqrtS=Psum.mag();
00825         G4double     S=Psum.mag2();
00826 
00827 //G4cout<<"SqrtS < SumMasses "<<SqrtS<<" "<<SumMasses<<G4endl;
00828 
00829         if(SqrtS < SumMasses)      {return false;} // It is impossible to simulate
00830                                                    // after putting nuclear nucleons
00831                                                    // on mass-shell
00832 
00833         SumMasses -= std::sqrt(sqr(ResidualMass)+PnuclearResidual.perp2()); // Uzhi 16.05.2013
00834         SumMasses += std::sqrt(sqr(ResidualMass+ResidualExcitationEnergy)
00835                     +PnuclearResidual.perp2());                             // Uzhi 16.05.2013
00836         if(SqrtS < SumMasses)                                              // Uzhi 12.06.2012
00837         {
00838          SumMasses -= std::sqrt(sqr(ResidualMass+ResidualExcitationEnergy)
00839                      +PnuclearResidual.perp2());                            // Uzhi 16.05.2013
00840          SumMasses += std::sqrt(sqr(ResidualMass)+PnuclearResidual.perp2());// Uzhi 16.05.2013
00841          ResidualExcitationEnergy=0.;
00842         }
00843 
00844         ResidualMass +=ResidualExcitationEnergy;
00845 //      SumMasses    +=ResidualExcitationEnergy;                           // Uzhi 12.06.2012
00846 //G4cout<<"ResidualMass SumMasses ResidualExcitationEnergy "<<ResidualMass<<" "<<SumMasses<<" "<<ResidualExcitationEnergy<<G4endl;
00847 //-------------------------------------------------------------
00848 // Sampling of nucleons what are transfered to delta-isobars --
00849         G4int MaxNumberOfDeltas = (int)((SqrtS - SumMasses)/(400.*MeV));
00850         G4int NumberOfDeltas(0);
00851 //G4cout<<"MaxNumberOfDeltas "<<MaxNumberOfDeltas<<G4endl;
00852         if(theNucleus->GetMassNumber() != 1)
00853         {
00854 //G4cout<<"NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
00855           G4double ProbDeltaIsobar(0.05);                                  // Uzhi 6.07.2012
00856           for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
00857           {
00858             if((G4UniformRand() < ProbDeltaIsobar)&&(NumberOfDeltas < MaxNumberOfDeltas))
00859             {
00860               NumberOfDeltas++;
00861               G4VSplitableHadron * targetSplitable=TheInvolvedNucleon[i]->GetSplitableHadron();
00862               G4double MassDec=std::sqrt(sqr(targetSplitable->GetDefinition()->GetPDGMass())
00863                                            + targetSplitable->Get4Momentum().perp2());
00864 
00865               G4int PDGcode = targetSplitable->GetDefinition()->GetPDGEncoding();
00866               G4ParticleDefinition* Old_def = targetSplitable->GetDefinition();
00867 
00868               G4int newPDGcode = PDGcode/10; newPDGcode=newPDGcode*10+4; // Delta
00869               G4ParticleDefinition* ptr = 
00870                  G4ParticleTable::GetParticleTable()->FindParticle(newPDGcode);
00871               targetSplitable->SetDefinition(ptr);
00872               G4double MassInc=std::sqrt(sqr(targetSplitable->GetDefinition()->GetPDGMass())
00873                                            + targetSplitable->Get4Momentum().perp2());
00874               if(SqrtS < SumMasses + MassInc - MassDec)                    // Uzhi 12.06.2012
00875               { // Change cannot be acsepted!
00876                targetSplitable->SetDefinition(Old_def);
00877                ProbDeltaIsobar = 0.;
00878               } else
00879               { // Change is acsepted.
00880                SumMasses += (MassInc - MassDec);
00881               }
00882             } 
00883           }   // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
00884         }   // end of if(theNucleus.GetMassNumber() != 1)
00885 
00886 //-------------------------------------------------------------
00887 
00888         G4LorentzRotation toCms(-1*Psum.boostVector());
00889         G4LorentzVector Ptmp=toCms*Pprojectile;
00890         if ( Ptmp.pz() <= 0. )                                
00891         {  // "String" moving backwards in  CMS, abort collision !!
00892            //G4cout << " abort ColliDeleteVSplitableHadronsion!! " << G4endl;
00893          return false; 
00894         }
00895 
00896         G4LorentzRotation toLab(toCms.inverse());
00897 
00898         Ptmp=toCms*Ptarget;                      
00899         G4double YtargetNucleus=Ptmp.rapidity();
00900 //G4cout<<"YtargetNucleus "<<YtargetNucleus<<G4endl;
00901 //-------------------------------------------------------------
00902 //------- Ascribing of the involved nucleons Pt and Xminus ----
00903         G4double Dcor        = theParameters->GetDofNuclearDestruction()/
00904                                                theNucleus->GetMassNumber();
00905 
00906         G4double AveragePt2  = theParameters->GetPt2ofNuclearDestruction();
00907         G4double maxPtSquare = theParameters->GetMaxPt2ofNuclearDestruction();
00908 //G4cout<<"Dcor "<<theParameters->GetDofNuclearDestruction()<<" "<<Dcor<<" AveragePt2 "<<AveragePt2<<G4endl;
00909         G4double M2target(0.);
00910         G4double WminusTarget(0.);
00911         G4double WplusProjectile(0.);
00912 
00913         G4int    NumberOfTries(0);
00914         G4double ScaleFactor(1.);
00915         G4bool OuterSuccess(true);
00916         do    // while (!OuterSuccess)
00917         {
00918           OuterSuccess=true;
00919 
00920           do    // while (SqrtS < Mprojectile + std::sqrt(M2target))
00921           {     // while (DecayMomentum < 0.)
00922 
00923             NumberOfTries++;
00924 
00925             if(NumberOfTries == 100*(NumberOfTries/100))   // 100
00926             { // At large number of tries it would be better to reduce the values
00927               ScaleFactor/=2.;
00928               Dcor       *=ScaleFactor;
00929               AveragePt2 *=ScaleFactor;
00930             }
00931 
00932             G4ThreeVector PtSum(0.,0.,0.);
00933             G4double XminusSum(0.);
00934             G4double Xminus(0.);
00935             G4bool InerSuccess=true;
00936 
00937             do      // while(!InerSuccess);
00938             {
00939              InerSuccess=true;
00940 
00941              PtSum    =G4ThreeVector(0.,0.,0.);
00942              XminusSum=0.;
00943 
00944              for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
00945              {
00946                G4Nucleon * aNucleon = TheInvolvedNucleon[i];
00947 
00948                G4ThreeVector tmpPt = GaussianPt(AveragePt2, maxPtSquare);
00949                PtSum += tmpPt;
00950 
00951                G4ThreeVector tmpX=GaussianPt(Dcor*Dcor, 1.);
00952                Xminus=tmpX.x();
00953                XminusSum+=Xminus;
00954 
00955                G4LorentzVector tmp(tmpPt.x(),tmpPt.y(),Xminus,     // 6 Dec.2010
00956                                    aNucleon->Get4Momentum().e());  // 6 Dec.2010
00957 
00958                aNucleon->SetMomentum(tmp);
00959              }   // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
00960 
00961 //---------------------------------------------------------------------------
00962              G4double DeltaX = (PtSum.x()-PnuclearResidual.x())/NumberOfInvolvedNucleon;
00963              G4double DeltaY = (PtSum.y()-PnuclearResidual.y())/NumberOfInvolvedNucleon;
00964              G4double DeltaXminus(0.);
00965 
00966              if(ResidualMassNumber == 0)
00967              {
00968               DeltaXminus = (XminusSum-1.)/NumberOfInvolvedNucleon;
00969              }
00970              else
00971              {
00972               DeltaXminus = -1./theNucleus->GetMassNumber();
00973              }
00974 
00975              XminusSum=1.;
00976              M2target =0.;
00977 
00978              for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
00979              {
00980                G4Nucleon * aNucleon = TheInvolvedNucleon[i];
00981 
00982                Xminus = aNucleon->Get4Momentum().pz() - DeltaXminus;
00983                XminusSum-=Xminus;               
00984 
00985                if(ResidualMassNumber == 0)               
00986                {
00987                 if((Xminus <= 0.)   || (Xminus > 1.))    {InerSuccess=false; break;}
00988                } else
00989                {
00990                 if((Xminus <= 0.)   || (Xminus > 1.) || 
00991                    (XminusSum <=0.) || (XminusSum > 1.)) {InerSuccess=false; break;}
00992                }                                          
00993 
00994                G4double Px=aNucleon->Get4Momentum().px() - DeltaX;
00995                G4double Py=aNucleon->Get4Momentum().py() - DeltaY;
00996 
00997 //               if(!ProjectileIsAntiBaryon)                          // 4.12.2010
00998 //               {
00999                 M2target +=(aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass()*
01000                             aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass()  + 
01001                             Px*Px + Py*Py)/Xminus;
01002 /*
01003                } else
01004                {
01005                 M2target +=(aNucleon->Get4Momentum().e() *
01006                             aNucleon->Get4Momentum().e()  +      // 6.12.2010
01007                             Px*Px + Py*Py)/Xminus;
01008                }
01009 */
01010                G4LorentzVector tmp(Px,Py,Xminus,aNucleon->Get4Momentum().e()); // 6.12.2010
01011                aNucleon->SetMomentum(tmp);
01012              }   // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01013 
01014              if(InerSuccess && (ResidualMassNumber != 0))
01015              {
01016               M2target +=(sqr(ResidualMass) + PnuclearResidual.perp2())/XminusSum; // Uzhi 16.05.2013
01017              }
01018 //G4cout<<"InerSuccess "<<InerSuccess<<" "<<SqrtS<<" "<<Mprojectile + std::sqrt(M2target)<<" "<<std::sqrt(M2target)<<G4endl;
01019 //G4int Uzhi;G4cin>>Uzhi;
01020             } while(!InerSuccess);
01021           } while (SqrtS < Mprojectile + std::sqrt(M2target));
01022 //-------------------------------------------------------------
01023           G4double DecayMomentum2= S*S+M2projectile*M2projectile+M2target*M2target
01024                                     -2.*S*M2projectile - 2.*S*M2target 
01025                                          -2.*M2projectile*M2target;
01026 
01027           WminusTarget=(S-M2projectile+M2target+std::sqrt(DecayMomentum2))/2./SqrtS;
01028           WplusProjectile=SqrtS - M2target/WminusTarget;
01029 
01030           G4double Pzprojectile=WplusProjectile/2. - M2projectile/2./WplusProjectile;// 8.06.11
01031           G4double Eprojectile =WplusProjectile/2. + M2projectile/2./WplusProjectile;// 8.06.11
01032           G4double Yprojectile=0.5*std::log((Eprojectile+Pzprojectile)/
01033                                             (Eprojectile-Pzprojectile));            // 1.07.11
01034 
01035 //G4cout<<"Yprojectile "<<Yprojectile<<G4endl;
01036 //G4LorentzVector TestPprojectile=Pprojectile;
01037 //TestPprojectile.setPz(Pzprojectile);  TestPprojectile.setE(Eprojectile);
01038 
01039 //G4cout<<"DecayMomentum2 "<<DecayMomentum2<<G4endl;
01040 //G4cout<<"WminusTarget WplusProjectile "<<WminusTarget<<" "<<WplusProjectile<<G4endl;
01041 //G4int Uzhi;G4cin>>Uzhi;
01042 //-------------------------------------------------------------
01043           for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01044           {
01045            G4Nucleon * aNucleon = TheInvolvedNucleon[i];
01046            G4LorentzVector tmp=aNucleon->Get4Momentum();
01047 
01048            G4double Mt2(0.);
01049 
01050 //           if(!ProjectileIsAntiBaryon)                          // 4.12.2010
01051 //           {
01052             Mt2 = sqr(tmp.x())+sqr(tmp.y())+
01053                   sqr(aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass());
01054 /*
01055            } else
01056            {
01057             Mt2 = sqr(tmp.x())+sqr(tmp.y())+                   // 4.12.2010
01058                   sqr(aNucleon->Get4Momentum().e());    // sqr
01059            }
01060 */
01061            G4double Xminus=tmp.z();
01062 
01063            G4double Pz=-WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
01064            G4double E = WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
01065            G4double YtargetNucleon=0.5*std::log((E+Pz)/(E-Pz));   // 1.07.11 //Uzhi 20 Sept.
01066 
01067 //G4cout<<"YtargetNucleon "<<YtargetNucleon<<G4endl;
01068 //G4cout<<"YtargetNucleon-YtargetNucleus "<<YtargetNucleon-YtargetNucleus<<G4endl;
01069 //G4cout<<"Yprojectile  YtargetNucleon "<<Yprojectile<<" "<<YtargetNucleon<<G4endl;
01070 if((std::abs(YtargetNucleon-YtargetNucleus) > 2) || 
01071             (Yprojectile  < YtargetNucleon))        {OuterSuccess=false; break;} // 1.07.11
01072 
01073           }   // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01074 //if(ProjectileIsAntiBaryon) {G4int Uzhi;G4cin>>Uzhi;}
01075         } while(!OuterSuccess);
01076 
01077 //-------------------------------------------------------------
01078         G4double Pzprojectile=WplusProjectile/2. - M2projectile/2./WplusProjectile;
01079         G4double Eprojectile =WplusProjectile/2. + M2projectile/2./WplusProjectile;
01080         Pprojectile.setPz(Pzprojectile);  Pprojectile.setE(Eprojectile);
01081 //G4cout<<"Proj after in CMS "<<Pprojectile<<G4endl;
01082 
01083         Pprojectile.transform(toLab);       // The work with the projectile
01084         primary->Set4Momentum(Pprojectile); // is finished at the moment.
01085 //G4cout<<"Final proj mom "<<primary->Get4Momentum()<<G4endl;
01086 
01087 //-------------------------------------------------------------
01088         G4ThreeVector Residual3Momentum(0.,0.,1.);
01089 
01090         for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01091         {
01092            G4Nucleon * aNucleon = TheInvolvedNucleon[i];
01093            G4LorentzVector tmp=aNucleon->Get4Momentum();
01094 //G4cout<<"trg "<<aNucleon->Get4Momentum()<<G4endl;
01095            Residual3Momentum-=tmp.vect();
01096 
01097            G4double Mt2(0.);
01098 
01099 //           if(!ProjectileIsAntiBaryon)                          // 4.12.2010
01100 //           {
01101             Mt2 = sqr(tmp.x())+sqr(tmp.y())+
01102                   sqr(aNucleon->GetSplitableHadron()->GetDefinition()->GetPDGMass());
01103 /*
01104            } else
01105            {
01106             Mt2 = sqr(tmp.x())+sqr(tmp.y())+                   // 4.12.2010
01107                   aNucleon->Get4Momentum().e()*aNucleon->Get4Momentum().e();
01108            }
01109 */
01110            G4double Xminus=tmp.z();
01111 
01112            G4double Pz=-WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
01113            G4double E = WminusTarget*Xminus/2. + Mt2/(2.*WminusTarget*Xminus);
01114 
01115            tmp.setPz(Pz); 
01116            tmp.setE(E);
01117 //G4cout<<"Targ after in CMS "<<tmp<<G4endl;
01118            tmp.transform(toLab);
01119 
01120            aNucleon->SetMomentum(tmp);
01121 //G4cout<<"Targ after in LAB "<<aNucleon->Get4Momentum()<<G4endl;
01122            G4VSplitableHadron * targetSplitable=aNucleon->GetSplitableHadron();
01123            targetSplitable->Set4Momentum(tmp);
01124            
01125         }   // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01126 
01127 //G4cout<<"ResidualMassNumber and Mom "<<ResidualMassNumber<<" "<<Residual3Momentum<<G4endl;
01128         G4double Mt2Residual=sqr(ResidualMass) +
01129                                  sqr(Residual3Momentum.x())+sqr(Residual3Momentum.y());
01130 //==========================
01131 //G4cout<<"WminusTarget Residual3Momentum.z() "<<WminusTarget<<" "<<Residual3Momentum.z()<<G4endl;
01132         G4double PzResidual=0.;
01133         G4double EResidual =0.;
01134         if(ResidualMassNumber != 0)
01135         {
01136          PzResidual=-WminusTarget*Residual3Momentum.z()/2. + 
01137                              Mt2Residual/(2.*WminusTarget*Residual3Momentum.z());
01138          EResidual = WminusTarget*Residual3Momentum.z()/2. + 
01139                              Mt2Residual/(2.*WminusTarget*Residual3Momentum.z());
01140         }
01141 //==========================
01142         Residual4Momentum.setPx(Residual3Momentum.x());
01143         Residual4Momentum.setPy(Residual3Momentum.y());
01144         Residual4Momentum.setPz(PzResidual); 
01145         Residual4Momentum.setE(EResidual);
01146 //G4cout<<"Residual4Momentum in CMS Y "<<Residual4Momentum.beta()<<G4endl;
01147 //G4int Uzhi; G4cin>>Uzhi;
01148         Residual4Momentum.transform(toLab);
01149 //G4cout<<"Residual4Momentum in Lab "<<Residual4Momentum<<G4endl;
01150 //G4int Uzhi; G4cin>>Uzhi;
01151 //-------------------------------------------------------------
01152  return true;
01153 }
01154 
01155 // ------------------------------------------------------------
01156 G4bool G4FTFModel::ExciteParticipants()
01157 {
01158 //G4cout<<"G4FTFModel::ExciteParticipants() "<<G4endl;
01159         G4bool Successfull(true);  //(false); // 1.07.11
01160 
01161         theParticipants.StartLoop();
01162         G4int CurrentInteraction(0);   // Uzhi Feb26
01163 
01164         G4int MaxNumOfInelCollisions=G4int(theParameters->GetMaxNumberOfCollisions());
01165 //G4cout<<"MaxNumOfInelCollisions "<<MaxNumOfInelCollisions<<G4endl;
01166         G4double NumberOfInel(0.);
01167 //
01168         if(MaxNumOfInelCollisions > 0)  
01169         {   //  Plab > Pbound, Normal application of FTF is possible
01170          G4double ProbMaxNumber=theParameters->GetMaxNumberOfCollisions()-
01171                                                   MaxNumOfInelCollisions;
01172          if(G4UniformRand() < ProbMaxNumber) {MaxNumOfInelCollisions++;}
01173          NumberOfInel=MaxNumOfInelCollisions;
01174 //G4cout<<"Plab > Pbound MaxNumOfInelCollisions "<<MaxNumOfInelCollisions<<G4endl;
01175         } else
01176         {   //  Plab < Pbound, Normal application of FTF is impossible, 
01177             //                 low energy corrections applied.
01178          if(theParticipants.theNucleus->GetMassNumber() > 1)
01179          {
01180           NumberOfInel = theParameters->GetProbOfInteraction();
01181           MaxNumOfInelCollisions = 1;
01182          } else
01183          { // Special case for hadron-nucleon interactions
01184           NumberOfInel = 1.;
01185           MaxNumOfInelCollisions = 1;
01186 //G4cout<<"Plab < Pbound MaxNumOfInelCollisions "<<MaxNumOfInelCollisions<<G4endl;
01187          }
01188         }  // end of if(MaxNumOfInelCollisions > 0)
01189 //
01190 //G4cout<<"MaxNumOfInelCollisions MaxNumOfInelCollisions "<<MaxNumOfInelCollisions<<" "<<MaxNumOfInelCollisions<<G4endl;
01191 
01192         while (theParticipants.Next())
01193         {          
01194            CurrentInteraction++;
01195            const G4InteractionContent & collision=theParticipants.GetInteraction();
01196 
01197            G4VSplitableHadron * projectile=collision.GetProjectile();
01198            G4VSplitableHadron * target=collision.GetTarget();
01199 //
01200 //G4cout<<"Ppr tr "<<projectile<<" "<<target<<G4endl;
01201 //G4cout<<"theInter Time "<<collision.GetInteractionTime()/fermi<<G4endl;
01202 //G4cout<<"Int Status    "<<collision.GetStatus()<<" "<<CurrentInteraction<<G4endl;
01203 //G4cout<<"Proj M "<<projectile->Get4Momentum()<<" "<<projectile->Get4Momentum().mag()<<G4endl;
01204 //G4cout<<"Targ M "<<target->Get4Momentum()<<" "<<target->Get4Momentum().mag()<<G4endl;
01205 //G4cout<<"ProbabilityOfElasticScatt "<<theParameters->GetProbabilityOfElasticScatt()<<G4endl;
01206 //G4cout<<"ProbabilityOfAnnihilation "<<theParameters->GetProbabilityOfAnnihilation()<<G4endl;
01207 //G4cout<<"projectile->GetStatus target->GetStatus "<<projectile->GetStatus()<<" "<<target->GetStatus()<<G4endl;
01208 //if((projectile->GetStatus() == 1) && (target->GetStatus() ==1))
01209 //
01210 if(collision.GetStatus())                                          // Uzhi Feb26
01211 {
01212 
01213 //theParameters->SetProbabilityOfElasticScatt(1.);
01214 //G4cout<<"before pro "<<projectile->Get4Momentum()<<" "<<projectile->Get4Momentum().mag()<<G4endl;
01215 //G4cout<<"before tar "<<target->Get4Momentum()<<" "<<target->Get4Momentum().mag()<<G4endl;
01216 //G4cout<<"Prob el "<<theParameters->GetProbabilityOfElasticScatt()<<G4endl;
01217 //G4cout<<"Prob an "<<theParameters->GetProbabilityOfAnnihilation()<<G4endl;
01218 
01219 //G4cout<<"Pr Tr "<<projectile->GetDefinition()->GetPDGEncoding()<<" "<<target->GetDefinition()->GetPDGEncoding()<<G4endl;
01220 //G4int Uzhi; G4cin>>Uzhi;
01221 
01222            if(G4UniformRand()< theParameters->GetProbabilityOfElasticScatt())
01223            { //   Elastic scattering -------------------------
01224 //G4cout<<"Elastic FTF"<<G4endl;
01225             Successfull = theElastic->ElasticScattering(projectile, target, theParameters)
01226                        || Successfull;              // 9.06.2012
01227            }
01228            else if(G4UniformRand() > theParameters->GetProbabilityOfAnnihilation())
01229            { //   Inelastic scattering ---------------------- 
01230 //G4cout<<"Inelastic FTF"<<G4endl;
01231 //G4cout<<"NumberOfInel MaxNumOfInelCollisions "<<NumberOfInel<<" "<<MaxNumOfInelCollisions<<G4endl;
01232             if(G4UniformRand()< NumberOfInel/MaxNumOfInelCollisions)
01233             {
01234              if(theExcitation->ExciteParticipants(projectile, target, 
01235                                                  theParameters, theElastic))
01236              {
01237               NumberOfInel--;
01238 //G4cout<<"Excitation FTF  Successfull "<<G4endl;
01239 //G4cout<<"After  pro "<<projectile->Get4Momentum()<<" "<<projectile->Get4Momentum().mag()<<G4endl;
01240 //G4cout<<"After  tar "<<target->Get4Momentum()<<" "<<target->Get4Momentum().mag()<<G4endl;
01241              } else
01242              {
01243 //G4cout<<"Excitation FTF  Non Successfull -> Elastic scattering "<<Successfull<<G4endl;
01244 
01245               Successfull = theElastic->ElasticScattering(projectile, target, theParameters)
01246                          || Successfull;              // 9.06.2012
01247 
01248 /*
01249               if(NumberOfInvolvedTargetNucleon > 1)
01250               {
01251                NumberOfInvolvedTargetNucleon--;
01252                target->SetStatus(0);  // 1->0 return nucleon to the target  VU 10.04.2012
01253               }
01254 */
01255              }
01256             } else // If NumOfInel
01257             {
01258 //G4cout<<"Elastic at rejected inelastic scattering"<<G4endl;
01259              Successfull = theElastic->ElasticScattering(projectile, target, theParameters)
01260                         || Successfull;              // 9.06.2012
01261 /*
01262              if(theElastic->ElasticScattering(projectile, target, theParameters))
01263              {
01264 //              Successfull = Successfull || true;
01265              } else
01266              {
01267 //            Successfull = Successfull || false;
01268 //Successfull = Successfull && false;
01269 Successfull = false; break;                         // 1.07.11
01270 
01271               if(NumberOfInvolvedTargetNucleon > 1)
01272               {
01273                NumberOfInvolvedTargetNucleon--;
01274                target->SetStatus(4); // 1->0 return nucleon to the target  VU 10.04.2012
01275               }
01276              }
01277 */
01278             }   // end if NumOfInel
01279            } 
01280            else  // Annihilation
01281            {
01282 //G4cout<<"Annihilation"<<G4endl;
01283 //G4cout<<"Before  pro "<<projectile->Get4Momentum()<<G4endl;
01284 //G4cout<<"Before  tar "<<target->Get4Momentum()<<G4endl;
01285 //G4cout<<"Mom pro "<<theProjectile.GetTotalMomentum()<<G4endl;
01286 //if(theProjectile.GetTotalMomentum() < 2000.*MeV)           
01287 { 
01288             while (theParticipants.Next())
01289             {   
01290             G4InteractionContent & acollision=theParticipants.GetInteraction();//Uzhi Feb26
01291 
01292              G4VSplitableHadron * NextProjectileNucleon=acollision.GetProjectile(); // Uzhi Feb26
01293              G4VSplitableHadron * NextTargetNucleon    =acollision.GetTarget();
01294              if((projectile == NextProjectileNucleon) ||
01295                 (target     == NextTargetNucleon        )) acollision.SetStatus(0);
01296 //             if(target != NextTargetNucleon) NextTargetNucleon->SetStatus(0); // Uzhi Feb26
01297             }
01298 
01299             theParticipants.StartLoop(); 
01300             for(G4int I=0; I < CurrentInteraction; I++) theParticipants.Next();
01301             
01302 //-----------------------------------------
01303 // 1Nov2011            AjustTargetNucleonForAnnihilation(projectile, target);
01304 //-----------------------------------------
01305 //G4cout<<"After Ajsd pro "<<projectile->Get4Momentum()<<G4endl;
01306 //G4cout<<"After Ajst tar "<<target->Get4Momentum()<<G4endl;
01307 }
01308             G4VSplitableHadron *AdditionalString=0;
01309             if(theAnnihilation->Annihilate(projectile, target, AdditionalString, theParameters))
01310             {
01311              Successfull = Successfull || true;
01312 //G4cout<<G4endl<<"*AdditionalString "<<AdditionalString<<G4endl;
01313 //G4cout<<"After  pro "<<projectile->Get4Momentum()<<G4endl;
01314 //G4cout<<"After  tar "<<target->Get4Momentum()<<G4endl;
01315 
01316              if(AdditionalString != 0) theAdditionalString.push_back(AdditionalString);
01317 
01318 //             break;
01319 
01320             } else
01321             {
01322               //A.R. 25-Jul-2012 : commenting the next line to fix a Coverity
01323               //                   "logically dead code".
01324               //Successfull = Successfull || false;
01325 
01326 //             target->SetStatus(2);
01327             }
01328            } 
01329 //
01330 } // End of if((projectile->GetStatus() == 1) && (target->GetStatus() ==1))
01331 
01332         }       // end of while (theParticipants.Next())
01333 
01334 //Successfull=true;
01335 //G4cout<<"G4FTFModel::ExciteParticipants() Successfull "<<Successfull<<G4endl;
01336 //G4int Uzhi; G4cin>>Uzhi;
01337         return Successfull;
01338 }
01339 
01340 //-------------------------------------------------------------------
01341 void G4FTFModel::AjustTargetNucleonForAnnihilation(G4VSplitableHadron *SelectedAntiBaryon,
01342                                                    G4VSplitableHadron *SelectedTargetNucleon)
01343 {
01344         G4LorentzVector Pparticipants=SelectedAntiBaryon->Get4Momentum()+
01345                                       SelectedTargetNucleon->Get4Momentum();
01346 
01347         G4V3DNucleus *theNucleus = GetWoundedNucleus();
01348 //G4cout<<"Init A mass "<<theNucleus->GetMass()<<" "<<theNucleus->GetMassNumber()<<" "<<theNucleus->GetCharge()<<G4endl;
01349 
01350         ResidualExcitationEnergy=0.;
01351         G4int ResidualCharge    =theNucleus->GetCharge();
01352         G4int ResidualMassNumber=theNucleus->GetMassNumber();
01353 
01354         G4ThreeVector   P3nuclearResidual(0.,0.,0.);
01355         G4LorentzVector PnuclearResidual(0.,0.,0.,0.);
01356 
01357 
01358         G4double ExcitationEnergyPerWoundedNucleon=
01359                  theParameters->GetExcitationEnergyPerWoundedNucleon();
01360 //-------
01361         G4Nucleon * aNucleon;
01362         theNucleus->StartLoop();
01363         G4int NumberOfHoles(0);
01364 //G4cout<<"Start loop"<<G4endl;
01365         while ((aNucleon = theNucleus->GetNextNucleon()))
01366         {
01367          G4int CurrentStatus=0;
01368          if(aNucleon->AreYouHit()) 
01369          {
01370           if(aNucleon->GetSplitableHadron() == SelectedTargetNucleon)
01371           {CurrentStatus=1;}
01372           else
01373           {
01374            if(aNucleon->GetSplitableHadron()->GetSoftCollisionCount() == 0) 
01375            {CurrentStatus=0;}
01376            else {CurrentStatus=1;}
01377           }
01378          }
01379 //G4cout<<"CurrentStatus "<<CurrentStatus<<G4endl;
01380          if(CurrentStatus != 0)
01381          {   // Participating nucleons
01382 //G4cout<<"              Partic "<<aNucleon->GetSplitableHadron()->GetStatus()<<" "<<aNucleon->GetSplitableHadron()->GetSoftCollisionCount()<<G4endl;
01383           NumberOfHoles++;
01384           ResidualExcitationEnergy+=ExcitationEnergyPerWoundedNucleon;
01385           ResidualCharge-=(G4int) aNucleon->GetDefinition()->GetPDGCharge();
01386           ResidualMassNumber--;
01387          }
01388          else
01389          {   // Spectator nucleon
01390           PnuclearResidual+=aNucleon->Get4Momentum();
01391          }
01392         }   // end of while (theNucleus->GetNextNucleon())
01393 
01394 //G4cout<<"Res Z M "<<ResidualCharge<<" "<<ResidualMassNumber<<G4endl;
01395 //-------------------------------
01396         G4LorentzVector Psum=Pparticipants + PnuclearResidual;  // 4-momentum in CMS
01397 
01398 // Transform momenta to cms and then rotate parallel to z axis;
01399         G4LorentzRotation toCms(-1*Psum.boostVector());
01400 
01401         G4LorentzVector Ptmp=toCms*Psum;
01402 
01403         toCms.rotateZ(-1*Ptmp.phi());
01404         toCms.rotateY(-1*Ptmp.theta());
01405 
01406         G4LorentzRotation toLab(toCms.inverse());
01407 
01408 //-------------------------------
01409         G4double SqrtS=Psum.mag();
01410         G4double S    =sqr(SqrtS);
01411 
01412         G4double ResidualMass(0.);
01413         if(ResidualMassNumber != 0) 
01414         {
01415          ResidualMass=G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass(
01416                                                    ResidualCharge,ResidualMassNumber);
01417         } else {return;}
01418 
01419 //G4cout<<"Res Mass E* "<<ResidualMass<<" "<<ResidualExcitationEnergy<<G4endl;
01420 
01421         if(ResidualMass > SqrtS) {return;}
01422         else 
01423         {
01424          if(ResidualMass+ResidualExcitationEnergy > SqrtS)
01425            ResidualExcitationEnergy = SqrtS-ResidualMass;
01426         }
01427 
01428         ResidualMass+=ResidualExcitationEnergy;
01429         G4double ResidualMass2=sqr(ResidualMass);
01430 //G4cout<<"New Res Mass E* "<<ResidualMass<<" "<<ResidualExcitationEnergy<<G4endl;
01431 
01432 //-------
01433         G4double ParticipantMass=Pparticipants.mag();
01434         G4double ParticipantMass2=sqr(ParticipantMass);
01435 
01436         if(ResidualMass + ParticipantMass > SqrtS) ParticipantMass=SqrtS-ResidualMass;
01437 
01438 //G4cout<<"Parts P "<<Pparticipants<<G4endl;
01439 //G4cout<<"Res Nuc "<<PnuclearResidual<<G4endl;
01440 
01441         G4double DecayMomentum2= 
01442                       sqr(S)+sqr(ParticipantMass2)+ sqr(ResidualMass2) -
01443                           2.*S*ParticipantMass2 - 2.*S*ResidualMass2 
01444                               -2.*ParticipantMass2*ResidualMass2;
01445 
01446         if(DecayMomentum2 < 0.) return;
01447 
01448         DecayMomentum2/=(4.*S);
01449         G4double DecayMomentum = std::sqrt(DecayMomentum2);
01450 //G4cout<<"DecayMomentum "<<DecayMomentum<<G4endl;
01451 
01452         G4LorentzVector New_Pparticipants(0.,0.,DecayMomentum,
01453                                 std::sqrt(DecayMomentum2+ParticipantMass2));
01454 
01455         G4LorentzVector New_PnuclearResidual(0.,0.,-DecayMomentum,
01456                                 std::sqrt(DecayMomentum2+ResidualMass2));
01457 
01458 //G4cout<<"New part P "<<New_Pparticipants<<" "<<New_Pparticipants.mag()<<G4endl;
01459 //G4cout<<"New resd P "<<New_PnuclearResidual<<" "<<New_PnuclearResidual.mag()<<G4endl;
01460 
01461         New_Pparticipants.transform(toLab);
01462         New_PnuclearResidual.transform(toLab);
01463 //G4cout<<"New part P "<<New_Pparticipants<<" "<<New_Pparticipants.mag()<<G4endl;
01464 //G4cout<<"New resd P "<<New_PnuclearResidual<<" "<<New_PnuclearResidual.mag()<<G4endl;
01465 
01466         G4LorentzVector DeltaP_participants=(Pparticipants - New_Pparticipants)/2.;
01467         G4LorentzVector DeltaP_nuclearResidual=(PnuclearResidual - New_PnuclearResidual)/
01468                                                (G4double) ResidualMassNumber;
01469 //------------------
01470 
01471         Ptmp=SelectedAntiBaryon->Get4Momentum() - DeltaP_participants;
01472         SelectedAntiBaryon->Set4Momentum(Ptmp);
01473 
01474         Ptmp=SelectedTargetNucleon->Get4Momentum() - DeltaP_participants;
01475         SelectedTargetNucleon->Set4Momentum(Ptmp);
01476 //-----------
01477 
01478         //A.R. 25-Jul-2012 : Fix to Covery "Division by zero"
01479         //G4double DeltaExcitationEnergy=ResidualExcitationEnergy/((G4double) NumberOfHoles);
01480         G4double DeltaExcitationEnergy = 0.0;
01481         if ( NumberOfHoles != 0 ) {
01482           DeltaExcitationEnergy = ResidualExcitationEnergy / ((G4double) NumberOfHoles);
01483         }
01484  
01485 // Re-definition of the wounded nucleon momenta
01486         theNucleus->StartLoop();
01487         while ((aNucleon = theNucleus->GetNextNucleon()))
01488         {
01489          G4int CurrentStatus=0;
01490          if(aNucleon->AreYouHit()) 
01491          {
01492           if(aNucleon->GetSplitableHadron() == SelectedTargetNucleon)
01493           {CurrentStatus=1;}
01494           else
01495           {
01496            if(aNucleon->GetSplitableHadron()->GetSoftCollisionCount() == 0) 
01497            {CurrentStatus=0;}
01498            else {CurrentStatus=1;}
01499           }
01500          }
01501 //G4cout<<"CurrentStatus "<<CurrentStatus<<G4endl;
01502          if(CurrentStatus != 0)
01503          {   // Participating nucleons
01504 //G4cout<<"              Partic "<<aNucleon->GetSplitableHadron()->GetStatus()<<" "<<aNucleon->GetSplitableHadron()->GetSoftCollisionCount()<<G4endl;
01505           aNucleon->SetBindingEnergy(DeltaExcitationEnergy);
01506          }
01507          else
01508          { // Spectator nucleon of nuclear residual
01509           Ptmp=aNucleon->Get4Momentum() - DeltaP_nuclearResidual;
01510           aNucleon->SetMomentum(Ptmp);
01511          }
01512         }   // end of while (theNucleus->GetNextNucleon())
01513 
01514 //-------------------------------
01515         return;
01516 }
01517 
01518 // ------------------------------------------------------------
01519 G4ExcitedStringVector * G4FTFModel::BuildStrings()
01520 {       
01521 // Loop over all collisions; find all primaries, and all target ( targets may 
01522 //  be duplicate in the List ( to unique G4VSplitableHadrons)
01523 
01524         G4ExcitedStringVector * strings;
01525         strings = new G4ExcitedStringVector();
01526         
01527         std::vector<G4VSplitableHadron *> primaries;
01528         
01529         G4ExcitedString * FirstString(0);     // If there will be a kink,
01530         G4ExcitedString * SecondString(0);    // two strings will be produced.
01531 
01532         theParticipants.StartLoop();    // restart a loop 
01533 //
01534         while ( theParticipants.Next() ) 
01535         {
01536             const G4InteractionContent & interaction=theParticipants.GetInteraction();
01537 //         if(interaction.GetStatus() != 0)   // Uzhi Feb26
01538          {
01539                  //  do not allow for duplicates ...
01540             if ( primaries.end() == std::find(primaries.begin(), primaries.end(),
01541                                                 interaction.GetProjectile()) )
01542                 primaries.push_back(interaction.GetProjectile());     
01543          } // Uzhi Feb26
01544         }
01545 
01546 //G4cout<<G4endl<<"primaries.size() "<<primaries.size()<<G4endl;
01547         for (unsigned int ahadron=0; ahadron < primaries.size() ; ahadron++)
01548         {
01549             G4bool isProjectile(0);
01550 
01551             if(primaries[ahadron]->GetStatus() <= 1) {isProjectile=true; } // VU 10.04.2012
01552 //            if(primaries[ahadron]->GetStatus() == 3) {isProjectile=false;}
01553 
01554             FirstString=0; SecondString=0;
01555             theExcitation->CreateStrings(primaries[ahadron], isProjectile,
01556                                          FirstString, SecondString,
01557                                          theParameters);
01558 
01559             if(FirstString  != 0) strings->push_back(FirstString);
01560             if(SecondString != 0) strings->push_back(SecondString);
01561 //G4cout<<"Quarks in the string in FTF"<<FirstString->GetRightParton()->GetPDGcode()<<" "<<FirstString->GetLeftParton()->GetPDGcode()<<G4endl;
01562 
01563 //G4cout<<FirstString<<" "<<SecondString<<G4endl;
01564         }
01565 
01566 //G4cout<<"Check "<<strings->operator[](0)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](0)->GetLeftParton()->GetPDGcode()<<G4endl;
01567 //
01568 // Looking for spectator nucleons of the projectile-----------
01569         G4V3DNucleus * ProjectileNucleus =theParticipants.GetProjectileNucleus();
01570         if(ProjectileNucleus)
01571         {
01572          ProjectileNucleus->StartLoop();
01573 
01574          G4Nucleon *    ProjectileNucleon;
01575          while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
01576          {
01577           if ( !ProjectileNucleon->AreYouHit() )
01578           {  // Projectile nucleon was involved in the interaction.
01579 
01580            G4VSplitableHadron * ProjectileSplitable=0;
01581            ProjectileSplitable= new G4DiffractiveSplitableHadron(*ProjectileNucleon);
01582            ProjectileNucleon->Hit(0);
01583 
01584            G4bool isProjectile=true;
01585            FirstString=0; SecondString=0;
01586            theExcitation->CreateStrings(ProjectileSplitable,
01587                                         isProjectile,
01588                                         FirstString, SecondString,
01589                                         theParameters);
01590            if(FirstString  != 0) strings->push_back(FirstString);
01591            if(SecondString != 0) strings->push_back(SecondString);
01592 
01593            delete  ProjectileSplitable;     
01594           }
01595          } // End of while ( (ProjectileNucleon=ProjectileNucleus->GetNextNucleon()) )
01596         }  // End of if(ProjectileNucleus)
01597 
01598 //G4cout<<G4endl<<"theAdditionalString.size() "<<theAdditionalString.size()<<G4endl;
01599         if(theAdditionalString.size() != 0)
01600         {
01601          for (unsigned int  ahadron=0; ahadron < theAdditionalString.size() ; ahadron++)
01602          {
01603             G4bool isProjectile(0);
01604 
01605             if(theAdditionalString[ahadron]->GetStatus() <= 1) {isProjectile=true; } // VU 10.04.2012
01606 //            if(theAdditionalString[ahadron]->GetStatus() == 3) {isProjectile=false;}
01607 
01608             FirstString=0; SecondString=0;
01609             theExcitation->CreateStrings(theAdditionalString[ahadron], isProjectile,
01610                                          FirstString, SecondString,
01611                                          theParameters);
01612 
01613             if(FirstString  != 0) strings->push_back(FirstString);
01614             if(SecondString != 0) strings->push_back(SecondString);
01615 //G4cout<<"Quarks in the string in FTF"<<FirstString->GetRightParton()->GetPDGcode()<<" "<<FirstString->GetLeftParton()->GetPDGcode()<<G4endl;
01616 //G4cout<<FirstString<<" "<<SecondString<<G4endl;
01617          }
01618         }
01619 //G4cout<<"Check "<<strings->operator[](0)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](0)->GetLeftParton()->GetPDGcode()<<G4endl;
01620 //G4cout<<"Check "<<strings->operator[](1)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](1)->GetLeftParton()->GetPDGcode()<<G4endl;
01621 //
01622 //G4cout<<G4endl<<"NumberOfInvolvedNucleon "<<NumberOfInvolvedNucleon<<G4endl;
01623         for (G4int ahadron=0; ahadron < NumberOfInvolvedNucleon ; ahadron++)
01624         {
01625 //G4cout<<"Nucleon status & int# "<<ahadron<<" "<<TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus()<<" "<<TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetSoftCollisionCount()<<G4endl;
01626             if(TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus() ==4)
01627             { // A nucleon is returned back to the nucleus after annihilation act for example
01628 //G4cout<<" Delete 0"<<G4endl;
01629              delete TheInvolvedNucleon[ahadron]->GetSplitableHadron();
01630              G4VSplitableHadron *aHit=0; 
01631              TheInvolvedNucleon[ahadron]->Hit(aHit);
01632             }
01633             else if((TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus() <=1)  && // VU 10.04.2012
01634             (TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetSoftCollisionCount() ==0))
01635             { // A nucleon is returned back to the nucleus after rejected interactions
01636               // due to an annihilation before
01637 //G4cout<<" Delete int# 0"<<G4endl;
01638              delete TheInvolvedNucleon[ahadron]->GetSplitableHadron();
01639              G4VSplitableHadron *aHit=0; 
01640              TheInvolvedNucleon[ahadron]->Hit(aHit);
01641             }
01642             else if((TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus() <=1)  && // VU 10.04.2012
01643             (TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetSoftCollisionCount() !=0))
01644             { // Nucleon which participate in the interactions, 
01645 //G4cout<<"Taken 1 !=0"<<G4endl;
01646              G4bool isProjectile=false;
01647              FirstString=0; SecondString=0;
01648              theExcitation->CreateStrings(
01649                             TheInvolvedNucleon[ahadron]->GetSplitableHadron(),
01650                                           isProjectile,
01651                                           FirstString, SecondString,
01652                                           theParameters);
01653              if(FirstString  != 0) strings->push_back(FirstString);
01654              if(SecondString != 0) strings->push_back(SecondString);
01655             }
01656             else if(TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus() ==2)
01657             { // Nucleon which was involved in the Reggeon cascading
01658 //G4cout<<"Taken st 2"<<G4endl;
01659              G4bool isProjectile=false;
01660              FirstString=0; SecondString=0;
01661              theExcitation->CreateStrings(
01662                             TheInvolvedNucleon[ahadron]->GetSplitableHadron(),
01663                                           isProjectile,
01664                                           FirstString, SecondString,
01665                                           theParameters);
01666              if(FirstString  != 0) strings->push_back(FirstString);
01667              if(SecondString != 0) strings->push_back(SecondString);
01668 //G4cout<<FirstString<<" "<<SecondString<<G4endl;
01669             }
01670             else if(TheInvolvedNucleon[ahadron]->GetSplitableHadron()->GetStatus() ==3)
01671             { // Nucleon which has participated in annihilation and disappiered
01672 //G4cout<<"Status 3 "<<G4endl;
01673               TheInvolvedNucleon[ahadron]->SetBindingEnergy(theParameters->GetExcitationEnergyPerWoundedNucleon());
01674             }
01675             else {}
01676 
01677         }
01678 /*
01679 G4cout<<"Check "<<strings->operator[](0)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](0)->GetLeftParton()->GetPDGcode()<<G4endl;
01680 G4cout<<"Check "<<strings->operator[](1)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](1)->GetLeftParton()->GetPDGcode()<<G4endl;
01681 //G4cout<<"Check "<<strings->operator[](2)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](2)->GetLeftParton()->GetPDGcode()<<G4endl;
01682 
01683 G4cout<<"*** "<<strings->operator[](0)->GetRightParton()<<" "<<strings->operator[](0)->GetLeftParton()<<G4endl;
01684 G4cout<<"*** "<<strings->operator[](1)->GetRightParton()<<" "<<strings->operator[](1)->GetLeftParton()<<G4endl;
01685 //G4cout<<"*** "<<strings->operator[](2)->GetRightParton()<<" "<<strings->operator[](2)->GetLeftParton()<<G4endl;
01686 */
01687         std::for_each(primaries.begin(), primaries.end(), DeleteVSplitableHadron());
01688         primaries.clear();
01689 /*
01690 G4cout<<"*** "<<strings->operator[](0)->GetRightParton()<<" "<<strings->operator[](0)->GetLeftParton()<<G4endl;
01691 G4cout<<"*** "<<strings->operator[](1)->GetRightParton()<<" "<<strings->operator[](1)->GetLeftParton()<<G4endl;
01692 G4cout<<"*** "<<strings->operator[](2)->GetRightParton()<<" "<<strings->operator[](2)->GetLeftParton()<<G4endl;
01693 
01694 G4cout<<"Check "<<strings->operator[](0)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](0)->GetLeftParton()->GetPDGcode()<<G4endl;
01695 G4cout<<"Check "<<strings->operator[](1)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](1)->GetLeftParton()->GetPDGcode()<<G4endl;
01696 G4cout<<"Check "<<strings->operator[](2)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](2)->GetLeftParton()->GetPDGcode()<<G4endl;
01697 */
01698 
01699 /*
01700 for (unsigned int ahadron=0; ahadron < strings->size() ; ahadron++)
01701 {
01702 G4cout<<ahadron<<" "<<strings->operator[](ahadron)->GetRightParton()->GetPDGcode()<<" "<<strings->operator[](ahadron)->GetLeftParton()->GetPDGcode()<<G4endl;
01703 }
01704 G4cout<<"------------------------"<<G4endl;
01705 */
01706 //G4int Uzhi; G4cin >> Uzhi;
01707         return strings;
01708 }
01709 // ------------------------------------------------------------
01710 void G4FTFModel::GetResidualNucleus()
01711 { // This method is needed for the correct application of G4PrecompoundModelInterface
01712         G4double DeltaExcitationE=ResidualExcitationEnergy/
01713                                   (G4double) NumberOfInvolvedNucleon;
01714         G4LorentzVector DeltaPResidualNucleus = Residual4Momentum/
01715                                   (G4double) NumberOfInvolvedNucleon;
01716 
01717         for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01718         {
01719          G4Nucleon * aNucleon = TheInvolvedNucleon[i];
01720 //         G4LorentzVector tmp=aNucleon->Get4Momentum()-DeltaPResidualNucleus;
01721          G4LorentzVector tmp=-DeltaPResidualNucleus;
01722          aNucleon->SetMomentum(tmp);
01723          aNucleon->SetBindingEnergy(DeltaExcitationE);
01724         }   // end of for(G4int i=0; i < NumberOfInvolvedNucleon; i++ )
01725 
01726 }
01727 
01728 // ------------------------------------------------------------
01729 G4ThreeVector G4FTFModel::GaussianPt(G4double AveragePt2, G4double maxPtSquare) const
01730 {            //  @@ this method is used in FTFModel as well. Should go somewhere common!
01731         
01732         G4double Pt2(0.);
01733         if(AveragePt2 <= 0.) {Pt2=0.;}
01734         else
01735         {
01736          Pt2 = -AveragePt2 * std::log(1. + G4UniformRand() * 
01737                 (std::exp(-maxPtSquare/AveragePt2)-1.)); 
01738         }
01739         G4double Pt=std::sqrt(Pt2);
01740         G4double phi=G4UniformRand() * twopi;
01741         
01742         return G4ThreeVector (Pt*std::cos(phi), Pt*std::sin(phi), 0.);    
01743 }
01744 
01745 void G4FTFModel::ModelDescription(std::ostream& desc) const
01746 {
01747         desc << "please add description here" << G4endl;
01748 }

Generated on Mon May 27 17:48:18 2013 for Geant4 by  doxygen 1.4.7