00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <algorithm>
00055
00056 #include "G4QString.hh"
00057 #include "G4PhysicalConstants.hh"
00058 #include "G4SystemOfUnits.hh"
00059
00060
00061 G4double G4QString::MassCut=350.*MeV;
00062 G4double G4QString::SigmaQT=0.5*GeV;
00063 G4double G4QString::DiquarkSuppress=0.1;
00064 G4double G4QString::DiquarkBreakProb=0.1;
00065 G4double G4QString::SmoothParam=0.9;
00066 G4double G4QString::StrangeSuppress=0.435;
00067 G4double G4QString::widthOfPtSquare=-0.72*GeV*GeV;
00068
00069 G4QString::G4QString() : theDirection(0), thePosition(G4ThreeVector(0.,0.,0.)),
00070 theStableParton(0), theDecayParton(0){}
00071
00072 G4QString::G4QString(G4QParton* Color, G4QParton* AntiColor, G4int Direction)
00073 : SideOfDecay(0)
00074 {
00075 #ifdef debug
00076 G4cout<<"G4QString::PPD-Constructor: Direction="<<Direction<<G4endl;
00077 #endif
00078 ExciteString(Color, AntiColor, Direction);
00079 #ifdef debug
00080 G4cout<<"G4QString::PPD-Constructor: ------>> String is excited"<<G4endl;
00081 #endif
00082 }
00083
00084 G4QString::G4QString(G4QPartonPair* CAC): SideOfDecay(0)
00085 {
00086 #ifdef debug
00087 G4cout<<"G4QString::PartonPair-Constructor: Is CALLED"<<G4endl;
00088 #endif
00089 ExciteString(CAC->GetParton1(), CAC->GetParton2(), CAC->GetDirection());
00090 #ifdef debug
00091 G4cout<<"G4QString::PartonPair-Constructor: ------>> String is excited"<<G4endl;
00092 #endif
00093 }
00094
00095 G4QString::G4QString(G4QParton* QCol,G4QParton* Gluon,G4QParton* QAntiCol,G4int Direction)
00096 : theDirection(Direction), thePosition(QCol->GetPosition()), SideOfDecay(0)
00097 {
00098 thePartons.push_back(QCol);
00099 G4LorentzVector sum=QCol->Get4Momentum();
00100 thePartons.push_back(Gluon);
00101 sum+=Gluon->Get4Momentum();
00102 thePartons.push_back(QAntiCol);
00103 sum+=QAntiCol->Get4Momentum();
00104 Pplus =sum.e() + sum.pz();
00105 Pminus=sum.e() - sum.pz();
00106 decaying=None;
00107 }
00108
00109 G4QString::G4QString(const G4QString &right) : theDirection(right.GetDirection()),
00110 thePosition(right.GetPosition()), SideOfDecay(0)
00111 {
00112
00113
00114 Ptleft=right.Ptleft;
00115 Ptright=right.Ptright;
00116 Pplus=right.Pplus;
00117 Pminus=right.Pminus;
00118 decaying=right.decaying;
00119 }
00120
00121 G4QString::~G4QString()
00122 {if(thePartons.size()) std::for_each(thePartons.begin(),thePartons.end(),DeleteQParton());}
00123
00124 G4LorentzVector G4QString::Get4Momentum() const
00125 {
00126 G4LorentzVector momentum(0.,0.,0.,0.);
00127 for(unsigned i=0; i<thePartons.size(); i++) momentum += thePartons[i]->Get4Momentum();
00128 return momentum;
00129 }
00130
00131 void G4QString::LorentzRotate(const G4LorentzRotation & rotation)
00132 {
00133 for(unsigned i=0; i<thePartons.size(); i++)
00134 thePartons[i]->Set4Momentum(rotation*thePartons[i]->Get4Momentum());
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 void G4QString::Boost(G4ThreeVector& Velocity)
00153 {
00154 for(unsigned cParton=0; cParton<thePartons.size(); cParton++)
00155 {
00156 G4LorentzVector Mom = thePartons[cParton]->Get4Momentum();
00157 Mom.boost(Velocity);
00158 thePartons[cParton]->Set4Momentum(Mom);
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 void G4QString::SetParameters(G4double mCut, G4double sigQT, G4double DQSup, G4double DQBU,
00182 G4double smPar, G4double SSup, G4double SigPt)
00183 {
00184 MassCut = mCut;
00185 SigmaQT = sigQT;
00186 DiquarkSuppress = DQSup;
00187 DiquarkBreakProb= DQBU;
00188 SmoothParam = smPar;
00189 StrangeSuppress = SSup;
00190 widthOfPtSquare = -2*SigPt*SigPt;
00191 }
00192
00193
00194 G4ThreeVector G4QString::GaussianPt(G4double widthSquare, G4double maxPtSquare) const
00195 {
00196 G4double pt2; do{pt2=widthSquare*std::log(G4UniformRand());} while (pt2>maxPtSquare);
00197 pt2=std::sqrt(pt2);
00198 G4double phi=G4UniformRand()*twopi;
00199 return G4ThreeVector(pt2*std::cos(phi),pt2*std::sin(phi),0.);
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 void G4QString::ExciteString(G4QParton* Color, G4QParton* AntiColor, G4int Direction)
00255 {
00256 #ifdef debug
00257 G4cout<<"G4QString::ExciteString: **Called**, direction="<<Direction<<G4endl;
00258 #endif
00259 if(thePartons.size()) std::for_each(thePartons.begin(),thePartons.end(),DeleteQParton());
00260 thePartons.clear();
00261 theDirection = Direction;
00262 thePosition = Color->GetPosition();
00263 #ifdef debug
00264 G4cout<<"G4QString::ExciteString: ColourPosition = "<<thePosition<<", beg="<<Color->GetPDGCode()
00265 <<",end="<<AntiColor->GetPDGCode()<<G4endl;
00266 #endif
00267 thePartons.push_back(Color);
00268 G4LorentzVector sum=Color->Get4Momentum();
00269 thePartons.push_back(AntiColor);
00270 sum+=AntiColor->Get4Momentum();
00271 Pplus =sum.e() + sum.pz();
00272 Pminus=sum.e() - sum.pz();
00273 decaying=None;
00274 #ifdef debug
00275 G4cout<<"G4QString::ExciteString: ***Done***, beg="<<(*thePartons.begin())->GetPDGCode()
00276 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00277 #endif
00278 }
00279
00280
00281 G4double G4QString::GetLundLightConeZ(G4double zmin, G4double zmax, G4int ,
00282 G4QHadron* pHadron, G4double Px, G4double Py)
00283 {
00284 static const G4double alund = 0.7/GeV/GeV;
00285
00286
00287 G4double z, yf;
00288 G4double Mt2 = Px*Px + Py*Py + pHadron->GetMass2();
00289 G4double zOfMaxyf=alund*Mt2/(alund*Mt2+1.);
00290 G4double maxYf=(1.-zOfMaxyf)/zOfMaxyf * std::exp(-alund*Mt2/zOfMaxyf);
00291 do
00292 {
00293 z = zmin + G4UniformRand()*(zmax-zmin);
00294
00295 yf = (1-z)/z * std::exp(-alund*Mt2/z);
00296 } while (G4UniformRand()*maxYf>yf);
00297 return z;
00298 }
00299
00300
00301
00302 G4double G4QString::GetQGSMLightConeZ(G4double zmin, G4double zmax, G4int PartonEncoding,
00303 G4QHadron* , G4double, G4double)
00304 {
00305 static const G4double arho=0.5;
00306 static const G4double aphi=0.;
00307 static const G4double an=-0.5;
00308 static const G4double ala=-0.75;
00309 static const G4double aksi=-1.;
00310 static const G4double alft=0.5;
00311 G4double z;
00312 G4double theA(0), d2, yf;
00313 G4int absCode = std::abs(PartonEncoding);
00314
00315 if (absCode < 10)
00316 {
00317 if(absCode == 1 || absCode == 2) theA = arho;
00318 else if(absCode == 3) theA = aphi;
00319 else
00320 {
00321 G4cerr<<"***G4QString::GetQGSMLightConeZ: CHIPS is SU(3), quakCode="<<absCode<<G4endl;
00322 G4Exception("G4QString::GetQGSMLightConeZ:","72",FatalException,"WrongQuark");
00323 }
00324 do
00325 {
00326 z = zmin + G4UniformRand()*(zmax - zmin);
00327 d2 = alft - theA;
00328 yf = std::pow( 1.-z, d2);
00329 }
00330 while (G4UniformRand()>yf);
00331 }
00332 else
00333 {
00334 if (absCode==3101||absCode==3103||absCode==3201||absCode==3203) d2=alft-ala-ala+arho;
00335 else if(absCode==1103||absCode==2101||absCode==2203||absCode==2103) d2=alft-an-an+arho;
00336 else d2=alft-aksi-aksi+arho;
00337 do
00338 {
00339 z = zmin + G4UniformRand()*(zmax - zmin);
00340 yf = std::pow(1.-z, d2);
00341 }
00342 while (G4UniformRand()>yf);
00343 }
00344 return z;
00345 }
00346
00347
00348 G4QHadronVector* G4QString::FragmentString(G4bool QL)
00349 {
00350
00351 #ifdef edebug
00352 G4LorentzVector string4M=Get4Momentum();
00353 #endif
00354 #ifdef debug
00355 G4cout<<"G4QString::FragmentString:-->Called,QL="<<QL<<", M="<<Get4Momentum().m()<<", L="
00356 <<GetLeftParton()->Get4Momentum()<<",R="<<GetRightParton()->Get4Momentum()<<G4endl;
00357 #endif
00358
00359 G4QHadronVector* LeftVector = LightFragmentationTest();
00360 if(LeftVector)
00361 {
00362 #ifdef edebug
00363 G4LorentzVector sL=string4M;
00364 for(unsigned L = 0; L < LeftVector->size(); L++)
00365 {
00366 G4QHadron* LH = (*LeftVector)[L];
00367 G4LorentzVector L4M=LH->Get4Momentum();
00368 sL-=L4M;
00369 G4cout<<"-EMC-G4QStr::FragStr:L#"<<L<<",PDG="<<LH->GetPDGCode()<<",4M="<<L4M<<G4endl;
00370 }
00371 G4cout<<"-EMC-G4QString::FragmentString:---LightFragmentation---> Res4M="<<sL<<G4endl;
00372 #endif
00373 return LeftVector;
00374 }
00375 #ifdef debug
00376 G4cout<<"G4QString::FragmentString:OUTPUT is not yet defined, define Left/Right"<<G4endl;
00377 #endif
00378 LeftVector = new G4QHadronVector;
00379 G4QHadronVector* RightVector = new G4QHadronVector;
00380
00381 G4LorentzVector left4M=GetLeftParton()->Get4Momentum();
00382 G4LorentzVector right4M=GetRightParton()->Get4Momentum();
00383 #ifdef debug
00384 G4cout<<"G4QString::FragmString: ***Remember*** L4M="<<left4M<<", R4M="<<right4M<<G4endl;
00385 #endif
00386 G4int leftPDG=GetLeftParton()->GetPDGCode();
00387 G4int rightPDG=GetRightParton()->GetPDGCode();
00388
00389 G4LorentzVector momentum=Get4Momentum();
00390 G4LorentzRotation toCms(-(momentum.boostVector()));
00391 momentum= toCms * thePartons[0]->Get4Momentum();
00392 toCms.rotateZ(-1*momentum.phi());
00393 toCms.rotateY(-1*momentum.theta());
00394 for(unsigned index=0; index<thePartons.size(); index++)
00395 {
00396 momentum = toCms * thePartons[index]->Get4Momentum();
00397 thePartons[index]->Set4Momentum(momentum);
00398 }
00399
00400 G4QParton* LeftParton = new G4QParton(GetLeftParton());
00401 G4QParton* RightParton= new G4QParton(GetRightParton());
00402 G4QString* theStringInCMS = new G4QString(LeftParton,RightParton,GetDirection());
00403 #ifdef debug
00404 G4cout<<"G4QString::FragmentString: Copy with nP="<<theStringInCMS->thePartons.size()
00405 <<", beg="<<(*(theStringInCMS->thePartons.begin()))->GetPDGCode()
00406 <<", end="<<(*(theStringInCMS->thePartons.end()-1))->GetPDGCode()<<G4endl;
00407 #endif
00408 G4bool success=false;
00409 G4bool inner_sucess=true;
00410 G4int attempt=0;
00411 G4int StringLoopInterrupt=27;
00412 #ifdef debug
00413 G4cout<<"G4QString::FragmentString: BeforeWhileLOOP, max = "<<StringLoopInterrupt
00414 <<", nP="<<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00415 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00416 #endif
00417 #ifdef edebug
00418 G4LorentzVector cmS4M=theStringInCMS->Get4Momentum();
00419 G4cout<<"-EMC-G4QString::FragmString: c4M="<<cmS4M<<",Max="<<StringLoopInterrupt<<G4endl;
00420 #endif
00421 while (!success && attempt++ < StringLoopInterrupt)
00422 {
00423
00424 LeftParton = new G4QParton(theStringInCMS->GetLeftParton());
00425 RightParton= new G4QParton(theStringInCMS->GetRightParton());
00426 ExciteString(LeftParton, RightParton, theStringInCMS->GetDirection());
00427 #ifdef edebug
00428 G4LorentzVector cm4M=cmS4M;
00429 G4cout<<"-EMC-.G4QString::FragmentString: CHEK "<<cm4M<<" ?= "<<Get4Momentum()<<G4endl;
00430 #endif
00431 #ifdef debug
00432 G4cout<<"G4QString::FragmentString:===>LOOP, attempt = "<<attempt<<", nP="
00433 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00434 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00435 #endif
00436
00437 if(LeftVector->size())
00438 {
00439 std::for_each(LeftVector->begin(), LeftVector->end(), DeleteQHadron());
00440 LeftVector->clear();
00441 }
00442
00443 if(RightVector->size())
00444 {
00445 std::for_each(RightVector->begin(), RightVector->end(), DeleteQHadron());
00446 RightVector->clear();
00447 }
00448
00449 inner_sucess=true;
00450 while (!StopFragmentation())
00451 {
00452 #ifdef debug
00453 G4cout<<"G4QString::FragmentString:-->Begin LOOP/LOOP, decaying="<<decaying<<G4endl;
00454 #endif
00455 G4QHadron* Hadron=Splitup(QL);
00456 #ifdef edebug
00457 cm4M-=Hadron->Get4Momentum();
00458 G4cout<<"-EMC-G4QString::FragmentString:LOOP/LOOP,d4M="<<cm4M-Get4Momentum()<<G4endl;
00459 #endif
00460 G4bool canBeFrag=IsFragmentable();
00461 #ifdef debug
00462 G4cout<<"G4QString::FragmentString: LOOP/LOOP, canBeFrag="<<canBeFrag<<", decay="
00463 <<decaying<<", H="<<Hadron<<", newStringMass="<<Get4Momentum().m()<<G4endl;
00464 #endif
00465 if(Hadron && canBeFrag)
00466 {
00467 #ifdef debug
00468 G4cout<<">>G4QString::FragmentString: LOOP/LOOP-NO FRAGM-, dec="<<decaying<<G4endl;
00469 #endif
00470 if(GetDecayDirection()>0) LeftVector->push_back(Hadron);
00471 else RightVector->push_back(Hadron);
00472 }
00473 else
00474 {
00475
00476
00477 #ifdef debug
00478 G4cout<<"G4QString::FragmentString: LOOP/LOOP, Start from scratch"<<G4endl;
00479 #endif
00480 if (Hadron) delete Hadron;
00481 inner_sucess=false;
00482 break;
00483 }
00484 #ifdef debug
00485 G4cout<<"G4QString::FragmentString: LOOP/LOOP End, nP="
00486 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00487 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00488 #endif
00489 }
00490 #ifdef edebug
00491 G4LorentzVector fLR=cmS4M-Get4Momentum();
00492 for(unsigned L = 0; L < LeftVector->size(); L++)
00493 {
00494 G4QHadron* LH = (*LeftVector)[L];
00495 G4LorentzVector L4M=LH->Get4Momentum();
00496 fLR-=L4M;
00497 G4cout<<"-EMC-G4QStr::FrStr:L#"<<L<<",PDG="<<LH->GetPDGCode()<<",4M="<<L4M<<G4endl;
00498 }
00499 for(unsigned R = 0; R < RightVector->size(); R++)
00500 {
00501 G4QHadron* RH = (*RightVector)[R];
00502 G4LorentzVector R4M=RH->Get4Momentum();
00503 fLR-=R4M;
00504 G4cout<<"-EMC-G4QStr::FrStr:R#"<<R<<",PDG="<<RH->GetPDGCode()<<",4M="<<R4M<<G4endl;
00505 }
00506 G4cout<<"-EMC-G4QString::FragmentString:L/R_BeforLast->r4M/M2="<<fLR<<fLR.m2()<<G4endl;
00507 #endif
00508
00509 #ifdef debug
00510 G4cout<<"G4QString::FragmentString: inner_success = "<<inner_sucess<<G4endl;
00511 #endif
00512 if(inner_sucess)
00513 {
00514 success=true;
00515
00516 G4LorentzVector tot4M = Get4Momentum();
00517 G4double totM = tot4M.m();
00518 #ifdef debug
00519 G4cout<<"G4QString::FragmString: string4M="<<tot4M<<totM<<G4endl;
00520 #endif
00521 G4QHadron* LeftHadron;
00522 G4QHadron* RightHadron;
00523 G4QParton* RQuark = 0;
00524 SetLeftPartonStable();
00525 if(DecayIsQuark() && StableIsQuark())
00526 {
00527 #ifdef debug
00528 G4cout<<"G4QString::FragmentString: LOOP Quark Algorithm"<<G4endl;
00529 #endif
00530 LeftHadron= QuarkSplitup(GetLeftParton(), RQuark);
00531 }
00532 else
00533 {
00534 #ifdef debug
00535 G4cout<<"G4QString::FragmentString: LOOP Di-Quark Algorithm"<<G4endl;
00536 #endif
00537
00538 G4int IsParticle;
00539 if(StableIsQuark()) IsParticle=(GetLeftParton()->GetPDGCode()>0)?-1:1;
00540 else IsParticle=(GetLeftParton()->GetPDGCode()>0)?1:-1;
00541 G4QPartonPair QuarkPair = CreatePartonPair(IsParticle,false);
00542 RQuark = QuarkPair.GetParton2();
00543 G4QParton* LQuark = QuarkPair.GetParton1();
00544 LeftHadron = CreateHadron(LQuark, GetLeftParton());
00545 delete LQuark;
00546 }
00547 RightHadron = CreateHadron(GetRightParton(), RQuark);
00548 delete RQuark;
00549
00550 G4double LhM=LeftHadron->GetMass();
00551 G4double RhM=RightHadron->GetMass();
00552 #ifdef debug
00553 G4cout<<"G4QStr::FrSt:L="<<LeftHadron->GetPDGCode()<<",R="<<RightHadron->GetPDGCode()
00554 <<",ML="<<LhM<<",MR="<<RhM<<",SumM="<<LhM+RhM<<",tM="<<totM<<G4endl;
00555 #endif
00556 if(totM < LhM + RhM) success=false;
00557
00558 if(success)
00559 {
00560 G4ThreeVector Pos=GetPosition();
00561 G4LorentzVector Lh4M(0.,0.,0.,LhM);
00562 G4LorentzVector Rh4M(0.,0.,0.,RhM);
00563 if(G4QHadron(tot4M).DecayIn2(Lh4M,Rh4M))
00564 {
00565 LeftVector->push_back(new G4QHadron(LeftHadron, 0, Pos, Lh4M));
00566 delete LeftHadron;
00567 RightVector->push_back(new G4QHadron(RightHadron, 0, Pos, Rh4M));
00568 delete RightHadron;
00569 }
00570 #ifdef debug
00571 G4cout<<"->>G4QStr::FragString:HFilled (L) PDG="<<LeftHadron->GetPDGCode()<<", 4M="
00572 <<Lh4M<<", (R) PDG="<<RightHadron->GetPDGCode()<<", 4M="<<Rh4M<<G4endl;
00573 #endif
00574 #ifdef edebug
00575 G4cout<<"-EMC-G4QString::FragmentString: Residual4M="<<tot4M-Lh4M-Rh4M<<G4endl;
00576 #endif
00577 }
00578 else
00579 {
00580 if(LeftHadron) delete LeftHadron;
00581 if(RightHadron) delete RightHadron;
00582 }
00583 }
00584 }
00585 delete theStringInCMS;
00586 #ifdef debug
00587 G4cout<<"G4QString::FragmentString: LOOP/LOOP, success="<<success<<G4endl;
00588 #endif
00589 if (!success)
00590 {
00591 if(RightVector->size())
00592 {
00593 std::for_each(RightVector->begin(), RightVector->end(), DeleteQHadron());
00594 RightVector->clear();
00595 }
00596 delete RightVector;
00597 if(LeftVector->size())
00598 {
00599 std::for_each(LeftVector->begin(), LeftVector->end(), DeleteQHadron());
00600 LeftVector->clear();
00601 }
00602 delete LeftVector;
00603 #ifdef debug
00604 G4cout<<"G4QString::FragmString:StringNotFragm,L4M="<<left4M<<",R4M="<<right4M<<G4endl;
00605 #endif
00606
00607 GetLeftParton()->SetPDGCode(leftPDG);
00608 GetRightParton()->SetPDGCode(rightPDG);
00609 GetLeftParton()->Set4Momentum(left4M);
00610 GetRightParton()->Set4Momentum(right4M);
00611 return 0;
00612 }
00613
00614 #ifdef edebug
00615 G4LorentzVector sLR=cmS4M;
00616 for(unsigned L = 0; L < LeftVector->size(); L++)
00617 {
00618 G4QHadron* LH = (*LeftVector)[L];
00619 G4LorentzVector L4M=LH->Get4Momentum();
00620 sLR-=L4M;
00621 G4cout<<"-EMC-G4QStr::FragmStri:L#"<<L<<",PDG="<<LH->GetPDGCode()<<",4M="<<L4M<<G4endl;
00622 }
00623 for(unsigned R = 0; R < RightVector->size(); R++)
00624 {
00625 G4QHadron* RH = (*RightVector)[R];
00626 G4LorentzVector R4M=RH->Get4Momentum();
00627 sLR-=R4M;
00628 G4cout<<"-EMC-G4QStr::FragmStri:R#"<<R<<",PDG="<<RH->GetPDGCode()<<",4M="<<R4M<<G4endl;
00629 }
00630 G4cout<<"-EMC-G4QString::FragmentString:---L/R_BeforeMerge---> Res4M="<<sLR<<G4endl;
00631 #endif
00632
00633 while(!RightVector->empty())
00634 {
00635 LeftVector->push_back(RightVector->back());
00636 RightVector->erase(RightVector->end()-1);
00637 }
00638 delete RightVector;
00639
00640 G4QHadronVector::iterator ilv;
00641 for(ilv = LeftVector->begin(); ilv < LeftVector->end(); ilv++)
00642 {
00643 G4ThreeVector CV=(*ilv)->Get4Momentum().vect();
00644 if(CV.x()==0. && CV.y()==0. && CV.z()==0.) LeftVector->erase(ilv);
00645 }
00646
00647 G4double StringMass=Get4Momentum().mag();
00648 static const G4double dkappa = 2.0 * GeV/fermi;
00649 for(unsigned c1 = 0; c1 < LeftVector->size(); c1++)
00650 {
00651 G4double SumPz = 0;
00652 G4double SumE = 0;
00653 for(unsigned c2 = 0; c2 < c1; c2++)
00654 {
00655 G4LorentzVector hc2M=(*LeftVector)[c2]->Get4Momentum();
00656 SumPz += hc2M.pz();
00657 SumE += hc2M.e();
00658 }
00659 G4QHadron* hc1=(*LeftVector)[c1];
00660 G4LorentzVector hc1M=hc1->Get4Momentum();
00661 G4double HadronE = hc1M.e();
00662 G4double HadronPz= hc1M.pz();
00663 hc1->SetFormationTime((StringMass-SumPz-SumPz+HadronE-HadronPz)/dkappa);
00664 hc1->SetPosition(G4ThreeVector(0,0,(StringMass-SumE-SumE-HadronE+HadronPz)/dkappa));
00665 }
00666 G4LorentzRotation toObserverFrame(toCms.inverse());
00667 #ifdef debug
00668 G4cout<<"G4QString::FragmentString: beforeLoop LVsize = "<<LeftVector->size()<<G4endl;
00669 #endif
00670 for(unsigned C1 = 0; C1 < LeftVector->size(); C1++)
00671 {
00672 G4QHadron* Hadron = (*LeftVector)[C1];
00673 G4LorentzVector Momentum = Hadron->Get4Momentum();
00674 Momentum = toObserverFrame*Momentum;
00675 Hadron->Set4Momentum(Momentum);
00676 G4LorentzVector Coordinate(Hadron->GetPosition(), Hadron->GetFormationTime());
00677 Momentum = toObserverFrame*Coordinate;
00678 Hadron->SetFormationTime(Momentum.e());
00679 Hadron->SetPosition(GetPosition()+Momentum.vect());
00680 }
00681 #ifdef edebug
00682 G4LorentzVector sLA=string4M;
00683 for(unsigned L = 0; L < LeftVector->size(); L++)
00684 {
00685 G4QHadron* LH = (*LeftVector)[L];
00686 G4LorentzVector L4M=LH->Get4Momentum();
00687 sLA-=L4M;
00688 G4cout<<"-EMC-G4QStr::FragmStri:L#"<<L<<",PDG="<<LH->GetPDGCode()<<",4M="<<L4M<<G4endl;
00689 }
00690 G4cout<<"-EMC-G4QString::FragmentString:---LSAfterMerge&Conv---> Res4M="<<sLA<<G4endl;
00691 #endif
00692 #ifdef debug
00693 G4cout<<"G4QString::FragmentString: *** Done *** "<<G4endl;
00694 #endif
00695 return LeftVector;
00696 }
00697
00698
00699
00700
00701
00702 G4QHadronVector* G4QString::LightFragmentationTest()
00703 {
00704
00705 G4LorentzVector tot4M=Get4Momentum();
00706 #ifdef debug
00707 G4cout<<"G4QString::LightFragmentationTest: ***Called***, string4M="<<tot4M<<G4endl;
00708 #endif
00709 G4QHadronVector* result=0;
00710
00711 G4QHadronPair hadrons((G4QHadron*)0, (G4QHadron*)0);
00712 G4double fragMass = FragmentationMass(0,&hadrons);
00713 #ifdef debug
00714 G4cout<<"G4QString::LightFragTest: before check nP="<<thePartons.size()<<", MS2="
00715 <<Mass2()<<", MCut="<<MassCut<<", beg="<<(*thePartons.begin())->GetPDGCode()
00716 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<", fM="<<fragMass<<G4endl;
00717 #endif
00718 if(Mass2() > sqr(fragMass+MassCut))
00719 {
00720 if(hadrons.first) delete hadrons.first;
00721 if(hadrons.second) delete hadrons.second;
00722 #ifdef debug
00723 G4cout<<"G4QString::LightFragTest:NO,M2="<<Mass2()<<">"<<sqr(fragMass+MassCut)<<G4endl;
00724 #endif
00725 return result;
00726 }
00727 G4double totM= tot4M.m();
00728 G4QHadron* h1=hadrons.first;
00729 G4QHadron* h2=hadrons.second;
00730 if(h1 && h2)
00731 {
00732 G4double h1M = h1->GetMass();
00733 G4double h2M = h2->GetMass();
00734 #ifdef debug
00735 G4cout<<"G4QString::LightFragTest:tM="<<totM<<","<<h1M<<"+"<<h2M<<"+"<<h1M+h2M<<G4endl;
00736 #endif
00737 if(h1M + h2M <= totM)
00738 {
00739
00740 G4LorentzVector h4M1(0.,0.,0.,h1M);
00741 G4LorentzVector h4M2(0.,0.,0.,h2M);
00742 if(G4QHadron(tot4M).DecayIn2(h4M1,h4M2))
00743 {
00744 result = new G4QHadronVector;
00745 result->push_back(new G4QHadron(hadrons.first, 0, GetPosition(), h4M1));
00746 result->push_back(new G4QHadron(hadrons.second,0, GetPosition(), h4M2));
00747 }
00748 #ifdef edebug
00749 G4int L=result->size(); if(L) for(G4int i=0; i<L; i++)
00750 {
00751 tot4M-=(*result)[i]->Get4Momentum();
00752 G4cout<<"-EMC-G4QString::LightFragTest: i="<<i<<", residual4M="<<tot4M<<G4endl;
00753 }
00754 #endif
00755 }
00756 #ifdef debug
00757 else G4cout<<"-Warning-G4QString::LightFragTest: TooBigHadronMasses to decay"<<G4endl;
00758 #endif
00759 }
00760 #ifdef debug
00761 else G4cout<<"-Warning-G4QString::LightFragTest: No Hadrons have been proposed"<<G4endl;
00762 #endif
00763 delete hadrons.first;
00764 delete hadrons.second;
00765 return result;
00766 }
00767
00768
00769 G4double G4QString::FragmentationMass(G4int HighSpin, G4QHadronPair* pdefs)
00770 {
00771 G4double mass=0.;
00772 #ifdef debug
00773 G4cout<<"G4QString::FragmMass: ***Called***, s4M="<<Get4Momentum()<<G4endl;
00774 #endif
00775
00776 G4QHadron* Hadron1 = 0;
00777 G4QHadron* Hadron2 = 0;
00778 #ifdef debug
00779 G4cout<<"G4QString::FragmentationMass: Create spin-0 or spin-1/2 hadron: nP="
00780 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00781 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00782 #endif
00783 G4int iflc = (G4UniformRand() < 0.5) ? 1 : 2;
00784 G4int LPDG= GetLeftParton()->GetPDGCode();
00785 G4int LT = GetLeftParton()->GetType();
00786 if ( (LPDG > 0 && LT == 1) || (LPDG < 0 && LT == 2) ) iflc = -iflc;
00787 G4QParton* piflc = new G4QParton( iflc);
00788 G4QParton* miflc = new G4QParton(-iflc);
00789 if(HighSpin)
00790 {
00791 Hadron1 = CreateHighSpinHadron(GetLeftParton(),piflc);
00792 Hadron2 = CreateHighSpinHadron(GetRightParton(),miflc);
00793 #ifdef debug
00794 G4cout<<"G4QString::FragmentationMass: High, PDG1="<<Hadron1->GetPDGCode()
00795 <<", PDG2="<<Hadron2->GetPDGCode()<<G4endl;
00796 #endif
00797 }
00798 else
00799 {
00800 Hadron1 = CreateLowSpinHadron(GetLeftParton(),piflc);
00801 Hadron2 = CreateLowSpinHadron(GetRightParton(),miflc);
00802 #ifdef debug
00803 G4cout<<"G4QString::FragmentationMass: Low, PDG1="<<Hadron1->GetPDGCode()
00804 <<", PDG2="<<Hadron2->GetPDGCode()<<G4endl;
00805 #endif
00806 }
00807 mass = Hadron1->GetMass() + Hadron2->GetMass();
00808 if(pdefs)
00809 {
00810 pdefs->first = Hadron1;
00811 pdefs->second = Hadron2;
00812 }
00813 else
00814 {
00815 if(Hadron1) delete Hadron1;
00816 if(Hadron2) delete Hadron2;
00817 }
00818 delete piflc;
00819 delete miflc;
00820 #ifdef debug
00821 G4cout<<"G4QString::FragmentationMass: ***Done*** mass="<<mass<<G4endl;
00822 #endif
00823 return mass;
00824 }
00825
00826 void G4QString::SetLeftPartonStable()
00827 {
00828 theStableParton=GetLeftParton();
00829 theDecayParton=GetRightParton();
00830 decaying=Right;
00831 }
00832
00833 void G4QString::SetRightPartonStable()
00834 {
00835 theStableParton=GetRightParton();
00836 theDecayParton=GetLeftParton();
00837 decaying=Left;
00838 }
00839
00840 G4int G4QString::GetDecayDirection() const
00841 {
00842 if (decaying == Left ) return +1;
00843 else if (decaying == Right) return -1;
00844 else
00845 {
00846 G4cerr<<"***G4QString::GetDecayDirection: wrong DecayDirection="<<decaying<<G4endl;
00847 G4Exception("G4QString::GetDecayDirection:","72",FatalException,"WrongDecayDirection");
00848 }
00849 return 0;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 G4ThreeVector G4QString::DecayPt()
00865 {
00866 if (decaying == Left ) return Ptleft;
00867 else if (decaying == Right ) return Ptright;
00868 else
00869 {
00870 G4cerr<<"***G4QString::DecayPt: wrong DecayDirection="<<decaying<<G4endl;
00871 G4Exception("G4QString::DecayPt:","72",FatalException,"WrongDecayDirection");
00872 }
00873 return G4ThreeVector();
00874 }
00875
00876
00877 G4QHadron* G4QString::Splitup(G4bool QL)
00878 {
00879 SideOfDecay = (G4UniformRand() < 0.5) ? 1: -1;
00880 #ifdef debug
00881 G4cout<<"G4QString::Splitup:**Called**,s="<<SideOfDecay<<",s4M="<<Get4Momentum()<<G4endl;
00882 #endif
00883 if(SideOfDecay<0) SetLeftPartonStable();
00884 else SetRightPartonStable();
00885 G4QParton* newStringEnd;
00886 G4QHadron* Hadron;
00887 if(DecayIsQuark()) Hadron= QuarkSplitup(theDecayParton, newStringEnd);
00888 else Hadron= DiQuarkSplitup(theDecayParton, newStringEnd);
00889 #ifdef debug
00890 G4cout<<"G4QString::Splitup: newStringEndPDG="<<newStringEnd->GetPDGCode()<<", nP="
00891 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00892 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00893 #endif
00894
00895 G4LorentzVector* HadronMomentum=SplitEandP(Hadron, QL);
00896 #ifdef debug
00897 G4cout<<"G4QString::Splitup: HM="<<HadronMomentum<<", nP="
00898 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00899 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00900 #endif
00901 if(HadronMomentum)
00902 {
00903 #ifdef pdebug
00904 G4cout<<"---->>G4QString::Splitup: HFilled 4M="<<*HadronMomentum<<",PDG="
00905 <<Hadron->GetPDGCode()<<",s4M-h4M="<<Get4Momentum()-*HadronMomentum<<G4endl;
00906 #endif
00907 newStringEnd->Set4Momentum(theDecayParton->Get4Momentum()-*HadronMomentum);
00908 Hadron->Set4Momentum(*HadronMomentum);
00909 Hadron->SetPosition(GetPosition());
00910 if(decaying == Left)
00911 {
00912 G4QParton* theFirst = thePartons[0];
00913 delete theFirst;
00914 thePartons[0] = newStringEnd;
00915 #ifdef debug
00916 G4cout<<"G4QString::Splitup: theFirstPDG="<<theFirst->GetPDGCode()<<G4endl;
00917 #endif
00918 Ptleft -= HadronMomentum->vect();
00919 Ptleft.setZ(0.);
00920 }
00921 else if (decaying == Right)
00922 {
00923 G4QParton* theLast = thePartons[thePartons.size()-1];
00924 delete theLast;
00925 thePartons[thePartons.size()-1] = newStringEnd;
00926 #ifdef debug
00927 G4cout<<"G4QString::Splitup: theLastPDG="<<theLast->GetPDGCode()<<", nP="
00928 <<thePartons.size()<<", beg="<<thePartons[0]->GetPDGCode()<<",end="
00929 <<thePartons[thePartons.size()-1]->GetPDGCode()<<",P="<<theLast
00930 <<"="<<thePartons[thePartons.size()-1]<<G4endl;
00931 #endif
00932 Ptright -= HadronMomentum->vect();
00933 Ptright.setZ(0.);
00934 }
00935 else
00936 {
00937 G4cerr<<"***G4QString::Splitup: wrong oldDecay="<<decaying<<G4endl;
00938 G4Exception("G4QString::Splitup","72",FatalException,"WrongDecayDirection");
00939 }
00940 Pplus -= HadronMomentum->e() + HadronMomentum->pz();
00941 Pminus -= HadronMomentum->e() - HadronMomentum->pz();
00942 #ifdef debug
00943 G4cout<<"G4QString::Splitup: P+="<<Pplus<<",P-="<<Pminus<<", nP="
00944 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00945 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00946 G4cout<<">...>G4QString::Splitup: NewString4M="<<Get4Momentum()<<G4endl;
00947 #endif
00948 delete HadronMomentum;
00949 }
00950 #ifdef debug
00951 G4cout<<"G4QString::Splitup: ***Done*** H4M="<<Hadron->Get4Momentum()<<", nP="
00952 <<thePartons.size()<<", beg="<<(*thePartons.begin())->GetPDGCode()
00953 <<",end="<<(*(thePartons.end()-1))->GetPDGCode()<<G4endl;
00954 #endif
00955 return Hadron;
00956 }
00957
00958
00959 G4LorentzVector* G4QString::SplitEandP(G4QHadron* pHadron, G4bool QL)
00960 {
00961 G4double HadronMass = pHadron->GetMass();
00962 #ifdef debug
00963 G4cout<<"G4QString::SplitEandP: ***Called*** HMass="<<HadronMass<<G4endl;
00964 #endif
00965
00966 G4ThreeVector HadronPt = SampleQuarkPt() + DecayPt();
00967 HadronPt.setZ(0.);
00968
00969
00970 G4double HadronMass2T = HadronMass*HadronMass + HadronPt.mag2();
00971 if (HadronMass2T >= SmoothParam*Mass2() ) return 0;
00972
00973 G4double zMin = HadronMass2T/Mass2();
00974 G4double zMax = 1.;
00975 #ifdef debug
00976 G4cout<<"G4QString::SplitEandP: zMin="<<zMin<<", zMax"<<zMax<<G4endl;
00977 #endif
00978 if (zMin >= zMax) return 0;
00979 G4double z=0;
00980 if(QL) z = GetQGSMLightConeZ(zMin, zMax, theDecayParton->GetPDGCode(), pHadron,
00981 HadronPt.x(), HadronPt.y());
00982 else z = GetLundLightConeZ(zMin, zMax, theDecayParton->GetPDGCode(), pHadron,
00983 HadronPt.x(), HadronPt.y());
00984
00985
00986 G4double zl= z;
00987 if (decaying == Left ) zl*=Pplus;
00988 else if (decaying == Right ) zl*=Pminus;
00989 else
00990 {
00991 G4cerr<<"***G4QString::SplitEandP: wrong DecayDirection="<<decaying<<G4endl;
00992 G4Exception("G4QString::SplitEandP:","72",FatalException,"WrongDecayDirection");
00993 }
00994 G4double HadronE = (zl + HadronMass2T/zl)/2;
00995 HadronPt.setZ( GetDecayDirection() * (zl - HadronE) );
00996 G4LorentzVector* a4Momentum= new G4LorentzVector(HadronPt,HadronE);
00997 return a4Momentum;
00998 }
00999
01000 G4ThreeVector G4QString::SampleQuarkPt()
01001 {
01002 G4double Pt = SigmaQT * std::sqrt( -std::log(G4UniformRand()));
01003 G4double phi = twopi*G4UniformRand();
01004 return G4ThreeVector(Pt * std::cos(phi),Pt * std::sin(phi),0);
01005 }
01006
01007 G4QHadron* G4QString::QuarkSplitup(G4QParton* decay, G4QParton* &created)
01008 {
01009 G4int IsParticle=(decay->GetPDGCode()>0) ? -1 : +1;
01010 G4QPartonPair QuarkPair = CreatePartonPair(IsParticle);
01011 created = QuarkPair.GetParton2();
01012 #ifdef debug
01013 G4cout<<"G4QString::QuarkSplitup: ***Called*** crP="<<created->GetPDGCode()<<G4endl;
01014 #endif
01015 G4QParton* P1=QuarkPair.GetParton1();
01016 G4QHadron* result=CreateHadron(P1, decay);
01017 delete P1;
01018 return result;
01019 }
01020
01021
01022 G4QHadron* G4QString::DiQuarkSplitup(G4QParton* decay, G4QParton* &created)
01023 {
01024
01025 if (G4UniformRand() < DiquarkBreakProb )
01026 {
01027
01028 G4int stableQuarkEncoding = decay->GetPDGCode()/1000;
01029 G4int decayQuarkEncoding = (decay->GetPDGCode()/100)%10;
01030 if (G4UniformRand() < 0.5)
01031 {
01032 G4int Swap = stableQuarkEncoding;
01033 stableQuarkEncoding = decayQuarkEncoding;
01034 decayQuarkEncoding = Swap;
01035 }
01036 G4int IsParticle=(decayQuarkEncoding>0) ? -1 : +1;
01037 G4QPartonPair QuarkPair = CreatePartonPair(IsParticle,false);
01038 G4QParton* P2=QuarkPair.GetParton2();
01039 G4int QuarkEncoding=P2->GetPDGCode();
01040 delete P2;
01041 G4int i10 = std::max(std::abs(QuarkEncoding), std::abs(stableQuarkEncoding));
01042 G4int i20 = std::min(std::abs(QuarkEncoding), std::abs(stableQuarkEncoding));
01043 G4int spin = (i10 != i20 && G4UniformRand() <= 0.5) ? 1 : 3;
01044 G4int NewDecayEncoding = -1*IsParticle*(i10 * 1000 + i20 * 100 + spin);
01045 created = new G4QParton(NewDecayEncoding);
01046 #ifdef debug
01047 G4cout<<"G4QString::DiQuarkSplitup: inside, crP="<<created->GetPDGCode()<<G4endl;
01048 #endif
01049 G4QParton* decayQuark= new G4QParton(decayQuarkEncoding);
01050 G4QParton* P1=QuarkPair.GetParton1();
01051 G4QHadron* newH=CreateHadron(P1, decayQuark);
01052 delete P1;
01053 delete decayQuark;
01054 return newH;
01055 }
01056 else
01057 {
01058
01059 G4int IsParticle=(decay->GetPDGCode()>0) ? +1 : -1;
01060 G4QPartonPair QuarkPair = CreatePartonPair(IsParticle,false);
01061 created = QuarkPair.GetParton2();
01062 #ifdef debug
01063 G4cout<<"G4QString::DiQuarkSplitup: diQ not break, crP="<<created->GetPDGCode()<<G4endl;
01064 #endif
01065 G4QParton* P1=QuarkPair.GetParton1();
01066 G4QHadron* newH=CreateHadron(P1, decay);
01067 delete P1;
01068 return newH;
01069 }
01070 }
01071
01072 G4QPartonPair G4QString::CreatePartonPair(G4int NeedParticle, G4bool AllowDiquarks)
01073 {
01074 #ifdef debug
01075 G4cout<<"G4QString::CreatePartonPair: ***Called***, P="<<NeedParticle<<", ALLOWdQ="
01076 <<AllowDiquarks<<G4endl;
01077 #endif
01078
01079 if(AllowDiquarks && G4UniformRand() < DiquarkSuppress)
01080 {
01081
01082 G4int q1 = SampleQuarkFlavor();
01083 G4int q2 = SampleQuarkFlavor();
01084 G4int spin = (q1 != q2 && G4UniformRand() <= 0.5) ? 1 : 3;
01085
01086 G4int PDGcode = (std::max(q1,q2) * 1000 + std::min(q1,q2) * 100 + spin) * NeedParticle;
01087 #ifdef debug
01088 G4cout<<"G4QString::CreatePartonPair: Created dQ-AdQ, PDG="<<PDGcode<<G4endl;
01089 #endif
01090 return G4QPartonPair(new G4QParton(-PDGcode), new G4QParton(PDGcode));
01091 }
01092 else
01093 {
01094
01095 G4int PDGcode=SampleQuarkFlavor()*NeedParticle;
01096 #ifdef debug
01097 G4cout<<"G4QString::CreatePartonPair: Created Q-aQ, PDG="<<PDGcode<<G4endl;
01098 #endif
01099 return G4QPartonPair(new G4QParton(PDGcode), new G4QParton(-PDGcode));
01100 }
01101 }
01102
01103
01104 G4QHadron* G4QString::CreateMeson(G4QParton* black, G4QParton* white, Spin theSpin)
01105 {
01106 static G4double scalarMesonMixings[6]={0.5, 0.25, 0.5, 0.25, 1.0, 0.5};
01107 static G4double vectorMesonMixings[6]={0.5, 0.0, 0.5, 0.0, 1.0, 1.0};
01108 G4int id1= black->GetPDGCode();
01109 G4int id2= white->GetPDGCode();
01110 #ifdef debug
01111 G4cout<<"G4QString::CreateMeson: bT="<<black->GetType()<<"("<<id1<<"), wT="
01112 <<white->GetType()<<"("<<id2<<")"<<G4endl;
01113 #endif
01114 if (std::abs(id1) < std::abs(id2))
01115 {
01116 G4int xchg = id1;
01117 id1 = id2;
01118 id2 = xchg;
01119 }
01120 if(std::abs(id1)>3)
01121 {
01122 G4cerr<<"***G4QString::CreateMeson: q1="<<id1<<", q2="<<id2
01123 <<" while CHIPS is only SU(3)"<<G4endl;
01124 G4Exception("G4QString::CreateMeson:","72",FatalException,"HeavyQuarkFound");
01125 }
01126 G4int PDGEncoding=0;
01127 if(!(id1+id2))
01128 {
01129 G4double rmix = G4UniformRand();
01130 G4int imix = 2*std::abs(id1) - 1;
01131 if(theSpin == SpinZero)
01132 PDGEncoding = 110*(1 + G4int(rmix + scalarMesonMixings[imix - 1])
01133 + G4int(rmix + scalarMesonMixings[imix] ) ) + theSpin;
01134 else
01135 PDGEncoding = 110*(1 + G4int(rmix + vectorMesonMixings[imix - 1])
01136 + G4int(rmix + vectorMesonMixings[imix] ) ) + theSpin;
01137 }
01138 else
01139 {
01140 PDGEncoding = 100 * std::abs(id1) + 10 * std::abs(id2) + theSpin;
01141 G4bool IsUp = (std::abs(id1)&1) == 0;
01142 G4bool IsAnti = id1 < 0;
01143 if( (IsUp && IsAnti) || (!IsUp && !IsAnti) ) PDGEncoding = - PDGEncoding;
01144
01145 if( PDGEncoding == -111 || PDGEncoding == -113 || PDGEncoding == -223 ||
01146 PDGEncoding == -221 || PDGEncoding == -331 || PDGEncoding == -333 )
01147 PDGEncoding = - PDGEncoding;
01148 }
01149 G4QHadron* Meson= new G4QHadron(PDGEncoding);
01150 #ifdef debug
01151 G4cout<<"G4QString::CreateBaryon: Meson is created with PDG="<<PDGEncoding<<G4endl;
01152 #endif
01153
01154
01155 return Meson;
01156 }
01157
01158
01159 G4QHadron* G4QString::CreateBaryon(G4QParton* black, G4QParton* white, Spin theSpin)
01160 {
01161 G4int id1= black->GetPDGCode();
01162 G4int id2= white->GetPDGCode();
01163 #ifdef debug
01164 G4cout<<"G4QString::CreateBaryon: bT="<<black->GetType()<<"("<<id1<<"), wT="
01165 <<white->GetType()<<"("<<id2<<")"<<G4endl;
01166 #endif
01167 if(std::abs(id1) < std::abs(id2))
01168 {
01169 G4int xchg = id1;
01170 id1 = id2;
01171 id2 = xchg;
01172 }
01173 if(std::abs(id1)<1000 || std::abs(id2)> 3)
01174 {
01175 G4cerr<<"***G4QString::CreateBaryon: q1="<<id1<<", q2="<<id2
01176 <<" can't create a Baryon"<<G4endl;
01177 G4Exception("G4QString::CreateBaryon:","72",FatalException,"WrongQdQSequence");
01178 }
01179 G4int ifl1= std::abs(id1)/1000;
01180 G4int ifl2 = (std::abs(id1) - ifl1 * 1000)/100;
01181 G4int diquarkSpin = std::abs(id1)%10;
01182 G4int ifl3 = id2;
01183 if (id1 < 0) {ifl1 = - ifl1; ifl2 = - ifl2;}
01184
01185 G4int kfla = std::abs(ifl1);
01186 G4int kflb = std::abs(ifl2);
01187 G4int kflc = std::abs(ifl3);
01188 G4int kfld = std::max(kfla,kflb);
01189 kfld = std::max(kfld,kflc);
01190 G4int kflf = std::min(kfla,kflb);
01191 kflf = std::min(kflf,kflc);
01192 G4int kfle = kfla + kflb + kflc - kfld - kflf;
01193
01194 if(kfla==kflb && kflb==kflc) theSpin=SpinThreeHalf;
01195
01196 G4int kfll = 0;
01197 if(theSpin == SpinHalf && kfld > kfle && kfle > kflf)
01198 {
01199
01200
01201
01202
01203 if(diquarkSpin == 1 )
01204 {
01205 if ( kfla == kfld) kfll = 1;
01206 else kfll = G4int(0.25 + G4UniformRand());
01207 }
01208 if(diquarkSpin==3 && kfla!=kfld) kfll = G4int(0.75+G4UniformRand());
01209 }
01210 G4int PDGEncoding=0;
01211 if (kfll == 1) PDGEncoding = 1000 * kfld + 100 * kflf + 10 * kfle + theSpin;
01212 else PDGEncoding = 1000 * kfld + 100 * kfle + 10 * kflf + theSpin;
01213 if (id1 < 0) PDGEncoding = -PDGEncoding;
01214 G4QHadron* Baryon= new G4QHadron(PDGEncoding);
01215 #ifdef debug
01216 G4cout<<"G4QString::CreateBaryon: Baryon is created with PDG="<<PDGEncoding<<G4endl;
01217 #endif
01218
01219
01220 return Baryon;
01221 }
01222
01223 G4QHadron* G4QString::CreateHadron(G4QParton* black, G4QParton* white)
01224 {
01225
01226
01227 static G4double mesonLowSpin = 0.5;
01228 static G4double baryonLowSpin= 0.5;
01229 G4int bT=black->GetType();
01230 G4int wT=white->GetType();
01231 #ifdef debug
01232 G4cout<<"G4QString::CreateHadron: bT="<<bT<<"("<<black->GetPDGCode()<<"), wT="<<wT<<"("
01233 <<white->GetPDGCode()<<")"<<G4endl;
01234 #endif
01235 if(bT==2 || wT==2)
01236 {
01237
01238 Spin spin = (G4UniformRand() < baryonLowSpin) ? SpinHalf : SpinThreeHalf;
01239 #ifdef debug
01240 G4cout<<"G4QString::CreateHadron: ----> Baryon is under creation"<<G4endl;
01241 #endif
01242 return CreateBaryon(black, white, spin);
01243 }
01244 else
01245 {
01246
01247 Spin spin = (G4UniformRand() < mesonLowSpin) ? SpinZero : SpinOne;
01248 #ifdef debug
01249 G4cout<<"G4QString::CreateHadron: ----> Meson is under creation"<<G4endl;
01250 #endif
01251 return CreateMeson(black, white, spin);
01252 }
01253 }
01254
01255
01256 G4QHadron* G4QString::CreateLowSpinHadron(G4QParton* black, G4QParton* white)
01257 {
01258 G4int bT=black->GetType();
01259 G4int wT=white->GetType();
01260 #ifdef debug
01261 G4cout<<"G4QString::CreateLowSpinHadron: ***Called***, bT="<<bT<<"("<<black->GetPDGCode()
01262 <<"), wT="<<wT<<"("<<white->GetPDGCode()<<")"<<G4endl;
01263 #endif
01264 if(bT == 1 && wT == 1)
01265 {
01266 #ifdef debug
01267 G4cout<<"G4QString::CreateLowSpinHadron: ----> Meson is under creation"<<G4endl;
01268 #endif
01269 return CreateMeson(black, white, SpinZero);
01270 }
01271 else
01272 {
01273 #ifdef debug
01274 G4cout<<"G4QString::CreateLowSpinHadron: ----> Baryon is under creation"<<G4endl;
01275 #endif
01276 return CreateBaryon(black, white, SpinHalf);
01277 }
01278 }
01279
01280
01281 G4QHadron* G4QString::CreateHighSpinHadron(G4QParton* black, G4QParton* white)
01282 {
01283 G4int bT=black->GetType();
01284 G4int wT=white->GetType();
01285 #ifdef debug
01286 G4cout<<"G4QString::CreateHighSpinHadron:***Called***, bT="<<bT<<"("<<black->GetPDGCode()
01287 <<"), wT="<<wT<<"("<<white->GetPDGCode()<<")"<<G4endl;
01288 #endif
01289 if(bT == 1 && wT == 1)
01290 {
01291 #ifdef debug
01292 G4cout<<"G4QString::CreateHighSpinHadron: ----> Meson is created"<<G4endl;
01293 #endif
01294 return CreateMeson(black,white, SpinOne);
01295 }
01296 else
01297 {
01298 #ifdef debug
01299 G4cout<<"G4QString::CreateHighSpinHadron: ----> Baryon is created"<<G4endl;
01300 #endif
01301 return CreateBaryon(black,white,SpinThreeHalf);
01302 }
01303 }