CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/CommonAlignmentProducer/src/AlignmentTwoBoyDecayTrackSelector.cc

Go to the documentation of this file.
00001 //Framework
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "FWCore/Utilities/interface/EDMException.h"
00006 
00007 //DataFormats
00008 #include <DataFormats/TrackReco/interface/Track.h>
00009 #include <DataFormats/METReco/interface/CaloMET.h>
00010 #include <DataFormats/Math/interface/deltaPhi.h>
00011 
00012 //STL
00013 #include <math.h>
00014 //ROOT
00015 #include "TLorentzVector.h"
00016 
00017 #include "Alignment/CommonAlignmentProducer/interface/AlignmentTwoBodyDecayTrackSelector.h"
00018 //TODO put those namespaces into functions?
00019 using namespace std;
00020 using namespace edm; 
00021 // constructor ----------------------------------------------------------------
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" );//Number of candidates to keep
00033     secThrBool = cfg.getParameter<bool> ( "applySecThreshold" );
00034     thesecThr = cfg.getParameter<double>( "secondThreshold" );
00035     LogDebug("Alignment") << ">  Massrange min,max         :   " << theMinMass   << "," << theMaxMass 
00036                          << "\n>  Mass of daughter Particle :   " << theDaughterMass;
00037 
00038   }else{
00039     theMinMass = 0;
00040     theMaxMass = 0;
00041     theDaughterMass = 0;
00042   }
00043   theChargeSwitch = cfg.getParameter<bool>( "applyChargeFilter" );
00044   if(theChargeSwitch){
00045     theCharge = cfg.getParameter<int>( "charge" );
00046     theUnsignedSwitch = cfg.getParameter<bool>( "useUnsignedCharge" );
00047     if(theUnsignedSwitch) 
00048       theCharge=std::abs(theCharge);
00049     LogDebug("Alignment") << ">  Desired Charge, unsigned: "<<theCharge<<" , "<<theUnsignedSwitch;
00050   }else{
00051     theCharge =0;
00052     theUnsignedSwitch = true;
00053   }
00054   theMissingETSwitch = cfg.getParameter<bool>( "applyMissingETFilter" );
00055   if(theMissingETSwitch){
00056     theMissingETSource = cfg.getParameter<InputTag>( "missingETSource" );
00057     LogDebug("Alignment") << ">  missing Et Source: "<< theMissingETSource;
00058   }
00059   theAcoplanarityFilterSwitch = cfg.getParameter<bool>( "applyAcoplanarityFilter" );
00060   if(theAcoplanarityFilterSwitch){
00061     theAcoplanarDistance = cfg.getParameter<double>( "acoplanarDistance" );
00062     LogDebug("Alignment") << ">  Acoplanar Distance: "<<theAcoplanarDistance;
00063   }
00064   
00065 }
00066 
00067 // destructor -----------------------------------------------------------------
00068 
00069 AlignmentTwoBodyDecayTrackSelector::~AlignmentTwoBodyDecayTrackSelector()
00070 {}
00071 
00072 
00074 bool AlignmentTwoBodyDecayTrackSelector::useThisFilter()
00075 {
00076   return theMassrangeSwitch || theChargeSwitch || theAcoplanarityFilterSwitch;
00077 }
00078 
00079 // do selection ---------------------------------------------------------------
00080 
00081 AlignmentTwoBodyDecayTrackSelector::Tracks 
00082 AlignmentTwoBodyDecayTrackSelector::select(const Tracks& tracks, const edm::Event& iEvent, const edm::EventSetup& iSetup)
00083 {
00084   Tracks result = tracks;
00085 
00086   if (theMassrangeSwitch) {  
00087     if (theMissingETSwitch)
00088       result = checkMETMass(result,iEvent); 
00089     else
00090       result = checkMass(result); 
00091   }
00092 
00093   LogDebug("Alignment") << ">  TwoBodyDecay tracks all,kept: " << tracks.size() << "," << result.size();
00094   return result;
00095 }
00096 
00097 template<class T>
00098 struct higherTwoBodyDecayPt : public std::binary_function<T,T,bool>
00099 {
00100   bool operator()( const T& a, const T& b ) 
00101   { 
00102     return a.first > b.first ; 
00103   }
00104 };
00105 
00107 AlignmentTwoBodyDecayTrackSelector::Tracks 
00108 AlignmentTwoBodyDecayTrackSelector::checkMass(const Tracks& cands) const
00109 {
00110   Tracks result;
00111   
00112   LogDebug("Alignment") <<">  cands size : "<< cands.size();
00113   
00114   if (cands.size()<2) return result;
00115 
00116   TLorentzVector track0;
00117   TLorentzVector track1;
00118   TLorentzVector mother;
00119   typedef pair<const reco::Track*,const reco::Track*> constTrackPair;
00120   typedef pair<double,constTrackPair> candCollectionItem;
00121   vector<candCollectionItem> candCollection;
00122   
00123   for (unsigned int iCand = 0; iCand < cands.size(); iCand++) {
00124     
00125     track0.SetXYZT(cands.at(iCand)->px(),
00126                    cands.at(iCand)->py(),
00127                    cands.at(iCand)->pz(),
00128                    sqrt( cands.at(iCand)->p()*cands.at(iCand)->p() + theDaughterMass*theDaughterMass ));
00129     
00130     for (unsigned int jCand = iCand+1; jCand < cands.size(); jCand++) {
00131 
00132       track1.SetXYZT(cands.at(jCand)->px(),
00133                      cands.at(jCand)->py(),
00134                      cands.at(jCand)->pz(),
00135                      sqrt( cands.at(jCand)->p()*cands.at(jCand)->p() + theDaughterMass*theDaughterMass ));
00136       if (secThrBool==true && track1.Pt() < thesecThr && track0.Pt()< thesecThr) continue;          
00137       mother = track0 + track1;
00138       
00139       const reco::Track *trk1 = cands.at(iCand);
00140       const reco::Track *trk2 = cands.at(jCand);
00141 
00142       bool correctCharge = true;
00143       if (theChargeSwitch) correctCharge = this->checkCharge(trk1, trk2);
00144 
00145       bool acoplanarTracks = true;
00146       if (theAcoplanarityFilterSwitch) acoplanarTracks = this->checkAcoplanarity(trk1, trk2);
00147 
00148       if (mother.M() > theMinMass &&
00149           mother.M() < theMaxMass &&
00150           correctCharge &&
00151           acoplanarTracks) {
00152         candCollection.push_back(candCollectionItem(mother.Pt(),
00153                                                     constTrackPair(trk1, trk2)));
00154       }
00155     }
00156   }
00157 
00158   if (candCollection.size()==0) return result;
00159 
00160   sort(candCollection.begin(), candCollection.end(), 
00161        higherTwoBodyDecayPt<candCollectionItem>());
00162 
00163   std::map<const reco::Track*,unsigned int> uniqueTrackIndex;
00164   std::map<const reco::Track*,unsigned int>::iterator it;
00165   for (unsigned int i=0;
00166        i<candCollection.size() && i<theCandNumber;
00167        i++) {
00168     constTrackPair & trackPair = candCollection[i].second;
00169     
00170     it = uniqueTrackIndex.find(trackPair.first);
00171     if (it==uniqueTrackIndex.end()) {
00172       result.push_back(trackPair.first);
00173       uniqueTrackIndex[trackPair.first] = i;
00174     }
00175     
00176     it = uniqueTrackIndex.find(trackPair.second);
00177     if (it==uniqueTrackIndex.end()) {
00178       result.push_back(trackPair.second);
00179       uniqueTrackIndex[trackPair.second] = i;
00180     }
00181   }
00182 
00183   return result;
00184 }
00185 
00187 AlignmentTwoBodyDecayTrackSelector::Tracks 
00188 AlignmentTwoBodyDecayTrackSelector::checkMETMass(const Tracks& cands,const edm::Event& iEvent) const
00189 {
00190   Tracks result;
00191   
00192   LogDebug("Alignment") <<">  cands size : "<< cands.size();
00193   
00194   if (cands.size()==0) return result;
00195 
00196   TLorentzVector track;
00197   TLorentzVector met4;
00198   TLorentzVector mother;
00199 
00200   Handle<reco::CaloMETCollection> missingET;
00201   iEvent.getByLabel(theMissingETSource ,missingET);
00202   if (!missingET.isValid()) {
00203     LogError("Alignment")<< "@SUB=AlignmentTwoBodyDecayTrackSelector::checkMETMass"
00204                          << ">  could not optain missingET Collection!";
00205     return result;
00206   }
00207 
00208   typedef pair<double,const reco::Track*> candCollectionItem;
00209   vector<candCollectionItem> candCollection;
00210 
00211   for (reco::CaloMETCollection::const_iterator itMET = missingET->begin();
00212        itMET != missingET->end();
00213        ++itMET) {
00214     
00215     met4.SetXYZT((*itMET).px(),
00216                  (*itMET).py(),
00217                  (*itMET).pz(),
00218                  (*itMET).p());
00219   
00220     for (unsigned int iCand = 0; iCand < cands.size(); iCand++) {
00221     
00222       track.SetXYZT(cands.at(iCand)->px(),
00223                     cands.at(iCand)->py(),
00224                     cands.at(iCand)->pz(),
00225                     sqrt( cands.at(iCand)->p()*cands.at(iCand)->p() + theDaughterMass*theDaughterMass ));
00226       
00227       mother = track + met4;
00228       
00229       const reco::Track *trk = cands.at(iCand);
00230       const reco::CaloMET *met = &(*itMET);
00231 
00232       bool correctCharge = true;
00233       if (theChargeSwitch) correctCharge = this->checkCharge(trk);
00234 
00235       bool acoplanarTracks = true;
00236       if (theAcoplanarityFilterSwitch) acoplanarTracks = this->checkMETAcoplanarity(trk, met);
00237 
00238       if (mother.M() > theMinMass &&
00239           mother.M() < theMaxMass &&
00240           correctCharge &&
00241           acoplanarTracks) {
00242         candCollection.push_back(candCollectionItem(mother.Pt(), trk));
00243       }
00244     }
00245   }
00246 
00247   if (candCollection.size()==0) 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() && i<theCandNumber;
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 //===================HELPERS===================
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