00001
00002
00003
00004
00005 #include "RecoJets/JetAlgorithms/interface/CATopJetAlgorithm.h"
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include "DataFormats/Math/interface/deltaPhi.h"
00011 #include "DataFormats/Math/interface/angle.h"
00012
00013 using namespace std;
00014 using namespace reco;
00015 using namespace edm;
00016
00017
00018
00019
00020 void CATopJetAlgorithm::run( const vector<fastjet::PseudoJet> & cell_particles,
00021 vector<fastjet::PseudoJet> & hardjetsOutput,
00022 boost::shared_ptr<fastjet::ClusterSequence> & fjClusterSeq
00023 )
00024 {
00025 if ( verbose_ ) cout << "Welcome to CATopSubJetAlgorithm::run" << endl;
00026
00027
00028 double sumEt = 0.;
00029
00030
00031
00032 for (unsigned i = 0; i < cell_particles.size(); ++i) {
00033 sumEt += cell_particles[i].perp();
00034 }
00035
00036
00037 int sumEtBinId = -1;
00038 for ( unsigned int i = 0; i < sumEtBins_.size(); ++i ) {
00039 if ( sumEt > sumEtBins_[i] ) sumEtBinId = i;
00040 }
00041 if ( verbose_ ) cout << "Using sumEt = " << sumEt << ", bin = " << sumEtBinId << endl;
00042
00043
00044 if ( sumEtBinId < 0 ) {
00045 return;
00046 }
00047
00048
00049 fastjet::PseudoJet blankJetA(0,0,0,0);
00050 blankJetA.set_user_index(-1);
00051 const fastjet::PseudoJet blankJet = blankJetA;
00052
00053
00054 double deltarcut = deltarBins_[sumEtBinId];
00055 double nCellMin = nCellBins_[sumEtBinId];
00056
00057 if ( verbose_ )cout<<"useAdjacency_ = "<<useAdjacency_<<endl;
00058 if ( verbose_ && useAdjacency_==0)cout<<"No Adjacency"<<endl;
00059 if ( verbose_ && useAdjacency_==1)cout<<"using deltar adjacency"<<endl;
00060 if ( verbose_ && useAdjacency_==2)cout<<"using modified adjacency"<<endl;
00061 if ( verbose_ && useAdjacency_==3)cout<<"using calorimeter nearest neighbor based adjacency"<<endl;
00062 if ( verbose_ && useAdjacency_==1)cout << "Using deltarcut = " << deltarcut << endl;
00063 if ( verbose_ && useAdjacency_==3)cout << "Using nCellMin = " << nCellMin << endl;
00064
00065 if ( verbose_ ) cout << "About to do jet clustering in CA" << endl;
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 if ( verbose_ ) cout << "Getting inclusive jets" << endl;
00080
00081 vector<fastjet::PseudoJet> inclusiveJets = fjClusterSeq->inclusive_jets(ptMin_);
00082
00083 if ( verbose_ ) cout << "Getting central jets" << endl;
00084
00085 vector<fastjet::PseudoJet> centralJets;
00086 for (unsigned int i = 0; i < inclusiveJets.size(); i++) {
00087
00088 if (inclusiveJets[i].perp() > ptMin_ && fabs(inclusiveJets[i].rapidity()) < centralEtaCut_) {
00089 centralJets.push_back(inclusiveJets[i]);
00090 }
00091 }
00092
00093 GreaterByEtPseudoJet compEt;
00094 sort( centralJets.begin(), centralJets.end(), compEt );
00095
00096
00097 vector<math::XYZTLorentzVector> p4_hardJets;
00098
00099
00100
00101 vector<vector<int> > indices( centralJets.size() );
00102
00103
00104 vector<fastjet::PseudoJet>::iterator jetIt = centralJets.begin(),
00105 centralJetsEnd = centralJets.end();
00106 if ( verbose_ )cout<<"Loop over jets"<<endl;
00107 int i=0;
00108 for ( ; jetIt != centralJetsEnd; ++jetIt ) {
00109 if ( verbose_ )cout<<"\nJet "<<i<<endl;
00110 i++;
00111 fastjet::PseudoJet localJet = *jetIt;
00112
00113
00114 p4_hardJets.push_back( math::XYZTLorentzVector(localJet.px(), localJet.py(), localJet.pz(), localJet.e() ));
00115
00116
00117 if ( verbose_ )cout<<"local jet pt = "<<localJet.perp()<<endl;
00118 if ( verbose_ )cout<<"deltap = "<<ptFracBins_[sumEtBinId]<<endl;
00119
00120 double ptHard = ptFracBins_[sumEtBinId]*localJet.perp();
00121 vector<fastjet::PseudoJet> leftoversAll;
00122
00123
00124 if ( verbose_ ) cout << "Doing decomposition 1" << endl;
00125 fastjet::PseudoJet ja, jb;
00126 vector<fastjet::PseudoJet> leftovers1;
00127 bool hardBreak1 = decomposeJet(localJet,*fjClusterSeq,cell_particles,ptHard,nCellMin,deltarcut,ja,jb,leftovers1);
00128 leftoversAll.insert(leftoversAll.end(),leftovers1.begin(),leftovers1.end());
00129
00130
00131
00132
00133 if ( verbose_ ) cout << "Doing decomposition 2. ja->jaa+jab?" << endl;
00134 fastjet::PseudoJet jaa, jab;
00135 vector<fastjet::PseudoJet> leftovers2a;
00136 bool hardBreak2a = false;
00137 if (hardBreak1) hardBreak2a = decomposeJet(ja,*fjClusterSeq,cell_particles,ptHard,nCellMin,deltarcut,jaa,jab,leftovers2a);
00138 leftoversAll.insert(leftoversAll.end(),leftovers2a.begin(),leftovers2a.end());
00139
00140 if ( verbose_ ) cout << "Doing decomposition 2. ja->jba+jbb?" << endl;
00141 fastjet::PseudoJet jba, jbb;
00142 vector<fastjet::PseudoJet> leftovers2b;
00143 bool hardBreak2b = false;
00144 if (hardBreak1) hardBreak2b = decomposeJet(jb,*fjClusterSeq,cell_particles,ptHard,nCellMin,deltarcut,jba,jbb,leftovers2b);
00145 leftoversAll.insert(leftoversAll.end(),leftovers2b.begin(),leftovers2b.end());
00146
00147
00148
00149
00150
00151
00152 if ( verbose_ ) cout << "Done with decomposition" << endl;
00153
00154 if ( verbose_ ) cout<<"hardBreak1 = "<<hardBreak1<<endl;
00155 if ( verbose_ ) cout<<"hardBreak2a = "<<hardBreak2a<<endl;
00156 if ( verbose_ ) cout<<"hardBreak2b = "<<hardBreak2b<<endl;
00157
00158 fastjet::PseudoJet hardA = blankJet, hardB = blankJet, hardC = blankJet, hardD = blankJet;
00159 if (!hardBreak1) {
00160 hardA = localJet;
00161 hardB = blankJet;
00162 hardC = blankJet;
00163 hardD = blankJet;
00164 if(verbose_)cout<<"Hardbreak failed. Save subjet1=localJet"<<endl;
00165 }
00166 if (hardBreak1 && !hardBreak2a && !hardBreak2b) {
00167 hardA = ja;
00168 hardB = jb;
00169 hardC = blankJet;
00170 hardD = blankJet;
00171 if(verbose_)cout<<"First decomposition succeeded, both second decompositions failed. Save subjet1=ja subjet2=jb"<<endl;
00172 }
00173 if (hardBreak1 && hardBreak2a && !hardBreak2b) {
00174 hardA = jaa;
00175 hardB = jab;
00176 hardC = jb;
00177 hardD = blankJet;
00178 if(verbose_)cout<<"First decomposition succeeded, ja split succesfully, jb did not split. Save subjet1=jaa subjet2=jab subjet3=jb"<<endl;
00179 }
00180 if (hardBreak1 && !hardBreak2a && hardBreak2b) {
00181 hardA = jba;
00182 hardB = jbb;
00183 hardC = ja;
00184 hardD = blankJet;
00185 if(verbose_)cout<<"First decomposition succeeded, jb split succesfully, ja did not split. Save subjet1=jba subjet2=jbb subjet3=ja"<<endl;
00186 }
00187 if (hardBreak1 && hardBreak2a && hardBreak2b) {
00188 hardA = jaa;
00189 hardB = jab;
00190 hardC = jba;
00191 hardD = jbb;
00192 if(verbose_)cout<<"First decomposition and both secondary decompositions succeeded. Save subjet1=jaa subjet2=jab subjet3=jba subjet4=jbb"<<endl;
00193 }
00194
00195
00196 fastjet::PseudoJet subjet1 = blankJet;
00197 fastjet::PseudoJet subjet2 = blankJet;
00198 fastjet::PseudoJet subjet3 = blankJet;
00199 fastjet::PseudoJet subjet4 = blankJet;
00200 subjet1 = hardA; subjet2 = hardB; subjet3 = hardC; subjet4 = hardD;
00201
00202
00203 vector<fastjet::PseudoJet> hardSubjets;
00204
00205 if ( verbose_ ) {
00206 std::cout << "HardA : user_index = " << hardA.user_index() << ", (Pt,Y,Phi,M) = ("
00207 << hardA.pt() << ", " << hardA.rapidity() << ", "
00208 << hardA.phi() << ", " << hardA.m() << ")" << std::endl;
00209
00210 std::cout << "HardB : user_index = " << hardB.user_index() << ", (Pt,Y,Phi,M) = ("
00211 << hardB.pt() << ", " << hardB.rapidity() << ", "
00212 << hardB.phi() << ", " << hardB.m() << ")" << std::endl;
00213
00214 std::cout << "HardC : user_index = " << hardC.user_index() << ", (Pt,Y,Phi,M) = ("
00215 << hardC.pt() << ", " << hardC.rapidity() << ", "
00216 << hardC.phi() << ", " << hardC.m() << ")" << std::endl;
00217
00218 std::cout << "HardD : user_index = " << hardD.user_index() << ", (Pt,Y,Phi,M) = ("
00219 << hardD.pt() << ", " << hardD.rapidity() << ", "
00220 << hardD.phi() << ", " << hardD.m() << ")" << std::endl;
00221 }
00222
00223
00224
00225
00226
00227 if ( subjet1.pt() > 0.0001 )
00228 hardSubjets.push_back(subjet1);
00229 if ( subjet2.pt() > 0.0001 )
00230 hardSubjets.push_back(subjet2);
00231 if ( subjet3.pt() > 0.0001 )
00232 hardSubjets.push_back(subjet3);
00233 if ( subjet4.pt() > 0.0001 )
00234 hardSubjets.push_back(subjet4);
00235 sort(hardSubjets.begin(), hardSubjets.end(), compEt );
00236
00237
00238 fastjet::PseudoJet candidate = join(hardSubjets);
00239
00240 candidate.reset_momentum( jetIt->px(), jetIt->py(), jetIt->pz(), jetIt->e() );
00241
00242 if ( verbose_ ) {
00243 std::cout << "Final top-jet candidate: (Pt,Y,Phi,M) = ("
00244 << candidate.pt() << ", " << candidate.rapidity() << ", "
00245 << candidate.phi() << ", " << candidate.m() << ")" << std::endl;
00246 std::vector<fastjet::PseudoJet> pieces = candidate.pieces();
00247 std::cout << "Number of pieces = " << pieces.size() << std::endl;
00248 for ( std::vector<fastjet::PseudoJet>::const_iterator ibegin = pieces.begin(), iend = pieces.end(), i = ibegin;
00249 i != iend; ++i ) {
00250 std::cout << " Piece : " << i - ibegin << ", (Pt,Y,Phi,M) = ("
00251 << i->pt() << ", " << i->rapidity() << ", "
00252 << i->phi() << ", " << i->m() << ")" << std::endl;
00253 }
00254 }
00255
00256 hardjetsOutput.push_back( candidate );
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 bool CATopJetAlgorithm::adjacentCells(const fastjet::PseudoJet & jet1, const fastjet::PseudoJet & jet2,
00270 const vector<fastjet::PseudoJet> & cell_particles,
00271 const fastjet::ClusterSequence & theClusterSequence,
00272 double nCellMin ) const {
00273
00274
00275 double eta1 = jet1.rapidity();
00276 double phi1 = jet1.phi();
00277 double eta2 = jet2.rapidity();
00278 double phi2 = jet2.phi();
00279
00280 double deta = abs(eta2 - eta1) / 0.087;
00281 double dphi = fabs( reco::deltaPhi(phi2,phi1) ) / 0.087;
00282
00283 return ( ( deta + dphi ) <= nCellMin );
00284 }
00285
00286
00287
00288
00289
00290
00291 bool CATopJetAlgorithm::decomposeJet(const fastjet::PseudoJet & theJet,
00292 const fastjet::ClusterSequence & theClusterSequence,
00293 const vector<fastjet::PseudoJet> & cell_particles,
00294 double ptHard, double nCellMin, double deltarcut,
00295 fastjet::PseudoJet & ja, fastjet::PseudoJet & jb,
00296 vector<fastjet::PseudoJet> & leftovers) const {
00297
00298 bool goodBreak;
00299 fastjet::PseudoJet j = theJet;
00300 double InputObjectPt = j.perp();
00301 if ( verbose_ )cout<<"Input Object Pt = "<<InputObjectPt<<endl;
00302 if ( verbose_ )cout<<"ptHard = "<<ptHard<<endl;
00303 leftovers.clear();
00304 if ( verbose_ )cout<<"start while loop"<<endl;
00305
00306 while (1) {
00307 goodBreak = theClusterSequence.has_parents(j,ja,jb);
00308 if (!goodBreak){
00309 if ( verbose_ )cout<<"bad break. this is one cell. can't decluster anymore."<<endl;
00310 break;
00311 }
00312
00313 if ( verbose_ )cout<<"good break. ja Pt = "<<ja.perp()<<" jb Pt = "<<jb.perp()<<endl;
00314
00316
00317
00318 double clusters_deltar=fabs(ja.eta()-jb.eta())+fabs(deltaPhi(ja.phi(),jb.phi()));
00319
00320 if ( verbose_ && useAdjacency_ ==1)cout<<"clusters_deltar = "<<clusters_deltar<<endl;
00321 if ( verbose_ && useAdjacency_ ==1)cout<<"deltar cut = "<<deltarcut<<endl;
00322
00323 if ( useAdjacency_==1 && clusters_deltar < deltarcut){
00324 if ( verbose_ )cout<<"clusters too close. consant adj. break."<<endl;
00325 break;
00326 }
00327
00328
00329 double clusters_deltaR=deltaR( ja.rapidity(), ja.phi(), jb.rapidity(), jb.phi() );
00330
00331 if ( verbose_ && useAdjacency_ ==2)cout<<"clusters_deltaR = "<<clusters_deltaR<<endl;
00332 if ( verbose_ && useAdjacency_ ==2)cout<<"0.4-0.0004*InputObjectPt = "<<0.4-0.0004*InputObjectPt<<endl;
00333
00334 if ( useAdjacency_==2 && clusters_deltaR < 0.4-0.0004*InputObjectPt)
00335 {
00336 if ( verbose_ )cout<<"clusters too close. modified adj. break."<<endl;
00337 break;
00338 }
00339
00340
00341 if ( useAdjacency_==3 && adjacentCells(ja,jb,cell_particles,theClusterSequence,nCellMin) ){
00342 if ( verbose_ )cout<<"clusters too close in the calorimeter. calorimeter adj. break."<<endl;
00343 break;
00344 }
00345
00346 if ( verbose_ )cout<<"clusters pass distance cut"<<endl;
00347
00349
00350 if ( verbose_ )cout<<"ptHard = "<<ptHard<<endl;
00351
00352 if (ja.perp() < ptHard && jb.perp() < ptHard){
00353 if ( verbose_ )cout<<"two soft clusters. dead end"<<endl;
00354 break;
00355 }
00356
00357 if (ja.perp() > ptHard && jb.perp() > ptHard){
00358 if ( verbose_ )cout<<"two hard clusters. done"<<endl;
00359 return true;
00360 }
00361
00362 else if (ja.perp() > jb.perp()) {
00363 if ( verbose_ )cout<<"ja hard jb soft. try to split hard. j = ja"<<endl;
00364 j = ja;
00365 vector<fastjet::PseudoJet> particles = theClusterSequence.constituents(jb);
00366 leftovers.insert(leftovers.end(),particles.begin(),particles.end());
00367 }
00368 else {
00369 if ( verbose_ )cout<<"ja hard jb soft. try to split hard. j = jb"<<endl;
00370 j = jb;
00371 vector<fastjet::PseudoJet> particles = theClusterSequence.constituents(ja);
00372 leftovers.insert(leftovers.end(),particles.begin(),particles.end());
00373 }
00374 }
00375
00376 if ( verbose_ )cout<<"did not decluster."<<endl;
00377
00378 ja.reset(0,0,0,0);
00379 jb.reset(0,0,0,0);
00380 leftovers.clear();
00381 return false;
00382 }