Line data Source code
1 : // ColourTracing.cc is a part of the PYTHIA event generator.
2 : // Copyright (C) 2015 Torbjorn Sjostrand.
3 : // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 : // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 :
6 : // Function definitions (not found in the header) for the
7 : // ColourReconnection class.
8 :
9 : // Setup the list of colours, this is needed later for finding colour chains.
10 :
11 : #include "Pythia8/ColourTracing.h"
12 :
13 : namespace Pythia8 {
14 :
15 : //==========================================================================
16 :
17 : // The ColourTracing class.
18 :
19 : //--------------------------------------------------------------------------
20 :
21 : // Find all final coloured and anticoloured partons.
22 :
23 : bool ColourTracing::setupColList(Event& event) {
24 :
25 0 : iColEnd.resize(0);
26 0 : iAcolEnd.resize(0);
27 0 : iColAndAcol.resize(0);
28 0 : for (int i = 0; i < event.size(); ++i)
29 0 : if (event[i].isFinal()) {
30 0 : if (event[i].col() > 0 && event[i].acol() > 0) iColAndAcol.push_back(i);
31 0 : else if (event[i].col() > 0) iColEnd.push_back(i);
32 0 : else if (event[i].acol() > 0) iAcolEnd.push_back(i);
33 : // Colour sextets have additional tags (store with negative numbers).
34 0 : if (event[i].col() < 0) iAcolEnd.push_back(-i);
35 0 : else if (event[i].acol() < 0) iColEnd.push_back(-i);
36 : }
37 :
38 : // Return true if zero particles were found.
39 0 : if (int(iColEnd.size()) == 0 && int(iAcolEnd.size()) == 0 &&
40 0 : int(iColAndAcol.size()) == 0) return true;
41 0 : else return false;
42 :
43 0 : }
44 :
45 : //--------------------------------------------------------------------------
46 :
47 : // Trace a colour line, from an anticolour to a colour.
48 :
49 : bool ColourTracing::traceFromAcol(int indxCol, Event& event, int iJun,
50 : int iCol, vector<int>& iParton) {
51 :
52 : // Junction kind, if any.
53 0 : int kindJun = (iJun >= 0) ? event.kindJunction(iJun) : 0;
54 :
55 : // Begin to look for a matching colour.
56 : int loop = 0;
57 0 : int loopMax = iColAndAcol.size() + 2;
58 : bool hasFound = false;
59 0 : do {
60 0 : ++loop;
61 : hasFound= false;
62 :
63 : // First check list of matching colour ends.
64 : // Also check for sextets (negative anticolour tag = extra colour tag).
65 0 : for (int i = 0; i < int(iColEnd.size()); ++i) {
66 0 : if (event[ abs(iColEnd[i]) ].col() == indxCol
67 0 : || event[ abs(iColEnd[i]) ].acol() == -indxCol) {
68 0 : iParton.push_back( abs(iColEnd[i]) );
69 : indxCol = 0;
70 0 : iColEnd[i] = iColEnd.back();
71 0 : iColEnd.pop_back();
72 : hasFound = true;
73 0 : break;
74 : }
75 : }
76 :
77 : // Then check list of intermediate gluons.
78 0 : if (!hasFound)
79 0 : for (int i = 0; i < int(iColAndAcol.size()); ++i)
80 0 : if (event[ iColAndAcol[i] ].col() == indxCol) {
81 0 : iParton.push_back( iColAndAcol[i] );
82 : // Update to new colour. Remove gluon.
83 0 : indxCol = event[ iColAndAcol[i] ].acol();
84 0 : if (kindJun > 0) event.endColJunction(iJun, iCol, indxCol);
85 0 : iColAndAcol[i] = iColAndAcol.back();
86 0 : iColAndAcol.pop_back();
87 : hasFound = true;
88 0 : break;
89 0 : }
90 :
91 : // Check opposite-sign junction colours.
92 0 : if (!hasFound)
93 0 : for (int iAntiJun = 0; iAntiJun < event.sizeJunction(); ++iAntiJun)
94 0 : if (iAntiJun != iJun && event.kindJunction(iAntiJun) % 2 == 0)
95 0 : for (int iColAnti = 0; iColAnti < 3; ++iColAnti)
96 0 : if (event.colJunction(iAntiJun, iColAnti) == indxCol) {
97 0 : iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
98 : indxCol = 0;
99 : hasFound = true;
100 0 : break;
101 0 : }
102 :
103 : // In a pinch, check list of opposite-sign junction end colours.
104 : // Store in iParton list as -(10 + 10 * iAntiJun + iLeg).
105 : // This is for J-g-...-g-J connections; where instead of running both ways,
106 : // the second time we just store the two junctions.
107 0 : if (!hasFound && kindJun % 2 == 1 && event.sizeJunction() > 1)
108 0 : for (int iAntiJun = 0; iAntiJun < event.sizeJunction(); ++iAntiJun)
109 0 : if (iAntiJun != iJun && event.kindJunction(iAntiJun) % 2 == 0)
110 0 : for (int iColAnti = 0; iColAnti < 3; ++iColAnti)
111 0 : if (event.endColJunction(iAntiJun, iColAnti) == indxCol) {
112 0 : iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
113 : indxCol = 0;
114 : hasFound = true;
115 0 : break;
116 0 : }
117 :
118 : // Keep on tracing via gluons until reached end of leg.
119 0 : } while (hasFound && indxCol > 0 && loop < loopMax);
120 :
121 : // Something went wrong in colour tracing.
122 0 : if (!hasFound || loop == loopMax) {
123 0 : infoPtr->errorMsg("Error in ColourTracing::traceFromAcol: "
124 : "colour tracing failed");
125 0 : return false;
126 : }
127 :
128 : // Done.
129 0 : return true;
130 :
131 0 : }
132 :
133 : //--------------------------------------------------------------------------
134 :
135 : // Trace a colour line, from a colour to an anticolour.
136 :
137 : bool ColourTracing::traceFromCol(int indxCol, Event& event, int iJun,
138 : int iCol, vector<int>& iParton) {
139 :
140 : // If none specified, select next colour tag from back of list.
141 0 : if (iJun < 0 && iCol < 0) {
142 0 : int iColEndBack = iColEnd.back();
143 0 : if (iColEndBack > 0) indxCol = event[iColEnd.back()].col();
144 : // Negative index implies extra (sextet) colour tag in anticolour slot.
145 0 : else indxCol = -event[-iColEnd.back()].acol();
146 0 : iParton.push_back(iColEnd.back());
147 0 : iColEnd.pop_back();
148 0 : }
149 :
150 : // Junction kind, if any.
151 0 : int kindJun = (iJun >= 0) ? event.kindJunction(iJun) : 0;
152 :
153 : // Begin to look for a matching anticolour.
154 : int loop = 0;
155 0 : int loopMax = iColAndAcol.size() + 2;
156 : bool hasFound = false;
157 0 : do {
158 0 : ++loop;
159 : hasFound= false;
160 :
161 : // First check list of matching anticolour ends.
162 : // Also check for sextets (negative colour tag = extra anticolour tag).
163 0 : for (int i = 0; i < int(iAcolEnd.size()); ++i) {
164 0 : if (event[ abs(iAcolEnd[i]) ].acol() == indxCol
165 0 : || event[ abs(iAcolEnd[i]) ].col() == -indxCol) {
166 0 : iParton.push_back( abs(iAcolEnd[i]) );
167 : indxCol = 0;
168 0 : iAcolEnd[i] = iAcolEnd.back();
169 0 : iAcolEnd.pop_back();
170 : hasFound = true;
171 0 : break;
172 : }
173 : }
174 :
175 : // Then check list of intermediate gluons.
176 0 : if (!hasFound)
177 0 : for (int i = 0; i < int(iColAndAcol.size()); ++i)
178 0 : if (event[ iColAndAcol[i] ].acol() == indxCol) {
179 0 : iParton.push_back( iColAndAcol[i] );
180 :
181 : // Update to new colour. Remove gluon.
182 0 : indxCol = event[ iColAndAcol[i] ].col();
183 0 : if (kindJun > 0) event.endColJunction(iJun, iCol, indxCol);
184 0 : iColAndAcol[i] = iColAndAcol.back();
185 0 : iColAndAcol.pop_back();
186 : hasFound = true;
187 0 : break;
188 0 : }
189 :
190 : // Check opposite-sign junction colours.
191 0 : if (!hasFound)
192 0 : for (int iAntiJun = 0; iAntiJun < event.sizeJunction(); ++iAntiJun)
193 0 : if (iAntiJun != iJun && event.kindJunction(iAntiJun) %2 == 1)
194 0 : for (int iColAnti = 0; iColAnti < 3; ++iColAnti)
195 0 : if (event.colJunction(iAntiJun, iColAnti) == indxCol) {
196 0 : iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
197 : indxCol = 0;
198 : hasFound = true;
199 0 : break;
200 0 : }
201 :
202 : // In a pinch, check list of opposite-sign junction end colours.
203 : // Store in iParton list as -(10 + 10 * iAntiJun + iAntiLeg).
204 : // This is for J-g-...-g-J connections; where instead of running both ways,
205 : // the second time we just store the two junctions.
206 0 : if (!hasFound && kindJun % 2 == 0 && event.sizeJunction() > 1)
207 0 : for (int iAntiJun = 0; iAntiJun < event.sizeJunction(); ++iAntiJun)
208 0 : if (iAntiJun != iJun && event.kindJunction(iAntiJun) %2 == 1)
209 0 : for (int iColAnti = 0; iColAnti < 3; ++iColAnti)
210 0 : if (event.endColJunction(iAntiJun, iColAnti) == indxCol) {
211 0 : iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
212 : indxCol = 0;
213 : hasFound = true;
214 0 : break;
215 0 : }
216 :
217 : // Keep on tracing via gluons until reached end of leg.
218 0 : } while (hasFound && indxCol > 0 && loop < loopMax);
219 :
220 : // Something went wrong in colour tracing.
221 0 : if (!hasFound || loop == loopMax) {
222 0 : infoPtr->errorMsg("Error in ColourTracing::traceFromCol: "
223 : "colour tracing failed");
224 0 : return false;
225 : }
226 :
227 : // Done.
228 0 : return true;
229 :
230 0 : }
231 :
232 : //--------------------------------------------------------------------------
233 :
234 : // Trace a colour loop, from a colour back to the anticolour of the same.
235 :
236 : bool ColourTracing::traceInLoop(Event& event, vector<int>& iParton) {
237 :
238 : // Add starting gluon.
239 0 : iParton.push_back( iColAndAcol[0] );
240 0 : int indxCol = event[ iColAndAcol[0] ].col();
241 0 : int indxAcol = event[ iColAndAcol[0] ].acol();
242 0 : iColAndAcol[0] = iColAndAcol.back();
243 0 : iColAndAcol.pop_back();
244 :
245 : // Move around until back where begun.
246 : int loop = 0;
247 0 : int loopMax = iColAndAcol.size() + 2;
248 : bool hasFound = false;
249 0 : do {
250 0 : ++loop;
251 : hasFound= false;
252 :
253 : // Check list of gluons.
254 0 : for (int i = 0; i < int(iColAndAcol.size()); ++i)
255 0 : if (event[ iColAndAcol[i] ].acol() == indxCol) {
256 0 : iParton.push_back( iColAndAcol[i] );
257 0 : indxCol = event[ iColAndAcol[i] ].col();
258 0 : iColAndAcol[i] = iColAndAcol.back();
259 0 : iColAndAcol.pop_back();
260 : hasFound = true;
261 0 : break;
262 : }
263 0 : } while (hasFound && indxCol != indxAcol && loop < loopMax);
264 :
265 : // Something went wrong in colour tracing.
266 0 : if (!hasFound || loop == loopMax) {
267 0 : infoPtr->errorMsg("Error in ColourTracing::traceInLoop: "
268 : "colour tracing failed");
269 :
270 0 : return false;
271 : }
272 :
273 : // Done.
274 0 : return true;
275 :
276 0 : }
277 :
278 : //--------------------------------------------------------------------------
279 :
280 : // Get junction chains, where the junctions are directly connected.
281 :
282 : vector<vector<int > > ColourTracing::getJunChains(Event& event) {
283 :
284 : // Make list of junction chains and help array.
285 0 : vector<vector<int> > junChains;
286 0 : vector<bool> usedJuncs(event.sizeJunction(),false);
287 :
288 : // Loop over junctions.
289 0 : for (int i = 0; i < event.sizeJunction(); ++i) {
290 0 : if (usedJuncs[i])
291 : continue;
292 0 : std::list<int> curJun;
293 0 : vector<int> junList;
294 0 : usedJuncs[i] = true;
295 0 : curJun.push_back(i);
296 0 : junList.push_back(i);
297 :
298 : // Keep looping over connected junctions until no new junctions are found.
299 0 : while (!curJun.empty()) {
300 0 : for (int iLeg = 0;iLeg < 3; ++iLeg)
301 0 : for (int j = 0;j < event.sizeJunction(); ++j) {
302 0 : if (usedJuncs[j])
303 : continue;
304 0 : for (int jLeg = 0;jLeg < 3; ++jLeg) {
305 0 : if (event.colJunction(curJun.front(),iLeg) ==
306 0 : event.colJunction(j,jLeg)) {
307 0 : curJun.push_back(j);
308 0 : junList.push_back(j);
309 0 : usedJuncs[j] = true;
310 0 : break;
311 : }
312 : }
313 0 : }
314 0 : curJun.pop_front();
315 : }
316 0 : junChains.push_back(junList);
317 0 : }
318 : return junChains;
319 :
320 0 : }
321 :
322 : //==========================================================================
323 :
324 : } // end namespace Pythia8
|