void TTbarPhotonAnalyser::eMuSignalAnalysis(const EventPtr event) { if (topEMuPhotonSelection_->passesSelectionUpToStep(event, TTbarEMuReferenceSelection::JustOneGoodPhotonPostSelection)) { const JetCollection jets(topEMuPhotonSelection_->cleanedJets(event)); const JetCollection bJets(topEMuPhotonSelection_->cleanedBJets(event)); unsigned int numberOfBjets(bJets.size()); vector<double> bjetWeights; if (event->isRealData()) { for (unsigned int index = 0; index <= numberOfBjets; ++index) { if (index == numberOfBjets) bjetWeights.push_back(1.); else bjetWeights.push_back(0); } } else bjetWeights = BjetWeights(jets, numberOfBjets); histMan_->setCurrentJetBin(jets.size()); histMan_->setCurrentBJetBin(numberOfBjets); const LeptonPointer signalLepton = topEMuPhotonSelection_->signalLepton(event); const ElectronPointer signalElectron(boost::static_pointer_cast<Electron>(signalLepton)); //get dilepton collection const ElectronCollection electrons = topEMuPhotonSelection_->signalElectrons(event); const MuonCollection muons = topEMuPhotonSelection_->signalMuons(event); const PhotonCollection photons = topEMuPhotonSelection_->signalPhotons(event); for (unsigned int weightIndex = 0; weightIndex < bjetWeights.size(); ++weightIndex) { double bjetWeight = bjetWeights.at(weightIndex); histMan_->setCurrentBJetBin(weightIndex); histMan_->setCurrentHistogramFolder(histogramFolder_ + "/EMu/Ref selection"); //met metAnalyserEMuPhotonSelection_->setScale(bjetWeight); metAnalyserEMuPhotonSelection_->analyse(event, signalLepton); //jets jetAnalyserEMuPhotonSelection_->setScale(bjetWeight); jetAnalyserEMuPhotonSelection_->analyse(event); //DiLepton eMuAnalyserEMuPhotonSelection_->setScale(bjetWeight); eMuAnalyserEMuPhotonSelection_->analyse(event, electrons, muons); //Vertices //vertexAnalyserEMuPhotonSelection_->setScale(bjetWeight); //vertexAnalyserEMuPhotonSelection_->analyse(event); //abcdAnalyserEMuPhotonSelection_->setScale(bjetWeight); //abcdAnalyserEMuPhotonSelection_->analyse(event, photons, jets, electrons, muons); //photon photonAnalyserEMuPhotonSelection_->setScale(bjetWeight); photonAnalyserEMuPhotonSelection_->analyse(event, photons, jets, electrons, muons); if(event->getDataType() == DataType::TTGamma || event->getDataType() == DataType::TTJets){ //signal photon ttphotonAnalyserEMuPhotonSelection_->setScale(bjetWeight); ttphotonAnalyserEMuPhotonSelection_->analyse(event, photons, jets, electrons, muons); ttphotonAnalyserEMuPhotonSelection_->analyse_signalPhotons(event, photons, jets, electrons, muons); } //n-EtAndEta photons const PhotonCollection photonsMinusEtAndEta = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesEtAndEta"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinusEtAndEta, jets, electrons, muons, "passesEtAndEta"); //n-passesHOverE photons const PhotonCollection photonsMinusHOverE = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesHOverE"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinusHOverE, jets, electrons, muons, "passesHOverE"); //n-passesShowerShape photons const PhotonCollection photonsMinuspassesShowerShape = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesShowerShape"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesShowerShape, jets, electrons, muons, "passesShowerShape"); //n-passesPFChargedIso photons // const PhotonCollection photonsMinuspassesPFChargedIso = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesPFChargedIso"); // photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesPFChargedIso, jets, electrons, muons, "passesPFChargedIso"); //n-passesPFNeutralIso photons const PhotonCollection photonsMinuspassesPFNeutralIso = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesPFNeutralIso"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesPFNeutralIso, jets, electrons, muons, "passesPFNeutralIso"); //n-passesPFPhotonIso photons const PhotonCollection photonsMinuspassesPFPhotonIso = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesPFPhotonIso"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesPFPhotonIso, jets, electrons, muons, "passesPFPhotonIso"); //n-passesphoSCChIso photons const PhotonCollection photonsMinuspassesphoSCChIso = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesphoSCChIso"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesphoSCChIso, jets, electrons, muons, "passesphoSCChIso"); //n-passesphoSCNuIso photons const PhotonCollection photonsMinuspassesphoSCNuIso = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesphoSCNuIso"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesphoSCNuIso, jets, electrons, muons, "passesphoSCNuIso"); //n-passesphoSCPhIso photons const PhotonCollection photonsMinuspassesphoSCPhIso = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesphoSCPhIso"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesphoSCPhIso, jets, electrons, muons, "passesphoSCPhIso"); //n-passesDeltaRgammaMuons photons const PhotonCollection photonsMinuspassesDeltaRgammaMuons = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesDeltaRgammaMuons"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesDeltaRgammaMuons, jets, electrons, muons, "passesDeltaRgammaMuons"); //n-passesDeltaRgammaElectrons photons const PhotonCollection photonsMinuspassesDeltaRgammaElectrons = topEMuPhotonSelection_->nMinusOnePhotons(event, "passesDeltaRgammaElectrons"); photonAnalyserEMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesDeltaRgammaElectrons, jets, electrons, muons, "passesDeltaRgammaElectrons"); //n-passesDeltaRgammaJets photons const PhotonCollection photonsMinuspassesDeltaRgammaJets = topMuMuPhotonSelection_->nMinusOnePhotons(event, "passesDeltaRgammaJets"); photonAnalyserMuMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesDeltaRgammaJets, jets, electrons, muons, "passesDeltaRgammaJets"); //n-passesDeltaRjetsMuons photons const PhotonCollection photonsMinuspassesDeltaRjetsMuons = topMuMuPhotonSelection_->nMinusOnePhotons(event, "passesDeltaRjetsMuons"); photonAnalyserMuMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesDeltaRjetsMuons, jets, electrons, muons, "passesDeltaRjetsMuons"); //n-passesDeltaRjetsElectrons photons const PhotonCollection photonsMinuspassesDeltaRjetsElectrons = topMuMuPhotonSelection_->nMinusOnePhotons(event, "passesDeltaRjetsElectrons"); photonAnalyserMuMuPhotonSelection_->analyse_NminusOnePhotons(event, photonsMinuspassesDeltaRjetsElectrons, jets, electrons, muons, "passesDeltaRjetsElectrons"); } } }
BAT::TtbarHypothesis HitFitAnalyser::analyseAndReturn(const EventPtr event, const JetCollection jets, const JetCollection bjets, const LeptonPointer selectedLepton ) { weight_ = event->weight() * prescale_ * scale_; treeMan_->setCurrentFolder(histogramFolder_); treeMan_->Fill("EventWeight", weight_ ); // const JetCollection jets(event->getCleanedJets( SelectionCriteria::ElectronPlusJetsReference )); // const JetCollection bJets(event->getCleanedBJets( SelectionCriteria::ElectronPlusJetsReference )); // const LeptonPointer selectedLepton = event->getSignalLepton( SelectionCriteria::ElectronPlusJetsReference ); string metPrefix = METAlgorithm::names.at(0); const METPointer met(event->MET((METAlgorithm::value) 0)); // Get cleaned jets that aren't b tagged JetCollection leadingLightJets; JetCollection leadingBJets; unsigned int maxNJet = std::min(5, int(jets.size())); for ( unsigned int jetIndex=0; jetIndex < maxNJet; ++jetIndex ) { bool isBJet = false; JetPointer thisJet = jets[jetIndex]; for ( unsigned int bJetIndex=0; bJetIndex < bjets.size(); ++bJetIndex ) { JetPointer thisBJet = bjets[bJetIndex]; if ( thisJet == thisBJet ) { isBJet = true; break; } } if ( !isBJet ) leadingLightJets.push_back( thisJet ); else leadingBJets.push_back( thisJet ); } //set MC matching flag if (event->getDataType() == DataType::TTJets_amcatnloFXFX) do_MC_matching = true; else do_MC_matching = false; //prepare the jets collection // Copy jets into an array JetCollection jetCopy; for (JetCollection::const_iterator j = leadingLightJets.begin(); j != leadingLightJets.end(); ++j) { jetCopy.push_back(*j); } JetCollection bJetCopy; for (JetCollection::const_iterator j = leadingBJets.begin(); j != leadingBJets.end(); ++j) { bJetCopy.push_back(*j); } std::sort(jetCopy.begin(), jetCopy.end(), jetPtComp); std::sort(bJetCopy.begin(), bJetCopy.end(), jetPtComp); jetsForFitting.clear(); unsigned numJetsToFit = jetCopy.size(); if (jetCopy.size() >= 2) { if (numJetsToFit > 5) numJetsToFit = 5; jetsForFitting.insert(jetsForFitting.begin(), jetCopy.begin(), jetCopy.begin() + numJetsToFit); } bJetsForFitting.clear(); numJetsToFit = bJetCopy.size(); if (bJetCopy.size() >= 2) { if (numJetsToFit > 5) numJetsToFit = 5; bJetsForFitting.insert(bJetsForFitting.begin(), bJetCopy.begin(), bJetCopy.begin() + numJetsToFit); } BatHitFit hhFitter(electronTranslator_, muonTranslator_, jetTranslator_, metTranslator_, hitfitDefault_, hitfitLepWMass_, hitfitHadWMass_, hitfitTopMass_); // Clear the internal state hhFitter.clear(); // Add lepton into hitfit if ( isElectronChannel_ ) { const ElectronPointer signalElectron(boost::static_pointer_cast<Electron>(selectedLepton)); //TODO: fix the fitter to accept lepton class OR particle!! hhFitter.AddLepton(*signalElectron); } else { const MuonPointer signalMuon(boost::static_pointer_cast<Muon>(selectedLepton)); //TODO: fix the fitter to accept lepton class OR particle!! hhFitter.AddLepton(*signalMuon); } // Add jets into HitFit // Also check if jets matched to ttbar partons are in the jets passed to the fit bool quarkInCollection = false, quarkBarInCollection = false, lebBInCollection = false, hadBInCollection = false; for (size_t jet = 0; jet != jetsForFitting.size(); ++jet) { hhFitter.AddJet(*jetsForFitting.at(jet)); // cout << "Adding light jet with csv : " << jetsForFitting.at(jet)->getBTagDiscriminator(BAT::BtagAlgorithm::value::CombinedSecondaryVertexV2) << endl; if ( jetsForFitting.at(jet)->ttbar_decay_parton() ) { int partonPdg = jetsForFitting.at(jet)->ttbar_decay_parton(); if ( partonPdg == 3 ) quarkInCollection = true; else if ( partonPdg == 4 ) quarkBarInCollection = true; else if ( partonPdg == 5 ) lebBInCollection = true; else if ( partonPdg == 6 ) hadBInCollection = true; } } for (size_t jet = 0; jet != bJetsForFitting.size(); ++jet) { hhFitter.AddBJet(*bJetsForFitting.at(jet)); // cout << "Adding b jet with csv : " << bJetsForFitting.at(jet)->getBTagDiscriminator(BAT::BtagAlgorithm::value::CombinedSecondaryVertexV2) << endl; if ( bJetsForFitting.at(jet)->ttbar_decay_parton() ) { int partonPdg = bJetsForFitting.at(jet)->ttbar_decay_parton(); if ( partonPdg == 3 ) quarkInCollection = true; else if ( partonPdg == 4 ) quarkBarInCollection = true; else if ( partonPdg == 5 ) lebBInCollection = true; else if ( partonPdg == 6 ) hadBInCollection = true; } } // Check if jets matched to ttbar partons are in the jets passed to the fit if (do_MC_matching) { if ( quarkInCollection && quarkBarInCollection && lebBInCollection && hadBInCollection ) { allTTBarJetsPassedToFit_ = true; } int lastTTBarJetPosition = positionOfLastTTBarJet( jets ); if ( lastTTBarJetPosition != -1 ) { allTTBarJetsPassSelection_ = true; treeMan_->Fill("PositionOfLastTTbarJet", lastTTBarJetPosition + 1 ); } else treeMan_->Fill("PositionOfLastTTbarJet", lastTTBarJetPosition ); } // Add missing transverse energy into HitFit hhFitter.SetMet(*met); // Container for input of all jet permutation of the event std::vector<hitfit::Lepjets_Event> hitfitEventsInput; // Container for results of the fit for all jet permutation of the event std::vector<hitfit::Fit_Result> hitfitResult; // // R U N H I T F I T // // Run the kinematic fit and get how many permutations is possible // in the fit size_t nHitFit = hhFitter.FitAllPermutation(); // // Get the number of jets // nHitFitJet = hhFitter.GetEvent().njets(); // Get the input events for all permutations hitfitEventsInput = hhFitter.GetUnfittedEvent(); // Get the fit results for all permutations hitfitResult = hhFitter.GetFitAllPermutation(); double bestChi2 = 999.; unsigned bestX2pos = nHitFit + 1; // // Loop over all permutations and extract the information for (size_t fit = 0; fit != nHitFit; ++fit) { // Get the event after the fit hitfit::Fit_Result fitResult = hitfitResult[fit]; if (hitfitResult[fit].chisq() > 0.0) { treeMan_->Fill("FitChiSquaredAllSolutions",fitResult.chisq()); } // Is this the permutation with smallest chi2? if (fitResult.chisq() > 0.0 && fitResult.chisq() < bestChi2) { bestChi2 = fitResult.chisq(); bestX2pos = fit; } } // // END PART WHICH EXTRACTS INFORMATION FROM HITFIT // if (bestX2pos < nHitFit + 1) { treeMan_->Fill("FitChiSquaredBestSolutions",hitfitResult[bestX2pos].chisq()); treeMan_->Fill("FitChiSquaredProbabilityBestSolutions",TMath::Prob(hitfitResult[bestX2pos].chisq(),1)); //pass hitfit event into BAT format lepton_charge = selectedLepton->charge(); BAT::TtbarHypothesis newHyp = BatEvent(hitfitResult[bestX2pos].ev(), event, "SolutionCategory"); treeMan_->Fill("FittedLeptonicTopPtBestSolution", newHyp.leptonicTop->pt()); treeMan_->Fill("FittedHadronicTopPtBestSolution", newHyp.hadronicTop->pt()); treeMan_->Fill("FittedLeptonicTopRapidityBestSolution", newHyp.leptonicTop->rapidity()); treeMan_->Fill("FittedHadronicTopRapidityBestSolution", newHyp.hadronicTop->rapidity()); treeMan_->Fill("FittedTTbarMassBestSolution", newHyp.resonance->mass()); treeMan_->Fill("FittedTTbarPtBestSolution", newHyp.resonance->pt()); treeMan_->Fill("FittedTTbarRapidityBestSolution", newHyp.resonance->rapidity()); // Get the event before the fit hitfit::Lepjets_Event unfittedEvent = hitfitEventsInput[bestX2pos]; // Now need to perform second kinematic fit hitfit::Fit_Result secondFitResult = performSecondKinematicFit( unfittedEvent, event); BAT::TtbarHypothesis newHyp_afterSecondFit = BatEvent(secondFitResult.ev(), event, "SolutionCategory_second"); treeMan_->Fill("FitChiSquaredBestSolutions_second",secondFitResult.chisq()); treeMan_->Fill("FitChiSquaredProbabilityBestSolutions_second",TMath::Prob(secondFitResult.chisq(),2)); treeMan_->Fill("FittedLeptonicTopPtBestSolution_second", newHyp_afterSecondFit.leptonicTop->pt()); treeMan_->Fill("FittedHadronicTopPtBestSolution_second", newHyp_afterSecondFit.hadronicTop->pt()); treeMan_->Fill("FittedLeptonicTopRapidityBestSolution_second", newHyp_afterSecondFit.leptonicTop->rapidity()); treeMan_->Fill("FittedHadronicTopRapidityBestSolution_second", newHyp_afterSecondFit.hadronicTop->rapidity()); treeMan_->Fill("FittedTTbarMassBestSolution_second", newHyp_afterSecondFit.resonance->mass()); treeMan_->Fill("FittedTTbarPtBestSolution_second", newHyp_afterSecondFit.resonance->pt()); treeMan_->Fill("FittedTTbarRapidityBestSolution_second", newHyp_afterSecondFit.resonance->rapidity()); return newHyp_afterSecondFit; } else { // cout << "No HitFit solution found for this event" << endl; treeMan_->Fill("SolutionCategory", 0 ); treeMan_->Fill("SolutionCategory_second", 0); } return BAT::TtbarHypothesis(); }