File: ConeSplitMerge.hpp

package info (click to toggle)
fastjet 3.0.6%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, stretch
  • size: 9,468 kB
  • ctags: 3,766
  • sloc: cpp: 21,498; sh: 10,546; fortran: 673; makefile: 518; ansic: 131
file content (336 lines) | stat: -rw-r--r-- 10,856 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#ifndef  D0RunIIconeJets_CONESPLITMERGE
#define  D0RunIIconeJets_CONESPLITMERGE
// ---------------------------------------------------------------------------
// ConeSplitMerge.hpp
//
// Created: 28-JUL-2000 Francois Touze
//
// Purpose: Implements the pT ordered jet split/merge algorithm for the 
//   Improved Legacy Cone Algorithm split/merge algo.
//
// Modified:
//   31-JUL-2000  Laurent Duflot
//     + introduce support for additional informations (ConeJetInfo)
//    1-AUG-2000  Laurent Duflot
//     + jet merge criteria was wrong, now calculate shared_ET and compare to 
//       neighbour jet pT.
//     + split was incomplete: shared items not really removed from jets.
//    4-Aug-2000  Laurent Duflot
//     + use item methods y() and phi() rather than p4vec() and then P2y and 
//       P2phi
//    7-Aug-2000  Laurent Duflot 
//     + force the list to be organized by decreasing ET and, for identical ET,
//       by decreasing seedET. Identical protojets can be found by eg nearby
//       seeds. The seedET ordering is such that for identical jets, the one
//       with the highest seedET is kept, which is what we want for efficiency
//       calculations.
//     + avoid unecessary copies of lists by using reference when possible
//    9-Aug-2000  Laurent Duflot
//     + save initial jet ET before split/merge
//    1-May-2007 Lars Sonnenschein
//    extracted from D0 software framework and modified to remove subsequent dependencies
//
//
// This file is distributed with FastJet under the terms of the GNU
// General Public License (v2). Permission to do so has been granted
// by Lars Sonnenschein and the D0 collaboration (see COPYING for
// details)
//
// History of changes in FastJet compared tothe original version of
// ConeSplitMerge.hpp
//
// 2011-12-13  Gregory Soyez  <soyez@fastjet.fr>
// 
//        * added license information
//
// 2009-01-17  Gregory Soyez  <soyez@fastjet.fr>
//
//        * put the code in the fastjet::d0 namespace
//
// 2007-12-14  Gavin Salam  <salam@lpthe.jussieu.fr>
// 
//        * replaced make_pair by std::make_pair
//
// ---------------------------------------------------------------------------


#include <iostream>
#include <map>
#include <utility>
#include <vector>
#include "ProtoJet.hpp"

//using namespace D0RunIIconeJets_CONEJETINFO;

#include <fastjet/internal/base.hh>

FASTJET_BEGIN_NAMESPACE

namespace d0{

//
// this class is used to order ProtoJets by decreasing ET and seed ET
template <class Item>
class ProtoJet_ET_seedET_order
{
public:
  bool operator()(const ProtoJet<Item> & first, const ProtoJet<Item> & second) const
  {
    if ( first.pT() > second.pT() ) return true;
    else
      if ( first.pT() < second.pT() ) return false;
      else return ( first.info().seedET() > second.info().seedET() );
  }
};


template <class Item>
class ConeSplitMerge {

public :

  typedef std::multimap<ProtoJet<Item>,float,ProtoJet_ET_seedET_order<Item> > PJMMAP;
  
  ConeSplitMerge();
  ConeSplitMerge(const std::vector<ProtoJet<Item> >& jvector);
  ConeSplitMerge(const std::list<ProtoJet<Item> >& jlist);
  ~ConeSplitMerge() {;}
  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);

private :
  PJMMAP _members;
};
///////////////////////////////////////////////////////////////////////////////
template<class Item>
ConeSplitMerge<Item>::ConeSplitMerge():_members() {;}

