9 #include "MiniStringFragmentation.h"
23 const int MiniStringFragmentation::NTRYDIFFRACTIVE = 200;
26 const int MiniStringFragmentation::NTRYLASTRESORT = 100;
29 const int MiniStringFragmentation::NTRYFLAV = 10;
35 void MiniStringFragmentation::init(Info* infoPtrIn, Settings& settings,
36 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
37 StringFlav* flavSelPtrIn, StringPT* pTSelPtrIn, StringZ* zSelPtrIn) {
41 particleDataPtr = particleDataPtrIn;
43 flavSelPtr = flavSelPtrIn;
44 pTSelPtr = pTSelPtrIn;
48 nTryMass = settings.mode(
"MiniStringFragmentation:nTry");
51 bLund = zSelPtr->bAreaLund();
59 bool MiniStringFragmentation::fragment(
int iSub, ColConfig& colConfig,
60 Event& event,
bool isDiff) {
63 iParton = colConfig[iSub].iParton;
64 flav1 = FlavContainer( event[ iParton.front() ].id() );
65 flav2 = FlavContainer( event[ iParton.back() ].id() );
66 pSum = colConfig[iSub].pSum;
67 mSum = colConfig[iSub].mass;
69 isClosed = colConfig[iSub].isClosed;
72 int nTryFirst = (isDiff) ? NTRYDIFFRACTIVE : nTryMass;
75 if (ministring2two( nTryFirst, event))
return true;
78 if (ministring2one( iSub, colConfig, event))
return true;
81 if (ministring2two( NTRYLASTRESORT, event))
return true;
84 infoPtr->errorMsg(
"Error in MiniStringFragmentation::fragment: "
85 "no 1- or 2-body state found above mass threshold");
94 bool MiniStringFragmentation::ministring2two(
int nTry,
Event& event) {
104 for (
int iTry = 0; iTry < nTry; ++iTry) {
108 int idStart = flavSelPtr->pickLightQ();
109 FlavContainer flavStart(idStart, 1);
110 flavStart = flavSelPtr->pick( flavStart);
111 flav1 = flavSelPtr->pick( flavStart);
113 }
while (flav1.id == 0 || flav1.nPop > 0);
118 FlavContainer flav3 =
119 (flav1.isDiquark() || (!flav2.isDiquark() && rndmPtr->flat() < 0.5) )
120 ? flavSelPtr->pick( flav1) : flavSelPtr->pick( flav2).anti();
121 idHad1 = flavSelPtr->combine( flav1, flav3);
122 idHad2 = flavSelPtr->combine( flav2, flav3.anti());
123 }
while (idHad1 == 0 || idHad2 == 0);
126 mHad1 = particleDataPtr->mass(idHad1);
127 mHad2 = particleDataPtr->mass(idHad2);
128 mHadSum = mHad1 + mHad2;
129 if (mHadSum < mSum)
break;
131 if (mHadSum >= mSum)
return false;
135 Vec4 pSum1 =
event[ iParton.front() ].p();
136 Vec4 pSum2 =
event[ iParton.back() ].p();
137 if (iParton.size() > 2) {
140 Vec4 pEndSum = pEnd1 + pEnd2;
141 for (
int i = 1; i < int(iParton.size()) - 1 ; ++i) {
142 Vec4 pNow =
event[ iParton[i] ].p();
143 double ratio = (pEnd2 * pNow) / (pEndSum * pNow);
144 pSum1 += ratio * pNow;
145 pSum2 += (1. - ratio) * pNow;
151 region.setUp( pSum1, pSum2);
155 double pAbs2 = 0.25 * ( pow2(m2Sum - mHad1*mHad1 - mHad2*mHad2)
156 - pow2(2. * mHad1 * mHad2) ) / m2Sum;
159 double cosTheta = rndmPtr->flat();
160 pT2 = (1. - pow2(cosTheta)) * pAbs2;
161 }
while (pTSelPtr->suppressPT2(pT2) < rndmPtr->flat() );
164 double mT21 = mHad1*mHad1 + pT2;
165 double mT22 = mHad2*mHad2 + pT2;
166 double lambda = sqrtpos( pow2(m2Sum - mT21 - mT22) - 4. * mT21 * mT22 );
167 double probReverse = 1. / (1. + exp( min( 50., bLund * lambda) ) );
170 double xpz1 = 0.5 * lambda/ m2Sum;
171 if (probReverse > rndmPtr->flat()) xpz1 = -xpz1;
172 double xmDiff = (mT21 - mT22) / m2Sum;
173 double xe1 = 0.5 * (1. + xmDiff);
174 double xe2 = 0.5 * (1. - xmDiff );
177 double phi = 2. * M_PI * rndmPtr->flat();
178 double pT = sqrt(pT2);
179 double px = pT * cos(phi);
180 double py = pT * sin(phi);
183 Vec4 pHad1 = region.pHad( xe1 + xpz1, xe1 - xpz1, px, py);
184 Vec4 pHad2 = region.pHad( xe2 - xpz1, xe2 + xpz1, -px, -py);
187 int iFirst =
event.append( idHad1, 82, iParton.front(), iParton.back(),
188 0, 0, 0, 0, pHad1, mHad1);
189 int iLast =
event.append( idHad2, 82, iParton.front(), iParton.back(),
190 0, 0, 0, 0, pHad2, mHad2);
193 if (event[iParton.front()].hasVertex()) {
194 Vec4 vDec =
event[iParton.front()].vDec();
195 event[iFirst].vProd( vDec );
196 event[iLast].vProd( vDec );
200 event[iFirst].tau( event[iFirst].tau0() * rndmPtr->exp() );
201 event[iLast].tau( event[iLast].tau0() * rndmPtr->exp() );
204 for (
int i = 0; i < int(iParton.size()); ++i) {
205 event[ iParton[i] ].statusNeg();
206 event[ iParton[i] ].daughters(iFirst, iLast);
222 bool MiniStringFragmentation::ministring2one(
int iSub,
223 ColConfig& colConfig,
Event& event) {
226 if (abs(flav1.id) > 100 && abs(flav2.id) > 100)
return false;
230 int idStart = flavSelPtr->pickLightQ();
231 FlavContainer flavStart(idStart, 1);
232 flav1 = flavSelPtr->pick( flavStart);
233 flav2 = flav1.anti();
234 }
while (abs(flav1.id) > 100);
238 for (
int iTryFlav = 0; iTryFlav < NTRYFLAV; ++iTryFlav) {
239 idHad = flavSelPtr->combine( flav1, flav2);
240 if (idHad != 0)
break;
242 if (idHad == 0)
return false;
245 double mHad = particleDataPtr->mass(idHad);
250 double deltaM2 = mHad*mHad - mSum*mSum;
251 double delta2Max = 0.;
252 for (
int iRec = iSub + 1; iRec < colConfig.size(); ++iRec) {
253 double delta2Rec = 2. * (pSum * colConfig[iRec].pSum) - deltaM2
254 - 2. * mHad * colConfig[iRec].mass;
255 if (delta2Rec > delta2Max) { iMax = iRec; delta2Max = delta2Rec;}
257 if (iMax == -1)
return false;
260 Vec4& pRec = colConfig[iMax].pSum;
261 double mRec = colConfig[iMax].mass;
262 double vecProd = pSum * pRec;
263 double coefOld = mSum*mSum + vecProd;
264 double coefNew = mHad*mHad + vecProd;
265 double coefRec = mRec*mRec + vecProd;
266 double coefSum = coefOld + coefNew;
267 double sHat = coefOld + coefRec;
268 double root = sqrtpos( (pow2(coefSum) - 4. * sHat * mHad*mHad)
269 / (pow2(vecProd) - pow2(mSum * mRec)) );
270 double k2 = 0.5 * (coefOld * root - coefSum) / sHat;
271 double k1 = (coefRec * k2 + 0.5 * deltaM2) / coefOld;
272 Vec4 pHad = (1. + k1) * pSum - k2 * pRec;
273 Vec4 pRecNew = (1. + k2) * pRec - k1 * pSum;
276 int iHad =
event.append( idHad, 81, iParton.front(), iParton.back(),
277 0, 0, 0, 0, pHad, mHad);
280 if (event[iParton.front()].hasVertex()) {
281 Vec4 vDec =
event[iParton.front()].vDec();
282 event[iHad].vProd( vDec );
286 event[iHad].tau( event[iHad].tau0() * rndmPtr->exp() );
289 for (
int i = 0; i < int(iParton.size()); ++i) {
290 event[ iParton[i] ].statusNeg();
291 event[ iParton[i] ].daughters(iHad, iHad);
296 M.bst(pRec, pRecNew);
297 for (
int i = 0; i < colConfig[iMax].size(); ++i) {
298 int iOld = colConfig[iMax].iParton[i];
301 int iNew =
event.copy(iOld, 72);
302 event[iNew].rotbst(M);
303 colConfig[iMax].iParton[i] = iNew;
306 colConfig[iMax].pSum = pRecNew;
307 colConfig[iMax].isCollected =
true;