diff --git a/inc/LauFlavTag.hh b/inc/LauFlavTag.hh index a0669fa..2baf719 100644 --- a/inc/LauFlavTag.hh +++ b/inc/LauFlavTag.hh @@ -1,222 +1,225 @@ /* Copyright 2017 University of Warwick Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Laura++ package authors: John Back Paul Harrison Thomas Latham */ /*! \file LauFlavTag.hh \brief File containing declaration of LauFlavTag class. */ /*! \class LauFlavTag \brief Class for defining the flavour tagging approach. Define the flavour tagging categories and all associated parameters to be passed to the relevant fit models. */ #ifndef LAU_FLAVTAG #define LAU_FLAVTAG #include #include #include #include #include "TString.h" #include "TStopwatch.h" #include "TSystem.h" #include "LauConstants.hh" #include "LauParameter.hh" #include "LauFitDataTree.hh" #include "LauAbsFitModel.hh" #include "LauDecayTimePdf.hh" class LauFlavTag { public: //! Constructor /*! \param [in] modelB0bar DP model for the antiparticle \param [in] modelB0 DP model for the particle \param [in] useUntaggedEvents should the untagged sample be used or excluded? \param [in] tagVarName the variable name in the data tree that specifies the event tag \param [in] tagCatVarName the variable name in the data tree that specifies the event tagging category */ LauFlavTag(const std::vector& params, const Bool_t useUntaggedEvents = kTRUE, const TString& tagVarName = "tagFlv", const TString& tagCatVarName = "tagCat"); //! Destructor virtual ~LauFlavTag(); void initialise(); //! Add a tagging category to the list of valid categories /*! NB category 0 is always valid and corresponds to untagged events. Whether untagged events are used in the fit or note is controlled by a constructor argument. \param [in] tagCat the tagging category ID */ void addValidTagCat(const Int_t tagCat); //! Add several tagging categories to the list of valid categories /*! NB category 0 is always valid and corresponds to untagged events. Whether untagged events are used in the fit or note is controlled by a constructor argument. \param [in] tagCats the list of tagging category IDs */ void addValidTagCats(const std::vector& tagCats); //! Check the validity of the given tagging category /*! \param [in] tagCat the tagging category ID */ Bool_t validTagCat(const Int_t tagCat) const; //! Return the set of valid tagging categories std::set getValidTagCats(); //! Change the dilutions, delta dilutions and tagCatFrac for signal if needed /*! \param [in] tagCat the tagging category to adjust \param [in] tagCatFrac the tagging category fraction \param [in] dilution the tagging category average dilution = (1 - 2 * avg_mistag_fraction) \param [in] deltaDilution the tagging category dilution difference TODO - check sign convention \param [in] fixTCFrac whether to fix or float the tagging category fraction \param [in] usePerEvtMistag whether to use per event mistag information or not \param [in] mistagVarName the name of the branch in the tree containing per event mistag information + \param [in] calib_p0 the calibration parameter p0 when using per event mistags + \param [in] calib_p1 the calibration parameter p1 when using per event mistags */ void setSignalTagCatPars(const Int_t tagCat, const Double_t tagCatFrac, const Double_t dilution, const Double_t deltaDilution, - const Bool_t fixTCFrac = kTRUE, const Bool_t usePerEvtMistag = kFALSE, const TString& mistagVarName = "tagMistag"); + const Bool_t fixTCFrac = kTRUE, const Bool_t usePerEvtMistag = kFALSE, const TString& mistagVarName = "tagMistag", + const Double_t calib_p0=0.25, const Double_t calib_p1=1.0); //! Read in the input fit data variables, e.g. m13Sq and m23Sq void cacheInputFitVars(LauFitDataTree* inputFitData); Bool_t getUsePerEvtMistag(){return usePerEvtMistag_;}; typedef std::map< Int_t, LauParameter> LauTagCatParamMap; LauTagCatParamMap getDilution(){return dilution_;}; LauTagCatParamMap getDeltaDilution(){return deltaDilution_;}; LauTagCatParamMap& getSignalTagCatFrac(){return signalTagCatFrac_;}; //! Update the fraction of the first tagging category for all species void setFirstTagCatFractions(); //std::vector getEvtTagFlvVals(){return evtTagFlvVals_;}; //std::vector getEvtTagCatVals(){return evtTagCatVals_;}; //std::vector getEvtMistagVals(){return evtMistagVals_;}; Int_t getEvtTagFlvVals(UInt_t iEvt){return evtTagFlvVals_[iEvt];}; Int_t getEvtTagCatVals(UInt_t iEvt){return evtTagCatVals_[iEvt];}; Double_t getEvtMistagVals(UInt_t iEvt){return evtMistagVals_[iEvt];}; const TString& getMistagVarName(){return mistagVarName_;}; LauParameter* findParameter(const TString& parName); //std::vector getCalibParameters(Int_t tagCat); LauTagCatParamMap getCalibP0(){return calib_p0_;}; LauTagCatParamMap getCalibP1(){return calib_p1_;}; std::map< Int_t, Double_t> getPerEvtAvgMistag() const {return perEvtAvgMistag_;}; Double_t getOmega(const UInt_t ievt);// const; Double_t getOmegaGen(const Double_t eta);// const; Double_t getEtaGen(LauAbsPdf* hist) const; protected: //! Check the signal tagging category fractions void checkSignalTagCatFractions(); //! Check that the background tagging category fractions are all present and sum to unity /*! \param [in] theMap the container of tagcat fractions */ Bool_t checkTagCatFracMap(const LauTagCatParamMap& theMap) const; //! Calculates the fraction of the first tagging category based on the others /*! \param [in] theMap the container of tagcat fractions */ void setFirstTagCatFrac(LauTagCatParamMap& theMap); private: //! Whether or not to use untagged events const Bool_t useUntaggedEvents_; //! Signal tagging category fractions LauTagCatParamMap signalTagCatFrac_; //! Flavour tagging variable name TString tagVarName_; //! Tagging category variable name TString tagCatVarName_; //! Per event mistag variable name TString mistagVarName_; //! The allowed tagging categories std::set validTagCats_; //! Flavour tag for current event Int_t curEvtTagFlv_; //! Tagging category for current event Int_t curEvtTagCat_; //! Per event mistag for current event Double_t curEvtMistag_; //! Vector to store event flavour tags std::vector evtTagFlvVals_; //! Vector to store event tagging categories std::vector evtTagCatVals_; //! Vector to store event mistag values std::vector evtMistagVals_; //! Average dilutions LauTagCatParamMap dilution_; //! Dilution differences LauTagCatParamMap deltaDilution_; //! Use per event mistag Bool_t usePerEvtMistag_; //! Per-event average mistag value (eta hat) //Double_t perEvtAvgMistag_; std::map< Int_t, Double_t> perEvtAvgMistag_; //! Calibration parameters //LauParameter* calib_p0_; //LauParameter* calib_p1_; LauTagCatParamMap calib_p0_; LauTagCatParamMap calib_p1_; //! Input parameters std::vector params_; ClassDef(LauFlavTag,0) // Flaour tagging set up }; #endif diff --git a/src/LauFlavTag.cc b/src/LauFlavTag.cc index d096f1f..b9e9fd6 100644 --- a/src/LauFlavTag.cc +++ b/src/LauFlavTag.cc @@ -1,405 +1,405 @@ /* Copyright 2017 University of Warwick Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Laura++ package authors: John Back Paul Harrison Thomas Latham */ /*! \file LauFlavTag.cc \brief File containing implementation of LauFlavTag class. */ #include #include #include #include #include #include "TFile.h" #include "TMinuit.h" #include "TRandom.h" #include "TSystem.h" #include "TVirtualFitter.h" #include "LauAbsBkgndDPModel.hh" #include "LauAbsCoeffSet.hh" #include "LauAbsPdf.hh" #include "LauAsymmCalc.hh" #include "LauComplex.hh" #include "LauConstants.hh" #include "LauDPPartialIntegralInfo.hh" #include "LauDaughters.hh" #include "LauDecayTimePdf.hh" #include "LauFitNtuple.hh" #include "LauGenNtuple.hh" #include "LauIsobarDynamics.hh" #include "LauKinematics.hh" #include "LauPrint.hh" #include "LauRandom.hh" #include "LauScfMap.hh" #include "LauFlavTag.hh" ClassImp(LauFlavTag) LauFlavTag::LauFlavTag(const std::vector& params, const Bool_t useUntaggedEvents, const TString& tagVarName, const TString& tagCatVarName) : useUntaggedEvents_(useUntaggedEvents), signalTagCatFrac_(), tagVarName_(tagVarName), tagCatVarName_(tagCatVarName), mistagVarName_("tagMistag"), validTagCats_(), curEvtTagFlv_(0), curEvtTagCat_(0), curEvtMistag_(0.), evtTagFlvVals_(0), evtTagCatVals_(0), evtMistagVals_(0), dilution_(), deltaDilution_(), usePerEvtMistag_(kFALSE), perEvtAvgMistag_(), calib_p0_(), calib_p1_(), params_(params) { // Add the untagged category as a valid category this->addValidTagCat(0); // Set the fraction, average dilution and dilution difference for the untagged category this->setSignalTagCatPars(0, 1.0, 0.0, 0.0, kTRUE); } LauFlavTag::~LauFlavTag() { } void LauFlavTag::initialise() { this->checkSignalTagCatFractions(); } void LauFlavTag::addValidTagCats(const std::vector& tagCats) { for (std::vector::const_iterator iter = tagCats.begin(); iter != tagCats.end(); ++iter) { this->addValidTagCat(*iter); } } void LauFlavTag::addValidTagCat(const Int_t tagCat) { validTagCats_.insert(tagCat); } -void LauFlavTag::setSignalTagCatPars(const Int_t tagCat, const Double_t tagCatFrac, const Double_t dilution, const Double_t deltaDilution, const Bool_t fixTCFrac, const Bool_t usePerEvtMistag, const TString& mistagVarName) +void LauFlavTag::setSignalTagCatPars(const Int_t tagCat, const Double_t tagCatFrac, const Double_t dilution, const Double_t deltaDilution, const Bool_t fixTCFrac, const Bool_t usePerEvtMistag, const TString& mistagVarName, const Double_t calib_p0, const Double_t calib_p1) { if (!this->validTagCat(tagCat)) { std::cerr<<"ERROR in LauFlavTag::setSignalTagCatPars : Tagging category \""<first != 0) { const LauParameter& par = iter->second; totalTaggedFrac += par.value(); } } if ( ((totalTaggedFrac < (1.0-1.0e-8))&&!useUntaggedEvents_) || (totalTaggedFrac > (1.0+1.0e-8)) ) { std::cerr<<"WARNING in LauFlavTag::checkSignalTagCatFractions : Tagging category fractions add up to "<second; Double_t newVal = par.value() / totalTaggedFrac; par.value(newVal); par.initValue(newVal); par.genValue(newVal); } } else if (useUntaggedEvents_) { Double_t tagCatFrac = 1.0 - totalTaggedFrac; TString tagCatFracName("signalTagCatFrac0"); signalTagCatFrac_[0].name(tagCatFracName); signalTagCatFrac_[0].range(0.0,1.0); signalTagCatFrac_[0].value(tagCatFrac); signalTagCatFrac_[0].initValue(tagCatFrac); signalTagCatFrac_[0].genValue(tagCatFrac); signalTagCatFrac_[0].fixed(kTRUE); TString dilutionName("dilution0"); dilution_[0].name(dilutionName); dilution_[0].range(0.0,1.0); dilution_[0].value(0.0); dilution_[0].initValue(0.0); dilution_[0].genValue(0.0); dilution_[0].fixed(kTRUE); TString deltaDilutionName("deltaDilution0"); deltaDilution_[0].name(deltaDilutionName); deltaDilution_[0].range(-2.0,2.0); deltaDilution_[0].value(0.0); deltaDilution_[0].initValue(0.0); deltaDilution_[0].genValue(0.0); deltaDilution_[0].fixed(kTRUE); } for (LauTagCatParamMap::const_iterator iter=dilution_.begin(); iter!=dilution_.end(); ++iter) { std::cout<<"INFO in LauFlavTag::checkSignalTagCatFractions : Setting dilution for tagging category "<<(*iter).first<<" to "<<(*iter).second<setFirstTagCatFrac(signalTagCatFrac_); // TODO - add background maps } void LauFlavTag::setFirstTagCatFrac(LauTagCatParamMap& theMap) { Double_t firstCatFrac = 1.0; Int_t firstCat(0); for (LauTagCatParamMap::iterator iter = theMap.begin(); iter != theMap.end(); ++iter) { if (iter == theMap.begin()) { firstCat = iter->first; continue; } LauParameter& par = iter->second; firstCatFrac -= par.unblindValue(); } theMap[firstCat].value(firstCatFrac); } Bool_t LauFlavTag::validTagCat(Int_t tagCat) const { return (validTagCats_.find(tagCat) != validTagCats_.end()); } std::set LauFlavTag::getValidTagCats() { return validTagCats_; } Bool_t LauFlavTag::checkTagCatFracMap(const LauTagCatParamMap& theMap) const { // TODO - this is for checking the the background maps are OK (so it is unused at the moment) // First check that there is an entry for each tagging category. // NB an entry won't have been added if it isn't a valid category // so don't need to check for that here. if (theMap.size() != signalTagCatFrac_.size()) { std::cerr<<"ERROR in LauFlavTag::checkTagCatFracMap : Not all tagging categories present."< 1E-10) { std::cerr<<"ERROR in LauFlavTag::checkTagCatFracMap : Tagging category event fractions do not sum to unity."<haveBranch( tagCatVarName_ ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << tagCatVarName_ << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } if ( ! inputFitData->haveBranch( tagVarName_ ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << tagVarName_ << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } if ( ! inputFitData->haveBranch( mistagVarName_ ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << mistagVarName_ << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } UInt_t nEvents = inputFitData->nEvents(); evtTagCatVals_.reserve( nEvents ); evtTagFlvVals_.reserve( nEvents ); evtMistagVals_.reserve( nEvents ); //Running total to calc average mistag per tagCat //Double_t tot_mistag(0.); std::map< Int_t, Double_t> tot_mistag; //Int_t totalTagged = 0; std::map< Int_t, Int_t> totalTagged; LauFitData::const_iterator fitdata_iter; for (UInt_t iEvt = 0; iEvt < nEvents; iEvt++) { const LauFitData& dataValues = inputFitData->getData(iEvt); fitdata_iter = dataValues.find( tagCatVarName_ ); curEvtTagCat_ = static_cast( fitdata_iter->second ); if ( ! this->validTagCat( curEvtTagCat_ ) ) { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid tagging category " << curEvtTagCat_ << " for event " << iEvt << ", setting it to untagged" << std::endl; curEvtTagCat_ = 0; } evtTagCatVals_.push_back( curEvtTagCat_ ); fitdata_iter = dataValues.find( tagVarName_ ); curEvtTagFlv_ = static_cast( fitdata_iter->second ); if ( TMath::Abs( curEvtTagFlv_ ) != 1 ) { if ( curEvtTagFlv_ > 0 ) { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid tagging output " << curEvtTagFlv_ << " for event " << iEvt << ", setting it to +1" << std::endl; curEvtTagFlv_ = +1; } else { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid tagging output " << curEvtTagFlv_ << " for event " << iEvt << ", setting it to -1" << std::endl; curEvtTagFlv_ = -1; } } evtTagFlvVals_.push_back( curEvtTagFlv_ ); // TODO - surely this part should only be done if we have per-event mistagging fitdata_iter = dataValues.find( mistagVarName_); curEvtMistag_ = static_cast( fitdata_iter->second ); if (curEvtMistag_ > 0.5){ std::cerr<<"WARNING in LauFlavTag::cacheInputFitVars : Mistag value "<::iterator iter = perEvtAvgMistag_.begin(); iter != perEvtAvgMistag_.end(); ++iter) { perEvtAvgMistag_[iter->first] = tot_mistag[iter->first]/totalTagged[iter->first]; } } LauParameter* LauFlavTag::findParameter(const TString& parName) { for ( std::vector::iterator iter = params_.begin(); iter != params_.end(); ++iter ) { if ((*iter)->name().Contains(parName)) { return (*iter); } } std::cerr << "ERROR in LauFlavTag::findParameter : Parameter \"" << parName << "\" not found." << std::endl; return 0; } Double_t LauFlavTag::getOmega(const UInt_t iEvt) //const { return calib_p0_[curEvtTagCat_].unblindValue() + calib_p1_[curEvtTagCat_].unblindValue() * (evtMistagVals_[iEvt] - perEvtAvgMistag_[curEvtTagCat_]); } Double_t LauFlavTag::getOmegaGen(const Double_t eta) //const { return calib_p0_[curEvtTagCat_].unblindValue() + calib_p1_[curEvtTagCat_].unblindValue() * (eta - perEvtAvgMistag_[curEvtTagCat_]); } Double_t LauFlavTag::getEtaGen(LauAbsPdf* hist) const { if (hist==0){ std::cout << "Error in LauFlavTag::getEtaGen : Supplied LauAbsPdf is a null pointer" << std::endl; gSystem->Exit(EXIT_FAILURE); } LauFitData data = hist->generate(0); //TODO Add DP dependence? return data.find(hist->varName())->second; } //std::vector LauFlavTag::getCalibParameters(Int_t tagCat) //{ // if (!this->validTagCat(tagCat)){ // std::cout << "FATAL in LauFlavTag::setCalibParams : Invalid tagging category, number " << tagCat << "." << std::endl; // gSystem->Exit(EXIT_FAILURE); // } // std::vector calibParams; // calib_p0_[tagCat] = this->findParameter("calib_p0"); // calib_p1_[tagCat] = this->findParameter("calib_p1"); // // // calib_p0_->value(perEvtAvgMistag_); // WOULD BE NICE TO DO THIS // // calibParams.push_back( calib_p0_[tagCat] ); // calibParams.push_back( calib_p1_[tagCat] ); // if (calibParams.size() != 2) { // std::cout << "FATAL in LauFlavTag::setCalibParams : Expected two calibration parameters, received " << calibParams.size() << "." << std::endl; // gSystem->Exit(EXIT_FAILURE); // } // return calibParams; // //}