00001 #include "FWCore/Utilities/interface/EDMException.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "AnalysisDataFormats/TopObjects/interface/TtGenEvent.h"
00004 #include "TopQuarkAnalysis/TopSkimming/interface/TtDecayChannelSelector.h"
00005
00006
00007
00008 static const std::string kGenParticles = "genParticles";
00009
00010
00011 static const unsigned int kTopBranches = 2;
00012
00013
00014
00015 static const unsigned int kDecayChannels = 3;
00016
00017
00018 TtDecayChannelSelector::TtDecayChannelSelector(const edm::ParameterSet& cfg):
00019 invert_ ( cfg.getParameter<bool>("invert" ) )
00020 {
00021
00022 edm::ParameterSet allowedTauDecays = cfg.getParameter<edm::ParameterSet>("allowedTauDecays");
00023 allowLepton_ = allowedTauDecays.getParameter<bool>("leptonic");
00024 allow1Prong_ = allowedTauDecays.getParameter<bool>("oneProng");
00025 allow3Prong_ = allowedTauDecays.getParameter<bool>("threeProng");
00026
00027
00028 edm::ParameterSet allowedTopDecays = cfg.getParameter<edm::ParameterSet>("allowedTopDecays");
00029
00030
00031 edm::ParameterSet decayBranchA = allowedTopDecays.getParameter<edm::ParameterSet>("decayBranchA");
00032 decayBranchA_.push_back(decayBranchA.getParameter<bool>("electron"));
00033 decayBranchA_.push_back(decayBranchA.getParameter<bool>("muon" ));
00034 decayBranchA_.push_back(decayBranchA.getParameter<bool>("tau" ));
00035
00036
00037 edm::ParameterSet decayBranchB = allowedTopDecays.getParameter<edm::ParameterSet>("decayBranchB");
00038 decayBranchB_.push_back(decayBranchB.getParameter<bool>("electron"));
00039 decayBranchB_.push_back(decayBranchB.getParameter<bool>("muon" ));
00040 decayBranchB_.push_back(decayBranchB.getParameter<bool>("tau" ));
00041
00042
00043 for(unsigned int d=0; d<kDecayChannels; ++d){
00044 allowedDecays_.push_back(decayBranchA_[d]+decayBranchB_[d]);
00045 }
00046 }
00047
00048 TtDecayChannelSelector::~TtDecayChannelSelector()
00049 {
00050 }
00051
00052 bool
00053 TtDecayChannelSelector::operator()(const reco::GenParticleCollection& parts, std::string inputType) const
00054 {
00055 unsigned int iLep=0;
00056 unsigned int iTop=0,iBeauty=0,iElec=0,iMuon=0,iTau=0;
00057 for(reco::GenParticleCollection::const_iterator top=parts.begin(); top!=parts.end(); ++top){
00058 if( search(top, TopDecayID::tID, inputType) ){
00059 ++iTop;
00060 for(reco::GenParticle::const_iterator td=top->begin(); td!=top->end(); ++td){
00061 if( search(td, TopDecayID::bID, inputType) ){
00062 ++iBeauty;
00063 }
00064 if( search(td, TopDecayID::WID, inputType) ){
00065 for(reco::GenParticle::const_iterator wd=td->begin(); wd!=td->end(); ++wd){
00066 if( abs(wd->pdgId())==TopDecayID::elecID ){
00067 ++iElec;
00068 }
00069 if( abs(wd->pdgId())==TopDecayID::muonID ){
00070 ++iMuon;
00071 }
00072 if( abs(wd->pdgId())==TopDecayID::tauID ){
00073
00074
00075
00076 if(tauDecay(*wd)){
00077 ++iTau;
00078 } else{
00079 ++iLep;
00080 }
00081 }
00082 }
00083 }
00084 }
00085 }
00086 }
00087 edm::LogVerbatim log("TtDecayChannelSelector::selection");
00088 log << "----------------------" << "\n"
00089 << " iTop : " << iTop << "\n"
00090 << " iBeauty : " << iBeauty << "\n"
00091 << " iElec : " << iElec << "\n"
00092 << " iMuon : " << iMuon << "\n"
00093 << " iTau : " << iTau << "\n"
00094 << "- - - - - - - - - - - " << "\n";
00095 iLep+=iElec+iMuon+iTau;
00096
00097 bool accept=false;
00098 unsigned int channel = decayChannel();
00099 if( (iTop==2) && (iBeauty==2) ){
00100 if( channel==iLep ){
00101 if( channel==0 ){
00102
00103
00104 accept=true;
00105 }
00106 if( channel==1 ){
00107
00108 accept=(iElec&&allowedDecays_[Elec]) || (iMuon&&allowedDecays_[Muon]) || (iTau&&allowedDecays_[Tau]);
00109 }
00110 if( channel==2 ){
00111 if( checkSum(allowedDecays_)==channel ){
00112
00113 accept = (allowedDecays_[Elec]==(int)iElec) && (allowedDecays_[Muon]==(int)iMuon) && (allowedDecays_[Tau]==(int)iTau);
00114 }
00115 else{
00116
00117 if(iElec+iMuon+iTau!=channel){
00118 accept = false;
00119 }
00120 else {
00121 if((iElec==2)||(iMuon==2)||(iTau==2)) {
00122
00123 accept = (allowedDecays_[Elec]==(int)iElec)||(allowedDecays_[Muon]==(int)iMuon)||(allowedDecays_[Tau]==(int)iTau);
00124 }
00125 else {
00126
00127 accept = ( ((iElec&&decayBranchA_[Elec])&&((iMuon&&decayBranchB_[Muon])||(iTau &&decayBranchB_[Tau ]))) ||
00128 ((iMuon&&decayBranchA_[Muon])&&((iElec&&decayBranchB_[Elec])||(iTau &&decayBranchB_[Tau ]))) ||
00129 ((iTau &&decayBranchA_[Tau ])&&((iElec&&decayBranchB_[Elec])||(iMuon&&decayBranchB_[Muon]))) );
00130 }
00131 }
00132 }
00133 }
00134 }
00135 accept=( (!invert_&& accept) || (!(!invert_)&& !accept) );
00136 }
00137 else{
00138 edm::LogWarning ( "NoVtbDecay" ) << "Decay is not via Vtb";
00139 }
00140 log << " accept : " << accept;
00141 return accept;
00142 }
00143
00144 bool
00145 TtDecayChannelSelector::search(reco::GenParticleCollection::const_iterator& part, int pdgId, std::string& inputType) const
00146 {
00147 if(inputType==kGenParticles){
00148 return (abs(part->pdgId())==pdgId && part->status()==TopDecayID::unfrag) ? true : false;
00149 }
00150 else{
00151 return (abs(part->pdgId())==pdgId) ? true : false;
00152 }
00153 }
00154
00155 bool
00156 TtDecayChannelSelector::search(reco::GenParticle::const_iterator& part, int pdgId, std::string& inputType) const
00157 {
00158 if(inputType==kGenParticles){
00159 return (abs(part->pdgId())==pdgId && part->status()==TopDecayID::unfrag) ? true : false;
00160 }
00161 else{
00162 return (abs(part->pdgId())==pdgId) ? true : false;
00163 }
00164 }
00165
00166 unsigned int
00167 TtDecayChannelSelector::countProngs(const reco::Candidate& part) const
00168 {
00169
00170 if(part.status()==TopDecayID::stable){
00171 return (part.charge()!=0);
00172 }
00173
00174 int prong =0;
00175 for(reco::Candidate::const_iterator daughter=part.begin();daughter!=part.end(); ++daughter){
00176 prong += countProngs(*daughter);
00177 }
00178 return prong;
00179 }
00180
00181 bool
00182 TtDecayChannelSelector::tauDecay(const reco::Candidate& tau) const
00183 {
00184 bool leptonic = false;
00185 unsigned int nch = 0;
00186
00187
00188 for(reco::Candidate::const_iterator daughter=tau.begin();daughter!=tau.end(); ++daughter){
00189
00190
00191
00192 if(daughter->pdgId()==tau.pdgId()){
00193 return tauDecay(*daughter);
00194 }
00195
00196 leptonic |= (abs(daughter->pdgId())==TopDecayID::elecID || abs(daughter->pdgId())==TopDecayID::muonID);
00197
00198 nch += countProngs(*daughter);
00199 }
00200 return ((allowLepton_ && leptonic) ||
00201 (allow1Prong_ && !leptonic && nch==1)||
00202 (allow3Prong_ && !leptonic && nch >1));
00203 }