00001
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "FWCore/Utilities/interface/EDMException.h"
00006
00007
00008 #include <DataFormats/TrackReco/interface/Track.h>
00009 #include <DataFormats/METReco/interface/CaloMET.h>
00010 #include <DataFormats/Math/interface/deltaPhi.h>
00011
00012
00013 #include <math.h>
00014
00015 #include "TLorentzVector.h"
00016
00017 #include "Alignment/CommonAlignmentProducer/interface/AlignmentTwoBodyDecayTrackSelector.h"
00018
00019 using namespace std;
00020 using namespace edm;
00021
00022
00023 AlignmentTwoBodyDecayTrackSelector::AlignmentTwoBodyDecayTrackSelector(const edm::ParameterSet & cfg) :
00024 theMissingETSource("met")
00025 {
00026 LogDebug("Alignment") << "> applying two body decay Trackfilter ...";
00027 theMassrangeSwitch = cfg.getParameter<bool>( "applyMassrangeFilter" );
00028 if (theMassrangeSwitch){
00029 theMinMass = cfg.getParameter<double>( "minXMass" );
00030 theMaxMass = cfg.getParameter<double>( "maxXMass" );
00031 theDaughterMass = cfg.getParameter<double>( "daughterMass" );
00032 theCandNumber = cfg.getParameter<unsigned int>( "numberOfCandidates" );
00033 LogDebug("Alignment") << "> Massrange min,max : " << theMinMass << "," << theMaxMass
00034 << "\n> Mass of daughter Particle : " << theDaughterMass;
00035
00036 }else{
00037 theMinMass = 0;
00038 theMaxMass = 0;
00039 theDaughterMass = 0;
00040 }
00041 theChargeSwitch = cfg.getParameter<bool>( "applyChargeFilter" );
00042 if(theChargeSwitch){
00043 theCharge = cfg.getParameter<int>( "charge" );
00044 theUnsignedSwitch = cfg.getParameter<bool>( "useUnsignedCharge" );
00045 if(theUnsignedSwitch)
00046 theCharge=std::abs(theCharge);
00047 LogDebug("Alignment") << "> Desired Charge, unsigned: "<<theCharge<<" , "<<theUnsignedSwitch;
00048 }else{
00049 theCharge =0;
00050 theUnsignedSwitch = true;
00051 }
00052 theMissingETSwitch = cfg.getParameter<bool>( "applyMissingETFilter" );
00053 if(theMissingETSwitch){
00054 theMissingETSource = cfg.getParameter<InputTag>( "missingETSource" );
00055 LogDebug("Alignment") << "> missing Et Source: "<< theMissingETSource;
00056 }
00057 theAcoplanarityFilterSwitch = cfg.getParameter<bool>( "applyAcoplanarityFilter" );
00058 if(theAcoplanarityFilterSwitch){
00059 theAcoplanarDistance = cfg.getParameter<double>( "acoplanarDistance" );
00060 LogDebug("Alignment") << "> Acoplanar Distance: "<<theAcoplanarDistance;
00061 }
00062
00063 }
00064
00065
00066
00067 AlignmentTwoBodyDecayTrackSelector::~AlignmentTwoBodyDecayTrackSelector()
00068 {}
00069
00070
00072 bool AlignmentTwoBodyDecayTrackSelector::useThisFilter()
00073 {
00074 return theMassrangeSwitch || theChargeSwitch || theAcoplanarityFilterSwitch;
00075 }
00076
00077
00078
00079 AlignmentTwoBodyDecayTrackSelector::Tracks
00080 AlignmentTwoBodyDecayTrackSelector::select(const Tracks& tracks, const edm::Event& iEvent)
00081 {
00082 Tracks result = tracks;
00083
00084 if (theMassrangeSwitch) {
00085 if (theMissingETSwitch)
00086 result = checkMETMass(result,iEvent);
00087 else
00088 result = checkMass(result);
00089 }
00090
00091 LogDebug("Alignment") << "> TwoBodyDecay tracks all,kept: " << tracks.size() << "," << result.size();
00092 return result;
00093 }
00094
00095 template<class T>
00096 struct higherTwoBodyDecayPt : public std::binary_function<T,T,bool>
00097 {
00098 bool operator()( const T& a, const T& b )
00099 {
00100 return a.first > b.first ;
00101 }
00102 };
00103
00105 AlignmentTwoBodyDecayTrackSelector::Tracks
00106 AlignmentTwoBodyDecayTrackSelector::checkMass(const Tracks& cands) const
00107 {
00108 Tracks result;
00109
00110 LogDebug("Alignment") <<"> cands size : "<< cands.size();
00111
00112 if (cands.size()<2) return result;
00113
00114 TLorentzVector track0;
00115 TLorentzVector track1;
00116 TLorentzVector mother;
00117 typedef pair<const reco::Track*,const reco::Track*> constTrackPair;
00118 typedef pair<double,constTrackPair> candCollectionItem;
00119 vector<candCollectionItem> candCollection;
00120
00121 for (unsigned int iCand = 0; iCand < cands.size(); iCand++) {
00122
00123 track0.SetXYZT(cands.at(iCand)->px(),
00124 cands.at(iCand)->py(),
00125 cands.at(iCand)->pz(),
00126 sqrt( cands.at(iCand)->p()*cands.at(iCand)->p() + theDaughterMass*theDaughterMass ));
00127
00128 for (unsigned int jCand = iCand+1; jCand < cands.size(); jCand++) {
00129
00130 track1.SetXYZT(cands.at(jCand)->px(),
00131 cands.at(jCand)->py(),
00132 cands.at(jCand)->pz(),
00133 sqrt( cands.at(jCand)->p()*cands.at(jCand)->p() + theDaughterMass*theDaughterMass ));
00134
00135 mother = track0 + track1;
00136
00137 const reco::Track *trk1 = cands.at(iCand);
00138 const reco::Track *trk2 = cands.at(jCand);
00139
00140 bool correctCharge = true;
00141 if (theChargeSwitch) correctCharge = this->checkCharge(trk1, trk2);
00142
00143 bool acoplanarTracks = true;
00144 if (theAcoplanarityFilterSwitch) acoplanarTracks = this->checkAcoplanarity(trk1, trk2);
00145
00146 if (mother.M() > theMinMass &&
00147 mother.M() < theMaxMass &&
00148 correctCharge &&
00149 acoplanarTracks) {
00150 candCollection.push_back(candCollectionItem(mother.Pt(),
00151 constTrackPair(trk1, trk2)));
00152 }
00153 }
00154 }
00155
00156 if (candCollection.size()==0) return result;
00157 if (candCollection.size() > theCandNumber) return result;
00158
00159 sort(candCollection.begin(), candCollection.end(),
00160 higherTwoBodyDecayPt<candCollectionItem>());
00161
00162 std::map<const reco::Track*,unsigned int> uniqueTrackIndex;
00163 std::map<const reco::Track*,unsigned int>::iterator it;
00164 for (unsigned int i=0;
00165 i<candCollection.size();
00166 i++) {
00167 constTrackPair & trackPair = candCollection[i].second;
00168
00169 it = uniqueTrackIndex.find(trackPair.first);
00170 if (it==uniqueTrackIndex.end()) {
00171 result.push_back(trackPair.first);
00172 uniqueTrackIndex[trackPair.first] = i;
00173 }
00174
00175 it = uniqueTrackIndex.find(trackPair.second);
00176 if (it==uniqueTrackIndex.end()) {
00177 result.push_back(trackPair.second);
00178 uniqueTrackIndex[trackPair.second] = i;
00179 }
00180 }
00181
00182 return result;
00183 }
00184
00186 AlignmentTwoBodyDecayTrackSelector::Tracks
00187 AlignmentTwoBodyDecayTrackSelector::checkMETMass(const Tracks& cands,const edm::Event& iEvent) const
00188 {
00189 Tracks result;
00190
00191 LogDebug("Alignment") <<"> cands size : "<< cands.size();
00192
00193 if (cands.size()==0) return result;
00194
00195 TLorentzVector track;
00196 TLorentzVector met4;
00197 TLorentzVector mother;
00198
00199 Handle<reco::CaloMETCollection> missingET;
00200 iEvent.getByLabel(theMissingETSource ,missingET);
00201 if (!missingET.isValid()) {
00202 LogError("Alignment")<< "@SUB=AlignmentTwoBodyDecayTrackSelector::checkMETMass"
00203 << "> could not optain missingET Collection!";
00204 return result;
00205 }
00206
00207 typedef pair<double,const reco::Track*> candCollectionItem;
00208 vector<candCollectionItem> candCollection;
00209
00210 for (reco::CaloMETCollection::const_iterator itMET = missingET->begin();
00211 itMET != missingET->end();
00212 ++itMET) {
00213
00214 met4.SetXYZT((*itMET).px(),
00215 (*itMET).py(),
00216 (*itMET).pz(),
00217 (*itMET).p());
00218
00219 for (unsigned int iCand = 0; iCand < cands.size(); iCand++) {
00220
00221 track.SetXYZT(cands.at(iCand)->px(),
00222 cands.at(iCand)->py(),
00223 cands.at(iCand)->pz(),
00224 sqrt( cands.at(iCand)->p()*cands.at(iCand)->p() + theDaughterMass*theDaughterMass ));
00225
00226 mother = track + met4;
00227
00228 const reco::Track *trk = cands.at(iCand);
00229 const reco::CaloMET *met = &(*itMET);
00230
00231 bool correctCharge = true;
00232 if (theChargeSwitch) correctCharge = this->checkCharge(trk);
00233
00234 bool acoplanarTracks = true;
00235 if (theAcoplanarityFilterSwitch) acoplanarTracks = this->checkMETAcoplanarity(trk, met);
00236
00237 if (mother.M() > theMinMass &&
00238 mother.M() < theMaxMass &&
00239 correctCharge &&
00240 acoplanarTracks) {
00241 candCollection.push_back(candCollectionItem(mother.Pt(), trk));
00242 }
00243 }
00244 }
00245
00246 if (candCollection.size()==0) return result;
00247 if (candCollection.size() > theCandNumber) return result;
00248
00249 sort(candCollection.begin(), candCollection.end(),
00250 higherTwoBodyDecayPt<candCollectionItem>());
00251
00252 std::map<const reco::Track*,unsigned int> uniqueTrackIndex;
00253 std::map<const reco::Track*,unsigned int>::iterator it;
00254 for (unsigned int i=0;
00255 i<candCollection.size();
00256 i++) {
00257 it = uniqueTrackIndex.find(candCollection[i].second);
00258 if (it==uniqueTrackIndex.end()) {
00259 result.push_back(candCollection[i].second);
00260 uniqueTrackIndex[candCollection[i].second] = i;
00261 }
00262 }
00263
00264 return result;
00265 }
00266
00268 bool
00269 AlignmentTwoBodyDecayTrackSelector::checkCharge(const reco::Track* trk1, const reco::Track* trk2)const
00270 {
00271 int sumCharge = trk1->charge();
00272 if (trk2) sumCharge += trk2->charge();
00273 if (theUnsignedSwitch) sumCharge = std::abs(sumCharge);
00274 if (sumCharge == theCharge) return true;
00275 return false;
00276 }
00277
00279 bool
00280 AlignmentTwoBodyDecayTrackSelector::checkAcoplanarity(const reco::Track* trk1, const reco::Track* trk2)const
00281 {
00282 if (fabs(deltaPhi(trk1->phi(),trk2->phi()-M_PI)) < theAcoplanarDistance) return true;
00283 return false;
00284 }
00285
00287 bool
00288 AlignmentTwoBodyDecayTrackSelector::checkMETAcoplanarity(const reco::Track* trk1, const reco::CaloMET* met)const
00289 {
00290 if (fabs(deltaPhi(trk1->phi(),met->phi()-M_PI)) < theAcoplanarDistance) return true;
00291 return false;
00292 }
00293
00294
00295
00297 void AlignmentTwoBodyDecayTrackSelector::printTracks(const Tracks& col) const
00298 {
00299 int count = 0;
00300 LogDebug("Alignment") << ">......................................";
00301 for(Tracks::const_iterator it = col.begin();it < col.end();++it,++count){
00302 LogDebug("Alignment")
00303 <<"> Track No. "<< count <<": p = ("<<(*it)->px()<<","<<(*it)->py()<<","<<(*it)->pz()<<")\n"
00304 <<"> pT = "<<(*it)->pt()<<" eta = "<<(*it)->eta()<<" charge = "<<(*it)->charge();
00305 }
00306 LogDebug("Alignment") << ">......................................";
00307 }
00308
00309