/////////////////////////////////////////////////////////// // // File: conejet.cpp // // Purpose: make simple cone jets, similar to pxcone jet algorithm // // Created: Shaohua Fu // // History: // //////////////////////////////////////////////////////////// #include "mctest/conejet.hpp" #include "kinem_util/AnglesUtil.hpp" #include #include using namespace std; const float EPSILON = 0.001; const int MAXITER = 30; // Constructor ConeJet::ConeJet(list >& intracks, float coneR, float jetPTmin, float overlaplim, bool debug): _intracks(intracks), _coneR(coneR), _jetPTmin(jetPTmin), _overlaplim(overlaplim), _debug(debug) { _ptracks.clear(); _pjets.clear(); ////// _debug = debug; MakeConeJets(); } void ConeJet::MakeConeJets(){ if (_debug) { cout<<"-------------------- Make Cone Jets --------------------"< >::iterator it = _intracks.begin(); it != _intracks.end(); ++it) { for (vector::iterator itt = (*it).begin(); itt != (*it).end(); ++itt) cout< jets_pre; for (vector::iterator itrk = _ptracks.begin(); itrk != _ptracks.end(); ++itrk) { vector axis; axis.push_back((*itrk).eta); axis.push_back((*itrk).phi); Particle tjet; if (JetFromSeed(axis, tjet)) { if (IsNewJet(tjet, jets_pre)) { // if the jet is a new one, add it to our array jets_pre.push_back(tjet); } } } if (_debug) { cout<<" FIRST LIST OF JETS: "< jets_post = jets_pre; for (int i=0; i_coneR && dist<_coneR*2) { vector axis; axis.push_back((eta1+eta2)*0.5); axis.push_back((phi1+phi2)*0.5); Particle tjet; if (JetFromSeed(axis, tjet)) { if (IsNewJet(tjet, jets_post)) { jets_post.push_back(tjet); } } } } // j } // i if (_debug) { cout<<" SECOND LIST OF JETS: "< >& outjets){ _outjets.clear(); for (vector::iterator it = _pjets.begin(); it != _pjets.end(); ++it) { vector jet; jet.push_back((*it).Px); jet.push_back((*it).Py); jet.push_back((*it).Pz); jet.push_back((*it).E); jet.push_back((*it).eta); jet.push_back((*it).phi); jet.push_back((*it).PT); _outjets.push_back(jet); } outjets = _outjets; return; } // (Px,Py,Pz,E) -> (Px,Py,Pz,E,eta,phi,PT) void ConeJet::InitSeeds(){ list >::iterator itrk; for (itrk = _intracks.begin(); itrk != _intracks.end(); ++itrk) { if ((*itrk).size() != 4) { cout<<"WARNING: this input track 4-momenta wrong -- removed"<& partlist, double threshold){ if (partlist.size() == 0) return; vector oldlist = partlist; vector newlist; for (vector::iterator it = oldlist.begin(); it != oldlist.end(); ++it) { if ((*it).PT < threshold) continue; newlist.push_back(*it); } sort(newlist.begin(), newlist.end(), compareParticlePT()); partlist = newlist; // added check for duplicates if (partlist.size() == 0) return; oldlist = newlist; newlist.clear(); newlist.push_back(oldlist[0]); for (int i=1; i0 && oldlist[i].itrack==previous.itrack) {cout<<"Duplicate: same non-zero itrack!"<& axis, Particle& pjet){ // use seed as a trial axis, look for a stable jet // check stable jet against those already found and add to list // will try up to MAXITER iterations to get a stable set of particles in the cone for (int iter = 0; iter < MAXITER; ++iter) { Particle tmpjet; TryJet(axis, tmpjet); // return immediately if there were no particles in the cone if (tmpjet.itrack.size()==0) return false; if (iter==0) {pjet = tmpjet; continue;} if (tmpjet.itrack == pjet.itrack) { // we have a stable jet return true; } pjet = tmpjet; } cout<<"WARNING: this jet is still unstable after "<& axis, Particle& tmpjet){ for (int i = 0; i < _ptracks.size(); ++i) { double dR = kinem::delta_R(axis[0], axis[1], _ptracks[i].eta, _ptracks[i].phi); // check if particle is inside cone if (dR < _coneR) { tmpjet.Px += _ptracks[i].Px; tmpjet.Py += _ptracks[i].Py; tmpjet.Pz += _ptracks[i].Pz; tmpjet.E += _ptracks[i].E; tmpjet.itrack.push_back(i); } } // if there are particles in the cone, calculate new jet axis if (tmpjet.itrack.size() > 0) { tmpjet.eta = kinem::eta(tmpjet.Px, tmpjet.Py, tmpjet.Pz); tmpjet.phi = kinem::phi(tmpjet.Px, tmpjet.Py); tmpjet.PT = sqrt(tmpjet.Px*tmpjet.Px + tmpjet.Py*tmpjet.Py); } return; } bool ConeJet::IsNewJet(Particle& tmpjet, vector& pjets){ bool isnew = true; for (vector::iterator it = pjets.begin(); it != pjets.end() && isnew; ++it) { if (tmpjet.itrack == (*it).itrack) isnew = false; } return isnew; } // Look for particles assigned to more than 1 jet, and reassigns them // If more than a fraction _overlaplim of a jet's PT is contained in // higher energy jets, that jet is neglected // Particles assigned to the jet closest in angle void ConeJet::OverlappedJets(vector& pjets){ if (pjets.size()<1) return; // look for jets with large overlaps with higher energy jets // from now on only reply on jet.itrack info for (int i=1; i itrkover; for (vector::iterator it=pjets[i].itrack.begin(); it!=pjets[i].itrack.end(); ++it) for (vector::iterator jt=pjets[j].itrack.begin(); jt!=pjets[j].itrack.end(); ++jt) if ((*it)==(*jt)) itrkover.push_back(*it); for (vector::iterator it=itrkover.begin(); it!=itrkover.end(); ++it) ptover += _ptracks[(*it)].PT; } // is the fraction of energy shared larger than _overlaplim? if (ptover > _overlaplim*pjets[i].PT) { // de-assign all particles from jet "i" ! pjets[i].itrack.clear(); } } for (vector::iterator it=pjets.begin(); it!=pjets.end(); ++it) RefreshJet(*it); _isotrackid.clear(); // any particles in more than 1 jet are assigned to the CLOSEST jet in angle for (int i=0; i<_ptracks.size(); ++i) { double dRmin = 100; int jmin = -1; vector jids; for (int j=0; j::iterator jt=jids.begin(); jt!=jids.end(); ++jt) { if ((*jt) != jmin) { pjets[*jt].itrack.erase(find(pjets[*jt].itrack.begin(), pjets[*jt].itrack.end(), i)); } } } for (vector::iterator it=pjets.begin(); it!=pjets.end(); ++it) RefreshJet(*it); if (_debug) { cout<<" ==== ISOLATED TRACKS NOT IN ANY JETS : "<<_isotrackid.size()<<" ===="<::iterator iso=_isotrackid.begin(); iso!=_isotrackid.end(); ++iso) cout<first<<" : "<second<<" "<<_ptracks[iso->first].PT<::iterator it=jet.itrack.begin(); it!=jet.itrack.end(); ++it) { jet.Px += _ptracks[*it].Px; jet.Py += _ptracks[*it].Py; jet.Pz += _ptracks[*it].Pz; jet.E += _ptracks[*it].E; } jet.eta = kinem::eta(jet.Px, jet.Py, jet.Pz); jet.phi = kinem::phi(jet.Px, jet.Py); jet.PT = sqrt(jet.Px*jet.Px + jet.Py*jet.Py); return; } void ConeJet::PrintParts(vector& parts){ cout<<"**** size = "<::iterator it = parts.begin(); it != parts.end(); ++it) { cout<<"("< 0) { cout<<" itrack "<<(*it).itrack.size()<<" : "; for (vector::iterator j = (*it).itrack.begin(); j != (*it).itrack.end(); ++j) cout<<(*j)<<" "; cout<