template<class Item>
ConeSplitMerge<Item>::ConeSplitMerge(const std::vector<ProtoJet<Item> >& jvector) 
{
  // sort proto_jets in Et descending order
  typename std::vector<ProtoJet<Item> >::const_iterator jt;
  for(jt = jvector.begin(); jt != jvector.end(); ++jt) 
  {
    // this is supposed to be a stable cone, declare so
    ProtoJet<Item> jet(*jt);
    jet.NowStable();
    _members.insert(std::make_pair(jet,jet.pT()));
  }
}

template<class Item>
ConeSplitMerge<Item>::ConeSplitMerge(const std::list<ProtoJet<Item> >& jlist) 
{
  //_max_nb_items =-1;
  // sort proto_jets in Et descending order
  typename std::list<ProtoJet<Item> >::const_iterator jt;
  for(jt = jlist.begin(); jt != jlist.end(); ++jt) 
  {
    // this is supposed to be a stable cone, declare so
    ProtoJet<Item> jet(*jt);
    jet.NowStable();
    _members.insert(std::make_pair(jet,jet.pT()));
  }
}

template<class Item>
void ConeSplitMerge<Item>::split_merge(std::vector<ProtoJet<Item> >& jcv,
				       float shared_ET_fraction,
				       float pT_min_leading_protojet, float pT_min_second_protojet,
				       int MergeMax, float pT_min_noMergeMax) 
{
  while(!_members.empty()) 
  {
    /*
    {
      std::cout << std::endl;
      std::cout << " ---------------  list of protojets ------------------ " <<std::endl;
      for ( PJMMAP::iterator it = _members.begin();
	    it != _members.end(); ++it)
      {
	std::cout << " pT y phi " << (*it).pT() << " " << (*it).y() << " " << (*it).phi() << " " << (*it).info().seedET() <<  " " << (*it).info().nbMerge() << " " << (*it).info().nbSplit() << std::endl;
      }
      std::cout << " ----------------------------------------------------- " <<std::endl;
    }
    */


    // select highest Et jet
    typename PJMMAP::iterator itmax= _members.begin();
    ProtoJet<Item> imax((*itmax).first);
    const std::list<const Item*>& ilist(imax.LItems());

    _members.erase(itmax);
 
    // does jet share items?
    bool share= false;
    float shared_ET = 0.;
    typename PJMMAP::iterator jtmax;
    typename PJMMAP::iterator jt;
    for(jt = _members.begin(); jt != _members.end(); ++jt) 
    {
      const std::list<const Item*>& jlist((*jt).first.LItems());
      typename std::list<const Item*>::const_iterator tk;
      int count;
      for(tk = ilist.begin(), count = 0; tk != ilist.end(); 
	  ++tk, ++count) 
      {
	typename std::list<const Item*>::const_iterator where= 
	  find(jlist.begin(),jlist.end(),*tk);   
	if(where != jlist.end()) 
	{
	  share= true;
	  shared_ET += (*tk)->pT();
	}
      }
      if(share) 
      {
	jtmax = jt;
	break;
      }
    }
    
    if(!share) {
      // add jet to the final jet list
      jcv.push_back(imax);
      //std::cout << " final jet " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 
    }
    else 
    {
      // find highest Et neighbor
      ProtoJet<Item> jmax((*jtmax).first);

      // drop neighbor
      _members.erase(jtmax);


      //std::cout << " split or merge ? " << imax.pT() << " " << shared_ET << " " << jmax.pT() << " " << s << " " << (jmax.pT())*s << std::endl;

      // merge
      if( shared_ET > (jmax.pT())*shared_ET_fraction 
	  && (imax.pT() > pT_min_leading_protojet || jmax.pT() > pT_min_second_protojet)
	  && (imax.info().nbMerge() < MergeMax || imax.pT() > pT_min_noMergeMax))
	{
	  // add neighbor's items to imax
	  const std::list<const Item*>& jlist(jmax.LItems());
	  typename std::list<const Item*>::const_iterator tk;
	  typename std::list<const Item*>::const_iterator iend= ilist.end();
	  bool same = true; // is jmax just the same as imax ? 
	  for(tk = jlist.begin(); tk != jlist.end(); ++tk) 
	    {
	      typename std::list<const Item*>::const_iterator where= 
		find(ilist.begin(),iend,*tk);   
	      if(where == iend) 
		{
		  imax.addItem(*tk);
		  same = false;
		}
	    }
	  if ( ! same ) 
	    {
	      // recalculate
	      //float old_pT = imax.pT();
	      
	      imax.updateJet();
	      imax.merged();
	      //std::cout << " jet merge :: " << old_pT << " " << jmax.pT() << " " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 
	    }
	}
      
      //split and assign removed shared cells from lowest pT protojet
      else if(shared_ET > (jmax.pT())*shared_ET_fraction)
      {
	// here we need to pull the lists, because there are items to remove                                                                           
	std::list<const Item*> ilist(imax.LItems());
	std::list<const Item*> jlist(jmax.LItems());

        typename std::list<const Item*>::iterator tk;
        for(tk = jlist.begin(); tk != jlist.end(); )
	  {
	    typename std::list<const Item*>::iterator where=
	      find(ilist.begin(),ilist.end(),*tk);
	    if(where != ilist.end()) {
	      tk = jlist.erase(tk);
	    }
	    else ++tk;
	  }
	
        jmax.erase();

        for ( typename std::list<const Item*>::const_iterator it = jlist.begin();
              it != jlist.end(); ++it) jmax.addItem(*it);

        // recalculated jet quantities 
        jmax.updateJet();
        jmax.splitted();
        //std::cout << " jet split 1 :: " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl;                         
        _members.insert(std::make_pair(jmax,jmax.pT()));
      }

      // split and assign shared cells to nearest protojet
      else 
      {
	// here we need to pull the lists, because there are items to remove
	std::list<const Item*> ilist(imax.LItems());
	std::list<const Item*> jlist(jmax.LItems());
	
	typename std::list<const Item*>::iterator tk;
	for(tk = jlist.begin(); tk != jlist.end(); ) 
	{
	  typename std::list<const Item*>::iterator where= 
	    find(ilist.begin(),ilist.end(),*tk);
	  if(where != ilist.end()) {
	    float yk   = (*tk)->y();
	    float phik = (*tk)->phi();
	    float di= RD2(imax.y(),imax.phi(),yk,phik);
	    float dj= RD2(jmax.y(),jmax.phi(),yk,phik);
	    if(dj > di) 
	    {
	      tk = jlist.erase(tk);
	      //std::cout << " shared item " << (*tk)->pT() << " removed from neighbour jet " << std::endl;
	    }
	    else
	    {
	      ilist.erase(where);
	      ++tk;
	      //std::cout << " shared item " << (*tk)->pT() << " removed from leading jet " << std::endl;
	    }
	  }
	  else ++tk;
	}
	// recalculate jets imax and jmax
	
	// first erase all items
	imax.erase();
	// put items that are left
	for ( typename std::list<const Item*>::const_iterator it = ilist.begin();
	      it != ilist.end(); ++it) imax.addItem(*it);
	// recalculated jet quantities
	imax.updateJet();
	imax.splitted();
	//std::cout << " jet split 2 :: " << imax.pT() << " "<< imax.info().nbMerge() << " " << imax.info().nbSplit() << std::endl; 


	// first erase all items
	jmax.erase();
	// put items that are left
	for ( typename std::list<const Item*>::const_iterator it = jlist.begin();
	      it != jlist.end(); ++it) jmax.addItem(*it);
	// recalculated jet quantities
	jmax.updateJet();
	jmax.splitted();
	//std::cout << " jet split " << jmax.pT() << " "<< jmax.info().nbMerge() << " " << jmax.info().nbSplit() << std::endl; 

	_members.insert(std::make_pair(jmax,jmax.pT()));
      }
      _members.insert(std::make_pair(imax,imax.pT()));
    }
  } // while
}
///////////////////////////////////////////////////////////////////////////////

}  // namespace d0

FASTJET_END_NAMESPACE

#endif