1 #ifndef D0RunIIconeJets_ILCONEALGORITHM
2 #define D0RunIIconeJets_ILCONEALGORITHM
88 #include "ProtoJet.hpp"
90 #include "ConeSplitMerge.hpp"
93 #include "inline_maths.h"
96 #include <fastjet/internal/base.hh>
98 FASTJET_BEGIN_NAMESPACE
102 using namespace inline_maths;
120 #ifdef ILCA_USE_ORDERED_LIST
122 template <
class Item>
126 bool operator()(
const Item* first,
const Item* second)
128 return (first->y() < second->y());
130 bool operator()(
float const & first,
const Item* second)
132 return (first < second->y());
134 bool operator()(
const Item* first,
float const& second)
136 return (first->y() < second);
143 template <
class Item>
144 class ILConeAlgorithm
157 _DUPLICATE_DR(0.005),
158 _DUPLICATE_DPT(0.01),
160 _PT_MIN_LEADING_PROTOJET(0),
161 _PT_MIN_SECOND_PROTOJET(0),
163 _PT_MIN_noMERGE_MAX(0)
167 ILConeAlgorithm(
float cone_radius,
float min_jet_Et,
float split_ratio,
168 float far_ratio=0.5,
float Et_min_ratio=0.5,
169 bool kill_duplicate=
true,
float duplicate_dR=0.005,
170 float duplicate_dPT=0.01,
float search_factor=1.0,
171 float pT_min_leading_protojet=0.,
float pT_min_second_protojet=0.,
172 int merge_max=10000,
float pT_min_nomerge=0.) :
174 _CONE_RADIUS(cone_radius),
176 _MIN_JET_ET(min_jet_Et),
178 _ET_MIN_RATIO(Et_min_ratio),
180 _FAR_RATIO(far_ratio),
182 _SPLIT_RATIO(split_ratio),
183 _DUPLICATE_DR(duplicate_dR),
184 _DUPLICATE_DPT(duplicate_dPT),
185 _SEARCH_CONE(cone_radius/search_factor),
188 _KILL_DUPLICATE(kill_duplicate),
189 _PT_MIN_LEADING_PROTOJET(pT_min_leading_protojet),
190 _PT_MIN_SECOND_PROTOJET(pT_min_second_protojet),
191 _MERGE_MAX(merge_max),
192 _PT_MIN_noMERGE_MAX(pT_min_nomerge)
196 ~ILConeAlgorithm() {;}
202 std::list<Item> &jets,
203 std::list<const Item*>& itemlist,
208 const float Item_ET_Threshold);
211 std::vector<ProtoJet<Item> > ilcv;
221 float _DUPLICATE_DPT;
224 bool _KILL_DUPLICATE;
226 float _PT_MIN_LEADING_PROTOJET;
227 float _PT_MIN_SECOND_PROTOJET;
229 float _PT_MIN_noMERGE_MAX;
234 class TemporaryJet :
public ProtoJet<Item>
239 TemporaryJet(
float seedET) : ProtoJet<Item>(seedET) {;}
241 TemporaryJet(
float seedET,
float y_in,
float phi_in) :
242 ProtoJet<Item>(seedET,y_in,phi_in) {;}
246 float dist(TemporaryJet& jet)
const
248 return RDelta(this->_y,this->_phi,jet.y(),jet.phi());
251 void midpoint(
const TemporaryJet& jet,
float & y_out,
float & phi_out)
const
255 float pTsum = this->_pT + jet.pT();
256 y_out = (this->_y*this->_pT + jet.y()*jet.pT())/pTsum;
258 phi_out = (this->_phi*this->_pT + jet.phi()*jet.pT())/pTsum;
263 if ( fabs(phi_out-this->_phi)>2.0 ) {
264 phi_out = fmod( this->_phi+PI, TWOPI);
265 if (phi_out < 0.0) phi_out += TWOPI;
268 float temp=fmod( jet.phi()+PI, TWOPI);
269 if (temp < 0.0) temp += TWOPI;
272 phi_out = (phi_out*this->_pT + temp*jet.pT()) /pTsum;
275 if ( phi_out < 0. ) phi_out += TWOPI;
281 bool is_stable(
const std::multimap<float,const Item*>& items,
282 float radius,
float min_ET,
int max_iterations=50)
284 bool is_stable(
const std::list<const Item*>& itemlist,
float radius,
285 float min_ET,
int max_iterations=50)
289 float radius2 = radius*radius;
306 this->setJet(Yst,PHIst,0.0);
309 #ifdef ILCA_USE_ORDERED_LIST
310 std::list<const Item*>::const_iterator lower =
311 lower_bound(itemlist.begin(),itemlist.end(),Yst-radius,
312 rapidity_order<Item>());
313 std::list<const Item*>::const_iterator upper =
314 upper_bound(itemlist.begin(),itemlist.end(),Yst+radius,
315 rapidity_order<Item>());
316 for(std::list<const Item*>::const_iterator tk = lower; tk != upper; ++tk) {
318 if(RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) <= radius2)
326 for ( std::multimap<float,const Item*>::const_iterator
327 tk = items.lower_bound(Yst-radius);
328 tk != items.upper_bound(Yst+radius); ++tk )
331 if(RD2(((*tk).second)->y(),((*tk).second)->phi(),Yst,PHIst) <= radius2)
333 this->addItem((*tk).second);
340 for(
typename std::list<const Item*>::const_iterator tk = itemlist.begin(); tk != itemlist.end(); ++tk)
343 if(RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) <= radius2)
356 if(this->_pT < min_ET )
362 }
while(RD2(this->_y,this->_phi,Yst,PHIst) >= Rcut && trial <= max_iterations);
374 template <
class Item>
375 void ILConeAlgorithm <Item>::
378 std::list<Item> &jets,
379 std::list<const Item*>& ilist,
384 const float Item_ET_Threshold)
387 for (
typename std::list<const Item*>::iterator it = ilist.begin();
391 if ( (*it)->pT() < Item_ET_Threshold )
393 it = ilist.erase(it);
403 std::vector<const Item*> ecv;
404 for (
typename std::list<const Item*>::iterator it = ilist.begin();
405 it != ilist.end(); it++) {
416 float far_def = _FAR_RATIO*_CONE_RADIUS * _FAR_RATIO*_CONE_RADIUS;
419 float ratio= _MIN_JET_ET*_ET_MIN_RATIO;
422 #ifdef ILCA_USE_ORDERED_LIST
424 ilist.sort(rapidity_order<Item>());
428 std::multimap<float,const Item*> items;
429 std::list<const Item*>::const_iterator it;
430 for(it = ilist.begin(); it != ilist.end(); ++it)
432 pair<float,const Item*> p((*it)->y(),*it);
438 std::vector<ProtoJet<Item> > mcoll;
439 std::vector<TemporaryJet> scoll;
444 typename std::vector<const Item*>::iterator jclu;
445 for(jclu = ecv.begin(); jclu != ecv.end(); ++jclu)
448 const Item* ptr= *jclu;
452 float PHIst= P2phi(p);
457 for(
unsigned int i = 0; i < scoll.size(); ++i)
459 float y = scoll[i].y();
460 float phi= scoll[i].phi();
461 if(RD2(Yst,PHIst,y,phi) < far_def)
471 TemporaryJet jet(ptr->pT(),Yst,PHIst);
478 if(jet.is_stable(items,_CONE_RADIUS,ratio,0) && jet.is_stable(items,_SEARCH_CONE,3.0))
480 if(jet.is_stable(ilist,_CONE_RADIUS,ratio,0) && jet.is_stable(ilist,_SEARCH_CONE,3.0))
488 jet.is_stable(items,_CONE_RADIUS,ratio,0) ;
490 jet.is_stable(ilist,_CONE_RADIUS,ratio,0) ;
494 if ( _KILL_DUPLICATE )
497 float distmax = 999.;
int imax = -1;
498 for(
unsigned int i = 0; i < scoll.size(); ++i)
500 float dist = jet.dist(scoll[i]);
501 if ( dist < distmax )
507 if ( distmax > _DUPLICATE_DR ||
508 fabs((jet.pT()-scoll[imax].pT())/scoll[imax].pT())>_DUPLICATE_DPT )
510 scoll.push_back(jet);
511 mcoll.push_back(jet);
524 scoll.push_back(jet);
525 mcoll.push_back(jet);
534 for(
unsigned int i = 0; i < scoll.size(); ++i)
536 for(
unsigned int k = i+1; k < scoll.size(); ++k)
538 float djet= scoll[i].dist(scoll[k]);
539 if(djet > _CONE_RADIUS && djet < 2.*_CONE_RADIUS)
542 scoll[i].midpoint(scoll[k],y_mid,phi_mid);
543 TemporaryJet jet(-999999.,y_mid,phi_mid);
548 if(jet.is_stable(items,_CONE_RADIUS,ratio))
550 if(jet.is_stable(ilist,_CONE_RADIUS,ratio))
553 mcoll.push_back(jet);
562 ConeSplitMerge<Item> pjets(mcoll);
564 pjets.split_merge(ilcv,_SPLIT_RATIO, _PT_MIN_LEADING_PROTOJET, _PT_MIN_SECOND_PROTOJET, _MERGE_MAX, _PT_MIN_noMERGE_MAX);
567 for(
unsigned int i = 0; i < ilcv.size(); ++i)
569 if ( ilcv[i].pT() > _MIN_JET_ET )
575 std::list<const Item*> tlist=ilcv[i].LItems();
576 typename std::list<const Item*>::iterator tk;
577 for(tk = tlist.begin(); tk != tlist.end(); ++tk)
592 jets.push_back(ptrclu);
599 FASTJET_END_NAMESPACE