44 using namespace JetReco;
53 std::vector<InputItem> towersWithinCone(
const InputCollection& fInput,
double coneEta,
double conePhi,
double coneRadius){
54 std::vector<InputItem>
result;
55 double r2 = coneRadius*coneRadius;
56 InputCollection::const_iterator towerIter = fInput.begin();
57 InputCollection::const_iterator towerIterEnd = fInput.end();
58 for (;towerIter != towerIterEnd; ++towerIter) {
60 double dR2 =
deltaR2 (coneEta, conePhi, caloTowerPointer->
eta(), caloTowerPointer->
phi());
62 result.push_back(caloTowerPointer);
69 std::vector<InputItem> etOrderedCaloTowers(
const InputCollection& fInput,
double etThreshold) {
70 std::vector<InputItem>
result;
71 InputCollection::const_iterator towerIter = fInput.begin();
72 InputCollection::const_iterator towerIterEnd = fInput.end();
73 for (;towerIter != towerIterEnd; ++towerIter) {
75 if(caloTowerPointer->
et() > etThreshold){
76 result.push_back(caloTowerPointer);
80 sort (result.begin(), result.end(), compCandidate);
95 std::cerr <<
"CMSMidpointAlgorithm::run-> ERROR: no output collection" << std::endl;
97 if(theDebugLevel>=1)
cout <<
"[CMSMidpointAlgorithm] Num of input constituents = " << fInput.size() << endl;
98 if(theDebugLevel>=2) {
100 for (; index < fInput.size (); index++) {
101 cout << index <<
" consituent p/eta/phi: "
102 << fInput[
index]->p() <<
'/'
103 << fInput[
index]->eta() <<
'/'
104 << fInput[
index]->phi() << std::endl;
110 findStableConesFromSeeds(fInput, &protoJets);
111 if(theDebugLevel>=1)
cout <<
"[CMSMidpointAlgorithm] Num proto-jets from Seeds = " << protoJets.size() << endl;
114 if(protoJets.size()>0)findStableConesFromMidPoints(fInput, &protoJets);
115 if(theDebugLevel>=1)
cout <<
"[CMSMidpointAlgorithm] Num proto-jets from Seeds and Midpoints = " << protoJets.size() << endl;
118 if(protoJets.size()>0)splitAndMerge(fInput, &protoJets, fOutput);
119 if(theDebugLevel>=1)
cout <<
"[CMSMidpointAlgorithm] Num final jets = " << fOutput->size() << endl;
134 bool reduceConeSize =
true;
137 vector<InputItem> seedTowers = etOrderedCaloTowers(fInput, theSeedThreshold);
140 for(vector<InputItem>::const_iterator
i = seedTowers.begin();
i != seedTowers.end(); ++
i) {
141 double seedEta = (*i)->eta ();
142 double seedPhi = (*i)->phi ();
146 if(theDebugLevel>=2)
cout << endl <<
"[CMSMidpointAlgorithm] seed " <<
i-seedTowers.begin() <<
": eta=" << seedEta <<
", phi=" << seedPhi << endl;
147 iterateCone(fInput, seedEta, seedPhi, 0, reduceConeSize, fOutput);
156 double startRapidity,
169 double iterationtheConeRadius = theConeRadius;
170 if(reduceConeSize)iterationtheConeRadius *=
sqrt(theConeAreaFraction);
171 while(++nIterations <= theMaxIterations + 1 && keepJet){
174 if(nIterations == theMaxIterations + 1)iterationtheConeRadius = theConeRadius;
177 vector<InputItem> towersInSeedCluster
178 = towersWithinCone(fInput, startRapidity, startPhi, iterationtheConeRadius);
179 if(theDebugLevel>=2)
cout <<
"[CMSMidpointAlgorithm] iter=" << nIterations <<
", towers=" <<towersInSeedCluster.size();
181 if(towersInSeedCluster.size()<1) {
183 if(theDebugLevel>=2)
cout << endl;
186 trialCone->
putTowers(towersInSeedCluster);
187 double endRapidity = trialCone->
y();
188 double endPhi = trialCone->
phi();
189 double endPt = trialCone->
pt();
190 double endE = trialCone->
e();
191 if(theDebugLevel>=2)
cout <<
", y=" << endRapidity <<
", phi=" << endPhi <<
", PT=" << endPt <<
", constituents=" << trialCone->
getTowerList().size () << endl;
192 if(nIterations <= theMaxIterations){
194 if(
std::abs(endRapidity-startRapidity)<.001 &&
197 nIterations = theMaxIterations;
198 if(!reduceConeSize) ++nIterations;
202 startRapidity = endRapidity;
207 if(nIterations==theMaxIterations+1) {
208 for(vector<InputItem>::const_iterator
i = towersInSeedCluster.begin();
i != towersInSeedCluster.end(); ++
i) {
210 if(theDebugLevel>=2)
cout <<
"[CMSMidpointAlgorithm] Tower " <<
211 i-towersInSeedCluster.begin() <<
": eta=" << t->
eta() <<
212 ", phi=" << t->
phi() <<
", ET=" << t->
et() << endl;
219 bool identical =
false;
221 for (
unsigned icone = 0; icone < stableCones->size(); icone++) {
222 if (trialCone->
p4() == (*stableCones) [icone]->p4()) identical =
true;
225 stableCones->push_back(trialCone);
227 if(theDebugLevel>=2)
cout <<
"[CMSMidpointAlgorithm] Unique Proto-Jet Saved" << endl;
240 vector< vector<bool> > distanceOK;
241 distanceOK.resize(stableCones->size() - 1);
242 for(
unsigned int nCluster1 = 1; nCluster1 < stableCones->size(); ++nCluster1){
243 distanceOK[nCluster1 - 1].resize(nCluster1);
244 const ProtoJet* cluster1 = (*stableCones)[nCluster1];
245 for(
unsigned int nCluster2 = 0; nCluster2 < nCluster1; ++nCluster2){
246 const ProtoJet* cluster2 = (*stableCones)[nCluster2];
247 double dR2 =
deltaR2 (cluster1->
y(), cluster1->
phi(), cluster2->
y(), cluster2->
phi());
248 distanceOK[nCluster1 - 1][nCluster2] = dR2 < 4*theConeRadius*theConeRadius;
253 vector< vector<int> > pairs(0);
254 vector<int> testPair(0);
255 int maxClustersInPair = theMaxPairSize;
256 if(!maxClustersInPair)maxClustersInPair = stableCones->size();
257 addClustersToPairs(fInput, testPair,pairs,distanceOK,maxClustersInPair);
260 bool reduceConeSize =
false;
261 for(vector<vector<int> >::const_iterator iPair = pairs.begin(); iPair != pairs.end(); ++iPair) {
262 const vector<int> & Pair = *iPair;
265 for(vector<int>::const_iterator iPairMember = Pair.begin(); iPairMember != Pair.end(); ++iPairMember) {
266 midPoint += (*stableCones)[*iPairMember]->p4();
268 if(theDebugLevel>=2)
cout << endl <<
"[CMSMidpointAlgorithm] midpoint " << iPair-pairs.begin() <<
": y = " << midPoint.Rapidity() <<
", phi=" << midPoint.Phi() <<
269 ", size=" << Pair.size() << endl;
270 iterateCone(fInput, midPoint.Rapidity(),midPoint.Phi(),midPoint.e(),reduceConeSize,stableCones);
273 sort (stableCones->begin(), stableCones->end(), compJets);
279 vector<int>& testPair, vector< vector<int> >& pairs,
280 vector< vector<bool> >& distanceOK,
int maxClustersInPair)
285 int nextClusterStart = 0;
287 nextClusterStart = testPair.back() + 1;
288 for(
unsigned int nextCluster = nextClusterStart; nextCluster <= distanceOK.size(); ++nextCluster){
290 bool addCluster =
true;
291 for(
unsigned int iCluster = 0; iCluster < testPair.size() && addCluster; ++iCluster)
292 if(!distanceOK[nextCluster - 1][testPair[iCluster]])
296 testPair.push_back(nextCluster);
298 if(testPair.size() > 1)
299 pairs.push_back(testPair);
301 if(testPair.size() < unsigned(maxClustersInPair))
302 addClustersToPairs(fInput, testPair,pairs,distanceOK,maxClustersInPair);
318 if(theDebugLevel>=2){
320 int numProtojets = stableCones->size();
321 for(
int i = 0;
i < numProtojets ; ++
i){
322 const ProtoJet* icone = (*stableCones)[
i];
324 cout << endl <<
"[CMSMidpointAlgorithm] ProtoJet " <<
i <<
": PT=" << (*stableCones)[
i]->pt()
325 <<
", y="<< icone->
y()
326 <<
", phi="<< icone->
phi()
327 <<
", ntow="<< numTowers << endl;
329 for(
int j = 0;
j < numTowers; ++
j){
330 cout <<
"[CMSMidpointAlgorithm] Tower " <<
j <<
": ET=" << protojetTowers[
j]->et()
331 <<
", eta="<< protojetTowers[
j]->eta()
332 <<
", phi="<< protojetTowers[
j]->phi() << endl;
338 bool mergingNotFinished =
true;
339 while(mergingNotFinished){
343 sort(stableCones->begin(),stableCones->end(),compJets);
347 stableCones->erase (
find (stableCones->begin(), stableCones->end(), (
ProtoJet*)0), stableCones->end());
351 InternalCollection::iterator stableConeIter1 = stableCones->begin();
353 if(stableConeIter1 == stableCones->end()) {
354 mergingNotFinished =
false;
357 ProtoJet* stableCone1 = *stableConeIter1;
359 std::cerr <<
"CMSMidpointAlgorithm::splitAndMerge-> Error: stableCone1 should never be 0" << std::endl;
362 bool coneNotModified =
true;
365 InternalCollection::iterator stableConeIter2 = stableConeIter1;
368 while(coneNotModified && stableConeIter2 != stableCones->end()){
369 ProtoJet* stableCone2 = *stableConeIter2;
371 std::cerr <<
"CMSMidpointAlgorithm::splitAndMerge-> Error: stableCone2 should never be 0" << std::endl;
377 vector<InputItem> overlapTowers;
382 for(ProtoJet::Constituents::const_iterator towerIter1 = stableCone1->
getTowerList().begin();
387 bool isInCone2 =
false;
392 for(ProtoJet::Constituents::const_iterator towerIter2 = stableCone2->
getTowerList().begin();
400 if(sameTower(*towerIter1, *towerIter2)) {
407 overlapTowers.push_back(*towerIter1);
417 coneNotModified =
false;
420 if(overlap.
pt() >= theOverlapThreshold*stableCone2->
pt()){
427 for(ProtoJet::Constituents::const_iterator towerIter2 = stableCone2->
getTowerList().begin();
430 bool isInOverlap =
false;
433 for(vector<InputItem>::iterator overlapTowerIter = overlapTowers.begin();
434 overlapTowerIter != overlapTowers.end();
438 if(sameTower(*overlapTowerIter, *towerIter2)) isInOverlap =
true;
441 if(!isInOverlap)stableCone1Towers.push_back(*towerIter2);
444 if(theDebugLevel>=2)
cout << endl <<
"[CMSMidpointAlgorithm] Merging: 1st Proto-jet grows: "
445 " y=" << stableCone1->
y() <<
446 ", phi=" << stableCone1->
phi() <<
447 " increases from " << stableCone1->
getTowerList().size() <<
448 " to " << stableCone1Towers.size() <<
" towers." << endl;
451 stableCone1->
putTowers(stableCone1Towers);
453 if(theDebugLevel>=2)
cout <<
"[CMSMidpointAlgorithm] Merging: 1st protojet now at y=" << stableCone1->
y() <<
454 ", phi=" << stableCone1->
phi() << endl;
456 if(theDebugLevel>=2)
cout <<
"[CMSMidpointAlgorithm] Merging: 2nd Proto-jet removed:"
457 " y=" << stableCone2->
y() <<
458 ", phi=" << stableCone2->
phi() << endl;
461 delete *stableConeIter2;
462 *stableConeIter2 = 0;
469 vector<InputItem> removeFromCone1,removeFromCone2;
473 for(vector<InputItem>::iterator towerIter = overlapTowers.begin();
474 towerIter != overlapTowers.end();
476 double dR2Jet1 =
deltaR2 ((*towerIter)->p4().Rapidity(), (*towerIter)->phi(),
477 stableCone1->
y(), stableCone1->
phi());
479 double dR2Jet2 =
deltaR2 ((*towerIter)->p4().Rapidity(), (*towerIter)->phi(),
480 stableCone2->
y(), stableCone2->
phi());
482 if(dR2Jet1 < dR2Jet2){
484 removeFromCone2.push_back(*towerIter);
488 removeFromCone1.push_back(*towerIter);
497 for(vector<InputItem>::iterator towerIter = removeFromCone1.begin();
498 towerIter != removeFromCone1.end();
501 for(vector<InputItem>::iterator towerIter1 = towerList1.begin(); towerIter1 != towerList1.end(); ++towerIter1) {
503 if(sameTower(*towerIter, *towerIter1)) {
505 towerList1.erase(towerIter1);
511 if(theDebugLevel>=2)
cout << endl <<
"[CMSMidpointAlgorithm] Splitting: 1st Proto-jet shrinks: y=" <<
513 ", phi=" << stableCone1->
phi() <<
514 " decreases from" << stableCone1->
getTowerList().size() <<
515 " to " << towerList1.size() <<
" towers." << endl;
523 for(vector<InputItem>::iterator towerIter = removeFromCone2.begin();
524 towerIter != removeFromCone2.end();
527 for(vector<InputItem>::iterator towerIter2 = towerList2.begin(); towerIter2 != towerList2.end(); ++towerIter2){
529 if(sameTower(*towerIter, *towerIter2)) {
531 towerList2.erase(towerIter2);
537 if(theDebugLevel>=2)
cout <<
"[CMSMidpointAlgorithm] Splitting: 2nd Proto-jet shrinks: y=" <<
539 ", phi=" << stableCone2->
phi() <<
540 " decreases from" << stableCone2->
getTowerList().size() <<
541 " to " << towerList2.size() <<
" towers." << endl;
548 if(theDebugLevel>=2)
cout << endl <<
549 "[CMSMidpointAlgorithm] no overlap between 1st protojet at y=" << stableCone1->
y() <<
550 ", phi=" << stableCone1->
phi() <<
551 " and 2nd protojet at y=" << stableCone2->
y() <<
552 ", phi=" << stableCone2->
phi() <<endl;
559 if(theDebugLevel>=2)
cout <<
560 "[CMSMidpointAlgorithm] Saving: Proto-jet at y=" << stableCone1->
y() <<
561 ", phi=" << stableCone1->
phi() <<
" has no overlap" << endl;
564 delete *stableConeIter1;
565 *stableConeIter1 = 0;
571 sort(fFinalJets->begin(),fFinalJets->end(),compJets);
std::vector< ProtoJet > OutputCollection
JetReco::InputCollection Constituents
void splitAndMerge(const JetReco::InputCollection &fInput, InternalCollection *fProtoJets, JetReco::OutputCollection *fFinalJets)
virtual double et() const =0
transverse energy
void iterateCone(const JetReco::InputCollection &fInput, double startRapidity, double startPhi, double startPt, bool reduceConeSize, InternalCollection *fOutput)
std::vector< InputItem > InputCollection
const Constituents & getTowerList()
Transient Jet class used by the reconstruction algorithms.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
bool overlap(const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
double deltaR2(const Vector1 &v1, const Vector2 &v2)
const LorentzVector & p4() const
void findStableConesFromSeeds(const JetReco::InputCollection &fInput, InternalCollection *fOutput)
void addClustersToPairs(const JetReco::InputCollection &fInput, std::vector< int > &testPair, std::vector< std::vector< int > > &pairs, std::vector< std::vector< bool > > &distanceOK, int maxClustersInPair)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
void run(const JetReco::InputCollection &fInput, JetReco::OutputCollection *fOutput)
void findStableConesFromMidPoints(const JetReco::InputCollection &fInput, InternalCollection *fOutput)
void putTowers(const Constituents &towers)
std::vector< ProtoJet * > InternalCollection
virtual double phi() const =0
momentum azimuthal angle
virtual double eta() const =0
momentum pseudorapidity