1 | #ifndef D0RunIIconeJets_CONESPLITMERGE
|
---|
2 | #define D0RunIIconeJets_CONESPLITMERGE
|
---|
3 | // ---------------------------------------------------------------------------
|
---|
4 | // ConeSplitMerge.hpp
|
---|
5 | //
|
---|
6 | // Created: 28-JUL-2000 Francois Touze
|
---|
7 | //
|
---|
8 | // Purpose: Implements the pT ordered jet split/merge algorithm for the
|
---|
9 | // Improved Legacy Cone Algorithm split/merge algo.
|
---|
10 | //
|
---|
11 | // Modified:
|
---|
12 | // 31-JUL-2000 Laurent Duflot
|
---|
13 | // + introduce support for additional informations (ConeJetInfo)
|
---|
14 | // 1-AUG-2000 Laurent Duflot
|
---|
15 | // + jet merge criteria was wrong, now calculate shared_ET and compare to
|
---|
16 | // neighbour jet pT.
|
---|
17 | // + split was incomplete: shared items not really removed from jets.
|
---|
18 | // 4-Aug-2000 Laurent Duflot
|
---|
19 | // + use item methods y() and phi() rather than p4vec() and then P2y and
|
---|
20 | // P2phi
|
---|
21 | // 7-Aug-2000 Laurent Duflot
|
---|
22 | // + force the list to be organized by decreasing ET and, for identical ET,
|
---|
23 | // by decreasing seedET. Identical protojets can be found by eg nearby
|
---|
24 | // seeds. The seedET ordering is such that for identical jets, the one
|
---|
25 | // with the highest seedET is kept, which is what we want for efficiency
|
---|
26 | // calculations.
|
---|
27 | // + avoid unecessary copies of lists by using reference when possible
|
---|
28 | // 9-Aug-2000 Laurent Duflot
|
---|
29 | // + save initial jet ET before split/merge
|
---|
30 | // 1-May-2007 Lars Sonnenschein
|
---|
31 | // extracted from D0 software framework and modified to remove subsequent dependencies
|
---|
32 | //
|
---|
33 | //
|
---|
34 | // This file is distributed with FastJet under the terms of the GNU
|
---|
35 | // General Public License (v2). Permission to do so has been granted
|
---|
36 | // by Lars Sonnenschein and the D0 collaboration (see COPYING for
|
---|
37 | // details)
|
---|
38 | //
|
---|
39 | // History of changes in FastJet compared tothe original version of
|
---|
40 | // ConeSplitMerge.hpp
|
---|
41 | //
|
---|
42 | // 2011-12-13 Gregory Soyez <soyez@fastjet.fr>
|
---|
43 | //
|
---|
44 | // * added license information
|
---|
45 | //
|
---|
46 | // 2009-01-17 Gregory Soyez <soyez@fastjet.fr>
|
---|
47 | //
|
---|
48 | // * put the code in the fastjet::d0 namespace
|
---|
49 | //
|
---|
50 | // 2007-12-14 Gavin Salam <salam@lpthe.jussieu.fr>
|
---|
51 | //
|
---|
52 | // * replaced make_pair by std::make_pair
|
---|
53 | //
|
---|
54 | // ---------------------------------------------------------------------------
|
---|
55 |
|
---|
56 |
|
---|
57 | #include <iostream>
|
---|
58 | #include <map>
|
---|
59 | #include <utility>
|
---|
60 | #include <vector>
|
---|
61 | #include "ProtoJet.hpp"
|
---|
62 |
|
---|
63 | //using namespace D0RunIIconeJets_CONEJETINFO;
|
---|
64 |
|
---|
65 | #include <fastjet/internal/base.hh>
|
---|
66 |
|
---|
67 | FASTJET_BEGIN_NAMESPACE
|
---|
68 |
|
---|
69 | namespace d0{
|
---|
70 |
|
---|
71 | //
|
---|
72 | // this class is used to order ProtoJets by decreasing ET and seed ET
|
---|
73 | template <class Item>
|
---|
74 | class ProtoJet_ET_seedET_order
|
---|
75 | {
|
---|
76 | public:
|
---|
77 | bool operator()(const ProtoJet<Item> & first, const ProtoJet<Item> & second) const
|
---|
78 | {
|
---|
79 | if ( first.pT() > second.pT() ) return true;
|
---|
80 | else
|
---|
81 | if ( first.pT() < second.pT() ) return false;
|
---|
82 | else return ( first.info().seedET() > second.info().seedET() );
|
---|
83 | }
|
---|
84 | };
|
---|
85 |
|
---|
86 |
|
---|
87 | template <class Item>
|
---|
88 | class ConeSplitMerge {
|
---|
89 |
|
---|
90 | public :
|
---|
91 |
|
---|
92 | typedef std::multimap<ProtoJet<Item>,float,ProtoJet_ET_seedET_order<Item> > PJMMAP;
|
---|
93 |
|
---|
94 | ConeSplitMerge();
|
---|
95 | ConeSplitMerge(const std::vector<ProtoJet<Item> >& jvector);
|
---|
96 | ConeSplitMerge(const std::list<ProtoJet<Item> >& jlist);
|
---|
97 | ~ConeSplitMerge() {;}
|
---|
98 | void split_merge(std::vector<ProtoJet<Item> >& ecv,float s, float pT_min_leading_protojet, float pT_min_second_protojet, int MergeMax, float pT_min_noMergeMax);
|
---|
99 |
|
---|
100 | private :
|
---|
101 | PJMMAP _members;
|
---|
102 | };
|
---|
103 | ///////////////////////////////////////////////////////////////////////////////
|
---|
104 | template<class Item>
|
---|
105 | ConeSplitMerge<Item>::ConeSplitMerge():_members() {;}
|
---|
106 |
|
---|
107 | template<class Item>
|
---|
108 | ConeSplitMerge<Item>::ConeSplitMerge(const std::vector<ProtoJet<Item> >& jvector)
|
---|
109 | {
|
---|
110 | // sort proto_jets in Et descending order
|
---|
111 | typename std::vector<ProtoJet<Item> >::const_iterator jt;
|
---|
112 | for(jt = jvector.begin(); jt != jvector.end(); ++jt)
|
---|
113 | {
|
---|
114 | // this is supposed to be a stable cone, declare so
|
---|
115 | ProtoJet<Item> jet(*jt);
|
---|
116 | jet.NowStable();
|
---|
117 | _members.insert(std::make_pair(jet,jet.pT()));
|
---|
118 | }
|
---|
119 | }
|
---|
120 |
|
---|
121 | template<class Item>
|
---|
122 | ConeSplitMerge<Item>::ConeSplitMerge(const std::list<ProtoJet<Item> >& jlist)
|
---|
123 | {
|
---|
124 | //_max_nb_items =-1;
|
---|
125 | // sort proto_jets in Et descending order
|
---|
126 | typename std::list<ProtoJet<Item> >::const_iterator jt;
|
---|
127 | for(jt = jlist.begin(); jt != jlist.end(); ++jt)
|
---|
128 | {
|
---|
129 | // this is supposed to be a stable cone, declare so
|
---|
130 | ProtoJet<Item> jet(*jt);
|
---|
131 | jet.NowStable();
|
---|
132 | _members.insert(std::make_pair(jet,jet.pT()));
|
---|
133 | }
|
---|
134 | }
|
---|
135 |
|
---|
136 | template<class Item>
|
---|
137 | void ConeSplitMerge<Item>::split_merge(std::vector<ProtoJet<Item> >& jcv,
|
---|
138 | float shared_ET_fraction,
|
---|
139 | float pT_min_leading_protojet, float pT_min_second_protojet,
|
---|
140 | int MergeMax, float pT_min_noMergeMax)
|
---|
141 | {
|
---|
142 | while(!_members.empty())
|
---|
143 | {
|
---|
144 | /*
|
---|
145 | {
|
---|
146 | std::cout << std::endl;
|
---|
147 | std::cout << " --------------- list of protojets ------------------ " <<std::endl;
|
---|
148 | for ( PJMMAP::iterator it = _members.begin();
|
---|
149 | it != _members.end(); ++it)
|
---|
150 | {
|
---|
151 | std::cout << " pT y phi " << (*it).pT() << " " << (*it).y() << " " << (*it).phi() << " " << (*it).info().seedET() << " " << (*it).info().nbMerge() << " " << (*it).info().nbSplit() << std::endl;
|
---|
152 | }
|
---|
153 | std::cout << " ----------------------------------------------------- " <<std::endl;
|
---|
154 | }
|
---|
155 | */
|
---|
156 |
|
---|
157 |
|
---|
158 | // select highest Et jet
|
---|
159 | typename PJMMAP::iterator itmax= _members.begin();
|
---|
160 | ProtoJet<Item> imax((*itmax).first);
|
---|
161 | const std::list<const Item*>& ilist(imax.LItems());
|
---|
162 |
|
---|
163 | _members.erase(itmax);
|
---|
164 |
|
---|
165 | // does jet share items?
|
---|
166 | bool share= false;
|
---|
167 | float shared_ET = 0.;
|
---|
168 | typename PJMMAP::iterator jtmax;
|
---|
169 | typename PJMMAP::iterator jt;
|
---|
170 | for(jt = _members.begin(); jt != _members.end(); ++jt)
|
---|
171 | {
|
---|
172 | const std::list<const Item*>& jlist((*jt).first.LItems());
|
---|
173 | typename std::list<const Item*>::const_iterator tk;
|
---|
174 | int count;
|
---|
175 | for(tk = ilist.begin(), count = 0; tk != ilist.end();
|
---|
176 | ++tk, ++count)
|
---|
177 | {
|
---|
178 | typename std::list<const Item*>::const_iterator where=
|
---|
179 | find(jlist.begin(),jlist.end(),*tk);
|
---|
180 | if(where != jlist.end())
|
---|
181 | {
|
---|
182 | share= true;
|
---|
183 | shared_ET += (*tk)->pT();
|
---|
184 | }
|
---|
185 | }
|
---|
186 | if(share)
|
---|
187 | {
|
---|
188 | jtmax = jt;
|
---|
189 | break;
|
---|
190 | }
|
---|
191 | }
|
---|
192 |
|
---|
193 | if(!share) {
|
---|
194 | // add jet to the final jet list
|
---|
195 | jcv.push_back(imax);
|
---|
196 | //std::cout << " final jet " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl;
|
---|
197 | }
|
---|
198 | else
|
---|
199 | {
|
---|
200 | // find highest Et neighbor
|
---|
201 | ProtoJet<Item> jmax((*jtmax).first);
|
---|
202 |
|
---|
203 | // drop neighbor
|
---|
204 | _members.erase(jtmax);
|
---|
205 |
|
---|
206 |
|
---|
207 | //std::cout << " split or merge ? " << imax.pT() << " " << shared_ET << " " << jmax.pT() << " " << s << " " << (jmax.pT())*s << std::endl;
|
---|
208 |
|
---|
209 | // merge
|
---|
210 | if( shared_ET > (jmax.pT())*shared_ET_fraction
|
---|
211 | && (imax.pT() > pT_min_leading_protojet || jmax.pT() > pT_min_second_protojet)
|
---|
212 | && (imax.info().nbMerge() < MergeMax || imax.pT() > pT_min_noMergeMax))
|
---|
213 | {
|
---|
214 | // add neighbor's items to imax
|
---|
215 | const std::list<const Item*>& jlist(jmax.LItems());
|
---|
216 | typename std::list<const Item*>::const_iterator tk;
|
---|
217 | typename std::list<const Item*>::const_iterator iend= ilist.end();
|
---|
218 | bool same = true; // is jmax just the same as imax ?
|
---|
219 | for(tk = jlist.begin(); tk != jlist.end(); ++tk)
|
---|
220 | {
|
---|
221 | typename std::list<const Item*>::const_iterator where=
|
---|
222 | find(ilist.begin(),iend,*tk);
|
---|
223 | if(where == iend)
|
---|
224 | {
|
---|
225 | imax.addItem(*tk);
|
---|
226 | same = false;
|
---|
227 | }
|
---|
228 | }
|
---|
229 | if ( ! same )
|
---|
230 | {
|
---|
231 | // recalculate
|
---|
232 | //float old_pT = imax.pT();
|
---|
233 |
|
---|
234 | imax.updateJet();
|
---|
235 | imax.merged();
|
---|
236 | //std::cout << " jet merge :: " << old_pT << " " << jmax.pT() << " " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl;
|
---|
237 | }
|
---|
238 | }
|
---|
239 |
|
---|
240 | //split and assign removed shared cells from lowest pT protojet
|
---|
241 | else if(shared_ET > (jmax.pT())*shared_ET_fraction)
|
---|
242 | {
|
---|
243 | // here we need to pull the lists, because there are items to remove
|
---|
244 | std::list<const Item*> ilist(imax.LItems());
|
---|
245 | std::list<const Item*> jlist(jmax.LItems());
|
---|
246 |
|
---|
247 | typename std::list<const Item*>::iterator tk;
|
---|
248 | for(tk = jlist.begin(); tk != jlist.end(); )
|
---|
249 | {
|
---|
250 | typename std::list<const Item*>::iterator where=
|
---|
251 | find(ilist.begin(),ilist.end(),*tk);
|
---|
252 | if(where != ilist.end()) {
|
---|
253 | tk = jlist.erase(tk);
|
---|
254 | }
|
---|
255 | else ++tk;
|
---|
256 | }
|
---|
257 |
|
---|
258 | jmax.erase();
|
---|
259 |
|
---|
260 | for ( typename std::list<const Item*>::const_iterator it = jlist.begin();
|
---|
261 | it != jlist.end(); ++it) jmax.addItem(*it);
|
---|
262 |
|
---|
263 | // recalculated jet quantities
|
---|
264 | jmax.updateJet();
|
---|
265 | jmax.splitted();
|
---|
266 | //std::cout << " jet split 1 :: " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl;
|
---|
267 | _members.insert(std::make_pair(jmax,jmax.pT()));
|
---|
268 | }
|
---|
269 |
|
---|
270 | // split and assign shared cells to nearest protojet
|
---|
271 | else
|
---|
272 | {
|
---|
273 | // here we need to pull the lists, because there are items to remove
|
---|
274 | std::list<const Item*> ilist(imax.LItems());
|
---|
275 | std::list<const Item*> jlist(jmax.LItems());
|
---|
276 |
|
---|
277 | typename std::list<const Item*>::iterator tk;
|
---|
278 | for(tk = jlist.begin(); tk != jlist.end(); )
|
---|
279 | {
|
---|
280 | typename std::list<const Item*>::iterator where=
|
---|
281 | find(ilist.begin(),ilist.end(),*tk);
|
---|
282 | if(where != ilist.end()) {
|
---|
283 | float yk = (*tk)->y();
|
---|
284 | float phik = (*tk)->phi();
|
---|
285 | float di= RD2(imax.y(),imax.phi(),yk,phik);
|
---|
286 | float dj= RD2(jmax.y(),jmax.phi(),yk,phik);
|
---|
287 | if(dj > di)
|
---|
288 | {
|
---|
289 | tk = jlist.erase(tk);
|
---|
290 | //std::cout << " shared item " << (*tk)->pT() << " removed from neighbour jet " << std::endl;
|
---|
291 | }
|
---|
292 | else
|
---|
293 | {
|
---|
294 | ilist.erase(where);
|
---|
295 | ++tk;
|
---|
296 | //std::cout << " shared item " << (*tk)->pT() << " removed from leading jet " << std::endl;
|
---|
297 | }
|
---|
298 | }
|
---|
299 | else ++tk;
|
---|
300 | }
|
---|
301 | // recalculate jets imax and jmax
|
---|
302 |
|
---|
303 | // first erase all items
|
---|
304 | imax.erase();
|
---|
305 | // put items that are left
|
---|
306 | for ( typename std::list<const Item*>::const_iterator it = ilist.begin();
|
---|
307 | it != ilist.end(); ++it) imax.addItem(*it);
|
---|
308 | // recalculated jet quantities
|
---|
309 | imax.updateJet();
|
---|
310 | imax.splitted();
|
---|
311 | //std::cout << " jet split 2 :: " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl;
|
---|
312 |
|
---|
313 |
|
---|
314 | // first erase all items
|
---|
315 | jmax.erase();
|
---|
316 | // put items that are left
|
---|
317 | for ( typename std::list<const Item*>::const_iterator it = jlist.begin();
|
---|
318 | it != jlist.end(); ++it) jmax.addItem(*it);
|
---|
319 | // recalculated jet quantities
|
---|
320 | jmax.updateJet();
|
---|
321 | jmax.splitted();
|
---|
322 | //std::cout << " jet split " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl;
|
---|
323 |
|
---|
324 | _members.insert(std::make_pair(jmax,jmax.pT()));
|
---|
325 | }
|
---|
326 | _members.insert(std::make_pair(imax,imax.pT()));
|
---|
327 | }
|
---|
328 | } // while
|
---|
329 | }
|
---|
330 | ///////////////////////////////////////////////////////////////////////////////
|
---|
331 |
|
---|
332 | } // namespace d0
|
---|
333 |
|
---|
334 | FASTJET_END_NAMESPACE
|
---|
335 |
|
---|
336 | #endif
|
---|