FastJet 3.0.1
|
00001 #ifndef D0RunIIconeJets_ILCONEALGORITHM 00002 #define D0RunIIconeJets_ILCONEALGORITHM 00003 // --------------------------------------------------------------------------- 00004 // ILConeAlgorithm.hpp 00005 // 00006 // Created: 28-JUL-2000 Francois Touze (+ Laurent Duflot) 00007 // 00008 // Purpose: Implements the Improved Legacy Cone Algorithm 00009 // 00010 // Modified: 00011 // 31-JUL-2000 Laurent Duflot 00012 // + introduce support for additional informations (ConeJetInfo) 00013 // 1-AUG-2000 Laurent Duflot 00014 // + seedET for midpoint jet is -999999., consistent with seedET ordering 00015 // in ConeSplitMerge: final jets with seedET=-999999. will be midpoint 00016 // jets which were actually different from stable cones. 00017 // 4-Aug-2000 Laurent Duflot 00018 // + remove unecessary copy in TemporaryJet::is_stable() 00019 // 11-Aug-2000 Laurent Duflot 00020 // + remove using namespace std 00021 // + add threshold on item. The input list to makeClusters() IS modified 00022 // 20-June-2002 John Krane 00023 // + remove bug in midpoint calculation based on pT weight 00024 // + started to add new midpoint calculation based on 4-vectors, 00025 // but not enough info held by this class 00026 // 24-June-2002 John Krane 00027 // + modify is_stable() to not iterate if desired 00028 // (to expand search cone w/out moving it) 00029 // + added search cone logic for initial jets but not midpoint jets as per 00030 // agreement with CDF 00031 // 19-July-2002 John Krane 00032 // + _SEARCH_CONE size factor now provided by calreco/CalClusterReco.cpp 00033 // + (default = 1.0 = like original ILCone behavior) 00034 // 10-Oct-2002 John Krane 00035 // + Check min Pt of cone with full size first, then iterate with search cone 00036 // 07-Dec-2002 John Krane 00037 // + speed up the midpoint phi-wrap solution 00038 // 01-May-2007 Lars Sonnenschein 00039 // extracted from D0 software framework and modified to remove subsequent dependencies 00040 // 00041 // --------------------------------------------------------------------------- 00042 00043 // History of changes in FastJet compared tothe original version of 00044 // ProtoJet.hpp 00045 // 00046 // 2011-11-14 Gregory Soyez <soyez@fastjet.fr> 00047 // 00048 // * changed the name of a few parameters to avoid a gcc 00049 // -Wshadow warning 00050 // 00051 // 2009-01-17 Gregory Soyez <soyez@fastjet.fr> 00052 // 00053 // * put the code in the fastjet::d0 namespace 00054 // 00055 // 2007-12-14 Gavin Salam <salam@lpthe.jussieu.fr> 00056 // 00057 // * moved the 'std::vector<ProtoJet<Item> > ilcv' structure 00058 // containing the info about the final jets from a local 00059 // variable to a class variable (for integration in the 00060 // FastJet plugin core) 00061 00062 /////////////////////////////////////////////////////////////////////////////// 00063 #include <vector> 00064 #include <list> 00065 #include <utility> // defines pair<,> 00066 #include <map> 00067 #include <algorithm> 00068 #include <iostream> 00069 00070 00071 //#include "energycluster/EnergyClusterReco.hpp" 00072 //#include "energycluster/ProtoJet.hpp" 00073 #include "ProtoJet.hpp" 00074 //#include "energycluster/ConeSplitMerge.hpp" 00075 #include "ConeSplitMerge.hpp" 00076 //#include "energycluster/ConeJetInfoChunk.hpp" 00077 00078 #include "inline_maths.h" 00079 00080 /////////////////////////////////////////////////////////////////////////////// 00081 #include <fastjet/internal/base.hh> 00082 00083 FASTJET_BEGIN_NAMESPACE 00084 00085 namespace d0{ 00086 00087 using namespace inline_maths; 00088 00089 /* 00090 NB: Some attempt at optimizing the code has been made by ordering the object 00091 along rapidity but this did not improve the speed. There are traces of 00092 these atemps in the code, that will be cleaned up in the future. 00093 */ 00094 00095 // at most one of those ! 00096 // order the input list and use lower_bound() and upper_bound() to restrict the 00097 // on item to those that could possibly be in the cone. 00098 //#define ILCA_USE_ORDERED_LIST 00099 00100 // idem but use an intermediate multimap in hope that lower_bound() and 00101 // upper_bound() are faster in this case. 00102 //#define ILCA_USE_MMAP 00103 00104 00105 #ifdef ILCA_USE_ORDERED_LIST 00106 // this class is used to order the item list along rapidity 00107 template <class Item> 00108 class rapidity_order 00109 { 00110 public: 00111 bool operator()(const Item* first, const Item* second) 00112 { 00113 return (first->y() < second->y()); 00114 } 00115 bool operator()(float const & first, const Item* second) 00116 { 00117 return (first < second->y()); 00118 } 00119 bool operator()(const Item* first, float const& second) 00120 { 00121 return (first->y() < second); 00122 } 00123 }; 00124 #endif 00125 00126 00127 //template <class Item,class ItemAddress,class IChunk> 00128 template <class Item> 00129 class ILConeAlgorithm 00130 { 00131 00132 public: 00133 00134 // default constructor (default parameters are crazy: you should not use that 00135 // constructor !) 00136 ILConeAlgorithm(): 00137 _CONE_RADIUS(0.), 00138 _MIN_JET_ET(99999.), 00139 _ET_MIN_RATIO(0.5), 00140 _FAR_RATIO(0.5), 00141 _SPLIT_RATIO(0.5), 00142 _DUPLICATE_DR(0.005), 00143 _DUPLICATE_DPT(0.01), 00144 _SEARCH_CONE(0.5), 00145 _PT_MIN_LEADING_PROTOJET(0), 00146 _PT_MIN_SECOND_PROTOJET(0), 00147 _MERGE_MAX(10000), 00148 _PT_MIN_noMERGE_MAX(0) 00149 {;} 00150 00151 // full constructor 00152 ILConeAlgorithm(float cone_radius, float min_jet_Et, float split_ratio, 00153 float far_ratio=0.5, float Et_min_ratio=0.5, 00154 bool kill_duplicate=true, float duplicate_dR=0.005, 00155 float duplicate_dPT=0.01, float search_factor=1.0, 00156 float pT_min_leading_protojet=0., float pT_min_second_protojet=0., 00157 int merge_max=10000, float pT_min_nomerge=0.) : 00158 // cone radius 00159 _CONE_RADIUS(cone_radius), 00160 // minimum jet ET 00161 _MIN_JET_ET(min_jet_Et), 00162 // stable cones must have ET > _ET_MIN_RATIO*_MIN_JET_ET at any iteration 00163 _ET_MIN_RATIO(Et_min_ratio), 00164 // precluster at least _FAR_RATIO*_CONE_RADIUS away from stable cones 00165 _FAR_RATIO(far_ratio), 00166 // split or merge criterium 00167 _SPLIT_RATIO(split_ratio), 00168 _DUPLICATE_DR(duplicate_dR), 00169 _DUPLICATE_DPT(duplicate_dPT), 00170 _SEARCH_CONE(cone_radius/search_factor), 00171 // kill stable cone if within _DUPLICATE_DR and delta(pT)<_DUPLICATE_DPT 00172 // of another stable cone. 00173 _KILL_DUPLICATE(kill_duplicate), 00174 _PT_MIN_LEADING_PROTOJET(pT_min_leading_protojet), 00175 _PT_MIN_SECOND_PROTOJET(pT_min_second_protojet), 00176 _MERGE_MAX(merge_max), 00177 _PT_MIN_noMERGE_MAX(pT_min_nomerge) 00178 {;} 00179 00180 //destructor 00181 ~ILConeAlgorithm() {;} 00182 00183 // make jet clusters using improved legacy cone algorithm 00184 //void makeClusters(const EnergyClusterReco* r, 00185 void makeClusters( 00186 // the input list modified (ordered) 00187 std::list<Item> &jets, 00188 std::list<const Item*>& itemlist, 00189 //float zvertex, 00190 ////std::list<const Item*>& itemlist); 00191 //const EnergyClusterCollection<ItemAddress>& preclu, 00192 //IChunk* chunkptr, ConeJetInfoChunk* infochunkptr, 00193 const float Item_ET_Threshold); 00194 00195 // this will hold the final jets + contents 00196 std::vector<ProtoJet<Item> > ilcv; 00197 00198 private: 00199 00200 float _CONE_RADIUS; 00201 float _MIN_JET_ET; 00202 float _ET_MIN_RATIO; 00203 float _FAR_RATIO; 00204 float _SPLIT_RATIO; 00205 float _DUPLICATE_DR; 00206 float _DUPLICATE_DPT; 00207 float _SEARCH_CONE; 00208 00209 bool _KILL_DUPLICATE; 00210 00211 float _PT_MIN_LEADING_PROTOJET; 00212 float _PT_MIN_SECOND_PROTOJET; 00213 int _MERGE_MAX; 00214 float _PT_MIN_noMERGE_MAX; 00215 00216 // private class 00217 // This is a ProtoJet with additional methods dist(), midpoint() and 00218 // is_stable() 00219 class TemporaryJet : public ProtoJet<Item> 00220 { 00221 00222 public : 00223 00224 TemporaryJet(float seedET) : ProtoJet<Item>(seedET) {;} 00225 00226 TemporaryJet(float seedET,float y_in,float phi_in) : 00227 ProtoJet<Item>(seedET,y_in,phi_in) {;} 00228 00229 ~TemporaryJet() {;} 00230 00231 float dist(TemporaryJet& jet) const 00232 { 00233 return RDelta(this->_y,this->_phi,jet.y(),jet.phi()); 00234 } 00235 00236 void midpoint(const TemporaryJet& jet,float & y_out, float & phi_out) const 00237 { 00238 // Midpoint should probably be computed w/4-vectors but don't 00239 // have that info. Preserving Pt-weighted calculation - JPK 00240 float pTsum = this->_pT + jet.pT(); 00241 y_out = (this->_y*this->_pT + jet.y()*jet.pT())/pTsum; 00242 00243 phi_out = (this->_phi*this->_pT + jet.phi()*jet.pT())/pTsum; 00244 // careful with phi-wrap area: convert from [0,2pi] to [-pi,pi] 00245 //ls: original D0 code, as of 23/Mar/2007 00246 //if ( abs(phi-this->_phi)>2.0 ) { // assumes cones R=1.14 or smaller, merge within 2R only 00247 //ls: abs bug fixed 26/Mar/2007 00248 if ( fabs(phi_out-this->_phi)>2.0 ) { // assumes cones R=1.14 or smaller, merge within 2R only 00249 phi_out = fmod( this->_phi+PI, TWOPI); 00250 if (phi_out < 0.0) phi_out += TWOPI; 00251 phi_out -= PI; 00252 00253 float temp=fmod( jet.phi()+PI, TWOPI); 00254 if (temp < 0.0) temp += TWOPI; 00255 temp -= PI; 00256 00257 phi_out = (phi_out*this->_pT + temp*jet.pT()) /pTsum; 00258 } 00259 00260 if ( phi_out < 0. ) phi_out += TWOPI; 00261 } 00262 00263 00264 //////////////////////////////////////// 00265 #ifdef ILCA_USE_MMAP 00266 bool is_stable(const std::multimap<float,const Item*>& items, 00267 float radius, float min_ET, int max_iterations=50) 00268 #else 00269 bool is_stable(const std::list<const Item*>& itemlist, float radius, 00270 float min_ET, int max_iterations=50) 00271 #endif 00272 // Note: max_iterations = 0 will just recompute the jet using the specified cone 00273 { 00274 float radius2 = radius*radius; 00275 float Rcut= 1.E-06; 00276 00277 00278 // ?? if(_Increase_Delta_R) Rcut= 1.E-04; 00279 bool stable= true; 00280 int trial= 0; 00281 float Yst; 00282 float PHIst; 00283 do { 00284 trial++; 00285 //std::cout << " trial " << trial << " " << _y << " " << _phi << std::endl; 00286 Yst = this->_y; 00287 PHIst= this->_phi; 00288 //cout << "is_stable beginning do loop: this->_pT=" << this->_pT << " this->_y=" << this->_y << " this->_phi=" << this->_phi << endl; 00289 this->erase(); 00290 00291 this->setJet(Yst,PHIst,0.0); 00292 00293 00294 #ifdef ILCA_USE_ORDERED_LIST 00295 std::list<const Item*>::const_iterator lower = 00296 lower_bound(itemlist.begin(),itemlist.end(),Yst-radius, 00297 rapidity_order<Item>()); 00298 std::list<const Item*>::const_iterator upper = 00299 upper_bound(itemlist.begin(),itemlist.end(),Yst+radius, 00300 rapidity_order<Item>()); 00301 for(std::list<const Item*>::const_iterator tk = lower; tk != upper; ++tk) { 00302 //std::cout << " is_stable: item y=" << (*tk)->y() << " phi=" << (*tk)->phi() << " RD2=" << RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) << " " << Yst-radius << " " << Yst+radius << endl; 00303 if(RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) <= radius2) 00304 { 00305 addItem(*tk); 00306 } 00307 } 00308 #else 00309 #ifdef ILCA_USE_MMAP 00310 // need to loop only on the subset with Yst-R < y < Yst+R 00311 for ( std::multimap<float,const Item*>::const_iterator 00312 tk = items.lower_bound(Yst-radius); 00313 tk != items.upper_bound(Yst+radius); ++tk ) 00314 { 00315 //std::cout << " item " << (*tk)->y() << " " << (*tk)->phi() << " " << RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) << " " << Yst-radius << " " << Yst+radius << endl; 00316 if(RD2(((*tk).second)->y(),((*tk).second)->phi(),Yst,PHIst) <= radius2) 00317 { 00318 addItem((*tk).second); 00319 } 00320 } 00321 00322 #else 00323 00324 //cout << " is_stable: itemlist.size()=" << itemlist.size() << endl; 00325 for(typename std::list<const Item*>::const_iterator tk = itemlist.begin(); tk != itemlist.end(); ++tk) 00326 { 00327 //std::cout << " is_stable: item (*tk)->y()=" << (*tk)->y() << " (*tk)->phi=" << (*tk)->phi() << " RD2=" << RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) << " Yst-rad=" << Yst-radius << " Yst+rad=" << Yst+radius << endl; 00328 if(RD2((*tk)->y(),(*tk)->phi(),Yst,PHIst) <= radius2) 00329 { 00330 //cout << "add item to *tk" << endl; 00331 addItem(*tk); 00332 } 00333 } 00334 #endif 00335 #endif 00336 00337 //std::cout << "is_stable, before update: jet this->_y=" << this->_y << " _phi=" << this->_phi << " _pT=" << this->_pT << " min_ET=" << min_ET << std::endl; 00338 this->updateJet(); 00339 //std::cout << "is_stable, after update: jet this->_y=" << this->_y << " _phi=" << this->_phi << " _pT=" << this->_pT << " min_ET=" << min_ET << std::endl; 00340 00341 if(this->_pT < min_ET ) 00342 { 00343 stable= false; 00344 break; 00345 } 00346 //cout << "is_stable end while loop: this->_pT=" << this->_pT << " this->_y=" << this->_y << " this->_phi=" << this->_phi << endl; 00347 } while(RD2(this->_y,this->_phi,Yst,PHIst) >= Rcut && trial <= max_iterations); 00348 //std::cout << " trial stable " << trial << " " << stable << std::endl; 00349 return stable; 00350 } 00351 00352 private : 00353 00354 }; 00355 }; 00356 /////////////////////////////////////////////////////////////////////////////// 00357 //template <class Item,class ItemAddress,class IChunk> 00358 //void ILConeAlgorithm <Item,ItemAddress,IChunk>:: 00359 template <class Item> 00360 void ILConeAlgorithm <Item>:: 00361 //makeClusters(const EnergyClusterReco* r, 00362 makeClusters( 00363 std::list<Item> &jets, 00364 std::list<const Item*>& ilist, 00365 //float Zvertex, 00366 ////std::list<const Item*>& ilist) 00367 //const EnergyClusterCollection<ItemAddress>& preclu, 00368 //IChunk* chunkptr, ConeJetInfoChunk* infochunkptr, 00369 const float Item_ET_Threshold) 00370 { 00371 // remove items below threshold 00372 for ( typename std::list<const Item*>::iterator it = ilist.begin(); 00373 00374 it != ilist.end(); ) 00375 { 00376 if ( (*it)->pT() < Item_ET_Threshold ) 00377 { 00378 it = ilist.erase(it); 00379 } 00380 else ++it; 00381 } 00382 00383 // create an energy cluster collection for jets 00384 //EnergyClusterCollection<ItemAddress>* ptrcol; 00385 //Item* ptrcol; 00386 //r->createClusterCollection(chunkptr,ptrcol); 00387 ////std::vector<const EnergyCluster<ItemAddress>*> ecv; 00388 std::vector<const Item*> ecv; 00389 for ( typename std::list<const Item*>::iterator it = ilist.begin(); 00390 it != ilist.end(); it++) { 00391 ecv.push_back(*it); 00392 } 00393 00394 00395 //preclu.getClusters(ecv); 00396 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% need to fill here vector ecv 00397 00398 //std::cout << " number of seed clusters: " << ecv.size() << std::endl; 00399 00400 // skip precluster close to jets 00401 float far_def = _FAR_RATIO*_CONE_RADIUS * _FAR_RATIO*_CONE_RADIUS; 00402 00403 // skip if jet Et is below some value 00404 float ratio= _MIN_JET_ET*_ET_MIN_RATIO; 00405 00406 00407 #ifdef ILCA_USE_ORDERED_LIST 00408 // sort the list in rapidity order 00409 ilist.sort(rapidity_order<Item>()); 00410 #else 00411 #ifdef ILCA_USE_MMAP 00412 // create a y ordered list of items 00413 std::multimap<float,const Item*> items; 00414 std::list<const Item*>::const_iterator it; 00415 for(it = ilist.begin(); it != ilist.end(); ++it) 00416 { 00417 pair<float,const Item*> p((*it)->y(),*it); 00418 items.insert(p); 00419 } 00420 #endif 00421 #endif 00422 00423 std::vector<ProtoJet<Item> > mcoll; 00424 std::vector<TemporaryJet> scoll; 00425 00426 00427 // find stable jets around seeds 00428 //typename std::vector<const EnergyCluster<ItemAddress>* >::iterator jclu; 00429 typename std::vector<const Item*>::iterator jclu; 00430 for(jclu = ecv.begin(); jclu != ecv.end(); ++jclu) 00431 { 00432 //const EnergyCluster<ItemAddress>* ptr= *jclu; 00433 const Item* ptr= *jclu; 00434 float p[4]; 00435 ptr->p4vec(p); 00436 float Yst = P2y(p); 00437 float PHIst= P2phi(p); 00438 00439 // don't keep preclusters close to jet 00440 bool is_far= true; 00441 // ?? if(_Kill_Far_Clusters) { 00442 for(unsigned int i = 0; i < scoll.size(); ++i) 00443 { 00444 float y = scoll[i].y(); 00445 float phi= scoll[i].phi(); 00446 if(RD2(Yst,PHIst,y,phi) < far_def) 00447 { 00448 is_far= false; 00449 break; 00450 } 00451 } 00452 // ?? } 00453 00454 if(is_far) 00455 { 00456 TemporaryJet jet(ptr->pT(),Yst,PHIst); 00457 //cout << "temporary jet: pt=" << ptr->pT() << " y=" << Yst << " phi=" << PHIst << endl; 00458 00459 // Search cones are smaller, so contain less jet Et 00460 // Don't throw out too many little jets during search phase! 00461 // Strategy: check Et first with full cone, then search with low-GeV min_et thresh 00462 #ifdef ILCA_USE_MMAP 00463 if(jet.is_stable(items,_CONE_RADIUS,ratio,0) && jet.is_stable(items,_SEARCH_CONE,3.0)) 00464 #else 00465 if(jet.is_stable(ilist,_CONE_RADIUS,ratio,0) && jet.is_stable(ilist,_SEARCH_CONE,3.0)) 00466 #endif 00467 { 00468 00469 //cout << "temporary jet is stable" << endl; 00470 00471 // jpk Resize the found jets 00472 #ifdef ILCA_USE_MMAP 00473 jet.is_stable(items,_CONE_RADIUS,ratio,0) ; 00474 #else 00475 jet.is_stable(ilist,_CONE_RADIUS,ratio,0) ; 00476 #endif 00477 //cout << "found jet has been resized if any" << endl; 00478 00479 if ( _KILL_DUPLICATE ) 00480 { 00481 // check if we are not finding the same jet again 00482 float distmax = 999.; int imax = -1; 00483 for(unsigned int i = 0; i < scoll.size(); ++i) 00484 { 00485 float dist = jet.dist(scoll[i]); 00486 if ( dist < distmax ) 00487 { 00488 distmax = dist; 00489 imax = i; 00490 } 00491 } 00492 if ( distmax > _DUPLICATE_DR || 00493 fabs((jet.pT()-scoll[imax].pT())/scoll[imax].pT())>_DUPLICATE_DPT ) 00494 { 00495 scoll.push_back(jet); 00496 mcoll.push_back(jet); 00497 //std::cout << " stable cone " << jet.y() << " " << jet.phi() << " " << jet.pT() << std::endl; 00498 } 00499 /* 00500 else 00501 { 00502 std::cout << " jet too close to a found jet " << distmax << " " << 00503 fabs((jet.pT()-scoll[imax].pT())/scoll[imax].pT()) << std::endl; 00504 } 00505 */ 00506 } 00507 else 00508 { 00509 scoll.push_back(jet); 00510 mcoll.push_back(jet); 00511 //std::cout << " stable cone " << jet.y() << " " << jet.phi() << " " << jet.pT() << std::endl; 00512 } 00513 00514 } 00515 } 00516 } 00517 00518 // find stable jets around midpoints 00519 for(unsigned int i = 0; i < scoll.size(); ++i) 00520 { 00521 for(unsigned int k = i+1; k < scoll.size(); ++k) 00522 { 00523 float djet= scoll[i].dist(scoll[k]); 00524 if(djet > _CONE_RADIUS && djet < 2.*_CONE_RADIUS) 00525 { 00526 float y_mid,phi_mid; 00527 scoll[i].midpoint(scoll[k],y_mid,phi_mid); 00528 TemporaryJet jet(-999999.,y_mid,phi_mid); 00529 //std::cout << " midpoint: " << scoll[i].pT() << " " << scoll[i].info().seedET() << " " << scoll[k].pT() << " " << scoll[k].info().seedET() << " " << y_mid << " " << phi_mid << std::endl; 00530 00531 // midpoint jets are full size 00532 #ifdef ILCA_USE_MMAP 00533 if(jet.is_stable(items,_CONE_RADIUS,ratio)) 00534 #else 00535 if(jet.is_stable(ilist,_CONE_RADIUS,ratio)) 00536 #endif 00537 { 00538 mcoll.push_back(jet); 00539 //std::cout << " stable midpoint cone " << jet.y() << " " << jet.phi() << " " << jet.pT() << std::endl; 00540 } 00541 } 00542 } 00543 } 00544 00545 00546 // do a pT ordered splitting/merging 00547 ConeSplitMerge<Item> pjets(mcoll); 00548 ilcv.clear(); 00549 pjets.split_merge(ilcv,_SPLIT_RATIO, _PT_MIN_LEADING_PROTOJET, _PT_MIN_SECOND_PROTOJET, _MERGE_MAX, _PT_MIN_noMERGE_MAX); 00550 00551 00552 for(unsigned int i = 0; i < ilcv.size(); ++i) 00553 { 00554 if ( ilcv[i].pT() > _MIN_JET_ET ) 00555 { 00556 //EnergyCluster<ItemAddress>* ptrclu; 00557 Item ptrclu; 00558 //r->createCluster(ptrcol,ptrclu); 00559 00560 std::list<const Item*> tlist=ilcv[i].LItems(); 00561 typename std::list<const Item*>::iterator tk; 00562 for(tk = tlist.begin(); tk != tlist.end(); ++tk) 00563 { 00564 //ItemAddress addr= (*tk)->address(); 00565 float pk[4]; 00566 (*tk)->p4vec(pk); 00567 //std::cout << (*tk)->index <<" " << (*tk) << std::endl; 00568 //float emE= (*tk)->emE(); 00569 //r->addClusterItem(ptrclu,addr,pk,emE); 00570 //ptrclu->Add(*tk); 00571 ptrclu.Add(**tk); 00572 } 00573 // print out 00574 //ptrclu->print(cout); 00575 00576 //infochunkptr->addInfo(ilcv[i].info()); 00577 jets.push_back(ptrclu); 00578 } 00579 } 00580 } 00581 00582 } // namespace d0 00583 00584 FASTJET_END_NAMESPACE 00585 00586 #endif 00587 00588