Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ExcitedStringDecay.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// Historic fragment from M.Komogorov; clean-up still necessary @@@
27
29#include "G4SystemOfUnits.hh"
30#include "G4KineticTrack.hh"
33
34#include "G4SampleResonance.hh"
35
36//#define debug_G4ExcitedStringDecay
37//#define debug_G4ExcitedStringCorr
38
40 : G4VStringFragmentation(), theStringDecay(ptr)
41{
42 if(!ptr) {
44 G4HadronicInteractionRegistry::Instance()->FindModel("LundStringFragmentation");
45 theStringDecay = static_cast<G4VLongitudinalStringDecay*>(p);
46 if(!theStringDecay) { theStringDecay = new G4LundStringFragmentation(); }
47 }
48 SetModelName(theStringDecay->GetModelName());
49}
50
52{}
53
54G4KineticTrackVector *G4ExcitedStringDecay::FragmentString(const G4ExcitedString &theString)
55{
56 return theStringDecay->FragmentString(theString);
57}
58
60{
61 G4LorentzVector KTsum(0.,0.,0.,0.);
62
63 #ifdef debug_G4ExcitedStringDecay
65 G4cout<<"--------------------------- G4ExcitedStringDecay ----------------------"<<G4endl;
66 G4cout<<"Hadronization of Excited Strings: theStrings->size() "<<theStrings->size()<<G4endl;
67 #endif
68
69 for ( unsigned int astring=0; astring < theStrings->size(); astring++)
70 // for ( unsigned int astring=0; astring < 1; astring++)
71 {
72 // G4cout<<"theStrings->operator[](astring)->IsExcited() "<<" "<<astring<<" "<<theStrings->operator[](astring)->IsExcited()<<G4endl;
73 if ( theStrings->operator[](astring)->IsExcited() )
74 {KTsum+= theStrings->operator[](astring)->Get4Momentum();}
75 else {KTsum+=theStrings->operator[](astring)->GetKineticTrack()->Get4Momentum();}
76 }
77
78 G4LorentzRotation toCms( -1 * KTsum.boostVector() );
79 G4LorentzRotation toLab(toCms.inverse());
80 G4LorentzVector Ptmp;
81 KTsum=G4LorentzVector(0.,0.,0.,0.);
82
83 for ( unsigned int astring=0; astring < theStrings->size(); astring++)
84 // for ( unsigned int astring=0; astring < 1; astring++)
85 {
86 if ( theStrings->operator[](astring)->IsExcited() )
87 {
88 Ptmp=toCms * theStrings->operator[](astring)->GetLeftParton()->Get4Momentum();
89 theStrings->operator[](astring)->GetLeftParton()->Set4Momentum(Ptmp);
90
91 Ptmp=toCms * theStrings->operator[](astring)->GetRightParton()->Get4Momentum();
92 theStrings->operator[](astring)->GetRightParton()->Set4Momentum(Ptmp);
93
94 KTsum+= theStrings->operator[](astring)->Get4Momentum();
95 }
96 else
97 {
98 Ptmp=toCms * theStrings->operator[](astring)->GetKineticTrack()->Get4Momentum();
99 theStrings->operator[](astring)->GetKineticTrack()->Set4Momentum(Ptmp);
100 KTsum+= theStrings->operator[](astring)->GetKineticTrack()->Get4Momentum();
101 }
102 }
103
105 const G4ParticleDefinition* TrackDefinition=0;
106
108 G4int attempts(0);
109 G4bool success=false;
110 G4bool NeedEnergyCorrector=false;
111 do {
112 #ifdef debug_G4ExcitedStringDecay
113 G4cout<<"New try No "<<attempts<<" to hadronize strings"<<G4endl;
114 #endif
115
116 std::for_each(theResult->begin() , theResult->end() , DeleteKineticTrack());
117 theResult->clear();
118
119 attempts++;
120
121 G4LorentzVector KTsecondaries(0.,0.,0.,0.);
122 NeedEnergyCorrector=false;
123
124 for ( unsigned int astring=0; astring < theStrings->size(); astring++)
125 // for ( unsigned int astring=0; astring < 1; astring++) // Proj. Last Str. Decay for FTF
126 // for ( unsigned int astring=1; astring < 2; astring++) // Proj. Last Str. Decay for QGS
127 // for ( unsigned int astring=0; astring < 1; astring++) // For testing purposes
128 {
129 #ifdef debug_G4ExcitedStringDecay
130 G4cout<<"String No "<<astring+1<<" Excited? "<<theStrings->operator[](astring)->IsExcited()<<G4endl;
131
132 G4cout<<"String No "<<astring+1<<" 4Momentum "<<theStrings->operator[](astring)->Get4Momentum()
133 <<" "<<theStrings->operator[](astring)->Get4Momentum().mag()<<G4endl;
134 #endif
135
136 G4KineticTrackVector * generatedKineticTracks = NULL;
137 if ( theStrings->operator[](astring)->IsExcited() )
138 {
139 #ifdef debug_G4ExcitedStringDecay
140 G4cout<<"Fragment String with partons: "
141 <<theStrings->operator[](astring)->GetLeftParton()->GetPDGcode() <<" "
142 <<theStrings->operator[](astring)->GetRightParton()->GetPDGcode()<<" "
143 <<"Direction "<<theStrings->operator[](astring)->GetDirection()<<G4endl;
144 #endif
145 generatedKineticTracks=FragmentString(*theStrings->operator[](astring));
146 #ifdef debug_G4ExcitedStringDecay
147 G4cout<<"(G4ExcitedStringDecay) Number of produced hadrons = "
148 <<generatedKineticTracks->size()<<G4endl;
149 #endif
150 } else {
151 #ifdef debug_G4ExcitedStringDecay
152 G4cout<<" GetTrack from the String"<<G4endl;
153 #endif
154 G4LorentzVector Mom=theStrings->operator[](astring)->GetKineticTrack()->Get4Momentum();
155 G4KineticTrack * aTrack= new G4KineticTrack(
156 theStrings->operator[](astring)->GetKineticTrack()->GetDefinition(),
157 theStrings->operator[](astring)->GetKineticTrack()->GetFormationTime(),
158 G4ThreeVector(0), Mom);
159
160 aTrack->SetPosition(theStrings->operator[](astring)->GetKineticTrack()->GetPosition());
161
162 #ifdef debug_G4ExcitedStringDecay
163 G4cout<<" A particle stored in the track is "<<aTrack->GetDefinition()->GetParticleName()<<G4endl;
164 #endif
165
166 generatedKineticTracks = new G4KineticTrackVector;
167 generatedKineticTracks->push_back(aTrack);
168 }
169
170 if (generatedKineticTracks == nullptr || generatedKineticTracks->size() == 0)
171 {
172 // G4cerr << "G4VPartonStringModel:No KineticTracks produced" << G4endl;
173 continue;
174 }
175
176 G4LorentzVector KTsum1(0.,0.,0.,0.);
177 for ( unsigned int aTrack=0; aTrack<generatedKineticTracks->size();aTrack++)
178 {
179 #ifdef debug_G4ExcitedStringDecay
180 G4cout<<"Prod part No. "<<aTrack+1<<" "
181 <<(*generatedKineticTracks)[aTrack]->GetDefinition()->GetParticleName()<<" "
182 <<(*generatedKineticTracks)[aTrack]->Get4Momentum()
183 <<(*generatedKineticTracks)[aTrack]->Get4Momentum().mag()<<G4endl;
184 #endif
185 // --------------- Sampling mass of unstable hadronic resonances ----------------
186 TrackDefinition = (*generatedKineticTracks)[aTrack]->GetDefinition();
187
188 if (TrackDefinition->IsShortLived())
189 {
190 G4double NewTrackMass =
191 BrW.SampleMass( TrackDefinition->GetPDGMass(), TrackDefinition->GetPDGWidth(),
192 BrW.GetMinimumMass( TrackDefinition ) + 10.0*MeV,
193 TrackDefinition->GetPDGMass() + 5.0*TrackDefinition->GetPDGWidth() );
194 G4LorentzVector Tmp=G4LorentzVector((*generatedKineticTracks)[aTrack]->Get4Momentum());
195 Tmp.setE(std::sqrt(sqr(NewTrackMass) + Tmp.vect().mag2()));
196
197 (*generatedKineticTracks)[aTrack]->Set4Momentum(Tmp);
198
199 #ifdef debug_G4ExcitedStringDecay
200 G4cout<<"Resonance *** "<<aTrack+1<<" "
201 <<(*generatedKineticTracks)[aTrack]->GetDefinition()->GetParticleName()<<" "
202 <<(*generatedKineticTracks)[aTrack]->Get4Momentum()
203 <<(*generatedKineticTracks)[aTrack]->Get4Momentum().mag()<<G4endl;
204 #endif
205 }
206 //-------------------------------------------------------------------------------
207
208 theResult->push_back(generatedKineticTracks->operator[](aTrack));
209 KTsum1+= (*generatedKineticTracks)[aTrack]->Get4Momentum();
210 }
211 KTsecondaries+=KTsum1;
212
213 #ifdef debug_G4ExcitedStringDecay
214 G4cout << "String secondaries(" <<generatedKineticTracks->size()<< ")"<<G4endl
215 <<"Init string momentum: "<< theStrings->operator[](astring)->Get4Momentum()<<G4endl
216 <<"Final hadrons momentum: "<< KTsum1 << G4endl;
217 #endif
218
219 if ( KTsum1.e() > 0 &&
220 std::abs((KTsum1.e()-theStrings->operator[](astring)->Get4Momentum().e()) / KTsum1.e()) > perMillion )
221 {
222 NeedEnergyCorrector=true;
223 }
224
225 #ifdef debug_G4ExcitedStringDecay
226 G4cout<<"NeedEnergyCorrection yes/no "<<NeedEnergyCorrector<<G4endl;
227 #endif
228
229 // clean up
230 delete generatedKineticTracks;
231 success=true;
232 }
233
234 if ( NeedEnergyCorrector ) success=EnergyAndMomentumCorrector(theResult, KTsum);
235 } while (!success && (attempts < 100)); /* Loop checking, 07.08.2015, A.Ribon */
236
237 for ( unsigned int aTrack=0; aTrack<theResult->size();aTrack++)
238 {
239 Ptmp=(*theResult)[aTrack]->Get4Momentum();
240 Ptmp.transform( toLab);
241 (*theResult)[aTrack]->Set4Momentum(Ptmp);
242 }
243
244 #ifdef debug_G4ExcitedStringDecay
245 G4cout<<"End of the strings fragmentation (G4ExcitedStringDecay)"<<G4endl;
246
247 G4LorentzVector KTsum1(0.,0.,0.,0.);
248
249 for ( unsigned int aTrack=0; aTrack<theResult->size();aTrack++)
250 {
251 G4cout << " corrected tracks .. " << (*theResult)[aTrack]->GetDefinition()->GetParticleName()
252 <<" " << (*theResult)[aTrack]->Get4Momentum()
253 <<" " << (*theResult)[aTrack]->Get4Momentum().mag()<< G4endl;
254 KTsum1+= (*theResult)[aTrack]->Get4Momentum();
255 }
256
257 G4cout << "Needcorrector/success " << NeedEnergyCorrector << "/" << success
258 << ", Corrected total 4 momentum " << KTsum1 << G4endl;
259 if ( ! success ) G4cout << "failed to correct E/p" << G4endl;
260
261 G4cout<<"End of the Hadronization (G4ExcitedStringDecay)"<<G4endl;
262 #endif
263
264 if (!success)
265 {
266 if (theResult->size() != 0)
267 {
268 std::for_each(theResult->begin() , theResult->end() , DeleteKineticTrack());
269 theResult->clear();
270 delete theResult; theResult=0;
271 }
272 for ( unsigned int astring=0; astring < theStrings->size(); astring++)
273 // for ( unsigned int astring=0; astring < 1; astring++) // Need more correct. For testing purposes.
274 {
275 if ( theStrings->operator[](astring)->IsExcited() )
276 {
277 Ptmp=theStrings->operator[](astring)->GetLeftParton()->Get4Momentum();
278 Ptmp.transform( toLab);
279 theStrings->operator[](astring)->GetLeftParton()->Set4Momentum(Ptmp);
280
281 Ptmp=theStrings->operator[](astring)->GetRightParton()->Get4Momentum();
282 Ptmp.transform( toLab);
283 theStrings->operator[](astring)->GetRightParton()->Set4Momentum(Ptmp);
284 }
285 else
286 {
287 Ptmp=theStrings->operator[](astring)->GetKineticTrack()->Get4Momentum();
288 Ptmp.transform( toLab);
289 theStrings->operator[](astring)->GetKineticTrack()->Set4Momentum(Ptmp);
290 }
291 }
292 }
293 return theResult;
294}
295
296
297G4bool G4ExcitedStringDecay::
298EnergyAndMomentumCorrector(G4KineticTrackVector* Output, G4LorentzVector& TotalCollisionMom)
299{
300 const int nAttemptScale = 500;
301 const double ErrLimit = 1.E-5;
302 if (Output->empty()) return TRUE;
303 G4LorentzVector SumMom;
304 G4double SumMass = 0;
305 G4double TotalCollisionMass = TotalCollisionMom.m();
306
307 std::vector<G4double> HadronMass; G4double HadronM(0.);
308
309 #ifdef debug_G4ExcitedStringCorr
310 G4cout<<G4endl<<"EnergyAndMomentumCorrector. Number of particles: "<<Output->size()<<G4endl;
311 #endif
312 // Calculate sum hadron 4-momenta and summing hadron mass
313 unsigned int cHadron;
314 for (cHadron = 0; cHadron < Output->size(); cHadron++)
315 {
316 SumMom += Output->operator[](cHadron)->Get4Momentum();
317 HadronM=Output->operator[](cHadron)->Get4Momentum().mag(); HadronMass.push_back(HadronM);
318 SumMass += Output->operator[](cHadron)->Get4Momentum().mag(); //GetDefinition()->GetPDGMass();
319 }
320
321 #ifdef debug_G4ExcitedStringCorr
322 G4cout<<"Sum part mom "<<SumMom<<" "<<SumMom.mag()<<G4endl
323 <<"Sum str mom "<<TotalCollisionMom<<" "<<TotalCollisionMom.mag()<<G4endl;
324 G4cout<<"SumMass TotalCollisionMass "<<SumMass<<" "<<TotalCollisionMass<<G4endl;
325 #endif
326
327 // Cannot correct a single particle
328 if (Output->size() < 2) return FALSE;
329
330 if (SumMass > TotalCollisionMass) return FALSE;
331 SumMass = SumMom.m2();
332 if (SumMass < 0) return FALSE;
333 SumMass = std::sqrt(SumMass);
334
335 // Compute c.m.s. hadron velocity and boost KTV to hadron c.m.s.
336 // G4ThreeVector Beta = -SumMom.boostVector();
337 G4ThreeVector Beta = -TotalCollisionMom.boostVector();
338 Output->Boost(Beta);
339
340 // Scale total c.m.s. hadron energy (hadron system mass).
341 // It should be equal interaction mass
342 G4double Scale = 1;
343 G4int cAttempt = 0;
344 G4double Sum = 0;
345 G4bool success = false;
346 for (cAttempt = 0; cAttempt < nAttemptScale; cAttempt++)
347 {
348 Sum = 0;
349 for (cHadron = 0; cHadron < Output->size(); cHadron++)
350 {
351 HadronM = HadronMass.at(cHadron);
352 G4LorentzVector HadronMom = Output->operator[](cHadron)->Get4Momentum();
353 HadronMom.setVect(Scale*HadronMom.vect());
354 G4double E = std::sqrt(HadronMom.vect().mag2() + sqr(HadronM));
355 //sqr(Output->operator[](cHadron)->GetDefinition()->GetPDGMass()));
356 HadronMom.setE(E);
357 Output->operator[](cHadron)->Set4Momentum(HadronMom);
358 Sum += E;
359 }
360 Scale = TotalCollisionMass/Sum;
361 #ifdef debug_G4ExcitedStringCorr
362 G4cout << "Scale-1=" << Scale -1
363 << ", TotalCollisionMass=" << TotalCollisionMass
364 << ", Sum=" << Sum
365 << G4endl;
366 #endif
367 if (std::fabs(Scale - 1) <= ErrLimit)
368 {
369 success = true;
370 break;
371 }
372 }
373
374 #ifdef debug_G4ExcitedStringCorr
375 if (!success)
376 {
377 G4cout << "G4ExcitedStringDecay::EnergyAndMomentumCorrector - Warning"<<G4endl;
378 G4cout << " Scale not unity at end of iteration loop: "<<TotalCollisionMass<<" "<<Sum<<" "<<Scale<<G4endl;
379 G4cout << " Number of secondaries: " << Output->size() << G4endl;
380 G4cout << " Wanted total energy: " << TotalCollisionMom.e() << G4endl;
381 G4cout << " Increase number of attempts or increase ERRLIMIT"<<G4endl;
382 // throw G4HadronicException(__FILE__, __LINE__, "G4ExcitedStringDecay failed to correct...");
383 }
384 #endif
385
386 // Compute c.m.s. interaction velocity and KTV back boost
387 Beta = TotalCollisionMom.boostVector();
388 Output->Boost(Beta);
389
390 return success;
391}
392
std::vector< G4ExcitedString * > G4ExcitedStringVector
CLHEP::HepLorentzVector G4LorentzVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double mag2() const
HepLorentzRotation inverse() const
Hep3Vector boostVector() const
Hep3Vector vect() const
void setVect(const Hep3Vector &)
HepLorentzVector & transform(const HepRotation &)
virtual G4KineticTrackVector * FragmentStrings(const G4ExcitedStringVector *theStrings)
G4ExcitedStringDecay(G4VLongitudinalStringDecay *aStringDecay=nullptr)
G4HadronicInteraction * FindModel(const G4String &name)
static G4HadronicInteractionRegistry * Instance()
void SetModelName(const G4String &nam)
const G4String & GetModelName() const
void Boost(G4ThreeVector &Velocity)
void SetPosition(const G4ThreeVector aPosition)
const G4ParticleDefinition * GetDefinition() const
G4double GetPDGWidth() const
const G4String & GetParticleName() const
G4double SampleMass(const G4double poleMass, const G4double gamma, const G4double minMass, const G4double maxMass) const
G4double GetMinimumMass(const G4ParticleDefinition *p) const
virtual G4KineticTrackVector * FragmentString(const G4ExcitedString &theString)=0
#define TRUE
Definition: globals.hh:41
#define FALSE
Definition: globals.hh:38
T sqr(const T &x)
Definition: templates.hh:128