diff --git a/inc/LauFlavTag.hh b/inc/LauFlavTag.hh index ceb38e9..71b3143 100644 --- a/inc/LauFlavTag.hh +++ b/inc/LauFlavTag.hh @@ -1,347 +1,398 @@ /* 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 "TString.h" #include "LauParameter.hh" class LauAbsPdf; class LauFitDataTree; class LauFlavTag final { public: //! Define sign convention for B and Bbar flavours enum Flavour { Bbar = -1, //< Bbar flavour Unknown = 0, //< Unknown flavour B = +1 //< B flavour }; //! Define different types of background to control the behaviour for each source // Might want to move this somewhere more general later enum BkgndType { SignalLike = 0, Combinatorial = 1 }; //! Constructor /*! \param [in] useAveDelta use average and delta variables for tagging calibration and efficiency \param [in] useEtaPrime use eta prime rather the eta as the mistag throughout \param [in] bkgndInfo map containing names and types of the background sources (if applicable) */ LauFlavTag(const Bool_t useAveDelta = kFALSE, const Bool_t useEtaPrime = kFALSE, const std::map bkgndInfo={}); //! Initialise // TODO is this needed? Commented for the moment (here and where called in LauTimeDepFitModel) //void initialise(); // TODO - need to decide which functions need to be public (interface) and which should be private (implementation details) //! Change the dilutions, delta dilutions and tagCatFrac for signal if needed /*! \param [in] name the name of the tagger \param [in] tagVarName the tagging variable name of the tagger in the ntuple \param [in] mistagVarName the associated mistag variable name of the same tagger in the ntuple \param [in] etapdf the mistag distribution for the tagger \param [in] tagEff tagging efficiency - (particle, antiparticle) or (average, delta) depending on useAveDelta_ flag \param [in] calib_p0 calibration parameter p0 - (particle, antiparticle) or (average, delta) depending on useAveDelta_ flag \param [in] calib_p1 calibration parameter p1 - (particle, antiparticle) or (average, delta) depending on useAveDelta_ flag */ void addTagger(const TString& name, const TString& tagVarName, const TString& mistagVarName, LauAbsPdf* etapdf, const std::pair tagEff, const std::pair calib_p0, const std::pair calib_p1); //! Change the dilutions, delta dilutions and tagCatFrac for signal if needed /*! \param [in] name the name of the tagger \param [in] tagVarName the tagging variable name of the tagger in the ntuple \param [in] mistagVarName the associated mistag variable name of the same tagger in the ntuple \param [in] etapdf the mistag distribution for the tagger \param [in] tagEff tagging efficiency histograms - (particle, antiparticle) or (average, delta) depending on useAveDelta_ flag \param [in] calib_p0 calibration parameter p0 - (particle, antiparticle) or (average, delta) depending on useAveDelta_ flag \param [in] calib_p1 calibration parameter p1 - (particle, antiparticle) or (average, delta) depending on useAveDelta_ flag */ void addTagger(const TString& name, const TString& tagVarName, const TString& mistagVarName, LauAbsPdf* etapdf, const std::pair tagEff, const std::pair calib_p0, const std::pair calib_p1); //! Read in the input fit data variables, e.g. m13Sq and m23Sq void cacheInputFitVars(LauFitDataTree* inputFitData, const TString& decayTimeVarName=""); void generateEventInfo(const Flavour trueTagFlv, const Double_t curEvtDecayTime); void generateBkgndEventInfo(const Flavour trueTagFlv, const Double_t curEvtDecayTime, const ULong_t bkgndID); void updateEventInfo(const ULong_t iEvt); const std::vector& getTagVarNames() const {return tagVarNames_;}; const std::vector& getMistagVarNames() const {return mistagVarNames_;}; const TString& getTrueTagVarName() const {return trueTagVarName_;}; const TString& getDecayFlvVarName() const {return decayFlvVarName_;}; Flavour getCurEvtTrueTagFlv() const {return curEvtTrueTagFlv_;}; Flavour getCurEvtDecayFlv() const {return curEvtDecayFlv_;}; const std::vector& getCurEvtTagFlv() const {return curEvtTagFlv_;}; const std::vector& getCurEvtMistag() const {return curEvtMistag_;}; ULong_t getNTaggers() const {return tagVarNames_.size();} //! Get vector of calibration parameters for each tagging category std::vector getCalibP0B0(){return calib_p0_B0_;}; std::vector getCalibP0B0bar(){return calib_p0_B0bar_;}; std::vector getCalibP1B0(){return calib_p1_B0_;}; std::vector getCalibP1B0bar(){return calib_p1_B0bar_;}; //! Get vector of alternative calibration parameters for each tagging category std::vector getCalibP0Ave(){return calib_p0_ave_;}; std::vector getCalibP0Delta(){return calib_p0_delta_;}; std::vector getCalibP1Ave(){return calib_p1_ave_;}; std::vector getCalibP1Delta(){return calib_p1_delta_;}; //! Get vector of tagging efficiency parameters for each tagging category std::vector getTagEffAve(){return tagEff_ave_;}; std::vector getTagEffDelta(){return tagEff_delta_;}; std::vector getTagEffB0(){return tagEff_B0_;}; std::vector getTagEffB0bar(){return tagEff_B0bar_;}; //! Get 2D vector of background tagging efficiency parameters for each tagger (inner vec) and background source (outer vec) std::vector> getTagEffBkgndAve(){return tagEffBkgnd_ave_;}; std::vector> getTagEffBkgndDelta(){return tagEffBkgnd_delta_;}; std::vector> getTagEffBkgndB0(){return tagEffBkgnd_B0_;}; std::vector> getTagEffBkgndB0bar(){return tagEffBkgnd_B0bar_;}; //! Set some things for backgrounds //! Set background eta PDF for a given background and given tagger /*! \param [in] bkgndID background identifier number \param [in] taggerName name of the tagger \param [in] etaPdf the eta PDF itself \param [in] tagEff the tagging efficiency parameters */ void setBkgndParams(const TString& bkgndName, const TString& taggerName, LauAbsPdf* etaPdf, std::pair tagEff); //! Set background eta PDF for a given background and given tagger /*! \param [in] bkgndID background identifier number \param [in] taggerName name of the tagger \param [in] etaPdf the eta PDF itself \param [in] tagEff the tagging efficiency histograms */ void setBkgndParams(const TString& bkgndName, const TString& taggerName, LauAbsPdf* etaPdf, std::pair tagEff); const std::vector& getPerEvtAvgMistag() const {return perEvtAvgMistag_;}; //! Returns little omega (calibrated mistag) /*! \param [in] position index of the background source in the background vector(s) \param [in] flag choose to calculate omega or omegabar (corrsonding to B or Bbar) */ Double_t getLittleOmega(const ULong_t position, const Flavour flag) const; //! Capital Omega for signal decays /*! \param [in] position index of the background source in the background vector(s) \param [in] flag choose to calculate Omega or Omegabar (corrsonding to B or Bbar) */ Double_t getCapitalOmega(const ULong_t position, const Flavour flag) const; //! Capital Omega for backgrounds /*! \param [in] position index of the background source in the background vector(s) \param [in] flag choose to calculate Omega or Omegabar (corrsonding to B or Bbar) \param [in] type the background type */ Double_t getCapitalOmegaBkgnd(const ULong_t position, const Flavour flag, const UInt_t classID) const; Double_t getEtaGen(const ULong_t position); Double_t getEtaGenBkgnd(const ULong_t position, const ULong_t bkgndID); //! Return the Boolean controlling if we use the alternative tagging calibration parameters Bool_t getUseAveDelta() const {return useAveDelta_;}; void setTrueTagVarName(TString trueTagVarName); void setDecayFlvVarName(TString decayFlvVarName); //! Gaussian constraints for P0 parameters for a given tagger /*! \param [in] name name of the tagger \param [in] constraint1 the (mean, sigma) for the particle or average parameter \param [in] constraint2 the (mean, sigma) for the antiparticle or delta parameter */ void addP0GaussianConstraints(const TString name, const std::pair constraint1, const std::pair constraint2); //! Gaussian constraints for P1 parameters for a given tagger /*! \param [in] name name of the tagger \param [in] constraint1 the (mean, sigma) for the particle or average parameter \param [in] constraint2 the (mean, sigma) for the antiparticle or delta parameter */ void addP1GaussianConstraints(const TString name, const std::pair constraint1, const std::pair constraint2); //! Gaussian constraints for tagging efficiency parameters for a given tagger /*! \param [in] name name of the tagger \param [in] constraint1 the (mean, sigma) for the particle or average parameter \param [in] constraint2 the (mean, sigma) for the antiparticle or delta parameter */ void addTagEffGaussianConstraints(const TString name, const std::pair constraint1, const std::pair constraint2); const std::vector getBkgndNames(){return bkgndNames_;}; const std::vector getBkgndTypes(){return bkgndTypes_;}; + //! Float the P0 calibration parameters for B tags + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP0B0(const TString name = ""); + + //! Float the P0 calibration parameters for Bbar tags + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP0B0bar(const TString name = ""); + + //! Float the P1 calibration parameters for B tags + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP1B0(const TString name = ""); + + //! Float the P1 calibration parameters for Bbar tags + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP1B0bar(const TString name = ""); + + //! Float the P0 average calibration parameters + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP0Ave(const TString name = ""); + + //! Float the P0 delta calibration parameters + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP0Delta(const TString name = ""); + + //! Float the P1 average calibration parameters + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP1Ave(const TString name = ""); + + //! Float the P1 delta calibration parameters + /*! + \param [in] name name of the tagger, defaults to empty to float for all taggers + */ + void floatCalibParP1Delta(const TString name = ""); + + //! Float all calibration parameters + void floatAllCalibPars(); + protected: //! Internal function to extend vectors void extendVectors(const TString& tagVarName, const TString& mistagVarName); //! Internal function to setup Calib parameters void setupCalibParams(const TString& name, const ULong_t position, const std::pair calib_p0, const std::pair calib_p1); private: //! Flag to use alternative calibration parameters const Bool_t useAveDelta_; //! Flag to use eta prime not eta for the mistag const Bool_t useEtaPrime_; //! Map to link taggers to their vector position std::map taggerPosition_; //! Flavour tagging variable name std::vector tagVarNames_; //! Per event mistag variable name std::vector mistagVarNames_; //! True tag variable name for normalisation decays TString trueTagVarName_; //! Decay flavour tag variable name for normalisation decays TString decayFlvVarName_; //! Vector of background names std::vector bkgndNames_; //! Vector of background types std::vector bkgndTypes_; //! Vector of flavour tags for each event std::vector> evtTagFlv_; //! Flavour tag for current event std::vector curEvtTagFlv_; //! Vector of mistags for each event std::vector> evtMistag_; //! Per event mistag for current event std::vector curEvtMistag_; //! Vector of true tags for each event std::vector evtTrueTagFlv_; //! Vector of decay tags for each event std::vector evtDecayFlv_; //! True tag from normalisation mode for current event Flavour curEvtTrueTagFlv_{Unknown}; //! True tag from normalisation mode for current event Flavour curEvtDecayFlv_{Unknown}; //! Per-event average mistag value (eta hat) std::vector perEvtAvgMistag_; //! Decay time values for each event std::vector evtDecayTime_; //! Decay time value of the current event Double_t curEvtDecayTime_; //! Calibration parameters std::vector calib_p0_B0_; std::vector calib_p0_B0bar_; std::vector calib_p1_B0_; std::vector calib_p1_B0bar_; //! Alternative calibration parameters std::vector calib_p0_ave_; std::vector calib_p0_delta_; std::vector calib_p1_ave_; std::vector calib_p1_delta_; //! Tagging efficiency parameters std::vector tagEff_B0_; std::vector tagEff_B0bar_; std::vector tagEff_ave_; std::vector tagEff_delta_; //! Tagging efficiency histograms std::vector tagEff_hist_B0_; std::vector tagEff_hist_B0bar_; std::vector tagEff_hist_ave_; std::vector tagEff_hist_delta_; //! Tagging efficiency parameters for backgrounds std::vector> tagEffBkgnd_B0_; std::vector> tagEffBkgnd_B0bar_; std::vector> tagEffBkgnd_ave_; std::vector> tagEffBkgnd_delta_; //! Tagging efficiency histograms for backgrounds std::vector> tagEffBkgnd_hist_B0_; std::vector> tagEffBkgnd_hist_B0bar_; std::vector> tagEffBkgnd_hist_ave_; std::vector> tagEffBkgnd_hist_delta_; //! Eta PDFs std::vector etaPdfs_; //! Eta PDFs for backgrounds per tagger (inner vec) and per background source (outer vec) std::vector> etaBkgndPdfs_; ClassDef(LauFlavTag,0) // Flavour tagging set up }; #endif diff --git a/src/LauFlavTag.cc b/src/LauFlavTag.cc index 0353d88..fac268a 100644 --- a/src/LauFlavTag.cc +++ b/src/LauFlavTag.cc @@ -1,911 +1,1101 @@ /* 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 "TMath.h" #include "TString.h" #include "TSystem.h" #include "Lau1DHistPdf.hh" #include "LauAbsPdf.hh" #include "LauFlavTag.hh" #include "LauRandom.hh" ClassImp(LauFlavTag) LauFlavTag::LauFlavTag(const Bool_t useAveDelta, const Bool_t useEtaPrime, const std::map bkgndInfo) : useAveDelta_(useAveDelta), useEtaPrime_(useEtaPrime) { // Put map values into vectors for (const auto &bkgnd : bkgndInfo){ bkgndNames_.push_back(bkgnd.first); bkgndTypes_.push_back(bkgnd.second); std::cout<< "INFO in LauFlavTag::LauFlavTag : adding background " << bkgnd.first << " of type " << bkgnd.second < 0){ if (!useAveDelta_){ tagEffBkgnd_B0_.clear(); tagEffBkgnd_B0_.resize(nBkgnds); tagEffBkgnd_B0bar_.clear(); tagEffBkgnd_B0bar_.resize(nBkgnds); tagEffBkgnd_hist_B0_.clear(); tagEffBkgnd_hist_B0_.resize(nBkgnds); tagEffBkgnd_hist_B0bar_.clear(); tagEffBkgnd_hist_B0bar_.resize(nBkgnds); } else { tagEffBkgnd_ave_.clear(); tagEffBkgnd_ave_.resize(nBkgnds); tagEffBkgnd_delta_.clear(); tagEffBkgnd_delta_.resize(nBkgnds); tagEffBkgnd_hist_ave_.clear(); tagEffBkgnd_hist_ave_.resize(nBkgnds); tagEffBkgnd_hist_delta_.clear(); tagEffBkgnd_hist_delta_.resize(nBkgnds); } etaBkgndPdfs_.clear(); etaBkgndPdfs_.resize(nBkgnds); } } void LauFlavTag::addTagger(const TString& name, const TString& tagVarName, const TString& mistagVarName, LauAbsPdf* etapdf, const std::pair tagEff, const std::pair calib_p0, const std::pair calib_p1) { // Check that we don't already have a tagger with the same name if ( taggerPosition_.find(name) != taggerPosition_.end() ) { std::cerr << "ERROR in LauFlavTag::addTagger : tagger called " << name << " already added" << std::endl; gSystem->Exit(EXIT_FAILURE); } // Check that the PDF pointer is valid if ( not etapdf ) { std::cerr << "ERROR in LauFlavTag::addTagger : Eta PDF pointer is NULL" << std::endl; gSystem->Exit(EXIT_FAILURE); } // Find how many taggers have already been added const ULong_t position { tagVarNames_.size() }; // Update map to relate tagger name and position in the vectors taggerPosition_[name] = position; // Extend vectors this->extendVectors(tagVarName, mistagVarName); etaPdfs_.push_back(etapdf); Lau1DHistPdf* etahistpdf = dynamic_cast(etapdf); if (etahistpdf){ perEvtAvgMistag_.push_back(etahistpdf->getMean()); } else { std::cerr << "WARNING in LauFlavTag::addTagger : Couldn't determine average eta value from PDF. Setting it to 0.4." << std::endl; perEvtAvgMistag_.push_back(0.4); } //Calib parameters this->setupCalibParams(name,position,calib_p0,calib_p1); //Tagging efficiencies if (!useAveDelta_){ TString tagEff_b0Name("tagEff_b0_"+name); TString tagEff_b0barName("tagEff_b0bar_"+name); LauParameter* tageffb0 = new LauParameter(tagEff_b0Name,tagEff.first,0.0,1.0,kTRUE); tagEff_B0_.push_back(tageffb0); tagEff_B0_[position]->initValue(tagEff.first); tagEff_B0_[position]->genValue(tagEff.first); tagEff_B0_[position]->fixed(kTRUE); //Update once full code in place if (tagEff.second==-1.0){ tagEff_B0bar_.push_back(tagEff_B0_[position]->createClone(tagEff_b0barName)); } else { LauParameter* tageffb0bar = new LauParameter(tagEff_b0barName,tagEff.second,0.0,1.0,kTRUE); tagEff_B0bar_.push_back(tageffb0bar); tagEff_B0bar_[position]->initValue(tagEff.second); tagEff_B0bar_[position]->genValue(tagEff.second); tagEff_B0bar_[position]->fixed(kTRUE); //Update once full code in place } } else { //Use average and delta variables TString tagEff_aveName("tagEff_ave_"+name); TString tagEff_deltaName("tagEff_delta_"+name); LauParameter* tageffave = new LauParameter(tagEff_aveName,tagEff.first,0.0,1.0,kTRUE); tagEff_ave_.push_back(tageffave); tagEff_ave_[position]->initValue(tagEff.first); tagEff_ave_[position]->genValue(tagEff.first); tagEff_ave_[position]->fixed(kTRUE); //Update once full code in place LauParameter* tageffdelta = new LauParameter(tagEff_deltaName,tagEff.second,-1.0,1.0,kTRUE); tagEff_delta_.push_back(tageffdelta); tagEff_delta_[position]->initValue(tagEff.second); tagEff_delta_[position]->genValue(tagEff.second); tagEff_delta_[position]->fixed(kTRUE); //Update once full code in place } std::cout<<"INFO in LauFlavTag::addTagger : Added tagger with name "<< name << std::endl; } void LauFlavTag::addTagger(const TString& name, const TString& tagVarName, const TString& mistagVarName, LauAbsPdf* etapdf, const std::pair tagEff, const std::pair calib_p0, const std::pair calib_p1) { // Check that we don't already have a tagger with the same name if ( taggerPosition_.find(name) != taggerPosition_.end() ) { std::cerr << "ERROR in LauFlavTag::addTagger : tagger called " << name << " already added" << std::endl; gSystem->Exit(EXIT_FAILURE); } // Check that the PDF pointer is valid if ( not etapdf ) { std::cerr << "ERROR in LauFlavTag::addTagger : Eta PDF pointer is NULL" << std::endl; gSystem->Exit(EXIT_FAILURE); } // Find how many taggers have already been added const ULong_t position { tagVarNames_.size() }; // Update map to relate tagger name and position in the vectors taggerPosition_[name] = position; // Extend vectors this->extendVectors(tagVarName, mistagVarName); etaPdfs_.push_back(etapdf); Lau1DHistPdf* etahistpdf = dynamic_cast(etapdf); if (etahistpdf){ perEvtAvgMistag_.push_back(etahistpdf->getMean()); } else { std::cerr << "WARNING in LauFlavTag::addTagger : Couldn't determine average eta value from PDF. Setting it to 0.4." << std::endl; perEvtAvgMistag_.push_back(0.4); } //Calib parameters this->setupCalibParams(name,position,calib_p0,calib_p1); //Tagging efficiencies if (!useAveDelta_){ tagEff_hist_B0_.push_back(tagEff.first); tagEff_B0_.push_back(nullptr); if (tagEff.second==nullptr){ tagEff_hist_B0bar_.push_back(tagEff.first); tagEff_B0bar_.push_back(nullptr); } else { tagEff_hist_B0bar_.push_back(tagEff.second); tagEff_B0bar_.push_back(nullptr); } } else { //Use average and delta variables tagEff_hist_ave_.push_back(tagEff.first); tagEff_hist_delta_.push_back(tagEff.second); tagEff_ave_.push_back(nullptr); tagEff_delta_.push_back(nullptr); } std::cout<<"INFO in LauFlavTag::addTagger : Added tagger with name "<< name << std::endl; } void LauFlavTag::extendVectors(const TString& tagVarName, const TString& mistagVarName){ tagVarNames_.push_back(tagVarName); mistagVarNames_.push_back(mistagVarName); curEvtTagFlv_.push_back(Flavour::Unknown); curEvtMistag_.push_back(Flavour::Unknown); if (bkgndNames_.size()>0){ if (!useAveDelta_){ //Loop over the outer vector and extend the inner vectors for (auto& innerVec : tagEffBkgnd_B0_){ innerVec.push_back(nullptr); } for (auto& innerVec : tagEffBkgnd_hist_B0_){ innerVec.push_back(nullptr); } for (auto& innerVec : tagEffBkgnd_B0bar_){ innerVec.push_back(nullptr); } for (auto& innerVec : tagEffBkgnd_hist_B0bar_){ innerVec.push_back(nullptr); } } else { //Loop over the outer vector and extend the inner vectors for (auto& innerVec : tagEffBkgnd_ave_){ innerVec.push_back(nullptr); } for (auto& innerVec : tagEffBkgnd_hist_ave_){ innerVec.push_back(nullptr); } for (auto& innerVec : tagEffBkgnd_delta_){ innerVec.push_back(nullptr); } for (auto& innerVec : tagEffBkgnd_hist_delta_){ innerVec.push_back(nullptr); } } for (auto& innerVec : etaBkgndPdfs_){ innerVec.push_back(nullptr); } } } void LauFlavTag::setupCalibParams(const TString& name, const ULong_t position, const std::pair calib_p0, const std::pair calib_p1) { if (!useAveDelta_){ TString calib_p0_b0Name("calib_p0_b0_"+name); TString calib_p0_b0barName("calib_p0_b0bar_"+name); TString calib_p1_b0Name("calib_p1_b0_"+name); TString calib_p1_b0barName("calib_p1_b0bar_"+name); LauParameter* calibp0b0 = new LauParameter(calib_p0_b0Name,calib_p0.first,-10.0,10.0,kTRUE); calib_p0_B0_.push_back(calibp0b0); calib_p0_B0_[position]->initValue(calib_p0.first); calib_p0_B0_[position]->genValue(calib_p0.first); calib_p0_B0_[position]->fixed(kTRUE); //Update once full code in place LauParameter* calibp1b0 = new LauParameter(calib_p1_b0Name,calib_p1.first,0.0,1.5,kTRUE); calib_p1_B0_.push_back(calibp1b0); calib_p1_B0_[position]->initValue(calib_p1.first); calib_p1_B0_[position]->genValue(calib_p1.first); calib_p1_B0_[position]->fixed(kTRUE); //Update once full code in place if (calib_p0.second==-1.0 && calib_p1.second==-1.0){ calib_p0_B0bar_.push_back(calib_p0_B0_[position]->createClone(calib_p0_b0barName)); calib_p1_B0bar_.push_back(calib_p1_B0_[position]->createClone(calib_p1_b0barName)); } else { LauParameter* calibp0b0bar = new LauParameter(calib_p0_b0barName,calib_p0.second,-10.0,10.0,kTRUE); calib_p0_B0bar_.push_back(calibp0b0bar); calib_p0_B0bar_[position]->initValue(calib_p0.second); calib_p0_B0bar_[position]->genValue(calib_p0.second); calib_p0_B0bar_[position]->fixed(kTRUE); //Update once full code in place LauParameter* calibp1b0bar = new LauParameter(calib_p1_b0barName,calib_p1.second,0.0,1.5,kTRUE); calib_p1_B0bar_.push_back(calibp1b0bar); calib_p1_B0bar_[position]->initValue(calib_p1.second); calib_p1_B0bar_[position]->genValue(calib_p1.second); calib_p1_B0bar_[position]->fixed(kTRUE); //Update once full code in place } } else { //Use average and delta variables TString calib_p0_aveName("calib_p0_ave_"+name); TString calib_p0_deltaName("calib_p0_delta_"+name); TString calib_p1_aveName("calib_p1_ave_"+name); TString calib_p1_deltaName("calib_p1_delta_"+name); LauParameter* calibp0ave = new LauParameter(calib_p0_aveName,calib_p0.first,-10.0,10.0,kTRUE); calib_p0_ave_.push_back(calibp0ave); calib_p0_ave_[position]->initValue(calib_p0.first); calib_p0_ave_[position]->genValue(calib_p0.first); calib_p0_ave_[position]->fixed(kTRUE); //Update once full code in place LauParameter* calibp1ave = new LauParameter(calib_p1_aveName,calib_p1.first,0.0,1.5,kTRUE); calib_p1_ave_.push_back(calibp1ave); calib_p1_ave_[position]->initValue(calib_p1.first); calib_p1_ave_[position]->genValue(calib_p1.first); calib_p1_ave_[position]->fixed(kTRUE); //Update once full code in place LauParameter* calibp0delta = new LauParameter(calib_p0_deltaName,calib_p0.second,-10.0,10.0,kTRUE); calib_p0_delta_.push_back(calibp0delta); calib_p0_delta_[position]->initValue(calib_p0.second); calib_p0_delta_[position]->genValue(calib_p0.second); calib_p0_delta_[position]->fixed(kTRUE); //Update once full code in place LauParameter* calibp1delta = new LauParameter(calib_p1_deltaName,calib_p1.second,-10.0,10.0,kTRUE); calib_p1_delta_.push_back(calibp1delta); calib_p1_delta_[position]->initValue(calib_p1.second); calib_p1_delta_[position]->genValue(calib_p1.second); calib_p1_delta_[position]->fixed(kTRUE); //Update once full code in place } } void LauFlavTag::cacheInputFitVars(LauFitDataTree* inputFitData, const TString& decayTimeVarName) { evtTagFlv_.clear(); evtMistag_.clear(); evtTrueTagFlv_.clear(); evtDecayFlv_.clear(); evtDecayTime_.clear(); // Loop over the taggers to check the branches for (ULong_t i=0; i < tagVarNames_.size(); ++i){ if ( not inputFitData->haveBranch( tagVarNames_[i] ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << tagVarNames_[i] << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } if ( not inputFitData->haveBranch( mistagVarNames_[i] ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << mistagVarNames_[i] << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } } if ( trueTagVarName_ != "" and not inputFitData->haveBranch( trueTagVarName_ ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << trueTagVarName_ << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } if ( decayFlvVarName_ != "" and not inputFitData->haveBranch( decayFlvVarName_ ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << decayFlvVarName_ << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } if ( decayTimeVarName != "" and not inputFitData->haveBranch( decayTimeVarName ) ) { std::cerr << "ERROR in LauFlavTag::cacheInputFitVars : Input data does not contain branch \"" << decayTimeVarName << "\"." << std::endl; gSystem->Exit(EXIT_FAILURE); } const ULong_t nEvents { inputFitData->nEvents() }; evtTagFlv_.reserve( nEvents ); evtMistag_.reserve( nEvents ); evtTrueTagFlv_.reserve( nEvents ); evtDecayFlv_.reserve( nEvents ); evtDecayTime_.reserve( nEvents ); LauFitData::const_iterator fitdata_iter; for (ULong_t iEvt = 0; iEvt < nEvents; iEvt++) { const LauFitData& dataValues = inputFitData->getData(iEvt); // For untagged events see if we have a truth tag for normalisation modes Int_t curEvtTrueTagFlv { ( trueTagVarName_ != "" ) ? static_cast( dataValues.at( trueTagVarName_ ) ) : 0 }; if ( curEvtTrueTagFlv > 1 ) { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid true tag value " << curEvtTrueTagFlv << " for event " << iEvt << ", setting it to +1" << std::endl; curEvtTrueTagFlv = +1; } else if ( curEvtTrueTagFlv < -1 ){ std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid true tag value " << curEvtTrueTagFlv << " for event " << iEvt << ", setting it to -1" << std::endl; curEvtTrueTagFlv = -1; } curEvtTrueTagFlv_ = static_cast(curEvtTrueTagFlv); evtTrueTagFlv_.push_back(curEvtTrueTagFlv_); // Flavour at decay Int_t curEvtDecayFlv { ( decayFlvVarName_ != "" ) ? static_cast( dataValues.at( decayFlvVarName_ ) ) : 0 }; if ( curEvtDecayFlv > 1 ) { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid decay flavour value " << curEvtDecayFlv << " for event " << iEvt << ", setting it to +1" << std::endl; curEvtDecayFlv = +1; } else if ( curEvtDecayFlv < -1 ){ std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid decay flavour value " << curEvtDecayFlv << " for event " << iEvt << ", setting it to -1" << std::endl; curEvtDecayFlv = -1; } curEvtDecayFlv_ = static_cast(curEvtDecayFlv); evtDecayFlv_.push_back(curEvtDecayFlv_); for (ULong_t i=0; i < tagVarNames_.size(); ++i){ Int_t curEvtTagFlv { static_cast( dataValues.at( tagVarNames_[i] ) ) }; if ( curEvtTagFlv > 1 ) { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid tagging output " << curEvtTagFlv << " for event " << iEvt << ", setting it to +1" << std::endl; curEvtTagFlv = +1; } else if ( curEvtTagFlv < -1 ) { std::cerr << "WARNING in LauFlavTag::cacheInputFitVars : Invalid tagging output " << curEvtTagFlv << " for event " << iEvt << ", setting it to -1" << std::endl; curEvtTagFlv = -1; } curEvtTagFlv_[i] = static_cast( curEvtTagFlv ); curEvtMistag_[i] = static_cast( dataValues.at( mistagVarNames_[i] ) ); // Calibrated mistag > 0.5 is just a tag flip - handled automatically in getCapitalOmega function if (curEvtMistag_[i] > 0.5){ std::cerr<<"WARNING in LauFlavTag::cacheInputFitVars : Mistag value "<( dataValues.at( decayTimeVarName ) ); evtDecayTime_.push_back(curEvtDecayTime_); } } void LauFlavTag::updateEventInfo(const ULong_t iEvt) { //Assign current event variables curEvtTagFlv_ = evtTagFlv_[iEvt]; curEvtMistag_ = evtMistag_[iEvt]; curEvtTrueTagFlv_ = evtTrueTagFlv_[iEvt]; curEvtDecayFlv_ = evtDecayFlv_[iEvt]; curEvtDecayTime_ = evtDecayTime_[iEvt]; } void LauFlavTag::generateEventInfo(const Flavour trueTagFlv, const Double_t curEvtDecayTime) { curEvtTrueTagFlv_ = trueTagFlv; curEvtDecayFlv_ = Flavour::Unknown; curEvtDecayTime_ = curEvtDecayTime; Double_t randNo{0.0}; Double_t tagEffB0{0.0}; Double_t tagEffB0bar{0.0}; const ULong_t nTaggers { this->getNTaggers() }; for ( ULong_t position{0}; positiongetEtaGen(position); if (this->getUseAveDelta()) { if (tagEff_ave_[position]==nullptr){ const Double_t ave = tagEff_hist_ave_[position]->GetBinContent(tagEff_hist_ave_[position]->FindFixBin(curEvtDecayTime_)); const Double_t delta = tagEff_hist_delta_[position]->GetBinContent(tagEff_hist_delta_[position]->FindFixBin(curEvtDecayTime_)); tagEffB0 = ave + 0.5 * delta; tagEffB0bar = ave - 0.5 * delta; } else { tagEffB0 = tagEff_ave_[position]->unblindValue() + 0.5 * tagEff_delta_[position]->unblindValue(); tagEffB0bar = tagEff_ave_[position]->unblindValue() - 0.5 * tagEff_delta_[position]->unblindValue(); } } else { if (tagEff_B0_[position]==nullptr){ tagEffB0 = tagEff_hist_B0_[position]->GetBinContent(tagEff_hist_B0_[position]->FindFixBin(curEvtDecayTime_)); tagEffB0bar = tagEff_hist_B0bar_[position]->GetBinContent(tagEff_hist_B0bar_[position]->FindFixBin(curEvtDecayTime_)); } else { tagEffB0 = tagEff_B0_[position]->unblindValue(); tagEffB0bar = tagEff_B0bar_[position]->unblindValue(); } } if (curEvtTrueTagFlv_ == Flavour::B) { randNo = LauRandom::randomFun()->Rndm(); // Try to tag in tageff% of cases if (randNo <= tagEffB0) { randNo = LauRandom::randomFun()->Rndm(); // Account for (calibrated) mistag if (randNo > this->getLittleOmega(position, Flavour::B)){ curEvtTagFlv_[position] = Flavour::B; } else { curEvtTagFlv_[position] = Flavour::Bbar; } } else { curEvtTagFlv_[position] = Flavour::Unknown; } } else if (curEvtTrueTagFlv_ == Flavour::Bbar) { randNo = LauRandom::randomFun()->Rndm(); // Try to tag in tageff% of cases if (randNo <= tagEffB0bar) { randNo = LauRandom::randomFun()->Rndm(); // Account for (calibrated) mistag if (randNo > this->getLittleOmega(position, Flavour::Bbar)){ curEvtTagFlv_[position] = Flavour::Bbar; } else { curEvtTagFlv_[position] = Flavour::B; } } else { curEvtTagFlv_[position] = Flavour::Unknown; } } else { std::cerr << "ERROR in LauFlavTag::generateEventInfo : Invalid true tag flavour, should be either B (+1) or Bbar (-1)" << std::endl; gSystem->Exit(EXIT_FAILURE); } } } void LauFlavTag::generateBkgndEventInfo(const Flavour trueTagFlv, const Double_t curEvtDecayTime, const ULong_t bkgndID) { if (bkgndID < 0 || bkgndID > bkgndNames_.size()){ std::cerr << "ERROR in LauFlavTag::generateBkgndEventInfo : Invalid backgrond class identifier" << std::endl; gSystem->Exit(EXIT_FAILURE); } curEvtTrueTagFlv_ = trueTagFlv; curEvtDecayFlv_ = Flavour::Unknown; curEvtDecayTime_ = curEvtDecayTime; Double_t randNo{0.0}; Double_t tagEffB0{0.0}; Double_t tagEffB0bar{0.0}; const ULong_t nTaggers { this->getNTaggers() }; for ( ULong_t position{0}; positiongetEtaGenBkgnd(position,bkgndID); //TODO If bkgnd is signal like should these parameters be clones of signal TagEff etc? //TODO Or call generateEventInfo() instead? if (this->getUseAveDelta()) { if (tagEffBkgnd_ave_[bkgndID][position]==nullptr){ const Double_t ave = tagEffBkgnd_hist_ave_[bkgndID][position]->GetBinContent(tagEffBkgnd_hist_ave_[bkgndID][position]->FindFixBin(curEvtDecayTime_)); const Double_t delta = tagEffBkgnd_hist_delta_[bkgndID][position]->GetBinContent(tagEffBkgnd_hist_delta_[bkgndID][position]->FindFixBin(curEvtDecayTime_)); tagEffB0 = ave + 0.5 * delta; tagEffB0bar = ave - 0.5 * delta; } else { tagEffB0 = tagEffBkgnd_ave_[bkgndID][position]->unblindValue() + 0.5 * tagEffBkgnd_delta_[bkgndID][position]->unblindValue(); tagEffB0bar = tagEffBkgnd_ave_[bkgndID][position]->unblindValue() - 0.5 * tagEffBkgnd_delta_[bkgndID][position]->unblindValue(); } } else { if (tagEffBkgnd_B0_[bkgndID][position]==nullptr){ tagEffB0 = tagEffBkgnd_hist_B0_[bkgndID][position]->GetBinContent(tagEffBkgnd_hist_B0_[bkgndID][position]->FindFixBin(curEvtDecayTime_)); tagEffB0bar = tagEffBkgnd_hist_B0bar_[bkgndID][position]->GetBinContent(tagEffBkgnd_hist_B0bar_[bkgndID][position]->FindFixBin(curEvtDecayTime_)); } else { tagEffB0 = tagEffBkgnd_B0_[bkgndID][position]->unblindValue(); tagEffB0bar = tagEffBkgnd_B0bar_[bkgndID][position]->unblindValue(); } } if (curEvtTrueTagFlv_ == Flavour::B) { randNo = LauRandom::randomFun()->Rndm(); // Try to tag in tageff% of cases if (randNo <= tagEffB0) { randNo = LauRandom::randomFun()->Rndm(); // Account for mistag - use eta not littleOmega for now (littleOmega only for SignalLike bkgnd?) //if (randNo > this->getLittleOmega(position, Flavour::B)){ if (randNo > curEvtMistag_[position]){ curEvtTagFlv_[position] = Flavour::B; } else { curEvtTagFlv_[position] = Flavour::Bbar; } } else { curEvtTagFlv_[position] = Flavour::Unknown; } } else if (curEvtTrueTagFlv_ == Flavour::Bbar) { randNo = LauRandom::randomFun()->Rndm(); // Try to tag in tageff% of cases if (randNo <= tagEffB0bar) { randNo = LauRandom::randomFun()->Rndm(); // Account for (calibrated) mistag //if (randNo > this->getLittleOmega(position, Flavour::Bbar)){ if (randNo > curEvtMistag_[position]){ curEvtTagFlv_[position] = Flavour::Bbar; } else { curEvtTagFlv_[position] = Flavour::B; } } else { curEvtTagFlv_[position] = Flavour::Unknown; } } else { std::cerr << "ERROR in LauFlavTag::generateBkgndEventInfo : Invalid true tag flavour, should be either B (+1) or Bbar (-1)" << std::endl; gSystem->Exit(EXIT_FAILURE); } } } Double_t LauFlavTag::getLittleOmega(const ULong_t position, const Flavour flag) const { if ( flag == Flavour::Unknown ){ std::cerr << "ERROR in LauFlavTag::getLittleOmega : Invalid flag, you must request either omega (+1) or omega bar (-1) to be returned" << std::endl; return 0.0; } Double_t calibp0(0.), calibp1(0.), calibp0bar(0.), calibp1bar(0.); //If we are floating average omega and delta omega we need to use those parameters instead if (useAveDelta_){ calibp0 = calib_p0_ave_[position]->unblindValue() + 0.5*calib_p0_delta_[position]->unblindValue(); calibp0bar = calib_p0_ave_[position]->unblindValue() - 0.5*calib_p0_delta_[position]->unblindValue(); calibp1 = calib_p1_ave_[position]->unblindValue() + 0.5*calib_p1_delta_[position]->unblindValue(); calibp1bar = calib_p1_ave_[position]->unblindValue() - 0.5*calib_p1_delta_[position]->unblindValue(); } else { calibp0 = calib_p0_B0_[position]->unblindValue(); calibp0bar = calib_p0_B0bar_[position]->unblindValue(); calibp1 = calib_p1_B0_[position]->unblindValue(); calibp1bar = calib_p1_B0bar_[position]->unblindValue(); } if ( flag == Flavour::B ){ return calibp0 + calibp1 * (curEvtMistag_[position] - perEvtAvgMistag_[position]); } else{ return calibp0bar + calibp1bar * (curEvtMistag_[position] - perEvtAvgMistag_[position]); } return 0.0; } Double_t LauFlavTag::getCapitalOmega(const ULong_t position, const Flavour flag) const { if ( flag == Flavour::Unknown ){ std::cerr << "ERROR in LauFlavTag::getCapitalOmega : Invalid flag, you must request either Omega (+1) or Omega bar (-1) to be returned" << std::endl; return 0.0; } //Delta functions to control which terms contribute Int_t deltap1(0), deltam1(0), delta0(0); if (curEvtTagFlv_[position] == Flavour::Bbar){ deltam1 = 1; } else if(curEvtTagFlv_[position] == Flavour::B){ deltap1 = 1; } else{ delta0 = 1; } //Efficiency Double_t eff(0.0); if (useAveDelta_){ if(flag==Flavour::B){ if (tagEff_ave_[position]==nullptr){ eff = tagEff_hist_ave_[position]->GetBinContent(tagEff_hist_ave_[position]->FindFixBin(curEvtDecayTime_)) + 0.5*tagEff_hist_delta_[position]->GetBinContent(tagEff_hist_delta_[position]->FindFixBin(curEvtDecayTime_)); } else { eff = tagEff_ave_[position]->unblindValue() + 0.5*tagEff_delta_[position]->unblindValue(); } } else { if (tagEff_ave_[position]==nullptr){ eff = tagEff_hist_ave_[position]->GetBinContent(tagEff_hist_ave_[position]->FindFixBin(curEvtDecayTime_)) - 0.5*tagEff_hist_delta_[position]->GetBinContent(tagEff_hist_delta_[position]->FindFixBin(curEvtDecayTime_)); } else { eff = tagEff_ave_[position]->unblindValue() - 0.5*tagEff_delta_[position]->unblindValue(); } } }else{ if(flag==Flavour::B){ if (tagEff_B0_[position]==nullptr){ eff = tagEff_hist_B0_[position]->GetBinContent(tagEff_hist_B0_[position]->FindFixBin(curEvtDecayTime_)); } else { eff = tagEff_B0_[position]->unblindValue(); } }else{ if (tagEff_B0bar_[position]==nullptr){ eff = tagEff_hist_B0bar_[position]->GetBinContent(tagEff_hist_B0bar_[position]->FindFixBin(curEvtDecayTime_)); } else { eff = tagEff_B0bar_[position]->unblindValue(); } } } //Little omega Double_t omega = this->getLittleOmega(position, flag); Double_t omegaPrime(0.); //Transform to omega prime - TODO isn't this the inverse, getLittleOmega is actually giving us omegaPrime and on the next line we convert back to omega? if (useEtaPrime_){ omegaPrime = (1/(1+TMath::Exp(-1.0*omega))); }else{ omegaPrime = omega; } //little omega must be between 0 and 1. Force this for now, if the fits keep getting stuck can look more closely at it. if (omegaPrime < 0.0){ std::cerr << "WARNING in LauFlavTag::getCapitalOmega : The value of little omega is less than 0, shifting to 0" << std::endl; omegaPrime = 0.0; } if (omegaPrime > 1.0){ std::cerr << "WARNING in LauFlavTag::getCapitalOmega : The value of little omega is greater than 1, shifting to 1" << std::endl; omegaPrime = 1.0; } //eta PDF value std::vector abs; abs.push_back(curEvtMistag_[position]); etaPdfs_[position]->calcLikelihoodInfo(abs); Double_t h { etaPdfs_[position]->getLikelihood() }; const Double_t u { 2.0 }; // the PDF value for a uniform PDF between 0.0 and 0.5 //If h returns 0 for a tagged event, the event likelihood will be zero if (h==0 && delta0==0){ std::cerr << "WARNING in LauFlavTag::getCapitalOmega : The value of the eta PDF is zero at eta = " << curEvtMistag_[position] << ", shifting to 0.1" << std::endl; h=0.1; } //Put it together if (flag == Flavour::B){ return (deltap1*eff*(1-omegaPrime) + deltam1*eff*omegaPrime)*h + delta0*(1-eff)*u; } else { return (deltam1*eff*(1-omegaPrime) + deltap1*eff*omegaPrime)*h + delta0*(1-eff)*u; } } Double_t LauFlavTag::getCapitalOmegaBkgnd(const ULong_t position, const Flavour flag, const UInt_t classID) const { //Fill in with the various options of flag = +-1, type = signal-like, combinatorial etc if ( flag == Flavour::Unknown ){ std::cerr << "ERROR in LauFlavTag::getCapitalOmegaBkgnd : Invalid flag, you must request either Omega (+1) or Omega bar (-1) to be returned" << std::endl; return 0.0; } //Delta functions to control which terms contribute Int_t deltap1(0), deltam1(0), delta0(0); if (curEvtTagFlv_[position] == Flavour::Bbar){ deltam1 = 1; } else if(curEvtTagFlv_[position] == Flavour::B){ deltap1 = 1; } else{ delta0 = 1; } //Efficiency Double_t effB0(0.0), effB0bar(0.0); if (useAveDelta_){ if(flag==Flavour::B){ if (tagEffBkgnd_ave_[classID][position]==nullptr){ effB0 = tagEffBkgnd_hist_ave_[classID][position]->GetBinContent(tagEffBkgnd_hist_ave_[classID][position]->FindFixBin(curEvtDecayTime_)) + 0.5*tagEffBkgnd_hist_delta_[classID][position]->GetBinContent(tagEffBkgnd_hist_delta_[classID][position]->FindFixBin(curEvtDecayTime_)); } else { effB0 = tagEffBkgnd_ave_[classID][position]->unblindValue() + 0.5*tagEffBkgnd_delta_[classID][position]->unblindValue(); } } else { if (tagEffBkgnd_ave_[classID][position]==nullptr){ effB0bar = tagEffBkgnd_hist_ave_[classID][position]->GetBinContent(tagEffBkgnd_hist_ave_[classID][position]->FindFixBin(curEvtDecayTime_)) - 0.5*tagEffBkgnd_hist_delta_[classID][position]->GetBinContent(tagEffBkgnd_hist_delta_[classID][position]->FindFixBin(curEvtDecayTime_)); } else { effB0bar = tagEffBkgnd_ave_[classID][position]->unblindValue() - 0.5*tagEffBkgnd_delta_[classID][position]->unblindValue(); } } }else{ if(flag==Flavour::B){ if (tagEffBkgnd_B0_[classID][position]==nullptr){ effB0 = tagEffBkgnd_hist_B0_[classID][position]->GetBinContent(tagEffBkgnd_hist_B0_[classID][position]->FindFixBin(curEvtDecayTime_)); } else { effB0 = tagEffBkgnd_B0_[classID][position]->unblindValue(); } }else{ if (tagEffBkgnd_B0bar_[classID][position]==nullptr){ effB0bar = tagEffBkgnd_hist_B0bar_[classID][position]->GetBinContent(tagEffBkgnd_hist_B0bar_[classID][position]->FindFixBin(curEvtDecayTime_)); } else { effB0bar = tagEffBkgnd_B0bar_[classID][position]->unblindValue(); } } } //Need to know which background eta PDF to use - classID std::vector abs; abs.push_back(curEvtMistag_[position]); etaBkgndPdfs_[classID][position]->calcLikelihoodInfo(abs); Double_t h { etaBkgndPdfs_[classID][position]->getLikelihood() }; const Double_t u { 2.0 }; // the PDF value for a uniform PDF between 0.0 and 0.5 if (bkgndTypes_[classID] == BkgndType::Combinatorial){ return (deltap1*effB0 + deltam1*effB0bar)*h + delta0*(1.0 - 0.5*(effB0 + effB0bar))*u; } else { return 1.0; } } void LauFlavTag::setBkgndParams(const TString& bkgndName, const TString& taggerName, LauAbsPdf* etaPdf, std::pair tagEff) { if (taggerPosition_.count(taggerName)==0){ std::cerr << "ERROR in LauFlavTag::setBkgndParams : Tagger name not recognised please check your options" << std::endl; return; } Int_t bkgndID(-1); for (ULong_t i=0; iname("tagEff_ave_"+taggerName+"_bkgnd_"+bkgndName); tagEffBkgnd_ave_[bkgndID][position] = tagEffB0; tagEffB0bar->name("tagEff_delta_"+taggerName+"_bkgnd_"+bkgndName); tagEffB0bar->range(-1.0,1.0); tagEffBkgnd_delta_[bkgndID][position] = tagEffB0bar; } else { tagEffBkgnd_B0_[bkgndID][position] = tagEffB0; tagEffBkgnd_B0bar_[bkgndID][position] = tagEffB0bar; } std::cout << "INFO in LauFlavTag::setBkgndParams : Added efficiency parameters and eta PDF for background " << bkgndName << " for tagger " << taggerName << std::endl; } void LauFlavTag::setBkgndParams(const TString& bkgndName, const TString& taggerName, LauAbsPdf* etaPdf, std::pair tagEff) { if (taggerPosition_.count(taggerName)==0){ std::cerr << "ERROR in LauFlavTag::setBkgndParams : Tagger name not recognised please check your options" << std::endl; return; } if (tagEff.first==nullptr || tagEff.second==nullptr){ std::cerr << "ERROR in LauFlavTag::setBkgndParams : Efficiency histogram(s) do not exist please check your options" << std::endl; return; } Int_t bkgndID(-1); for (ULong_t i=0; igenerate(nullptr) }; //TODO Add DP dependence? Double_t etagen { data.at(etaPdfs_[position]->varName()) }; if (etagen > 0.5){etagen = 0.5;} if (etagen < 0.0){etagen = 0.0;} curEvtMistag_[position] = etagen; return etagen; } Double_t LauFlavTag::getEtaGenBkgnd(const ULong_t position, const ULong_t bkgndID) { LauFitData data { etaBkgndPdfs_[bkgndID][position]->generate(nullptr) }; //TODO Add DP dependence? Double_t etagen { data.at(etaBkgndPdfs_[bkgndID][position]->varName()) }; if (etagen > 0.5){etagen = 0.5;} if (etagen < 0.0){etagen = 0.0;} curEvtMistag_[position] = etagen; return etagen; } void LauFlavTag::setTrueTagVarName(TString trueTagVarName){ trueTagVarName_ = std::move(trueTagVarName); } void LauFlavTag::setDecayFlvVarName(TString decayFlvVarName){ decayFlvVarName_ = std::move(decayFlvVarName); } void LauFlavTag::addP0GaussianConstraints(TString name, std::pair constraint1, std::pair constraint2){ //Does key exist? if (taggerPosition_.count(name)==0){ std::cerr << "ERROR in LauFlavTag::addP0GaussianConstraints : Tagger name not recognised please check your options" << std::endl; std::cerr << "ERROR in LauFlavTag::addP0GaussianConstraints : Constraints have not been applied" << std::endl; return; } //Find position in the vector from the tagger name Double_t pos = taggerPosition_.at(name); if (!useAveDelta_){ calib_p0_B0_[pos]->addGaussianConstraint(constraint1.first,constraint1.second); calib_p0_B0bar_[pos]->addGaussianConstraint(constraint2.first,constraint2.second); }else{ calib_p0_ave_[pos]->addGaussianConstraint(constraint1.first,constraint1.second); calib_p0_delta_[pos]->addGaussianConstraint(constraint2.first,constraint2.second); } std::cout << "INFO in LauFlavTag::addP0GaussianConstraints : Added Gaussian constraints for the P0 calibration parameters of tagger " << name << std::endl; } void LauFlavTag::addP1GaussianConstraints(TString name, std::pair constraint1, std::pair constraint2){ //Does key exist? if (taggerPosition_.count(name)==0){ std::cerr << "ERROR in LauFlavTag::addP1GaussianConstraints : Tagger name not recognised please check your options" << std::endl; std::cerr << "ERROR in LauFlavTag::addP1GaussianConstraints : Constraints have not been applied" << std::endl; return; } //Find position in the vector from the tagger name Double_t pos = taggerPosition_.at(name); if (!useAveDelta_){ calib_p1_B0_[pos]->addGaussianConstraint(constraint1.first,constraint1.second); calib_p1_B0bar_[pos]->addGaussianConstraint(constraint2.first,constraint2.second); }else{ calib_p1_ave_[pos]->addGaussianConstraint(constraint1.first,constraint1.second); calib_p1_delta_[pos]->addGaussianConstraint(constraint2.first,constraint2.second); } std::cout << "INFO in LauFlavTag::addP1GaussianConstraints : Added Gaussian constraints for the P1 calibration parameters of tagger " << name << std::endl; } void LauFlavTag::addTagEffGaussianConstraints(TString name, std::pair constraint1, std::pair constraint2){ //Does key exist? if (taggerPosition_.count(name)==0){ std::cerr << "ERROR in LauFlavTag::addTagEffGaussianConstraints : Tagger name not recognised please check your options" << std::endl; std::cerr << "ERROR in LauFlavTag::addTagEffGaussianConstraints : Constraints have not been applied" << std::endl; return; } //Find position in the vector from the tagger name Double_t pos = taggerPosition_.at(name); if (!useAveDelta_){ tagEff_B0_[pos]->addGaussianConstraint(constraint1.first,constraint1.second); tagEff_B0bar_[pos]->addGaussianConstraint(constraint2.first,constraint2.second); }else{ tagEff_ave_[pos]->addGaussianConstraint(constraint1.first,constraint1.second); tagEff_delta_[pos]->addGaussianConstraint(constraint2.first,constraint2.second); } std::cout << "INFO in LauFlavTag::addTagEffGaussianConstraints : Added Gaussian constraints for the tagging efficiency parameters of tagger " << name << std::endl; } + +void LauFlavTag::floatCalibParP0B0(const TString name){ + if (useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0B0 : Trying to set calibration parameters for B0/B0bar not average/delta" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p0_B0_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0B0 : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p0_B0_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP1B0(const TString name){ + if (useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1B0 : Trying to set calibration parameters for B0/B0bar not average/delta" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p1_B0_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1B0 : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p1_B0_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP0B0bar(const TString name){ + if (useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0B0bar : Trying to set calibration parameters for B0/B0bar not average/delta" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p0_B0bar_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0B0bar : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p0_B0bar_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP1B0bar(const TString name){ + if (useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1B0bar : Trying to set calibration parameters for B0/B0bar not average/delta" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p1_B0bar_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1B0bar : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p1_B0bar_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP0Ave(const TString name){ + if (!useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0Ave : Trying to set calibration parameters for average/delta not B0/B0bar" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p0_ave_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0Ave : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p0_ave_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP0Delta(const TString name){ + if (!useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0Delta : Trying to set calibration parameters for average/delta not B0/B0bar" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p0_delta_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP0Delta : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p0_delta_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP1Ave(const TString name){ + if (!useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1Ave : Trying to set calibration parameters for average/delta not B0/B0bar" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p1_ave_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1Ave : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p1_ave_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatCalibParP1Delta(const TString name){ + if (!useAveDelta_){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1Delta : Trying to set calibration parameters for average/delta not B0/B0bar" << std::endl; + return; + } + if (name==""){ + for (auto& param : calib_p1_delta_){ + if (param==nullptr){continue;} + param->fixed(kFALSE); + } + } else { + //Does key exist? + if (taggerPosition_.count(name)==0){ + std::cerr << "ERROR in LauFlavTag::floatCalibParP1Delta : Tagger name not recognised please check your options" << std::endl; + return; + } + //Find position in the vector from the tagger name + Double_t position = taggerPosition_.at(name); + calib_p1_delta_[position]->fixed(kFALSE); + } +} + +void LauFlavTag::floatAllCalibPars(){ + if (useAveDelta_){ + this->floatCalibParP0Ave(); + this->floatCalibParP0Delta(); + this->floatCalibParP1Ave(); + this->floatCalibParP1Delta(); + } else { + this->floatCalibParP0B0(); + this->floatCalibParP1B0(); + this->floatCalibParP0B0bar(); + this->floatCalibParP1B0bar(); + } +}