// // ******************************************************************** // * 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: G4LundStringFragmentation.cc,v 1.18 2009/10/05 12:52:48 vuzhinsk Exp $ // GEANT4 tag $Name: geant4-09-03 $ 1.8 // // ----------------------------------------------------------------------------- // GEANT 4 class implementation file // // History: first implementation, Maxim Komogorov, 10-Jul-1998 // ----------------------------------------------------------------------------- #include "G4LundStringFragmentation.hh" #include "G4FragmentingString.hh" #include "G4DiQuarks.hh" #include "G4Quarks.hh" #include "Randomize.hh" // Class G4LundStringFragmentation //************************************************************************************* G4LundStringFragmentation::G4LundStringFragmentation() { // ------ For estimation of a minimal string mass --------------- Mass_of_light_quark =140.*MeV; Mass_of_heavy_quark =500.*MeV; Mass_of_string_junction=720.*MeV; // ------ An estimated minimal string mass ---------------------- MinimalStringMass = 0.; MinimalStringMass2 = 0.; // ------ Minimal invariant mass used at a string fragmentation - WminLUND = 0.7*GeV; // Uzhi 0.8 1.5 // ------ Smooth parameter used at a string fragmentation for --- // ------ smearinr sharp mass cut-off --------------------------- SmoothParam = 0.2; // SetStringTensionParameter(0.25); // Uzhi 20 June 08 SetStringTensionParameter(1.); // Uzhi 20 June 09 } // -------------------------------------------------------------- G4LundStringFragmentation::G4LundStringFragmentation(const G4LundStringFragmentation &) : G4VLongitudinalStringDecay() { } G4LundStringFragmentation::~G4LundStringFragmentation() { } //************************************************************************************* const G4LundStringFragmentation & G4LundStringFragmentation::operator=(const G4LundStringFragmentation &) { throw G4HadronicException(__FILE__, __LINE__, "G4LundStringFragmentation::operator= meant to not be accessable"); return *this; } int G4LundStringFragmentation::operator==(const G4LundStringFragmentation &right) const { return !memcmp(this, &right, sizeof(G4LundStringFragmentation)); } int G4LundStringFragmentation::operator!=(const G4LundStringFragmentation &right) const { return memcmp(this, &right, sizeof(G4LundStringFragmentation)); } //-------------------------------------------------------------------------------------- void G4LundStringFragmentation::SetMinimalStringMass(const G4FragmentingString * const string) // Uzhi { /* G4cout<<"In SetMinMass -------------------"<Mass2())<GetLeftParton()->GetPDGEncoding()<<" "<< string->GetRightParton()->GetPDGEncoding()<GetLeftParton()->GetPDGEncoding()); if( Qleft > 1000) { Number_of_quarks+=2; G4int q1=Qleft/1000; if( q1 < 3) {EstimatedMass +=Mass_of_light_quark;} if( q1 > 2) {EstimatedMass +=Mass_of_heavy_quark;} G4int q2=(Qleft/100)%10; if( q2 < 3) {EstimatedMass +=Mass_of_light_quark;} if( q2 > 2) {EstimatedMass +=Mass_of_heavy_quark;} EstimatedMass +=Mass_of_string_junction; } else { Number_of_quarks++; if( Qleft < 3) {EstimatedMass +=Mass_of_light_quark;} if( Qleft > 2) {EstimatedMass +=Mass_of_heavy_quark;} } G4int Qright=std::abs(string->GetRightParton()->GetPDGEncoding()); if( Qright > 1000) { Number_of_quarks+=2; G4int q1=Qright/1000; if( q1 < 3) {EstimatedMass +=Mass_of_light_quark;} if( q1 > 2) {EstimatedMass +=Mass_of_heavy_quark;} G4int q2=(Qright/100)%10; if( q2 < 3) {EstimatedMass +=Mass_of_light_quark;} if( q2 > 2) {EstimatedMass +=Mass_of_heavy_quark;} EstimatedMass +=Mass_of_string_junction; } else { Number_of_quarks++; if( Qright < 3) {EstimatedMass +=Mass_of_light_quark;} if( Qright > 2) {EstimatedMass +=Mass_of_heavy_quark;} } if(Number_of_quarks==2){EstimatedMass +=100.*MeV;} if(Number_of_quarks==3){EstimatedMass += 20.*MeV;} if(Number_of_quarks==4){EstimatedMass -=2.*Mass_of_string_junction; if(EstimatedMass <= 1600.*MeV){EstimatedMass-=200.*MeV;} else {EstimatedMass+=100.*MeV;} } MinimalStringMass=EstimatedMass; SetMinimalStringMass2(EstimatedMass); //G4cout<<"Out SetMinimalStringMass "<size() == 1){ // One hadron is saved in the interaction LeftVector->operator[](0)->SetFormationTime(theString.GetTimeOfCreation()); LeftVector->operator[](0)->SetPosition(theString.GetPosition()); /* // To set large formation time open * LeftVector->operator[](0)->SetFormationTime(theString.GetTimeOfCreation()+100.*fermi); LeftVector->operator[](0)->SetPosition(theString.GetPosition()); G4ThreeVector aPosition(theString.GetPosition().x(), theString.GetPosition().y(), theString.GetPosition().z()+100.*fermi); LeftVector->operator[](0)->SetPosition(aPosition); */ //G4cout<<"Single hadron "<operator[](0)->Get4Momentum()<<" "<operator[](0)->Get4Momentum().mag()<operator[](0)->SetFormationTime(theString.GetTimeOfCreation()); LeftVector->operator[](0)->SetPosition(theString.GetPosition()); LeftVector->operator[](1)->SetFormationTime(theString.GetTimeOfCreation()); LeftVector->operator[](1)->SetPosition(theString.GetPosition()); } // Uzhi insert 6.05.08 end return LeftVector; } //--------------------- The string can fragment ------------------------------- //--------------- At least two particles can be produced ---------------------- LeftVector =new G4KineticTrackVector; G4KineticTrackVector * RightVector=new G4KineticTrackVector; G4ExcitedString *theStringInCMS=CPExcited(theString); G4LorentzRotation toCms=theStringInCMS->TransformToAlignedCms(); G4bool success=false, inner_sucess=true; G4int attempt=0; while ( !success && attempt++ < StringLoopInterrupt ) { // If the string fragmentation do not be happend, repeat the fragmentation--- G4FragmentingString *currentString=new G4FragmentingString(*theStringInCMS); //G4cout<<"FragmentString cur M2 "<Mass2())<begin() , LeftVector->end() , DeleteKineticTrack()); LeftVector->clear(); std::for_each(RightVector->begin(), RightVector->end(), DeleteKineticTrack()); RightVector->clear(); // Main fragmentation loop until the string will not be able to fragment ---- inner_sucess=true; // set false on failure.. while (! StopFragmenting(currentString) ) { // Split current string into hadron + new string G4FragmentingString *newString=0; // used as output from SplitUp... //G4cout<<"FragmentString to Splitup ===================================="<>Uzhi; // Uzhi G4KineticTrack * Hadron=Splitup(currentString,newString); //G4cout<<" Hadron "<GetDecayDirection() > 0 ) LeftVector->push_back(Hadron); else RightVector->push_back(Hadron); delete currentString; currentString=newString; } }; // Split remaining string into 2 final Hadrons ------------------------ //G4cout<<"FragmentString to SplitLast if inner_sucess#0"<begin(), LeftVector->end(), DeleteKineticTrack()); LeftVector->clear(); std::for_each(RightVector->begin(), RightVector->end(), DeleteKineticTrack()); delete RightVector; return LeftVector; } // Join Left- and RightVector into LeftVector in correct order. while(!RightVector->empty()) { LeftVector->push_back(RightVector->back()); RightVector->erase(RightVector->end()-1); } delete RightVector; //G4cout<<"CalculateHadronTimePosition"<operator[](0)->SetFormationTime(theString.GetTimeOfCreation()); // LeftVector->operator[](0)->SetPosition(theString.GetPosition()); G4double TimeOftheStringCreation=theString.GetTimeOfCreation(); G4ThreeVector PositionOftheStringCreation(theString.GetPosition()); // Uzhi 11.07.09 //G4cout<<" String T Pos"< 100.*fermi){ // It is a projectile-like string ------------------------------------- G4double Zmin=theString.GetPosition().y()-1000.*fermi; G4double Zmax=theString.GetPosition().z(); TimeOftheStringCreation= (Zmax-Zmin)*theString.Get4Momentum().e()/theString.Get4Momentum().z(); G4ThreeVector aPosition(0.,0.,Zmax); PositionOftheStringCreation=aPosition; } */ //G4cout<<"Lund Frag # hadrons"<size()<size(); C1++) { G4KineticTrack* Hadron = LeftVector->operator[](C1); G4LorentzVector Momentum = Hadron->Get4Momentum(); Momentum = toObserverFrame*Momentum; Hadron->Set4Momentum(Momentum); G4LorentzVector Coordinate(Hadron->GetPosition(), Hadron->GetFormationTime()); Momentum = toObserverFrame*Coordinate; Hadron->SetFormationTime(TimeOftheStringCreation+Momentum.e() // Uzhi 11.07.09 -fermi/c_light); // Uzhi 11.07.09 G4ThreeVector aPosition(Momentum.vect()); // Hadron->SetPosition(theString.GetPosition()+aPosition); Hadron->SetPosition(PositionOftheStringCreation+aPosition); //G4cout<<"Hadron "<GetPosition()/fermi<<" "<GetFormationTime()/fermi<GetDefinition()->GetParticleName()<GetDefinition()->GetPDGMass()<<' ' <Get4Momentum()<GetFormationTime()<<' ' <GetPosition()<<' ' <GetPosition().z()/fermi<Get4Momentum().mag2())<Get4Momentum().mag2(); // Uzhi // return sqr(FragmentationMass(string)+MassCut) < // Uzhi // string->Mass2(); // Uzhi } //---------------------------------------------------------------------------------------- G4bool G4LundStringFragmentation::StopFragmenting(const G4FragmentingString * const string) { //G4cout<<"StopFragmenting"<Get4Momentum().mag2())< string->Mass(); } //---------------------------------------------------------------------------------------- G4bool G4LundStringFragmentation::SplitLast(G4FragmentingString * string, G4KineticTrackVector * LeftVector, G4KineticTrackVector * RightVector) { //... perform last cluster decay /* G4cout<<"SplitLast String mass "<Mass()<GetLeftParton()->GetPDGEncoding()<<" "<GetRightParton()->GetPDGEncoding()<<" "<Get4Momentum(); //G4cout<<"String 4 momentum "<Get4Momentum().boostVector(); G4double ResidualMass = string->Mass(); G4ParticleDefinition * LeftHadron, * RightHadron; G4int cClusterInterrupt = 0; do { //G4cout<<" Cicle "<= ClusterLoopInterrupt) { return false; } G4ParticleDefinition * quark = NULL; string->SetLeftPartonStable(); // to query quark contents.. if (!string->FourQuarkString() ) { // The string is q-qbar, or q-qq, or qbar-qqbar type if (string->DecayIsQuark() && string->StableIsQuark() ) { //... there are quarks on cluster ends LeftHadron= QuarkSplitup(string->GetLeftParton(), quark); } else { //... there is a Diquark on one of the cluster ends G4int IsParticle; if ( string->StableIsQuark() ) { IsParticle=(string->GetLeftParton()->GetPDGEncoding()>0) ? -1 : +1; } else { IsParticle=(string->GetLeftParton()->GetPDGEncoding()>0) ? +1 : -1; } pDefPair QuarkPair = CreatePartonPair(IsParticle,false); // no diquarks wanted quark = QuarkPair.second; LeftHadron=hadronizer->Build(QuarkPair.first, string->GetLeftParton()); } RightHadron = hadronizer->Build(string->GetRightParton(), quark); } else { // The string is qq-qqbar type. Diquarks are on the string ends G4int LiftQuark1= string->GetLeftParton()->GetPDGEncoding()/1000; G4int LiftQuark2=(string->GetLeftParton()->GetPDGEncoding()/100)%10; G4int RightQuark1= string->GetRightParton()->GetPDGEncoding()/1000; G4int RightQuark2=(string->GetRightParton()->GetPDGEncoding()/100)%10; if(G4UniformRand()<0.5) { LeftHadron =hadronizer->Build(FindParticle( LiftQuark1), FindParticle(RightQuark1)); RightHadron=hadronizer->Build(FindParticle( LiftQuark2), FindParticle(RightQuark2)); } else { LeftHadron =hadronizer->Build(FindParticle( LiftQuark1), FindParticle(RightQuark2)); RightHadron=hadronizer->Build(FindParticle( LiftQuark2), FindParticle(RightQuark1)); } } /* G4cout<<"SplitLast Left Right hadrons "<GetPDGEncoding()<<" "<GetPDGEncoding()<GetPDGMass()<<" "<GetPDGMass()<GetPDGMass() + RightHadron->GetPDGMass()<<" "<GetPDGMass() + RightHadron->GetPDGMass());// UzhiVOVA //... compute hadron momenta and energies G4LorentzVector LeftMom, RightMom; G4ThreeVector Pos; Sample4Momentum(&LeftMom, LeftHadron->GetPDGMass(), &RightMom, RightHadron->GetPDGMass(), ResidualMass); LeftMom.boost(ClusterVel); RightMom.boost(ClusterVel); LeftVector->push_back(new G4KineticTrack(LeftHadron, 0, Pos, LeftMom)); RightVector->push_back(new G4KineticTrack(RightHadron, 0, Pos, RightMom)); //G4cout<<"Out SplitLast "< 930. || AntiMass > 930.) // If there is a baryon { // ----------------- Isotripic decay ------------------------------------ G4double r_val = sqr(InitialMass*InitialMass - Mass*Mass - AntiMass*AntiMass) - sqr(2.*Mass*AntiMass); G4double Pabs = (r_val > 0.)? std::sqrt(r_val)/(2.*InitialMass) : 0; //... sample unit vector G4double pz = 1. - 2.*G4UniformRand(); G4double st = std::sqrt(1. - pz * pz)*Pabs; G4double phi = 2.*pi*G4UniformRand(); G4double px = st*std::cos(phi); G4double py = st*std::sin(phi); pz *= Pabs; Mom->setPx(px); Mom->setPy(py); Mom->setPz(pz); Mom->setE(std::sqrt(Pabs*Pabs + Mass*Mass)); AntiMom->setPx(-px); AntiMom->setPy(-py); AntiMom->setPz(-pz); AntiMom->setE (std::sqrt(Pabs*Pabs + AntiMass*AntiMass)); } else { do { // GF 22-May-09, limit sampled pt to allowed range G4double termD = InitialMass*InitialMass -Mass*Mass - AntiMass*AntiMass; G4double termab = 4*sqr(Mass*AntiMass); G4double termN = 2*termD + 4*Mass*Mass + 4*AntiMass*AntiMass; G4double pt2max=(termD*termD - termab )/ termN ; // G4cout << " termD, ab, N " << termD << " " << termab << " " << termN // << " pt2max= " << pt2max ; Pt=SampleQuarkPt(std::sqrt(pt2max)); Pt.setZ(0); G4double Pt2=Pt.mag2(); // G4cout << " sampled Pt2 = " << Pt2 << " " << pt2max-Pt2 << G4endl; // end.. GF //G4cout<<"Sample4Momentum Pt x y "< AntiMass){AvailablePz=-AvailablePz;} // May30 // Uzhi Mom->setPx(Px); Mom->setPy(Py); Mom->setPz(AvailablePz); Mom->setE(std::sqrt(MassMt2+AvailablePz2)); //G4cout<<" 1 part "<setPx(-Px); AntiMom->setPy(-Py); AntiMom->setPz(-AvailablePz); AntiMom->setE (std::sqrt(AntiMassMt2+AvailablePz2)); //G4cout<<" 2 part "<<-Px<<" "<<-Py<<" "<<-AvailablePz<<" "<Mass()<GetLeftParton()->GetPDGEncoding()<<" " <GetRightParton()->GetPDGEncoding()<<" "<GetLeftParton()->GetPDGEncoding()<<" "<GetRightParton()->GetPDGEncoding()<<" "<Get4Momentum(); G4double StringMT2=string->Get4Momentum().mt2(); //G4cout<<"StringMt2 "<GetPDGMass(); //G4cout<<"Hadron mass "<GetParticleName()<DecayPt(); HadronPt.setZ(0); //G4cout<<"Hadron Pt"<= zMax) return 0; // have to start all over! G4double z = GetLightConeZ(zMin, zMax, string->GetDecayParton()->GetPDGEncoding(), pHadron, HadronPt.x(), HadronPt.y()); //... now compute hadron longitudinal momentum and energy // longitudinal hadron momentum component HadronPz HadronPt.setZ(0.5* string->GetDecayDirection() * (z * string->LightConeDecay() - HadronMassT2/(z * string->LightConeDecay()))); G4double HadronE = 0.5* (z * string->LightConeDecay() + HadronMassT2/(z * string->LightConeDecay())); G4LorentzVector * a4Momentum= new G4LorentzVector(HadronPt,HadronE); //G4cout<<"Hadron Pt"<GetPDGMass(); // G4int HadronEncoding=pHadron->GetPDGEncoding(); G4double Mt2 = Px*Px + Py*Py + Mass*Mass; if(std::abs(PDGEncodingOfDecayParton) < 1000) { // ---------------- Quark fragmentation ---------------------- alund=0.35/GeV/GeV; // Instead of 0.7 because kinks are not considered G4double zOfMaxyf=alund*Mt2/(alund*Mt2 + 1.); G4double maxYf=(1-zOfMaxyf)/zOfMaxyf * std::exp(-alund*Mt2/zOfMaxyf); do { z = zmin + G4UniformRand()*(zmax-zmin); // yf = std::pow(1. - z, blund)/z*std::exp(-alund*Mt2/z); yf = (1-z)/z * std::exp(-alund*Mt2/z); } while (G4UniformRand()*maxYf > yf); } else { // ---------------- Di-quark fragmentation ---------------------- //G4cout<<"Di-quark"< yf); }; //G4cout<<" test z "<