// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4QFragmentation.cc,v 1.5 2009/04/29 07:53:18 mkossov Exp $ // GEANT4 tag $Name: geant4-09-03-beta-cand-01 $ // // ----------------------------------------------------------------------------- // GEANT 4 class header file // // History: // Created by Mikhail Kossov, October 2006 // CHIPS QGS fragmentation class // For comparison mirror member functions are taken from G4 classes: // G4QGSParticipants // G4QGSModels // G4ExcitedStringDecay // ----------------------------------------------------------------------------- // Short description: CHIPS string fragmentation class // ----------------------------------------------------------------------------- //#define debug //#define pdebug //#define ppdebug #include "globals.hh" #include "G4QFragmentation.hh" #include "G4LorentzVector.hh" #include // Promoting model parameters from local variables class properties @@(? M.K.) // Definition of static parameters G4int G4QFragmentation::nCutMax=7; G4double G4QFragmentation::ThersholdParameter=450.*MeV; G4double G4QFragmentation::QGSMThershold=3.*GeV; G4double G4QFragmentation::theNucleonRadius=1.5*fermi; // Parameters of diffractional fragmentation G4double G4QFragmentation::widthOfPtSquare=-0.72*GeV*GeV; // pt -width2 forStringExcitation G4double G4QFragmentation::minExtraMass=250.*MeV;// minimum excitation mass G4double G4QFragmentation::minmass=250.*MeV; // mean pion transverse mass for Xmin G4QFragmentation::G4QFragmentation() : theNucleus(0) { // Construct Shortlived particles (needed after the 2006 Particles revolution) G4ShortLivedConstructor ShortLived; ShortLived.ConstructParticle(); } G4QFragmentation::~G4QFragmentation() {if(theNucleus) delete theNucleus;} G4QHadronVector* G4QFragmentation::Scatter(const G4QNucleus &aNucleus, const G4QHadron &aPrimary) { G4QStringVector* strings=0; G4QHadron thePrimary = aPrimary; G4LorentzRotation toZ; G4LorentzVector Ptmp=thePrimary.Get4Momentum(); toZ.rotateZ(-1*Ptmp.phi()); toZ.rotateY(-1*Ptmp.theta()); thePrimary.Set4Momentum(toZ*Ptmp); G4LorentzRotation toLab(toZ.inverse()); G4int attempts = 0, maxAttempts=20; while(!strings) { if (attempts++ > maxAttempts ) { G4cerr<<"***G4QFragmentation::Scatter: "< max=" < try to increase maxAttempts"<size(); astring++) { // rotate string to lab frame, models have it aligned to z stringEnergy += (*strings)[astring]->GetLeftParton()->Get4Momentum().t(); stringEnergy += (*strings)[astring]->GetRightParton()->Get4Momentum().t(); (*strings)[astring]->LorentzRotate(toLab); } #ifdef debug G4cout<<"G4QFragmentation::Scatter: Total string energy = "<begin(), strings->end(), DeleteQString() ); delete strings; return theResult; } void G4QFragmentation::InitModel(const G4QNucleus& aNucleus,const G4QHadron& aProjectile) { static const G4double mProt = G4Proton::Proton()->GetPDGMass(); // Mass of proton Init(aNucleus.GetN(),aNucleus.GetZ()); theCurrentVelocity.setX(0); theCurrentVelocity.setY(0); // @@ "target Nucleon" == "Proton at rest" (M.K. ?) G4double nCons = 1; // 1 or baryon number of the projectile G4int projAbsB=std::abs(aProjectile.GetBaryonNumber()); // Baryon/anti-baryon if(projAbsB>1) nCons = projAbsB; G4LorentzVector proj4M = aProjectile.Get4Momentum(); G4double pz_per_projectile = proj4M.pz()/nCons; G4double e_per_projectile = proj4M.e()/nCons+mProt; // @@ Add mass of TargetProtonAtRest //G4double e_per_projectile = aProjectile.Get4Momentum()*aProjectile.Get4Momentum(); //e_per_projectile += proj4M.vect()*proj4M.vect(); //e_per_projectile /=nCons*nCons; //e_per_projectile = std::sqrt(e_per_projectile); //e_per_projectile += G4Proton::Proton()->GetPDGMass();//@@Add mass of TargetProtonAtRest G4double vz = pz_per_projectile/e_per_projectile; #ifdef debug G4cout<<"G4QFragmentation::Init: Projectile4M="<DoLorentzBoost(theCurrentVelocity); } G4QStringVector* G4QFragmentation::GetStrings() { G4QPartonPair* aPair; G4QStringVector* theStrings = new G4QStringVector; G4QString* aString=0; while((aPair = GetNextPartonPair())) // @@ At present no difference in stringBuild ? M.K. { if (aPair->GetCollisionType() == G4QPartonPair::DIFFRACTIVE) { aString = BuildString(aPair); // @@ ? #ifdef debug G4cout<<"G4QFragmentation::GetStrings:DifString4M="<Get4Momentum()< std::sqrt(s)=" < s) // thus only diffractive in cascade! { #ifdef debug G4cout<<"G4QFragmentation::SelectInteractions: ThrM="< std::sqrt(s)=" < only Diffraction is possible"< theImpactParameter; theImpactParameter = theNucleus->ChooseImpactXandY(outerRadius+theNucleonRadius); G4double impactX = theImpactParameter.first; G4double impactY = theImpactParameter.second; // loop over nuclei to find collissions HPW theNucleus->StartLoop(); G4int nucleonCount = 0; // debug //G4QFragmentation_NPart = 0; // ? M.K. while( (pNucleon = theNucleus->GetNextNucleon()) ) { if(totalCuts>1.5*eKin) break; nucleonCount++; // debug // Needs to be moved to Probability class @@@ G4double s = (aPrimaryMomentum + pNucleon->Get4Momentum()).mag2(); G4double Distance2 = sqr(impactX - pNucleon->GetPosition().x()) + sqr(impactY - pNucleon->GetPosition().y()); G4double Probability = theProbability.GetInelasticProbability(s, Distance2); // test for inelastic collision G4double rndNumber = G4UniformRand(); // ModelMode = DIFFRACTIVE; if (Probability > rndNumber) { #ifdef debug G4cout<<"G4QFragmentation::SelectInteractions: p="<IsExcited() ) { generatedHadrons=(*theStrings)[astring]->FragmentString(true);// Fragment QGSM String } else { //generatedHadrons = new G4QHadronVector; //generatedHadrons->push_back((*theStrings)[astring]->GetAsQHadron()); //@@ NotImplem } if (!generatedHadrons) { G4cerr<<"G4QFragmentation::FragmentStrings: No Hadrons produced" << G4endl; continue; } G4LorentzVector KTsum1(0.,0.,0.,0.); for(unsigned aTrack=0; aTracksize(); aTrack++) { theResult->push_back((*generatedHadrons)[aTrack]); KTsum1+= (*generatedHadrons)[aTrack]->Get4Momentum(); } if(std::abs((KTsum1.e()-(*theStrings)[astring]->Get4Momentum().e())/KTsum1.e()) > perMillion) NeedEnergyCorrector=true; // clean up delete generatedHadrons; } #ifdef debug G4cout<<"G4QFragmentation::FragmentStrings: String4mom="<empty()) return TRUE; G4LorentzVector SumMom; G4double SumMass = 0; G4double TotalCollisionMass = TotalCollisionMom.m(); if( !(TotalCollisionMass<1) && !(TotalCollisionMass>-1) ) { G4cerr<<"***G4QFragmentation::EnergyAndMomentumCorrect:M="<size(); cHadron++) { SumMom += Output->operator[](cHadron)->Get4Momentum(); if( !(SumMom<1) && !(SumMom>-1) ) { G4cerr<<"***G4QFragmentation::EnergyAndMomentumCorrector: SumMom="<GetMass(); if(!(SumMass<1) && !(SumMass>-1)) { G4cerr<<"***G4QFragmentation::EnergyAndMomentumCorrector: SumMass="<size() < 2) return FALSE; if (SumMass > TotalCollisionMass) return FALSE; SumMass = SumMom.m2(); if (SumMass < 0) return FALSE; SumMass = std::sqrt(SumMass); // Compute c.m.s. hadron velocity and boost KTV to hadron c.m.s. G4ThreeVector Beta = -SumMom.boostVector(); G4int nOut=Output->size(); if(nOut) for(G4int o=0; oBoost(Beta); // Scale total c.m.s. hadron energy (hadron system mass). // It should be equal interaction mass G4double Scale = 1; G4int cAttempt = 0; G4double Sum = 0; G4bool success = false; for(cAttempt = 0; cAttempt < nAttemptScale; cAttempt++) { Sum = 0; for(cHadron = 0; cHadron < Output->size(); cHadron++) { G4LorentzVector HadronMom = Output->operator[](cHadron)->Get4Momentum(); HadronMom.setVect(Scale*HadronMom.vect()); G4double E = std::sqrt(HadronMom.vect().mag2() + sqr((*Output)[cHadron]->GetMass())); HadronMom.setE(E); Output->operator[](cHadron)->Set4Momentum(HadronMom); Sum += E; } Scale = TotalCollisionMass/Sum; if (Scale - 1 <= ErrLimit) { success = true; break; } #ifdef debug G4cout<<"G4QFragmentation::EnergyAndMomentumCorrector: Scale-1="<size(); if(nOut) for(G4int o=0; oBoost(Beta); return TRUE; } // Excite double diffractive string G4bool G4QFragmentation::ExciteDiffParticipants(G4QHadron* projectile, G4QHadron* target) const { G4LorentzVector Pprojectile=projectile->Get4Momentum(); G4double Mprojectile=projectile->GetMass() + minExtraMass; G4double Mprojectile2=Mprojectile*Mprojectile; G4LorentzVector Ptarget=target->Get4Momentum(); G4double Mtarget=target->GetMass() + minExtraMass; G4double Mtarget2=Mtarget*Mtarget; #ifdef debug G4cout<<"G4QFragm::ExciteDiffPartici:Ep="<GetMass2()*(1.-perCent); // Isn't it too big reduction? M.K. } else { #ifdef debug G4cout<<"---1/2---G4QFragmentation::ExSingDiffParticipants: Target is fixed"<GetMass2()*(1.-perCent); // @@ Isn't it too big reduction? M.K. } // @@ From this point it repeats the Diffractional excitation (? Use flag ?) // Transform momenta to cms and then rotate parallel to z axis; G4LorentzVector Psum=Pprojectile+Ptarget; G4LorentzRotation toCms(-Psum.boostVector()); // Boost Rotation to CMS G4LorentzVector Ptmp=toCms*Pprojectile; if(Ptmp.pz()<=0.) // "String" moving backwards in CMS, abort collision !! ? M.K. { #ifdef debug G4cout<<"G4QFragment::ExciteSingDiffParticipants: *1* abort Collision!! *1*"<