From fe239d4efaa30480e86493eb6bc53309df8f2f72 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 24 Nov 2025 22:49:01 +0100 Subject: [PATCH] [RF][HF] Move all classes for Measurement specification to Measurement.h The Measurement uses several other helper classes, which are scattered in different header and implementation files. Merging these classes to one header and compilation unit has several advantages: * User only needs to include one header * Easier to get an overview on the structure of the Measurement class, which helps for refactoring and re-designing of HistFactor using the new ROOT histogram classes * Shorter compilation times There is no breaking of backwards compatibility, as the old header files are all kept around, just with no content. However, the headers are clearly deprecated with a warning that they are going to be removed in ROOT 7. --- roofit/histfactory/CMakeLists.txt | 14 - .../inc/RooStats/HistFactory/Asimov.h | 54 +- .../inc/RooStats/HistFactory/Channel.h | 110 +- .../inc/RooStats/HistFactory/ConfigParser.h | 2 - .../inc/RooStats/HistFactory/Data.h | 73 +- .../HistFactory/Detail/HistFactoryImpl.h | 2 +- .../inc/RooStats/HistFactory/HistRef.h | 81 +- .../HistFactory/HistoToWorkspaceFactoryFast.h | 2 +- .../inc/RooStats/HistFactory/Measurement.h | 882 ++++++- .../RooStats/HistFactory/PreprocessFunction.h | 40 +- .../inc/RooStats/HistFactory/Sample.h | 172 +- .../inc/RooStats/HistFactory/Systematics.h | 373 +-- roofit/histfactory/src/Asimov.cxx | 116 - roofit/histfactory/src/Channel.cxx | 488 ---- roofit/histfactory/src/Data.cxx | 74 - roofit/histfactory/src/HistRef.cxx | 37 - roofit/histfactory/src/Measurement.cxx | 2273 +++++++++++++---- roofit/histfactory/src/PreprocessFunction.cxx | 64 - roofit/histfactory/src/Sample.cxx | 436 ---- roofit/histfactory/src/Systematics.cxx | 327 --- roofit/histfactory/test/testHistFactory.cxx | 1 - .../test/testHistFactoryPlotting.cxx | 1 - 22 files changed, 2597 insertions(+), 3025 deletions(-) delete mode 100644 roofit/histfactory/src/Asimov.cxx delete mode 100644 roofit/histfactory/src/Channel.cxx delete mode 100644 roofit/histfactory/src/Data.cxx delete mode 100644 roofit/histfactory/src/HistRef.cxx delete mode 100644 roofit/histfactory/src/PreprocessFunction.cxx delete mode 100644 roofit/histfactory/src/Sample.cxx delete mode 100644 roofit/histfactory/src/Systematics.cxx diff --git a/roofit/histfactory/CMakeLists.txt b/roofit/histfactory/CMakeLists.txt index 6db7039d2a2fc..5241d32d035d2 100644 --- a/roofit/histfactory/CMakeLists.txt +++ b/roofit/histfactory/CMakeLists.txt @@ -24,45 +24,31 @@ endif() ROOT_STANDARD_LIBRARY_PACKAGE(HistFactory HEADERS - RooStats/HistFactory/Asimov.h - RooStats/HistFactory/Channel.h - RooStats/HistFactory/Data.h RooStats/HistFactory/Detail/HistFactoryImpl.h RooStats/HistFactory/FlexibleInterpVar.h RooStats/HistFactory/HistFactoryException.h RooStats/HistFactory/HistFactoryModelUtils.h RooStats/HistFactory/HistFactoryNavigation.h RooStats/HistFactory/HistoToWorkspaceFactoryFast.h - RooStats/HistFactory/HistRef.h RooStats/HistFactory/LinInterpVar.h RooStats/HistFactory/MakeModelAndMeasurementsFast.h RooStats/HistFactory/Measurement.h RooStats/HistFactory/ParamHistFunc.h RooStats/HistFactory/PiecewiseInterpolation.h - RooStats/HistFactory/PreprocessFunction.h RooStats/HistFactory/RooBarlowBeestonLL.h - RooStats/HistFactory/Sample.h - RooStats/HistFactory/Systematics.h ${HISTFACTORY_XML_HEADERS} SOURCES - src/Asimov.cxx - src/Channel.cxx - src/Data.cxx src/FlexibleInterpVar.cxx src/HistFactoryImpl.cxx src/HistFactoryModelUtils.cxx src/HistFactoryNavigation.cxx - src/HistRef.cxx src/HistoToWorkspaceFactoryFast.cxx src/LinInterpVar.cxx src/MakeModelAndMeasurementsFast.cxx src/Measurement.cxx src/ParamHistFunc.cxx src/PiecewiseInterpolation.cxx - src/PreprocessFunction.cxx src/RooBarlowBeestonLL.cxx - src/Sample.cxx - src/Systematics.cxx ${HISTFACTORY_XML_SOURCES} DICTIONARY_OPTIONS "-writeEmptyRootPCM" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Asimov.h b/roofit/histfactory/inc/RooStats/HistFactory/Asimov.h index 9a0fd72e0766c..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Asimov.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Asimov.h @@ -1,53 +1 @@ -// @(#)root/roostats:$Id$ -// Author: George Lewis, Kyle Cranmer -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -#ifndef HISTFACTORY_ASIMOV_H -#define HISTFACTORY_ASIMOV_H - -#include -#include - -#include "RooWorkspace.h" - -namespace RooStats{ - namespace HistFactory { - - class Asimov { - - public: - - Asimov() {;} - Asimov(std::string Name) : fName(Name) {;} - - void ConfigureWorkspace( RooWorkspace* ); - - std::string GetName() { return fName; } - void SetName(const std::string& name) { fName = name; } - - void SetFixedParam(const std::string& param, bool constant=true) { fParamsToFix[param] = constant; } - void SetParamValue(const std::string& param, double value) { fParamValsToSet[param] = value; } - - std::map< std::string, bool >& GetParamsToFix() { return fParamsToFix; } - std::map< std::string, double >& GetParamsToSet() { return fParamValsToSet; } - - protected: - - std::string fName; - - std::map fParamsToFix; - std::map< std::string, double > fParamValsToSet; - - }; - - - } // namespace HistFactory -} // namespace RooStats - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Channel.h b/roofit/histfactory/inc/RooStats/HistFactory/Channel.h index 2e6106d2709da..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Channel.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Channel.h @@ -1,109 +1 @@ -// @(#)root/roostats:$Id$ -// Author: George Lewis, Kyle Cranmer -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -#ifndef HISTFACTORY_CHANNEL_H -#define HISTFACTORY_CHANNEL_H - -#include "RooStats/HistFactory/Data.h" -#include "RooStats/HistFactory/Sample.h" -#include "RooStats/HistFactory/Systematics.h" - -#include -#include -#include -#include -#include -#include - -class TFile; - -namespace RooStats{ -namespace HistFactory { - -class Channel { - - -public: - friend class Measurement; - - Channel() = default; - Channel(std::string Name, std::string InputFile=""); - - /// set name of channel - void SetName( const std::string& Name ) { fName = Name; } - /// get name of channel - std::string GetName() const { return fName; } - /// set name of input file containing histograms - void SetInputFile( const std::string& file ) { fInputFile = file; } - /// get name of input file - std::string GetInputFile() const { return fInputFile; } - /// set path for histograms in input file - void SetHistoPath( const std::string& file ) { fHistoPath = file; } - /// get path to histograms in input file - std::string GetHistoPath() const { return fHistoPath; } - - /// set data object - void SetData( const RooStats::HistFactory::Data& data ) { fData = data; } - void SetData( std::string HistoName, std::string InputFile, std::string HistoPath="" ); - void SetData( double Val ); - void SetData( TH1* hData ); - /// get data object - RooStats::HistFactory::Data& GetData() { return fData; } - const RooStats::HistFactory::Data& GetData() const { return fData; } - - /// add additional data object - void AddAdditionalData( const RooStats::HistFactory::Data& data ) { fAdditionalData.push_back(data); } - /// retrieve vector of additional data objects - std::vector& GetAdditionalData() { return fAdditionalData; } - - void SetStatErrorConfig( double RelErrorThreshold, Constraint::Type ConstraintType ); - void SetStatErrorConfig( double RelErrorThreshold, std::string ConstraintType ); - /// define treatment of statistical uncertainties - void SetStatErrorConfig( RooStats::HistFactory::StatErrorConfig Config ) { fStatErrorConfig = Config; } - /// get information about threshold for statistical uncertainties and constraint term - HistFactory::StatErrorConfig& GetStatErrorConfig() { return fStatErrorConfig; } - const HistFactory::StatErrorConfig& GetStatErrorConfig() const { return fStatErrorConfig; } - - void AddSample( RooStats::HistFactory::Sample sample ); - /// get vector of samples for this channel - std::vector< RooStats::HistFactory::Sample >& GetSamples() { return fSamples; } - const std::vector< RooStats::HistFactory::Sample >& GetSamples() const { return fSamples; } - - void Print(std::ostream& = std::cout); - void PrintXML( std::string const& directory, std::string const& prefix="" ) const; - - void CollectHistograms(); - bool CheckHistograms() const; - -protected: - - std::string fName; - std::string fInputFile; - std::string fHistoPath; - - HistFactory::Data fData; - - /// One can add additional datasets - /// These are simply added to the xml under a different name - std::vector fAdditionalData; - - HistFactory::StatErrorConfig fStatErrorConfig; - - std::vector< RooStats::HistFactory::Sample > fSamples; - - TH1* GetHistogram( std::string InputFile, std::string HistoPath, std::string HistoName, std::map>& lsof); -}; - - extern Channel BadChannel; - -} // namespace HistFactory -} // namespace RooStats - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/ConfigParser.h b/roofit/histfactory/inc/RooStats/HistFactory/ConfigParser.h index ee9f66b0fd4e8..638480fac7db9 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/ConfigParser.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/ConfigParser.h @@ -12,9 +12,7 @@ #ifndef ROOSTATS_CONFIGPARSER_h #define ROOSTATS_CONFIGPARSER_h -#include "RooStats/HistFactory/Channel.h" #include "RooStats/HistFactory/Measurement.h" -#include "RooStats/HistFactory/Sample.h" #include #include diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Data.h b/roofit/histfactory/inc/RooStats/HistFactory/Data.h index 6160cc24bf457..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Data.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Data.h @@ -1,72 +1 @@ -// @(#)root/roostats:$Id$ -// Author: George Lewis, Kyle Cranmer -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -#ifndef HISTFACTORY_DATA_H -#define HISTFACTORY_DATA_H - -#include -#include -#include - -//#include "RooStats/HistFactory/HistCollector.h" -#include "RooStats/HistFactory/Sample.h" - -namespace RooStats{ -namespace HistFactory { - -class Data { - -public: - //friend class Channel; - - Data() {} - /// constructor from name, file and path. Name of the histogram should not include the path - Data( std::string HistoName, std::string InputFile, std::string HistoPath="" ); - - std::string const& GetName() const { return fName; } - void SetName(const std::string& name) { fName=name; } - - void SetInputFile(const std::string& InputFile) { fInputFile = InputFile; } - std::string const& GetInputFile() const { return fInputFile; } - - void SetHistoName(const std::string& HistoName) { fHistoName = HistoName; } - std::string const& GetHistoName() const { return fHistoName; } - - void SetHistoPath(const std::string& HistoPath) { fHistoPath = HistoPath; } - std::string const& GetHistoPath() const { return fHistoPath; } - - void Print(std::ostream& = std::cout); - void PrintXML( std::ostream& ) const; - void writeToFile( std::string FileName, std::string DirName ); - - TH1* GetHisto(); - const TH1* GetHisto() const; - void SetHisto(TH1* Hist) { fhData = Hist; fHistoName=Hist->GetName(); } - -protected: - - std::string fName; - - std::string fInputFile; - std::string fHistoName; - std::string fHistoPath; - - - // The Data Histogram - HistRef fhData; - - -}; - -} -} - - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Detail/HistFactoryImpl.h b/roofit/histfactory/inc/RooStats/HistFactory/Detail/HistFactoryImpl.h index cc9e1c62f0740..02e0846e76dda 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Detail/HistFactoryImpl.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Detail/HistFactoryImpl.h @@ -13,7 +13,7 @@ #ifndef HistFactoryImplHelpers_h #define HistFactoryImplHelpers_h -#include +#include #include #include diff --git a/roofit/histfactory/inc/RooStats/HistFactory/HistRef.h b/roofit/histfactory/inc/RooStats/HistFactory/HistRef.h index 5b37542e6bdea..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/HistRef.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/HistRef.h @@ -1,80 +1 @@ -// @(#)root/roostats:$Id$ -// Author: L. Moneta -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -#ifndef HISTFACTORY_HISTREF_H -#define HISTFACTORY_HISTREF_H - -#include -#include - -namespace RooStats{ -namespace HistFactory { - - -// Internal class wrapping an histogram and managing its content. -// conveninet for dealing with histogram pointers in the -// HistFactory class -class HistRef { - -public: - - - /// constructor - use gives away ownerhip of the given pointer - HistRef(TH1 * h = nullptr) : fHist(h) {} - - HistRef( const HistRef& other ) - { - if (other.fHist) fHist.reset(CopyObject(other.fHist.get())); - } - - HistRef(HistRef&& other) : - fHist(std::move(other.fHist)) {} - - ~HistRef() {} - - /// assignment operator (delete previous contained histogram) - HistRef & operator= (const HistRef & other) { - if (this == &other) return *this; - - fHist.reset(CopyObject(other.fHist.get())); - return *this; - } - - HistRef& operator=(HistRef&& other) { - fHist = std::move(other.fHist); - return *this; - } - - TH1 * GetObject() const { return fHist.get(); } - - /// set the object - user gives away the ownerhisp - void SetObject(TH1 *h) { - fHist.reset(h); - } - - /// operator= passing an object pointer : user gives away its ownerhisp - void operator= (TH1 * h) { SetObject(h); } - - /// Release ownership of object. - TH1* ReleaseObject() { - return fHist.release(); - } - - - -private: - static TH1 * CopyObject(const TH1 * h); - std::unique_ptr fHist; ///< pointer to contained histogram -}; - -} -} - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h b/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h index 9cb8c14197b62..16ee21f06a651 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h @@ -11,7 +11,7 @@ #ifndef ROOSTATS_HISTOTOWORKSPACEFACTORYFAST #define ROOSTATS_HISTOTOWORKSPACEFACTORYFAST -#include +#include #include #include diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Measurement.h b/roofit/histfactory/inc/RooStats/HistFactory/Measurement.h index fe89c3d0e554a..8c8cf30dc0bd8 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Measurement.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Measurement.h @@ -11,162 +11,780 @@ #ifndef HISTFACTORY_MEASUREMENT_H #define HISTFACTORY_MEASUREMENT_H -#include -#include +#include + #include #include +#include +#include +#include #include -#include "TNamed.h" +class TFile; +class TH1; -#include "PreprocessFunction.h" -#include "RooStats/HistFactory/Channel.h" -#include "RooStats/HistFactory/Asimov.h" +class RooWorkspace; -class TFile; +namespace RooStats::HistFactory { -namespace RooStats{ -namespace HistFactory { +namespace Constraint { -class Measurement : public TNamed { +enum Type { + Gaussian, + Poisson +}; +std::string Name(Type type); +Type GetType(const std::string &Name); + +} // namespace Constraint + +/** \class OverallSys + * \ingroup HistFactory + * Configuration for a constrained overall systematic to scale sample normalisations. + */ +class OverallSys { + +public: + void SetName(const std::string &Name) { fName = Name; } + const std::string &GetName() const { return fName; } + + void SetLow(double Low) { fLow = Low; } + void SetHigh(double High) { fHigh = High; } + double GetLow() const { return fLow; } + double GetHigh() const { return fHigh; } + + void Print(std::ostream & = std::cout) const; + void PrintXML(std::ostream &) const; + +protected: + std::string fName; + double fLow = 0.0; + double fHigh = 0.0; +}; + +/** \class NormFactor + * \ingroup HistFactory + * Configuration for an \a un- constrained overall systematic to scale sample normalisations. + */ +class NormFactor { + +public: + void SetName(const std::string &Name) { fName = Name; } + std::string GetName() const { return fName; } + + void SetVal(double Val) { fVal = Val; } + double GetVal() const { return fVal; } + + void SetLow(double Low) { fLow = Low; } + void SetHigh(double High) { fHigh = High; } + double GetLow() const { return fLow; } + double GetHigh() const { return fHigh; } + + void Print(std::ostream & = std::cout) const; + void PrintXML(std::ostream &) const; + +protected: + std::string fName; + double fVal = 1.0; + double fLow = 1.0; + double fHigh = 1.0; +}; + +/** //////////////////////////////////////////////////////////////////////////////////////////// + * \class HistogramUncertaintyBase + * \ingroup HistFactory + * Base class to store the up and down variations for histogram uncertainties. + * Use the derived classes for actual models. + */ +class HistogramUncertaintyBase { + +public: + HistogramUncertaintyBase(); + HistogramUncertaintyBase(const std::string &Name); + HistogramUncertaintyBase(const HistogramUncertaintyBase &oth); + HistogramUncertaintyBase(HistogramUncertaintyBase &&); + + virtual ~HistogramUncertaintyBase(); + + // Need deep copies because the class owns its histograms. + HistogramUncertaintyBase &operator=(const HistogramUncertaintyBase &oth); + HistogramUncertaintyBase &operator=(HistogramUncertaintyBase &&); + + virtual void Print(std::ostream & = std::cout) const; + virtual void PrintXML(std::ostream &) const = 0; + virtual void writeToFile(const std::string &FileName, const std::string &DirName); + + void SetHistoLow(TH1 *Low); + void SetHistoHigh(TH1 *High); + + const TH1 *GetHistoLow() const { return fhLow.get(); } + const TH1 *GetHistoHigh() const { return fhHigh.get(); } + + void SetName(const std::string &Name) { fName = Name; } + const std::string &GetName() const { return fName; } + + void SetInputFileLow(const std::string &InputFileLow) { fInputFileLow = InputFileLow; } + void SetInputFileHigh(const std::string &InputFileHigh) { fInputFileHigh = InputFileHigh; } + + const std::string &GetInputFileLow() const { return fInputFileLow; } + const std::string &GetInputFileHigh() const { return fInputFileHigh; } + + void SetHistoNameLow(const std::string &HistoNameLow) { fHistoNameLow = HistoNameLow; } + void SetHistoNameHigh(const std::string &HistoNameHigh) { fHistoNameHigh = HistoNameHigh; } + + const std::string &GetHistoNameLow() const { return fHistoNameLow; } + const std::string &GetHistoNameHigh() const { return fHistoNameHigh; } + + void SetHistoPathLow(const std::string &HistoPathLow) { fHistoPathLow = HistoPathLow; } + void SetHistoPathHigh(const std::string &HistoPathHigh) { fHistoPathHigh = HistoPathHigh; } + + const std::string &GetHistoPathLow() const { return fHistoPathLow; } + const std::string &GetHistoPathHigh() const { return fHistoPathHigh; } + +protected: + std::string fName; + + std::string fInputFileLow; + std::string fHistoNameLow; + std::string fHistoPathLow; + + std::string fInputFileHigh; + std::string fHistoNameHigh; + std::string fHistoPathHigh; + + // The Low and High Histograms + std::unique_ptr fhLow; + std::unique_ptr fhHigh; +}; + +/** \class HistoSys + * \ingroup HistFactory + * Configuration for a constrained, coherent shape variation of affected samples. + */ +class HistoSys final : public HistogramUncertaintyBase { +public: + void PrintXML(std::ostream &) const override; +}; + +/** \class HistoFactor + * \ingroup HistFactory + * Configuration for an *un*constrained, coherent shape variation of affected samples. + */ +class HistoFactor final : public HistogramUncertaintyBase { +public: + void PrintXML(std::ostream &) const override; +}; + +/** \class ShapeSys + * \ingroup HistFactory + * Constrained bin-by-bin variation of affected histogram. + */ +class ShapeSys final : public HistogramUncertaintyBase { + +public: + ShapeSys() : fConstraintType(Constraint::Gaussian) {} + ShapeSys(const ShapeSys &other) : HistogramUncertaintyBase(other), fConstraintType(other.fConstraintType) {} + ShapeSys &operator=(const ShapeSys &oth) + { + if (this == &oth) + return *this; + HistogramUncertaintyBase::operator=(oth); + fConstraintType = oth.fConstraintType; + return *this; + } + ShapeSys &operator=(ShapeSys &&) = default; + + void SetInputFile(const std::string &InputFile) { fInputFileHigh = InputFile; } + std::string GetInputFile() const { return fInputFileHigh; } + + void SetHistoName(const std::string &HistoName) { fHistoNameHigh = HistoName; } + std::string GetHistoName() const { return fHistoNameHigh; } + + void SetHistoPath(const std::string &HistoPath) { fHistoPathHigh = HistoPath; } + std::string GetHistoPath() const { return fHistoPathHigh; } + + void Print(std::ostream & = std::cout) const override; + void PrintXML(std::ostream &) const override; + void writeToFile(const std::string &FileName, const std::string &DirName) override; + + const TH1 *GetErrorHist() const { return fhHigh.get(); } + void SetErrorHist(TH1 *hError); + + void SetConstraintType(Constraint::Type ConstrType) { fConstraintType = ConstrType; } + Constraint::Type GetConstraintType() const { return fConstraintType; } + +protected: + Constraint::Type fConstraintType; +}; + +/** \class ShapeFactor + * \ingroup HistFactory + * *Un*constrained bin-by-bin variation of affected histogram. + */ +class ShapeFactor : public HistogramUncertaintyBase { + +public: + void Print(std::ostream & = std::cout) const override; + void PrintXML(std::ostream &) const override; + void writeToFile(const std::string &FileName, const std::string &DirName) override; + + void SetInitialShape(TH1 *shape); + const TH1 *GetInitialShape() const { return fhHigh.get(); } + + void SetConstant(bool constant) { fConstant = constant; } + bool IsConstant() const { return fConstant; } + + bool HasInitialShape() const { return fHasInitialShape; } + + void SetInputFile(const std::string &InputFile) + { + fInputFileHigh = InputFile; + fHasInitialShape = true; + } + const std::string &GetInputFile() const { return fInputFileHigh; } + + void SetHistoName(const std::string &HistoName) + { + fHistoNameHigh = HistoName; + fHasInitialShape = true; + } + const std::string &GetHistoName() const { return fHistoNameHigh; } + + void SetHistoPath(const std::string &HistoPath) + { + fHistoPathHigh = HistoPath; + fHasInitialShape = true; + } + const std::string &GetHistoPath() const { return fHistoPathHigh; } + +protected: + bool fConstant = false; + + // A histogram representing + // the initial shape + bool fHasInitialShape = false; +}; + +/** \class StatError + * \ingroup HistFactory + * Statistical error of Monte Carlo predictions. + */ +class StatError : public HistogramUncertaintyBase { + +public: + void Print(std::ostream & = std::cout) const override; + void PrintXML(std::ostream &) const override; + void writeToFile(const std::string &FileName, const std::string &DirName) override; + + void Activate(bool IsActive = true) { fActivate = IsActive; } + bool GetActivate() const { return fActivate; } + + void SetUseHisto(bool UseHisto = true) { fUseHisto = UseHisto; } + bool GetUseHisto() const { return fUseHisto; } + + void SetInputFile(const std::string &InputFile) { fInputFileHigh = InputFile; } + const std::string &GetInputFile() const { return fInputFileHigh; } + + void SetHistoName(const std::string &HistoName) { fHistoNameHigh = HistoName; } + const std::string &GetHistoName() const { return fHistoNameHigh; } + + void SetHistoPath(const std::string &HistoPath) { fHistoPathHigh = HistoPath; } + const std::string &GetHistoPath() const { return fHistoPathHigh; } + + const TH1 *GetErrorHist() const { return fhHigh.get(); } + void SetErrorHist(TH1 *Error); + +protected: + bool fActivate = false; + bool fUseHisto = false; // Use an external histogram for the errors +}; + +/** \class StatErrorConfig + * \ingroup HistFactory + * Configuration to automatically assign nuisance parameters for the statistical + * error of the Monte Carlo simulations. + * The default is to assign a Poisson uncertainty to a bin when its statistical uncertainty + * is larger than 5% of the bin content. + */ +class StatErrorConfig { public: + void Print(std::ostream & = std::cout) const; + void PrintXML(std::ostream &) const; + + void SetRelErrorThreshold(double Threshold) { fRelErrorThreshold = Threshold; } + double GetRelErrorThreshold() const { return fRelErrorThreshold; } + + void SetConstraintType(Constraint::Type ConstrType) { fConstraintType = ConstrType; } + Constraint::Type GetConstraintType() const { return fConstraintType; } + +protected: + double fRelErrorThreshold = 0.05; + Constraint::Type fConstraintType = Constraint::Poisson; +}; + +// Internal class wrapping an histogram and managing its content. +// conveninet for dealing with histogram pointers in the +// HistFactory class +class HistRef { + +public: + HistRef(TH1 *h = nullptr); + + HistRef(const HistRef &other); + + HistRef(HistRef &&other); + + ~HistRef(); + + HistRef &operator=(const HistRef &other); + HistRef &operator=(HistRef &&other); + + TH1 *GetObject() const; + + void SetObject(TH1 *h); - Measurement(); - /// Measurement( const Measurement& other ); // Copy - Measurement(const char* Name, const char* Title=""); - - /// set output prefix - void SetOutputFilePrefix( const std::string& prefix ) { fOutputFilePrefix = prefix; } - /// retrieve prefix for output files - std::string GetOutputFilePrefix() { return fOutputFilePrefix; } - - /// insert PoI at beginning of vector of PoIs - void SetPOI( const std::string& POI ) { fPOI.insert( fPOI.begin(), POI ); } - /// append parameter to vector of PoIs - void AddPOI( const std::string& POI ) { fPOI.push_back(POI); } - /// get name of PoI at given index - std::string GetPOI(unsigned int i=0) { return fPOI.at(i); } - /// get vector of PoI names - std::vector& GetPOIList() { return fPOI; } - - - /// Add a parameter to be set as constant - /// (Similar to ParamSetting method below) - void AddConstantParam( const std::string& param ); - /// empty vector of constant parameters - void ClearConstantParams() { fConstantParams.clear(); } - /// get vector of all constant parameters - std::vector< std::string >& GetConstantParams() { return fConstantParams; } - - /// Set a parameter to a specific value - /// (And optionally fix it) - void SetParamValue( const std::string& param, double value); - /// get map: parameter name <--> parameter value - std::map& GetParamValues() { return fParamValues; } - /// clear map of parameter values - void ClearParamValues() { fParamValues.clear(); } - - void AddPreprocessFunction( std::string name, std::string expression, std::string dependencies ); - /// add a preprocess function object - void AddFunctionObject( const RooStats::HistFactory::PreprocessFunction function) { fFunctionObjects.push_back( function ); } - void SetFunctionObjects( std::vector< RooStats::HistFactory::PreprocessFunction > objects ) { fFunctionObjects = objects; } - /// get vector of defined function objects - std::vector< RooStats::HistFactory::PreprocessFunction >& GetFunctionObjects() { return fFunctionObjects; } - const std::vector< RooStats::HistFactory::PreprocessFunction >& GetFunctionObjects() const { return fFunctionObjects; } - std::vector< std::string > GetPreprocessFunctions() const; - - /// get vector of defined Asimov Datasets - std::vector< RooStats::HistFactory::Asimov >& GetAsimovDatasets() { return fAsimovDatasets; } - /// add an Asimov Dataset - void AddAsimovDataset( RooStats::HistFactory::Asimov dataset ) { fAsimovDatasets.push_back(dataset); } - - /// set integrated luminosity used to normalise histograms (if NormalizeByTheory is true for this sample) - void SetLumi(double Lumi ) { fLumi = Lumi; } - /// set relative uncertainty on luminosity - void SetLumiRelErr( double RelErr ) { fLumiRelErr = RelErr; } - /// retrieve integrated luminosity - double GetLumi() { return fLumi; } - /// retrieve relative uncertainty on luminosity - double GetLumiRelErr() { return fLumiRelErr; } - - void SetBinLow( int BinLow ) { fBinLow = BinLow; } - void SetBinHigh ( int BinHigh ) { fBinHigh = BinHigh; } - int GetBinLow() { return fBinLow; } - int GetBinHigh() { return fBinHigh; } - - void PrintTree( std::ostream& = std::cout ); /// Print to a stream - void PrintXML( std::string Directory="", std::string NewOutputPrefix="" ); - - std::vector< RooStats::HistFactory::Channel >& GetChannels() { return fChannels; } - const std::vector< RooStats::HistFactory::Channel >& GetChannels() const { return fChannels; } - RooStats::HistFactory::Channel& GetChannel( std::string ); - /// add a completely configured channel - void AddChannel( RooStats::HistFactory::Channel chan ) { fChannels.push_back( chan ); } - - bool HasChannel( std::string ); - void writeToFile( TFile* file ); - - void CollectHistograms(); - - - void AddGammaSyst(std::string syst, double uncert); - void AddLogNormSyst(std::string syst, double uncert); - void AddUniformSyst(std::string syst); - void AddNoSyst(std::string syst); - - std::map< std::string, double >& GetGammaSyst() { return fGammaSyst; } - std::map< std::string, double >& GetUniformSyst() { return fUniformSyst; } - std::map< std::string, double >& GetLogNormSyst() { return fLogNormSyst; } - std::map< std::string, double >& GetNoSyst() { return fNoSyst; } - - std::map< std::string, double > const& GetGammaSyst() const { return fGammaSyst; } - std::map< std::string, double > const& GetUniformSyst() const { return fUniformSyst; } - std::map< std::string, double > const& GetLogNormSyst() const { return fLogNormSyst; } - std::map< std::string, double > const& GetNoSyst() const { return fNoSyst; } - - std::string GetInterpolationScheme() { return fInterpolationScheme; } + void operator=(TH1 *h); + + TH1 *ReleaseObject(); private: + static TH1 *CopyObject(const TH1 *h); + std::unique_ptr fHist; ///< pointer to contained histogram +}; + +class Asimov { + +public: + Asimov(std::string Name = "") : fName(Name) {} + + void ConfigureWorkspace(RooWorkspace *); + + std::string GetName() { return fName; } + void SetName(const std::string &name) { fName = name; } + + void SetFixedParam(const std::string ¶m, bool constant = true) { fParamsToFix[param] = constant; } + void SetParamValue(const std::string ¶m, double value) { fParamValsToSet[param] = value; } + + std::map &GetParamsToFix() { return fParamsToFix; } + std::map &GetParamsToSet() { return fParamValsToSet; } + +protected: + std::string fName; + + std::map fParamsToFix; + std::map fParamValsToSet; +}; + +class PreprocessFunction { +public: + PreprocessFunction() {} + + PreprocessFunction(std::string const &name, std::string const &expression, std::string const &dependents); + + void Print(std::ostream & = std::cout) const; + void PrintXML(std::ostream &) const; + + void SetName(const std::string &name) { fName = name; } + std::string const &GetName() const { return fName; } - /// Configurables of this measurement - std::string fOutputFilePrefix; - std::vector fPOI; - double fLumi; - double fLumiRelErr; - int fBinLow; - int fBinHigh; - bool fExportOnly = true; - std::string fInterpolationScheme; + void SetExpression(const std::string &expression) { fExpression = expression; } + std::string const &GetExpression() const { return fExpression; } - /// Channels that make up this measurement - std::vector< RooStats::HistFactory::Channel > fChannels; + void SetDependents(const std::string &dependents) { fDependents = dependents; } + std::string const &GetDependents() const { return fDependents; } + + std::string GetCommand() const; + +private: + std::string fName; + std::string fExpression; + std::string fDependents; +}; + +class Data { + +public: + // friend class Channel; + + Data() {} + /// constructor from name, file and path. Name of the histogram should not include the path + Data(std::string HistoName, std::string InputFile, std::string HistoPath = ""); + + std::string const &GetName() const { return fName; } + void SetName(const std::string &name) { fName = name; } + + void SetInputFile(const std::string &InputFile) { fInputFile = InputFile; } + std::string const &GetInputFile() const { return fInputFile; } + + void SetHistoName(const std::string &HistoName) { fHistoName = HistoName; } + std::string const &GetHistoName() const { return fHistoName; } + + void SetHistoPath(const std::string &HistoPath) { fHistoPath = HistoPath; } + std::string const &GetHistoPath() const { return fHistoPath; } + + void Print(std::ostream & = std::cout); + void PrintXML(std::ostream &) const; + void writeToFile(std::string FileName, std::string DirName); + + TH1 *GetHisto(); + const TH1 *GetHisto() const; + void SetHisto(TH1 *Hist); + +protected: + std::string fName; + + std::string fInputFile; + std::string fHistoName; + std::string fHistoPath; + + // The Data Histogram + HistRef fhData; +}; + +class Sample { + +public: + Sample(); + ~Sample(); + Sample(std::string Name); + Sample(const Sample &other); + Sample &operator=(const Sample &other); + /// constructor from name, file and path. Name of the histogram should not include the path + Sample(std::string Name, std::string HistoName, std::string InputFile, std::string HistoPath = ""); + + void Print(std::ostream & = std::cout) const; + void PrintXML(std::ofstream &xml) const; + void writeToFile(std::string FileName, std::string DirName); + + const TH1 *GetHisto() const; + // set histogram for this sample + void SetHisto(TH1 *histo); + void SetValue(double Val); + + // Some helper functions + // Note that histogram name should not include the path of the histogram in the file. + // This has to be given separately + + void ActivateStatError(); + void ActivateStatError(std::string HistoName, std::string InputFile, std::string HistoPath = ""); + + void AddOverallSys(std::string Name, double Low, double High); + void AddOverallSys(const OverallSys &Sys); + + void AddNormFactor(std::string const &Name, double Val, double Low, double High); + void AddNormFactor(const NormFactor &Factor); + + void AddHistoSys(std::string Name, std::string HistoNameLow, std::string HistoFileLow, std::string HistoPathLow, + std::string HistoNameHigh, std::string HistoFileHigh, std::string HistoPathHigh); + void AddHistoSys(const HistoSys &Sys); + + void AddHistoFactor(std::string Name, std::string HistoNameLow, std::string HistoFileLow, std::string HistoPathLow, + std::string HistoNameHigh, std::string HistoFileHigh, std::string HistoPathHigh); + void AddHistoFactor(const HistoFactor &Factor); + + void AddShapeFactor(std::string Name); + void AddShapeFactor(const ShapeFactor &Factor); + + void AddShapeSys(std::string Name, Constraint::Type ConstraintType, std::string HistoName, std::string HistoFile, + std::string HistoPath = ""); + void AddShapeSys(const ShapeSys &Sys); + + /// defines whether the normalization scale with luminosity + void SetNormalizeByTheory(bool norm) { fNormalizeByTheory = norm; } + /// does the normalization scale with luminosity + bool GetNormalizeByTheory() const { return fNormalizeByTheory; } + + /// get name of sample + std::string GetName() const { return fName; } + /// set name of sample + void SetName(const std::string &Name) { fName = Name; } + + /// get input ROOT file + std::string GetInputFile() const { return fInputFile; } + /// set input ROOT file + void SetInputFile(const std::string &InputFile) { fInputFile = InputFile; } + + /// get histogram name + std::string GetHistoName() const { return fHistoName; } + /// set histogram name + void SetHistoName(const std::string &HistoName) { fHistoName = HistoName; } + + /// get histogram path + std::string GetHistoPath() const { return fHistoPath; } + /// set histogram path + void SetHistoPath(const std::string &HistoPath) { fHistoPath = HistoPath; } + + /// get name of associated channel + std::string GetChannelName() const { return fChannelName; } + /// set name of associated channel + void SetChannelName(const std::string &ChannelName) { fChannelName = ChannelName; } + + std::vector &GetOverallSysList() { return fOverallSysList; } + std::vector &GetNormFactorList() { return fNormFactorList; } + std::vector &GetHistoSysList() { return fHistoSysList; } + std::vector &GetHistoFactorList() { return fHistoFactorList; } + std::vector &GetShapeSysList() { return fShapeSysList; } + std::vector &GetShapeFactorList() { return fShapeFactorList; } + + const std::vector &GetOverallSysList() const { return fOverallSysList; } + const std::vector &GetNormFactorList() const { return fNormFactorList; } + const std::vector &GetHistoSysList() const { return fHistoSysList; } + const std::vector &GetHistoFactorList() const { return fHistoFactorList; } + const std::vector &GetShapeSysList() const { return fShapeSysList; } + const std::vector &GetShapeFactorList() const { return fShapeFactorList; } + + bool HasStatError() const { return fStatErrorActivate; } + RooStats::HistFactory::StatError &GetStatError() { return fStatError; } + const RooStats::HistFactory::StatError &GetStatError() const { return fStatError; } + void SetStatError(RooStats::HistFactory::StatError Error) { fStatError = std::move(Error); } + +protected: + std::string fName; + std::string fInputFile; + std::string fHistoName; + std::string fHistoPath; + + /// The Name of the parent channel + std::string fChannelName; + + // + // Systematics + // + + std::vector fOverallSysList; + std::vector fNormFactorList; + + std::vector fHistoSysList; + std::vector fHistoFactorList; + + std::vector fShapeSysList; + std::vector fShapeFactorList; + + /// Properties + RooStats::HistFactory::StatError fStatError; + + bool fNormalizeByTheory = false; + bool fStatErrorActivate = false; + + /// The Nominal Shape + HistRef fhNominal; + std::unique_ptr fhCountingHist; +}; + +class Channel { + +public: + friend class Measurement; + + Channel() = default; + Channel(std::string Name, std::string InputFile = ""); + + /// set name of channel + void SetName(const std::string &Name) { fName = Name; } + /// get name of channel + std::string GetName() const { return fName; } + /// set name of input file containing histograms + void SetInputFile(const std::string &file) { fInputFile = file; } + /// get name of input file + std::string GetInputFile() const { return fInputFile; } + /// set path for histograms in input file + void SetHistoPath(const std::string &file) { fHistoPath = file; } + /// get path to histograms in input file + std::string GetHistoPath() const { return fHistoPath; } + + /// set data object + void SetData(const RooStats::HistFactory::Data &data) { fData = data; } + void SetData(std::string HistoName, std::string InputFile, std::string HistoPath = ""); + void SetData(double Val); + void SetData(TH1 *hData); + /// get data object + RooStats::HistFactory::Data &GetData() { return fData; } + const RooStats::HistFactory::Data &GetData() const { return fData; } + + /// add additional data object + void AddAdditionalData(const RooStats::HistFactory::Data &data) { fAdditionalData.push_back(data); } + /// retrieve vector of additional data objects + std::vector &GetAdditionalData() { return fAdditionalData; } + + void SetStatErrorConfig(double RelErrorThreshold, Constraint::Type ConstraintType); + void SetStatErrorConfig(double RelErrorThreshold, std::string ConstraintType); + /// define treatment of statistical uncertainties + void SetStatErrorConfig(RooStats::HistFactory::StatErrorConfig Config) { fStatErrorConfig = Config; } + /// get information about threshold for statistical uncertainties and constraint term + HistFactory::StatErrorConfig &GetStatErrorConfig() { return fStatErrorConfig; } + const HistFactory::StatErrorConfig &GetStatErrorConfig() const { return fStatErrorConfig; } + + void AddSample(RooStats::HistFactory::Sample sample); + /// get vector of samples for this channel + std::vector &GetSamples() { return fSamples; } + const std::vector &GetSamples() const { return fSamples; } + + void Print(std::ostream & = std::cout); + void PrintXML(std::string const &directory, std::string const &prefix = "") const; + + void CollectHistograms(); + bool CheckHistograms() const; + +protected: + std::string fName; + std::string fInputFile; + std::string fHistoPath; + + HistFactory::Data fData; + + /// One can add additional datasets + /// These are simply added to the xml under a different name + std::vector fAdditionalData; + + HistFactory::StatErrorConfig fStatErrorConfig; + + std::vector fSamples; + + TH1 *GetHistogram(std::string InputFile, std::string HistoPath, std::string HistoName, + std::map> &lsof); +}; + +extern Channel BadChannel; + +class Measurement : public TNamed { + +public: + Measurement(); + /// Measurement( const Measurement& other ); // Copy + Measurement(const char *Name, const char *Title = ""); + + /// set output prefix + void SetOutputFilePrefix(const std::string &prefix) { fOutputFilePrefix = prefix; } + /// retrieve prefix for output files + std::string GetOutputFilePrefix() { return fOutputFilePrefix; } + + /// insert PoI at beginning of vector of PoIs + void SetPOI(const std::string &POI) { fPOI.insert(fPOI.begin(), POI); } + /// append parameter to vector of PoIs + void AddPOI(const std::string &POI) { fPOI.push_back(POI); } + /// get name of PoI at given index + std::string GetPOI(unsigned int i = 0) { return fPOI.at(i); } + /// get vector of PoI names + std::vector &GetPOIList() { return fPOI; } + + /// Add a parameter to be set as constant + /// (Similar to ParamSetting method below) + void AddConstantParam(const std::string ¶m); + /// empty vector of constant parameters + void ClearConstantParams() { fConstantParams.clear(); } + /// get vector of all constant parameters + std::vector &GetConstantParams() { return fConstantParams; } + + /// Set a parameter to a specific value + /// (And optionally fix it) + void SetParamValue(const std::string ¶m, double value); + /// get map: parameter name <--> parameter value + std::map &GetParamValues() { return fParamValues; } + /// clear map of parameter values + void ClearParamValues() { fParamValues.clear(); } + + void AddPreprocessFunction(std::string name, std::string expression, std::string dependencies); + /// add a preprocess function object + void AddFunctionObject(const RooStats::HistFactory::PreprocessFunction function) + { + fFunctionObjects.push_back(function); + } + void SetFunctionObjects(std::vector objects) + { + fFunctionObjects = objects; + } + /// get vector of defined function objects + std::vector &GetFunctionObjects() { return fFunctionObjects; } + const std::vector &GetFunctionObjects() const { return fFunctionObjects; } + std::vector GetPreprocessFunctions() const; + + /// get vector of defined Asimov Datasets + std::vector &GetAsimovDatasets() { return fAsimovDatasets; } + /// add an Asimov Dataset + void AddAsimovDataset(RooStats::HistFactory::Asimov dataset) { fAsimovDatasets.push_back(dataset); } + + /// set integrated luminosity used to normalise histograms (if NormalizeByTheory is true for this sample) + void SetLumi(double Lumi) { fLumi = Lumi; } + /// set relative uncertainty on luminosity + void SetLumiRelErr(double RelErr) { fLumiRelErr = RelErr; } + /// retrieve integrated luminosity + double GetLumi() { return fLumi; } + /// retrieve relative uncertainty on luminosity + double GetLumiRelErr() { return fLumiRelErr; } + + void SetBinLow(int BinLow) { fBinLow = BinLow; } + void SetBinHigh(int BinHigh) { fBinHigh = BinHigh; } + int GetBinLow() { return fBinLow; } + int GetBinHigh() { return fBinHigh; } + + void PrintTree(std::ostream & = std::cout); /// Print to a stream + void PrintXML(std::string Directory = "", std::string NewOutputPrefix = ""); + + std::vector &GetChannels() { return fChannels; } + const std::vector &GetChannels() const { return fChannels; } + RooStats::HistFactory::Channel &GetChannel(std::string); + void AddChannel(RooStats::HistFactory::Channel chan); + + bool HasChannel(std::string); + void writeToFile(TFile *file); + + void CollectHistograms(); + + void AddGammaSyst(std::string syst, double uncert); + void AddLogNormSyst(std::string syst, double uncert); + void AddUniformSyst(std::string syst); + void AddNoSyst(std::string syst); + + std::map &GetGammaSyst() { return fGammaSyst; } + std::map &GetUniformSyst() { return fUniformSyst; } + std::map &GetLogNormSyst() { return fLogNormSyst; } + std::map &GetNoSyst() { return fNoSyst; } + + std::map const &GetGammaSyst() const { return fGammaSyst; } + std::map const &GetUniformSyst() const { return fUniformSyst; } + std::map const &GetLogNormSyst() const { return fLogNormSyst; } + std::map const &GetNoSyst() const { return fNoSyst; } + + std::string GetInterpolationScheme() { return fInterpolationScheme; } + +private: + /// Configurables of this measurement + std::string fOutputFilePrefix; + std::vector fPOI; + double fLumi; + double fLumiRelErr; + int fBinLow; + int fBinHigh; + bool fExportOnly = true; + std::string fInterpolationScheme; - /// List of Parameters to be set constant - std::vector< std::string > fConstantParams; + /// Channels that make up this measurement + std::vector fChannels; - /// Map of parameter names to initial values to be set - std::map< std::string, double > fParamValues; + /// List of Parameters to be set constant + std::vector fConstantParams; - /// List of Preprocess Function objects - std::vector< RooStats::HistFactory::PreprocessFunction > fFunctionObjects; + /// Map of parameter names to initial values to be set + std::map fParamValues; - /// List of Asimov datasets to generate - std::vector< RooStats::HistFactory::Asimov > fAsimovDatasets; + /// List of Preprocess Function objects + std::vector fFunctionObjects; - /// List of Alternate constraint terms - std::map< std::string, double > fGammaSyst; - std::map< std::string, double > fUniformSyst; - std::map< std::string, double > fLogNormSyst; - std::map< std::string, double > fNoSyst; + /// List of Asimov datasets to generate + std::vector fAsimovDatasets; - std::string GetDirPath( TDirectory* dir ); + /// List of Alternate constraint terms + std::map fGammaSyst; + std::map fUniformSyst; + std::map fLogNormSyst; + std::map fNoSyst; - ClassDefOverride(RooStats::HistFactory::Measurement, 3); + std::string GetDirPath(TDirectory *dir); + ClassDefOverride(RooStats::HistFactory::Measurement, 3); }; -} // namespace HistFactory -} // namespace RooStats +} // namespace RooStats::HistFactory #endif diff --git a/roofit/histfactory/inc/RooStats/HistFactory/PreprocessFunction.h b/roofit/histfactory/inc/RooStats/HistFactory/PreprocessFunction.h index 475254350effd..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/PreprocessFunction.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/PreprocessFunction.h @@ -1,39 +1 @@ -#ifndef PREPROCESS_FUNCTION_H -#define PREPROCESS_FUNCTION_H - -#include -#include - -namespace RooStats { -namespace HistFactory { - -class PreprocessFunction { -public: - PreprocessFunction() {} - - PreprocessFunction(std::string const &name, std::string const &expression, std::string const &dependents); - - void Print(std::ostream & = std::cout) const; - void PrintXML(std::ostream &) const; - - void SetName(const std::string &name) { fName = name; } - std::string const &GetName() const { return fName; } - - void SetExpression(const std::string &expression) { fExpression = expression; } - std::string const &GetExpression() const { return fExpression; } - - void SetDependents(const std::string &dependents) { fDependents = dependents; } - std::string const &GetDependents() const { return fDependents; } - - std::string GetCommand() const; - -private: - std::string fName; - std::string fExpression; - std::string fDependents; -}; - -} // namespace HistFactory -} // namespace RooStats - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Sample.h b/roofit/histfactory/inc/RooStats/HistFactory/Sample.h index a560c67ee32b0..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Sample.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Sample.h @@ -1,171 +1 @@ -// @(#)root/roostats:$Id$ -// Author: George Lewis, Kyle Cranmer -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -#ifndef HISTFACTORY_SAMPLE_H -#define HISTFACTORY_SAMPLE_H - -#include -#include -#include -#include - -class TH1; - -#include "RooStats/HistFactory/HistRef.h" -#include "RooStats/HistFactory/Systematics.h" - -namespace RooStats{ -namespace HistFactory { - -class Sample { - - -public: - - Sample(); - Sample(std::string Name); - Sample(const Sample& other); - Sample& operator=(const Sample& other); - /// constructor from name, file and path. Name of the histogram should not include the path - Sample(std::string Name, std::string HistoName, std::string InputFile, std::string HistoPath=""); - - void Print(std::ostream& = std::cout) const; - void PrintXML( std::ofstream& xml ) const; - void writeToFile( std::string FileName, std::string DirName ); - - const TH1* GetHisto() const; - // set histogram for this sample - void SetHisto( TH1* histo ) { fhNominal = histo; fHistoName=histo->GetName(); } - void SetValue( double Val ) ; - - // Some helper functions - // Note that histogram name should not include the path of the histogram in the file. - // This has to be given separately - - void ActivateStatError(); - void ActivateStatError( std::string HistoName, std::string InputFile, std::string HistoPath="" ); - - void AddOverallSys( std::string Name, double Low, double High ); - void AddOverallSys( const OverallSys& Sys ); - - void AddNormFactor( std::string const& Name, double Val, double Low, double High ); - void AddNormFactor( const NormFactor& Factor ); - - void AddHistoSys( std::string Name, std::string HistoNameLow, std::string HistoFileLow, std::string HistoPathLow, - std::string HistoNameHigh, std::string HistoFileHigh, std::string HistoPathHigh ); - void AddHistoSys( const HistoSys& Sys ); - - void AddHistoFactor( std::string Name, std::string HistoNameLow, std::string HistoFileLow, std::string HistoPathLow, - std::string HistoNameHigh, std::string HistoFileHigh, std::string HistoPathHigh ); - void AddHistoFactor( const HistoFactor& Factor ); - - void AddShapeFactor( std::string Name ); - void AddShapeFactor( const ShapeFactor& Factor ); - - void AddShapeSys( std::string Name, Constraint::Type ConstraintType, std::string HistoName, std::string HistoFile, std::string HistoPath="" ); - void AddShapeSys( const ShapeSys& Sys ); - - /// defines whether the normalization scale with luminosity - void SetNormalizeByTheory( bool norm ) { fNormalizeByTheory = norm; } - /// does the normalization scale with luminosity - bool GetNormalizeByTheory() const { return fNormalizeByTheory; } - - - /// get name of sample - std::string GetName() const { return fName; } - /// set name of sample - void SetName(const std::string& Name) { fName = Name; } - - /// get input ROOT file - std::string GetInputFile() const { return fInputFile; } - /// set input ROOT file - void SetInputFile(const std::string& InputFile) { fInputFile = InputFile; } - - /// get histogram name - std::string GetHistoName() const { return fHistoName; } - /// set histogram name - void SetHistoName(const std::string& HistoName) { fHistoName = HistoName; } - - /// get histogram path - std::string GetHistoPath() const { return fHistoPath; } - /// set histogram path - void SetHistoPath(const std::string& HistoPath) { fHistoPath = HistoPath; } - - /// get name of associated channel - std::string GetChannelName() const { return fChannelName; } - /// set name of associated channel - void SetChannelName(const std::string& ChannelName) { fChannelName = ChannelName; } - - - - std::vector< RooStats::HistFactory::OverallSys >& GetOverallSysList() { return fOverallSysList; } - std::vector< RooStats::HistFactory::NormFactor >& GetNormFactorList() { return fNormFactorList; } - std::vector< RooStats::HistFactory::HistoSys >& GetHistoSysList() { return fHistoSysList; } - std::vector< RooStats::HistFactory::HistoFactor >& GetHistoFactorList() { return fHistoFactorList; } - std::vector< RooStats::HistFactory::ShapeSys >& GetShapeSysList() { return fShapeSysList; } - std::vector< RooStats::HistFactory::ShapeFactor >& GetShapeFactorList() { return fShapeFactorList; } - - const std::vector< RooStats::HistFactory::OverallSys >& GetOverallSysList() const { return fOverallSysList; } - const std::vector< RooStats::HistFactory::NormFactor >& GetNormFactorList() const { return fNormFactorList; } - const std::vector< RooStats::HistFactory::HistoSys >& GetHistoSysList() const { return fHistoSysList; } - const std::vector< RooStats::HistFactory::HistoFactor >& GetHistoFactorList() const { return fHistoFactorList; } - const std::vector< RooStats::HistFactory::ShapeSys >& GetShapeSysList() const { return fShapeSysList; } - const std::vector< RooStats::HistFactory::ShapeFactor >& GetShapeFactorList() const { return fShapeFactorList; } - - - bool HasStatError() const { return fStatErrorActivate; } - RooStats::HistFactory::StatError& GetStatError() { return fStatError; } - const RooStats::HistFactory::StatError& GetStatError() const { return fStatError; } - void SetStatError( RooStats::HistFactory::StatError Error ) { - fStatError = std::move(Error); - } - -protected: - - std::string fName; - std::string fInputFile; - std::string fHistoName; - std::string fHistoPath; - - /// The Name of the parent channel - std::string fChannelName; - - // - // Systematics - // - - std::vector< RooStats::HistFactory::OverallSys > fOverallSysList; - std::vector< RooStats::HistFactory::NormFactor > fNormFactorList; - - std::vector< RooStats::HistFactory::HistoSys > fHistoSysList; - std::vector< RooStats::HistFactory::HistoFactor > fHistoFactorList; - - std::vector< RooStats::HistFactory::ShapeSys > fShapeSysList; - std::vector< RooStats::HistFactory::ShapeFactor > fShapeFactorList; - - - /// Properties - RooStats::HistFactory::StatError fStatError; - - bool fNormalizeByTheory = false; - bool fStatErrorActivate = false; - - - /// The Nominal Shape - HistRef fhNominal; - std::unique_ptr fhCountingHist; - -}; - - -} // namespace HistFactory -} // namespace RooStats - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/inc/RooStats/HistFactory/Systematics.h b/roofit/histfactory/inc/RooStats/HistFactory/Systematics.h index 8f93f0ee2f217..14fcf1568c989 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/Systematics.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/Systematics.h @@ -1,372 +1 @@ -// @(#)root/roostats:$Id$ -// Author: George Lewis, Kyle Cranmer -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -#ifndef HISTFACTORY_SYSTEMATICS_H -#define HISTFACTORY_SYSTEMATICS_H - -#include -#include -#include - -#include "TH1.h" -#include "TDirectory.h" -#include "RooStats/HistFactory/HistRef.h" - -namespace RooStats{ -namespace HistFactory { - - namespace Constraint { - enum Type{ Gaussian, Poisson }; - std::string Name( Type type ); - Type GetType( const std::string& Name ); - } - -/** \class OverallSys - * \ingroup HistFactory - * Configuration for a constrained overall systematic to scale sample normalisations. - */ - class OverallSys { - - public: - - OverallSys() : fLow(0), fHigh(0) {} - - void SetName( const std::string& Name ) { fName = Name; } - const std::string& GetName() const { return fName; } - - void SetLow( double Low ) { fLow = Low; } - void SetHigh( double High ) { fHigh = High; } - double GetLow() const { return fLow; } - double GetHigh() const { return fHigh; } - - void Print(std::ostream& = std::cout) const; - void PrintXML(std::ostream&) const; - - protected: - std::string fName; - double fLow; - double fHigh; - - }; - -/** \class NormFactor - * \ingroup HistFactory - * Configuration for an \a un- constrained overall systematic to scale sample normalisations. - */ - class NormFactor { - - public: - - NormFactor(); - - void SetName( const std::string& Name ) { fName = Name; } - std::string GetName() const { return fName; } - - void SetVal( double Val ) { fVal = Val; } - double GetVal() const { return fVal; } - - void SetLow( double Low ) { fLow = Low; } - void SetHigh( double High ) { fHigh = High; } - double GetLow() const { return fLow; } - double GetHigh() const { return fHigh; } - - void Print(std::ostream& = std::cout) const; - void PrintXML(std::ostream&) const; - - protected: - - std::string fName; - double fVal; - double fLow; - double fHigh; - - }; - - - /** //////////////////////////////////////////////////////////////////////////////////////////// - * \class HistogramUncertaintyBase - * \ingroup HistFactory - * Base class to store the up and down variations for histogram uncertainties. - * Use the derived classes for actual models. - */ - class HistogramUncertaintyBase { - - public: - - HistogramUncertaintyBase() : fhLow(nullptr), fhHigh(nullptr) {} - HistogramUncertaintyBase(const std::string& Name) : fName(Name), fhLow(nullptr), fhHigh(nullptr) {} - HistogramUncertaintyBase(const HistogramUncertaintyBase& oth) : - fName{oth.fName}, - fInputFileLow{oth.fInputFileLow}, fHistoNameLow{oth.fHistoNameLow}, fHistoPathLow{oth.fHistoPathLow}, - fInputFileHigh{oth.fInputFileHigh}, fHistoNameHigh{oth.fHistoNameHigh}, fHistoPathHigh{oth.fHistoPathHigh}, - fhLow{oth.fhLow ? static_cast(oth.fhLow->Clone()) : nullptr}, - fhHigh{oth.fhHigh ? static_cast(oth.fhHigh->Clone()) : nullptr} { - if (fhLow) - fhLow->SetDirectory(nullptr); - if (fhHigh) - fhHigh->SetDirectory(nullptr); - } - HistogramUncertaintyBase(HistogramUncertaintyBase&&) = default; - - virtual ~HistogramUncertaintyBase() {}; - - - // Need deep copies because the class owns its histograms. - HistogramUncertaintyBase& operator=(const HistogramUncertaintyBase& oth) { - fName = oth.fName; - fInputFileLow = oth.fInputFileLow; - fHistoNameLow = oth.fHistoNameLow; - fHistoPathLow = oth.fHistoPathLow; - fInputFileHigh = oth.fInputFileHigh; - fHistoNameHigh = oth.fHistoNameHigh; - fHistoPathHigh = oth.fHistoPathHigh; - - TDirectory::TContext ctx{nullptr}; // Don't associate clones to directories - fhLow.reset(oth.fhLow ? static_cast(oth.fhLow->Clone()) : nullptr); - fhHigh.reset(oth.fhHigh ? static_cast(oth.fhHigh->Clone()) : nullptr); - - return *this; - } - HistogramUncertaintyBase& operator=(HistogramUncertaintyBase&&) = default; - - virtual void Print(std::ostream& = std::cout) const; - virtual void PrintXML(std::ostream&) const = 0; - virtual void writeToFile( const std::string& FileName, const std::string& DirName ); - - void SetHistoLow(TH1* Low ) {Low->SetDirectory(nullptr); fhLow.reset(Low);} - void SetHistoHigh(TH1* High ) {High->SetDirectory(nullptr); fhHigh.reset(High);} - - const TH1* GetHistoLow() const {return fhLow.get();} - const TH1* GetHistoHigh() const {return fhHigh.get();} - - void SetName( const std::string& Name ) { fName = Name; } - const std::string& GetName() const { return fName; } - - void SetInputFileLow( const std::string& InputFileLow ) { fInputFileLow = InputFileLow; } - void SetInputFileHigh( const std::string& InputFileHigh ) { fInputFileHigh = InputFileHigh; } - - const std::string& GetInputFileLow() const { return fInputFileLow; } - const std::string& GetInputFileHigh() const { return fInputFileHigh; } - - void SetHistoNameLow( const std::string& HistoNameLow ) { fHistoNameLow = HistoNameLow; } - void SetHistoNameHigh( const std::string& HistoNameHigh ) { fHistoNameHigh = HistoNameHigh; } - - const std::string& GetHistoNameLow() const { return fHistoNameLow; } - const std::string& GetHistoNameHigh() const { return fHistoNameHigh; } - - void SetHistoPathLow( const std::string& HistoPathLow ) { fHistoPathLow = HistoPathLow; } - void SetHistoPathHigh( const std::string& HistoPathHigh ) { fHistoPathHigh = HistoPathHigh; } - - const std::string& GetHistoPathLow() const { return fHistoPathLow; } - const std::string& GetHistoPathHigh() const { return fHistoPathHigh; } - - protected: - - std::string fName; - - std::string fInputFileLow; - std::string fHistoNameLow; - std::string fHistoPathLow; - - std::string fInputFileHigh; - std::string fHistoNameHigh; - std::string fHistoPathHigh; - - // The Low and High Histograms - std::unique_ptr fhLow; - std::unique_ptr fhHigh; - - }; - -/** \class HistoSys - * \ingroup HistFactory - * Configuration for a constrained, coherent shape variation of affected samples. - */ -class HistoSys final : public HistogramUncertaintyBase { -public: - void PrintXML(std::ostream&) const override; -}; - -/** \class HistoFactor - * \ingroup HistFactory - * Configuration for an *un*constrained, coherent shape variation of affected samples. - */ - class HistoFactor final : public HistogramUncertaintyBase { - public: - void PrintXML(std::ostream&) const override; - }; - -/** \class ShapeSys - * \ingroup HistFactory - * Constrained bin-by-bin variation of affected histogram. - */ - class ShapeSys final : public HistogramUncertaintyBase { - - public: - ShapeSys() : fConstraintType(Constraint::Gaussian) {} - ShapeSys(const ShapeSys& other) : - HistogramUncertaintyBase(other), - fConstraintType(other.fConstraintType) {} - ShapeSys& operator=(const ShapeSys& oth) { - if (this == &oth) return *this; - HistogramUncertaintyBase::operator=(oth); - fConstraintType = oth.fConstraintType; - return *this; - } - ShapeSys& operator=(ShapeSys&&) = default; - - void SetInputFile( const std::string& InputFile ) { fInputFileHigh = InputFile; } - std::string GetInputFile() const { return fInputFileHigh; } - - void SetHistoName( const std::string& HistoName ) { fHistoNameHigh = HistoName; } - std::string GetHistoName() const { return fHistoNameHigh; } - - void SetHistoPath( const std::string& HistoPath ) { fHistoPathHigh = HistoPath; } - std::string GetHistoPath() const { return fHistoPathHigh; } - - void Print(std::ostream& = std::cout) const override; - void PrintXML(std::ostream&) const override; - void writeToFile( const std::string& FileName, const std::string& DirName ) override; - - const TH1* GetErrorHist() const { - return fhHigh.get(); - } - void SetErrorHist(TH1* hError) { - fhHigh.reset(hError); - } - - void SetConstraintType( Constraint::Type ConstrType ) { fConstraintType = ConstrType; } - Constraint::Type GetConstraintType() const { return fConstraintType; } - - protected: - Constraint::Type fConstraintType; - }; - -/** \class ShapeFactor - * \ingroup HistFactory - * *Un*constrained bin-by-bin variation of affected histogram. - */ - class ShapeFactor : public HistogramUncertaintyBase { - - public: - void Print(std::ostream& = std::cout) const override; - void PrintXML(std::ostream&) const override; - void writeToFile( const std::string& FileName, const std::string& DirName) override; - - void SetInitialShape(TH1* shape) { - fhHigh.reset(shape); - } - const TH1* GetInitialShape() const { return fhHigh.get(); } - - void SetConstant(bool constant) { fConstant = constant; } - bool IsConstant() const { return fConstant; } - - bool HasInitialShape() const { return fHasInitialShape; } - - void SetInputFile( const std::string& InputFile ) { - fInputFileHigh = InputFile; - fHasInitialShape=true; - } - const std::string& GetInputFile() const { return fInputFileHigh; } - - void SetHistoName( const std::string& HistoName ) { - fHistoNameHigh = HistoName; - fHasInitialShape=true; - } - const std::string& GetHistoName() const { return fHistoNameHigh; } - - void SetHistoPath( const std::string& HistoPath ) { - fHistoPathHigh = HistoPath; - fHasInitialShape=true; - } - const std::string& GetHistoPath() const { return fHistoPathHigh; } - - protected: - - bool fConstant = false; - - // A histogram representing - // the initial shape - bool fHasInitialShape = false; - }; - -/** \class StatError - * \ingroup HistFactory - * Statistical error of Monte Carlo predictions. - */ - class StatError : public HistogramUncertaintyBase { - - public: - void Print(std::ostream& = std::cout) const override; - void PrintXML(std::ostream&) const override; - void writeToFile( const std::string& FileName, const std::string& DirName ) override; - - void Activate( bool IsActive=true ) { fActivate = IsActive; } - bool GetActivate() const { return fActivate; } - - void SetUseHisto( bool UseHisto=true ) { fUseHisto = UseHisto; } - bool GetUseHisto() const { return fUseHisto; } - - void SetInputFile( const std::string& InputFile ) { fInputFileHigh = InputFile; } - const std::string& GetInputFile() const { return fInputFileHigh; } - - void SetHistoName( const std::string& HistoName ) { fHistoNameHigh = HistoName; } - const std::string& GetHistoName() const { return fHistoNameHigh; } - - void SetHistoPath( const std::string& HistoPath ) { fHistoPathHigh = HistoPath; } - const std::string& GetHistoPath() const { return fHistoPathHigh; } - - - const TH1* GetErrorHist() const { - return fhHigh.get(); - } - void SetErrorHist(TH1* Error) { - fhHigh.reset(Error); - } - - protected: - - bool fActivate = false; - bool fUseHisto = false; // Use an external histogram for the errors - }; - -/** \class StatErrorConfig - * \ingroup HistFactory - * Configuration to automatically assign nuisance parameters for the statistical - * error of the Monte Carlo simulations. - * The default is to assign a Poisson uncertainty to a bin when its statistical uncertainty - * is larger than 5% of the bin content. - */ - class StatErrorConfig { - - public: - - StatErrorConfig() : fRelErrorThreshold( .05 ), fConstraintType( Constraint::Poisson ) {;} - void Print(std::ostream& = std::cout) const; - void PrintXML(std::ostream&) const; - - void SetRelErrorThreshold( double Threshold ) { fRelErrorThreshold = Threshold; } - double GetRelErrorThreshold() const { return fRelErrorThreshold; } - - void SetConstraintType( Constraint::Type ConstrType ) { fConstraintType = ConstrType; } - Constraint::Type GetConstraintType() const { return fConstraintType; } - - protected: - - double fRelErrorThreshold; - Constraint::Type fConstraintType; - - }; - - -} -} - -#endif +#warning "Header is deprecated and will be removed in ROOT 7. Just include RooStats/HistFactory/Measurement.h" diff --git a/roofit/histfactory/src/Asimov.cxx b/roofit/histfactory/src/Asimov.cxx deleted file mode 100644 index 1c1436e910e28..0000000000000 --- a/roofit/histfactory/src/Asimov.cxx +++ /dev/null @@ -1,116 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: Kyle Cranmer, George Lewis -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// -/** \class RooStats::HistFactory::Asimov - * \ingroup HistFactory - * TODO Here, we are missing some documentation. -*/ - -#include "RooRealVar.h" -#include "RooStats/HistFactory/HistFactoryException.h" - -#include "RooStats/HistFactory/Asimov.h" - -void RooStats::HistFactory::Asimov::ConfigureWorkspace(RooWorkspace* wspace) { - - // Here is where we set the values, and constantness - // of all parameters in the workspace before creating - // an asimov dataset - - /* - // Okay, y'all, first we're going to create a snapshot - // of the current state of the variables in the workspace - - std::string ListOfVariableNames = ""; - for( std::map< std::string, double >::iterator itr = fParamValsToSet.begin(); - itr != fParamValsToSet.end(); ++itr) { - // Extend the Variable Name list - ListOfVariableNames += "," + itr->first; - } - for( std::map< std::string, bool >::iterator itr = fParamsToFix.begin(); - itr != fParamsToFix.end(); ++itr) { - // Extend the Variable Name list - ListOfVariableNames += "," + itr->first; - } - - // Save a snapshot - std::string SnapShotName = "NominalParamValues"; - wspace->saveSnapshot(SnapShotName.c_str(), ListOfVariableNames.c_str()); - */ - - // - // First we set all parameters to their given values - // - - - for( std::map< std::string, double >::iterator itr = fParamValsToSet.begin(); - itr != fParamValsToSet.end(); ++itr) { - - std::string param = itr->first; - double val = itr->second; - - // Try to get the variable in the workspace - RooRealVar* var = wspace->var(param); - if( !var ) { - std::cout << "Error: Trying to set variable: " << var - << " to a specific value in creation of asimov dataset: " << fName - << " but this variable doesn't appear to exist in the workspace" - << std::endl; - throw hf_exc(); - } - - // Check that the desired value is in the range of the variable - double inRange = var->inRange(val, nullptr); - if( !inRange ) { - std::cout << "Error: Attempting to set variable: " << var - << " to value: " << val << ", however it appears" - << " that this is not withn the variable's range: " - << "[" << var->getMin() << ", " << var->getMax() << "]" - << std::endl; - throw hf_exc(); - } - - // Set its value - std::cout << "Configuring Asimov Dataset: Setting " << param - << " = " << val << std::endl; - var->setVal( val ); - } - - - // - // Then, we set any variables to constant - // - - for( std::map< std::string, bool >::iterator itr = fParamsToFix.begin(); - itr != fParamsToFix.end(); ++itr) { - - std::string param = itr->first; - bool isConstant = itr->second; - - // Try to get the variable in the workspace - RooRealVar* var = wspace->var(param); - if( !var ) { - std::cout << "Error: Trying to set variable: " << var - << " constant in creation of asimov dataset: " << fName - << " but this variable doesn't appear to exist in the workspace" - << std::endl; - throw hf_exc(); - } - - std::cout << "Configuring Asimov Dataset: Setting " << param - << " to constant " << std::endl; - var->setConstant( isConstant ); - - } - - return; - -} diff --git a/roofit/histfactory/src/Channel.cxx b/roofit/histfactory/src/Channel.cxx deleted file mode 100644 index 33f0c2f2a40ca..0000000000000 --- a/roofit/histfactory/src/Channel.cxx +++ /dev/null @@ -1,488 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: Kyle Cranmer, George Lewis -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// -/** \class RooStats::HistFactory::Channel - * \ingroup HistFactory - This class encapsulates all information for the statistical interpretation of one experiment. - It can be combined with other channels (e.g. for the combination of multiple experiments, or - to constrain nuisance parameters with information obtained in a control region). - A channel contains one or more samples which describe the contribution from different processes - to this measurement. -*/ - - - -#include "RooStats/HistFactory/Channel.h" -#include "HFMsgService.h" -#include - -#include "TFile.h" -#include "TKey.h" -#include "TTimeStamp.h" -#include "TDirectory.h" - -#include "RooStats/HistFactory/HistFactoryException.h" - -using std::ofstream; - -RooStats::HistFactory::Channel::Channel(std::string ChanName, std::string ChanInputFile) : - fName( ChanName ), fInputFile( ChanInputFile ) -{ - // create channel with given name and input file -} - -namespace RooStats{ - namespace HistFactory{ - //BadChannel = Channel(); - Channel BadChannel; - // BadChannel.Name = "BadChannel"; // = Channel(); //.Name = "BadChannel"; - } -} - - -void RooStats::HistFactory::Channel::AddSample( RooStats::HistFactory::Sample sample ) -{ - // add fully configured sample to channel - - sample.SetChannelName( GetName() ); - fSamples.push_back( sample ); -} - -void RooStats::HistFactory::Channel::Print( std::ostream& stream ) { - // print information of channel to given stream - - stream << "\t Channel Name: " << fName - << "\t InputFile: " << fInputFile - << std::endl; - - stream << "\t Data:" << std::endl; - fData.Print( stream ); - - - stream << "\t statErrorConfig:" << std::endl; - fStatErrorConfig.Print( stream ); - - - if( !fSamples.empty() ) { - - stream << "\t Samples: " << std::endl; - for( unsigned int i = 0; i < fSamples.size(); ++i ) { - fSamples.at(i).Print( stream ); - } - } - - - stream << "\t End of Channel " << fName << std::endl; - - -} - - -void RooStats::HistFactory::Channel::PrintXML( std::string const& directory, std::string const& prefix ) const { - - // Create an XML file for this channel - cxcoutPHF << "Printing XML Files for channel: " << GetName() << std::endl; - - std::string XMLName = prefix + fName + ".xml"; - if(!directory.empty()) XMLName = directory + "/" + XMLName; - - ofstream xml( XMLName.c_str() ); - - // Add the time - xml << "" << std::endl; - - // Add the DOCTYPE - xml << " " << std::endl << std::endl; - - // Add the Channel - xml << " " << std::endl << std::endl; - - fData.PrintXML( xml ); - for(auto const& data : fAdditionalData) { - data.PrintXML(xml); - } - - fStatErrorConfig.PrintXML( xml ); - /* - xml << " " << std::endl << std::endl; - */ - - for(auto const& sample : fSamples) { - sample.PrintXML( xml ); - xml << std::endl << std::endl; - } - - xml << std::endl; - xml << " " << std::endl; - xml.close(); - - cxcoutPHF << "Finished printing XML files" << std::endl; - -} - - -void RooStats::HistFactory::Channel::SetData( std::string DataHistoName, std::string DataInputFile, std::string DataHistoPath ) { - // set data for this channel by specifying the name of the histogram, - // the external ROOT file and the path to the histogram inside the ROOT file - - fData.SetHistoName( DataHistoName ); - fData.SetInputFile( DataInputFile ); - fData.SetHistoPath( DataHistoPath ); - -} - - - -void RooStats::HistFactory::Channel::SetData( TH1* hData ) { - // set data directly to some histogram - fData.SetHisto( hData ); -} - -void RooStats::HistFactory::Channel::SetData( double val ) { - - // For a NumberCounting measurement only - // Set the value of data in a particular channel - // - // Internally, this simply creates a 1-bin TH1F for you - - std::string DataHistName = fName + "_data"; - - // Histogram has 1-bin (hard-coded) - TH1F* hData = new TH1F( DataHistName.c_str(), DataHistName.c_str(), 1, 0, 1 ); - hData->SetBinContent( 1, val ); - - // Set the histogram of the internally held data - // node of this channel to this newly created histogram - SetData( hData ); - -} - - -void RooStats::HistFactory::Channel::SetStatErrorConfig( double StatRelErrorThreshold, Constraint::Type StatConstraintType ) { - - fStatErrorConfig.SetRelErrorThreshold( StatRelErrorThreshold ); - fStatErrorConfig.SetConstraintType( StatConstraintType ); - -} - -void RooStats::HistFactory::Channel::SetStatErrorConfig( double StatRelErrorThreshold, std::string StatConstraintType ) { - - fStatErrorConfig.SetRelErrorThreshold( StatRelErrorThreshold ); - fStatErrorConfig.SetConstraintType( Constraint::GetType(StatConstraintType) ); - -} - - - -void RooStats::HistFactory::Channel::CollectHistograms() { - - // Loop through all Samples and Systematics - // and collect all necessary histograms - - // Handles to open files for collecting histograms - std::map> fileHandles; - - // Get the Data Histogram: - - if( !fData.GetInputFile().empty() ) { - fData.SetHisto( GetHistogram(fData.GetInputFile(), - fData.GetHistoPath(), - fData.GetHistoName(), - fileHandles) ); - } - - // Collect any histograms for additional Datasets - for(auto& data : fAdditionalData) { - if( !data.GetInputFile().empty() ) { - data.SetHisto( GetHistogram(data.GetInputFile(), data.GetHistoPath(), data.GetHistoName(), fileHandles) ); - } - } - - // Get the histograms for the samples: - for( unsigned int sampItr = 0; sampItr < fSamples.size(); ++sampItr ) { - - RooStats::HistFactory::Sample& sample = fSamples.at( sampItr ); - - - // Get the nominal histogram: - cxcoutDHF << "Collecting Nominal Histogram" << std::endl; - TH1* Nominal = GetHistogram(sample.GetInputFile(), - sample.GetHistoPath(), - sample.GetHistoName(), - fileHandles); - - sample.SetHisto( Nominal ); - - - // Get the StatError Histogram (if necessary) - if( sample.GetStatError().GetUseHisto() ) { - sample.GetStatError().SetErrorHist( GetHistogram(sample.GetStatError().GetInputFile(), - sample.GetStatError().GetHistoPath(), - sample.GetStatError().GetHistoName(), - fileHandles) ); - } - - - // Get the HistoSys Variations: - for( unsigned int histoSysItr = 0; histoSysItr < sample.GetHistoSysList().size(); ++histoSysItr ) { - - RooStats::HistFactory::HistoSys& histoSys = sample.GetHistoSysList().at( histoSysItr ); - - histoSys.SetHistoLow( GetHistogram(histoSys.GetInputFileLow(), - histoSys.GetHistoPathLow(), - histoSys.GetHistoNameLow(), - fileHandles) ); - - histoSys.SetHistoHigh( GetHistogram(histoSys.GetInputFileHigh(), - histoSys.GetHistoPathHigh(), - histoSys.GetHistoNameHigh(), - fileHandles) ); - } // End Loop over HistoSys - - - // Get the HistoFactor Variations: - for( unsigned int histoFactorItr = 0; histoFactorItr < sample.GetHistoFactorList().size(); ++histoFactorItr ) { - - RooStats::HistFactory::HistoFactor& histoFactor = sample.GetHistoFactorList().at( histoFactorItr ); - - histoFactor.SetHistoLow( GetHistogram(histoFactor.GetInputFileLow(), - histoFactor.GetHistoPathLow(), - histoFactor.GetHistoNameLow(), - fileHandles) ); - - histoFactor.SetHistoHigh( GetHistogram(histoFactor.GetInputFileHigh(), - histoFactor.GetHistoPathHigh(), - histoFactor.GetHistoNameHigh(), - fileHandles) ); - } // End Loop over HistoFactor - - - // Get the ShapeSys Variations: - for( unsigned int shapeSysItr = 0; shapeSysItr < sample.GetShapeSysList().size(); ++shapeSysItr ) { - - RooStats::HistFactory::ShapeSys& shapeSys = sample.GetShapeSysList().at( shapeSysItr ); - - shapeSys.SetErrorHist( GetHistogram(shapeSys.GetInputFile(), - shapeSys.GetHistoPath(), - shapeSys.GetHistoName(), - fileHandles) ); - } // End Loop over ShapeSys - - - // Get any initial shape for a ShapeFactor - for( unsigned int shapeFactorItr = 0; shapeFactorItr < sample.GetShapeFactorList().size(); ++shapeFactorItr ) { - - RooStats::HistFactory::ShapeFactor& shapeFactor = sample.GetShapeFactorList().at( shapeFactorItr ); - - // Check if we need an InitialShape - if( shapeFactor.HasInitialShape() ) { - TH1* hist = GetHistogram( shapeFactor.GetInputFile(), shapeFactor.GetHistoPath(), - shapeFactor.GetHistoName(), fileHandles ); - shapeFactor.SetInitialShape( hist ); - } - - } // End Loop over ShapeFactor - - } // End Loop over Samples -} - - -bool RooStats::HistFactory::Channel::CheckHistograms() const { - - // Check that all internal histogram pointers - // are properly configured (ie that they're not nullptr) - - if( fData.GetHisto() == nullptr && !fData.GetInputFile().empty() ) { - cxcoutEHF << "Error: Data Histogram for channel " << GetName() << " is nullptr." << std::endl; - return false; - } - - // Get the histograms for the samples: - for( unsigned int sampItr = 0; sampItr < fSamples.size(); ++sampItr ) { - - const RooStats::HistFactory::Sample& sample = fSamples.at( sampItr ); - - // Get the nominal histogram: - if( sample.GetHisto() == nullptr ) { - cxcoutEHF << "Error: Nominal Histogram for sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - else { - - // Check if any bins are negative - std::vector NegativeBinNumber; - std::vector NegativeBinContent; - const TH1* histNominal = sample.GetHisto(); - for(int ibin=1; ibin<=histNominal->GetNbinsX(); ++ibin) { - if(histNominal->GetBinContent(ibin) < 0) { - NegativeBinNumber.push_back(ibin); - NegativeBinContent.push_back(histNominal->GetBinContent(ibin)); - } - } - if(!NegativeBinNumber.empty()) { - cxcoutWHF << "WARNING: Nominal Histogram " << histNominal->GetName() << " for Sample = " << sample.GetName() - << " in Channel = " << GetName() << " has negative entries in bin numbers = "; - - for(unsigned int ibin=0; ibin0) std::cout << " , " ; - std::cout << NegativeBinNumber[ibin] << " : " << NegativeBinContent[ibin] ; - } - std::cout << std::endl; - } - - } - - // Get the StatError Histogram (if necessary) - if( sample.GetStatError().GetUseHisto() ) { - if( sample.GetStatError().GetErrorHist() == nullptr ) { - cxcoutEHF << "Error: Statistical Error Histogram for sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - } - - - // Get the HistoSys Variations: - for( unsigned int histoSysItr = 0; histoSysItr < sample.GetHistoSysList().size(); ++histoSysItr ) { - - const RooStats::HistFactory::HistoSys& histoSys = sample.GetHistoSysList().at( histoSysItr ); - - if( histoSys.GetHistoLow() == nullptr ) { - cxcoutEHF << "Error: HistoSyst Low for Systematic " << histoSys.GetName() - << " in sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - if( histoSys.GetHistoHigh() == nullptr ) { - cxcoutEHF << "Error: HistoSyst High for Systematic " << histoSys.GetName() - << " in sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - - } // End Loop over HistoSys - - - // Get the HistoFactor Variations: - for( unsigned int histoFactorItr = 0; histoFactorItr < sample.GetHistoFactorList().size(); ++histoFactorItr ) { - - const RooStats::HistFactory::HistoFactor& histoFactor = sample.GetHistoFactorList().at( histoFactorItr ); - - if( histoFactor.GetHistoLow() == nullptr ) { - cxcoutEHF << "Error: HistoSyst Low for Systematic " << histoFactor.GetName() - << " in sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - if( histoFactor.GetHistoHigh() == nullptr ) { - cxcoutEHF << "Error: HistoSyst High for Systematic " << histoFactor.GetName() - << " in sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - - } // End Loop over HistoFactor - - - // Get the ShapeSys Variations: - for( unsigned int shapeSysItr = 0; shapeSysItr < sample.GetShapeSysList().size(); ++shapeSysItr ) { - - const RooStats::HistFactory::ShapeSys& shapeSys = sample.GetShapeSysList().at( shapeSysItr ); - - if( shapeSys.GetErrorHist() == nullptr ) { - cxcoutEHF << "Error: HistoSyst High for Systematic " << shapeSys.GetName() - << " in sample " << sample.GetName() << " is nullptr." << std::endl; - return false; - } - - } // End Loop over ShapeSys - - } // End Loop over Samples - - return true; -} - - - -/// Open a file and copy a histogram -/// \param InputFile File where the histogram resides. -/// \param HistoPath Path of the histogram in the file. -/// \param HistoName Name of the histogram to retrieve. -/// \param lsof List of open files. Helps to prevent opening and closing a file hundreds of times. -TH1* RooStats::HistFactory::Channel::GetHistogram(std::string InputFile, std::string HistoPath, std::string HistoName, std::map>& lsof) { - - cxcoutPHF << "Getting histogram " << InputFile << ":" << HistoPath << "/" << HistoName << std::endl; - - auto& inFile = lsof[InputFile]; - if (!inFile || !inFile->IsOpen()) { - inFile.reset( TFile::Open(InputFile.c_str()) ); - if ( !inFile || !inFile->IsOpen() ) { - cxcoutEHF << "Error: Unable to open input file: " << InputFile << std::endl; - throw hf_exc(); - } - cxcoutIHF << "Opened input file: " << InputFile << ": " << std::endl; - } - - TDirectory* dir = inFile->GetDirectory(HistoPath.c_str()); - if (dir == nullptr) { - cxcoutEHF << "Histogram path '" << HistoPath - << "' wasn't found in file '" << InputFile << "'." << std::endl; - throw hf_exc(); - } - - // Have to read histograms via keys, to ensure that the latest-greatest - // name cycle is read from file. Otherwise, they might come from memory. - auto key = dir->GetKey(HistoName.c_str()); - if (key == nullptr) { - cxcoutEHF << "Histogram '" << HistoName - << "' wasn't found in file '" << InputFile - << "' in directory '" << HistoPath << "'." << std::endl; - throw hf_exc(); - } - - std::unique_ptr hist(key->ReadObject()); - if( !hist ) { - cxcoutEHF << "Histogram '" << HistoName - << "' wasn't found in file '" << InputFile - << "' in directory '" << HistoPath << "'." << std::endl; - throw hf_exc(); - } - - TDirectory::TContext ctx{nullptr}; - TH1 * ptr = static_cast(hist->Clone()); - - if(!ptr){ - std::cerr << "Not all necessary info are set to access the input file. Check your config" << std::endl; - std::cerr << "filename: " << InputFile - << "path: " << HistoPath - << "obj: " << HistoName << std::endl; - throw hf_exc(); - } - -#ifdef DEBUG - std::cout << "Found Histogram: " << HistoName " at address: " << ptr - << " with integral " << ptr->Integral() << " and mean " << ptr->GetMean() - << std::endl; -#endif - - // Done - return ptr; - -} diff --git a/roofit/histfactory/src/Data.cxx b/roofit/histfactory/src/Data.cxx deleted file mode 100644 index 5b2d6326e88fc..0000000000000 --- a/roofit/histfactory/src/Data.cxx +++ /dev/null @@ -1,74 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: Kyle Cranmer, George Lewis -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// -/** \class RooStats::HistFactory::Data - * \ingroup HistFactory -*/ - - -#include "RooStats/HistFactory/Data.h" - - -RooStats::HistFactory::Data::Data( std::string HistoName, std::string InputFile, - std::string HistoPath ) : - fInputFile( InputFile ), fHistoName( HistoName ), fHistoPath( HistoPath ) {;} - -TH1* RooStats::HistFactory::Data::GetHisto() { - return (TH1*) fhData.GetObject(); -} - -const TH1* RooStats::HistFactory::Data::GetHisto() const { - return (TH1*) fhData.GetObject(); -} - - -void RooStats::HistFactory::Data::Print( std::ostream& stream ) { - - - stream << "\t \t InputFile: " << fInputFile - << "\t HistoName: " << fHistoName - << "\t HistoPath: " << fHistoPath - << "\t HistoAddress: " << GetHisto() - << std::endl; - -} - -void RooStats::HistFactory::Data::writeToFile( std::string OutputFileName, std::string DirName ) { - - TH1* histData = GetHisto(); - - if( histData != nullptr) { - - histData->Write(); - - // Set the location of the data - // in the output measurement - - fInputFile = OutputFileName; - fHistoName = histData->GetName(); - fHistoPath = DirName; - - } - -} - - -void RooStats::HistFactory::Data::PrintXML( std::ostream& xml ) const { - - xml << " " << std::endl << std::endl; - -} diff --git a/roofit/histfactory/src/HistRef.cxx b/roofit/histfactory/src/HistRef.cxx deleted file mode 100644 index 4501d92be9ca4..0000000000000 --- a/roofit/histfactory/src/HistRef.cxx +++ /dev/null @@ -1,37 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: L. Moneta -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -/** \class RooStats::HistFactory::HistRef - * \ingroup HistFactory - * Internal class wrapping an histogram and managing its content. - * convenient for dealing with histogram pointers in the - * HistFactory class - */ - -#include "RooStats/HistFactory/HistRef.h" - -#include "TH1.h" -#include "TDirectory.h" - -namespace RooStats{ -namespace HistFactory { - - TH1 * HistRef::CopyObject(const TH1 * h) { - // implementation of method copying the contained pointer - // (just use Clone) - if (!h) return nullptr; - - TDirectory::TContext ctx{nullptr}; // Don't associate histogram with currently open file - return static_cast(h->Clone()); - } -} -} - - diff --git a/roofit/histfactory/src/Measurement.cxx b/roofit/histfactory/src/Measurement.cxx index 333827021f523..bc7b84e43e673 100644 --- a/roofit/histfactory/src/Measurement.cxx +++ b/roofit/histfactory/src/Measurement.cxx @@ -16,33 +16,36 @@ to set some general properties like the integrated luminosity, its relative uncertainty or the functional form of constraints on nuisance parameters. */ +#include -#include "RooStats/HistFactory/Measurement.h" -#include "RooStats/HistFactory/HistFactoryException.h" +#include -#include "HFMsgService.h" +#include +#include +#include + +#include #include +#include +#include #include #include +#include +#include #include #include -#include +#include #include -using std::ofstream; - +namespace RooStats::HistFactory { /// Standard constructor -RooStats::HistFactory::Measurement::Measurement() - : fLumi(1.0), fLumiRelErr(.10), fBinLow(0), fBinHigh(1) -{ - -} +Measurement::Measurement() : fLumi(1.0), fLumiRelErr(.10), fBinLow(0), fBinHigh(1) {} /* -RooStats::HistFactory::Measurement::Measurement(const Measurement& other) : +Measurement::Measurement(const Measurement& other) : POI( other.POI ), Lumi( other.Lumi ), LumiRelErr( other.LumiRelErr ), BinLow( other.BinLow ), BinHigh( other.BinHigh ), ExportOnly( other.ExportOnly ), channels( other.channels ), OutputFilePrefix( other.outputFilePrefix ), @@ -50,12 +53,16 @@ RooStats::HistFactory::Measurement::Measurement(const Measurement& other) : */ /// Standard constructor specifying name and title of measurement -RooStats::HistFactory::Measurement::Measurement(const char *Name, const char *Title) +Measurement::Measurement(const char *Name, const char *Title) : TNamed(Name, Title), fLumi(1.0), fLumiRelErr(.10), fBinLow(0), fBinHigh(1) { - } +/// add a completely configured channel +void Measurement::AddChannel(Channel chan) +{ + fChannels.push_back(chan); +} /// Set a parameter in the model to be constant. /// the parameter does not have to exist yet, the information will be used when @@ -65,367 +72,331 @@ RooStats::HistFactory::Measurement::Measurement(const char *Name, const char *Ti /// We don't need to set it constant twice, /// and we issue a warning in case this is a hint /// of a possible bug -void RooStats::HistFactory::Measurement::AddConstantParam( const std::string& param ) +void Measurement::AddConstantParam(const std::string ¶m) { + if (std::find(fConstantParams.begin(), fConstantParams.end(), param) != fConstantParams.end()) { + cxcoutWHF << "Warning: Setting parameter: " << param << " to constant, but it is already listed as constant. " + << "You may ignore this warning." << std::endl; + return; + } - if( std::find(fConstantParams.begin(), fConstantParams.end(), param) != fConstantParams.end() ) { - cxcoutWHF << "Warning: Setting parameter: " << param - << " to constant, but it is already listed as constant. " - << "You may ignore this warning." - << std::endl; - return; - } - - fConstantParams.push_back( param ); - + fConstantParams.push_back(param); } - /// Set parameter of the model to given value -void RooStats::HistFactory::Measurement::SetParamValue( const std::string& param, double value ) -{ - // Check if this parameter is already set to a value - // If so, issue a warning - // (Not sure if we want to throw an exception here, or - // issue a warning and move along. Thoughts?) - if( fParamValues.find(param) != fParamValues.end() ) { - cxcoutWHF << "Warning: Chainging parameter: " << param - << " value from: " << fParamValues[param] - << " to: " << value - << std::endl; - } - - // Store the parameter and its value - cxcoutIHF << "Setting parameter: " << param - << " value to " << value - << std::endl; +void Measurement::SetParamValue(const std::string ¶m, double value) +{ + // Check if this parameter is already set to a value + // If so, issue a warning + // (Not sure if we want to throw an exception here, or + // issue a warning and move along. Thoughts?) + if (fParamValues.find(param) != fParamValues.end()) { + cxcoutWHF << "Warning: Chainging parameter: " << param << " value from: " << fParamValues[param] + << " to: " << value << std::endl; + } - fParamValues[param] = value; + // Store the parameter and its value + cxcoutIHF << "Setting parameter: " << param << " value to " << value << std::endl; + fParamValues[param] = value; } - /// Add a preprocessed function by giving the function a name, /// a functional expression, and a string with a bracketed list of dependencies (eg "SigXsecOverSM[0,3]") -void RooStats::HistFactory::Measurement::AddPreprocessFunction( std::string name, std::string expression, std::string dependencies ) +void Measurement::AddPreprocessFunction(std::string name, std::string expression, std::string dependencies) { - - PreprocessFunction func(name, expression, dependencies); - AddFunctionObject(func); - + PreprocessFunction func(name, expression, dependencies); + AddFunctionObject(func); } /// Returns a list of defined preprocess function expressions -std::vector RooStats::HistFactory::Measurement::GetPreprocessFunctions() const +std::vector Measurement::GetPreprocessFunctions() const { - - std::vector PreprocessFunctionExpressions; - for( unsigned int i = 0; i < fFunctionObjects.size(); ++i ) { - std::string expression = fFunctionObjects.at(i).GetCommand(); - PreprocessFunctionExpressions.push_back( expression ); - } - return PreprocessFunctionExpressions; + std::vector PreprocessFunctionExpressions; + for (unsigned int i = 0; i < fFunctionObjects.size(); ++i) { + std::string expression = fFunctionObjects.at(i).GetCommand(); + PreprocessFunctionExpressions.push_back(expression); + } + return PreprocessFunctionExpressions; } /// Set constraint term for given systematic to Gamma distribution -void RooStats::HistFactory::Measurement::AddGammaSyst(std::string syst, double uncert) +void Measurement::AddGammaSyst(std::string syst, double uncert) { - fGammaSyst[syst] = uncert; + fGammaSyst[syst] = uncert; } /// Set constraint term for given systematic to LogNormal distribution -void RooStats::HistFactory::Measurement::AddLogNormSyst(std::string syst, double uncert) +void Measurement::AddLogNormSyst(std::string syst, double uncert) { - fLogNormSyst[syst] = uncert; + fLogNormSyst[syst] = uncert; } /// Set constraint term for given systematic to uniform distribution -void RooStats::HistFactory::Measurement::AddUniformSyst(std::string syst) +void Measurement::AddUniformSyst(std::string syst) { - fUniformSyst[syst] = 1.0; // Is this parameter simply a dummy? + fUniformSyst[syst] = 1.0; // Is this parameter simply a dummy? } /// Define given systematics to have no external constraint -void RooStats::HistFactory::Measurement::AddNoSyst(std::string syst) +void Measurement::AddNoSyst(std::string syst) { - fNoSyst[syst] = 1.0; // dummy value + fNoSyst[syst] = 1.0; // dummy value } /// Check if the given channel is part of this measurement -bool RooStats::HistFactory::Measurement::HasChannel( std::string ChanName ) +bool Measurement::HasChannel(std::string ChanName) { + for (unsigned int i = 0; i < fChannels.size(); ++i) { - for( unsigned int i = 0; i < fChannels.size(); ++i ) { - - Channel& chan = fChannels.at(i); - if( chan.GetName() == ChanName ) { - return true; - } - - } - - return false; + Channel &chan = fChannels.at(i); + if (chan.GetName() == ChanName) { + return true; + } + } + return false; } - /// Get channel with given name from this measurement /// throws an exception in case the channel is not found -RooStats::HistFactory::Channel& RooStats::HistFactory::Measurement::GetChannel( std::string ChanName ) +Channel &Measurement::GetChannel(std::string ChanName) { - for( unsigned int i = 0; i < fChannels.size(); ++i ) { - - Channel& chan = fChannels.at(i); - if( chan.GetName() == ChanName ) { - return chan; - } - - } - - // If we get here, we didn't find the channel + for (unsigned int i = 0; i < fChannels.size(); ++i) { - cxcoutEHF << "Error: Did not find channel: " << ChanName - << " in measurement: " << GetName() << std::endl; - throw hf_exc(); + Channel &chan = fChannels.at(i); + if (chan.GetName() == ChanName) { + return chan; + } + } - // No Need to return after throwing exception - // return RooStats::HistFactory::BadChannel; + // If we get here, we didn't find the channel + cxcoutEHF << "Error: Did not find channel: " << ChanName << " in measurement: " << GetName() << std::endl; + throw hf_exc(); + // No Need to return after throwing exception + // return BadChannel; } /* - void RooStats::HistFactory::Measurement::Print( Option_t* option ) const { - RooStats::HistFactory::Measurement::Print( std::cout ); + void Measurement::Print( Option_t* option ) const { + Measurement::Print( std::cout ); return; } */ /// Print information about measurement object in tree-like structure to given stream -void RooStats::HistFactory::Measurement::PrintTree( std::ostream& stream ) +void Measurement::PrintTree(std::ostream &stream) { + stream << "Measurement Name: " << GetName() << "\t OutputFilePrefix: " << fOutputFilePrefix << "\t POI: "; + for (unsigned int i = 0; i < fPOI.size(); ++i) { + stream << fPOI.at(i); + } + stream << "\t Lumi: " << fLumi << "\t LumiRelErr: " << fLumiRelErr << "\t BinLow: " << fBinLow + << "\t BinHigh: " << fBinHigh << "\t ExportOnly: " << fExportOnly << std::endl; - stream << "Measurement Name: " << GetName() - << "\t OutputFilePrefix: " << fOutputFilePrefix - << "\t POI: "; - for(unsigned int i = 0; i < fPOI.size(); ++i) { - stream << fPOI.at(i); - } - stream << "\t Lumi: " << fLumi - << "\t LumiRelErr: " << fLumiRelErr - << "\t BinLow: " << fBinLow - << "\t BinHigh: " << fBinHigh - << "\t ExportOnly: " << fExportOnly - << std::endl; - - - if( !fConstantParams.empty() ) { - stream << "Constant Params: "; - for( unsigned int i = 0; i < fConstantParams.size(); ++i ) { - stream << " " << fConstantParams.at(i); - } - stream << std::endl; - } - - if( !fFunctionObjects.empty() ) { - stream << "Preprocess Functions: "; - for( unsigned int i = 0; i < fFunctionObjects.size(); ++i ) { - stream << " " << fFunctionObjects.at(i).GetCommand(); - } - stream << std::endl; - } + if (!fConstantParams.empty()) { + stream << "Constant Params: "; + for (unsigned int i = 0; i < fConstantParams.size(); ++i) { + stream << " " << fConstantParams.at(i); + } + stream << std::endl; + } - if( !fChannels.empty() ) { - stream << "Channels:" << std::endl; - for( unsigned int i = 0; i < fChannels.size(); ++i ) { - fChannels.at(i).Print( stream ); - } - } + if (!fFunctionObjects.empty()) { + stream << "Preprocess Functions: "; + for (unsigned int i = 0; i < fFunctionObjects.size(); ++i) { + stream << " " << fFunctionObjects.at(i).GetCommand(); + } + stream << std::endl; + } - cxcoutIHF << "End Measurement: " << GetName() << std::endl; + if (!fChannels.empty()) { + stream << "Channels:" << std::endl; + for (unsigned int i = 0; i < fChannels.size(); ++i) { + fChannels.at(i).Print(stream); + } + } + cxcoutIHF << "End Measurement: " << GetName() << std::endl; } - /// Create XML files for this measurement in the given directory. /// XML files can be configured with a different output prefix /// Create an XML file for this measurement /// First, create the XML driver /// Then, create xml files for each channel -void RooStats::HistFactory::Measurement::PrintXML( std::string directory, std::string newOutputPrefix ) -{ - // First, check that the directory exists: - auto testExists = [](const std::string& theDirectory) { - void* dir = gSystem->OpenDirectory(theDirectory.c_str()); - bool exists = dir != nullptr; - if (exists) - gSystem->FreeDirectory(dir); - - return exists; - }; - - if ( !directory.empty() && !testExists(directory) ) { - int success = gSystem->MakeDirectory(directory.c_str() ); - if( success != 0 ) { - cxcoutEHF << "Error: Failed to make directory: " << directory << std::endl; - throw hf_exc(); - } - } - - // If supplied new Prefix, use that one: - - cxcoutPHF << "Printing XML Files for measurement: " << GetName() << std::endl; - - std::string XMLName = std::string(GetName()) + ".xml"; - if( !directory.empty() ) XMLName = directory + "/" + XMLName; - - ofstream xml( XMLName.c_str() ); - - if( ! xml.is_open() ) { - cxcoutEHF << "Error opening xml file: " << XMLName << std::endl; - throw hf_exc(); - } - +void Measurement::PrintXML(std::string directory, std::string newOutputPrefix) +{ + // First, check that the directory exists: + auto testExists = [](const std::string &theDirectory) { + void *dir = gSystem->OpenDirectory(theDirectory.c_str()); + bool exists = dir != nullptr; + if (exists) + gSystem->FreeDirectory(dir); + + return exists; + }; + + if (!directory.empty() && !testExists(directory)) { + int success = gSystem->MakeDirectory(directory.c_str()); + if (success != 0) { + cxcoutEHF << "Error: Failed to make directory: " << directory << std::endl; + throw hf_exc(); + } + } - // Add the time - xml << "" << std::endl; - - // Add the doctype - xml << "" << std::endl << std::endl; - - // Add the combination name - if (newOutputPrefix.empty() ) newOutputPrefix = fOutputFilePrefix; - xml << "" << std::endl << std::endl; - - // Add the Preprocessed Functions - for( unsigned int i = 0; i < fFunctionObjects.size(); ++i ) { - RooStats::HistFactory::PreprocessFunction func = fFunctionObjects.at(i); - func.PrintXML(xml); - /* - xml << "" << std::endl; - */ - } + // If supplied new Prefix, use that one: - xml << std::endl; + cxcoutPHF << "Printing XML Files for measurement: " << GetName() << std::endl; - // Add the list of channels - for( unsigned int i = 0; i < fChannels.size(); ++i ) { - xml << " " << "./"; - if (!directory.empty() ) xml << directory << "/"; - xml << GetName() << "_" << fChannels.at(i).GetName() << ".xml" << "" << std::endl; - } + std::string XMLName = std::string(GetName()) + ".xml"; + if (!directory.empty()) + XMLName = directory + "/" + XMLName; - xml << std::endl; + std::ofstream xml(XMLName.c_str()); - // Open the Measurement, Set Lumi - xml << " " << std::endl; + if (!xml.is_open()) { + cxcoutEHF << "Error opening xml file: " << XMLName << std::endl; + throw hf_exc(); + } + // Add the time + xml << "" << std::endl; + + // Add the doctype + xml << "" << std::endl << std::endl; + + // Add the combination name + if (newOutputPrefix.empty()) + newOutputPrefix = fOutputFilePrefix; + xml << "" << std::endl + << std::endl; - // Set the POI - xml << " " ; - for(unsigned int i = 0; i < fPOI.size(); ++i) { - if(i==0) xml << fPOI.at(i); - else xml << " " << fPOI.at(i); - } - xml << " " << std::endl; - - // Set the Constant Parameters - if(!fConstantParams.empty()) { - xml << " "; - for( unsigned int i = 0; i < fConstantParams.size(); ++i ) { - if (i==0) xml << fConstantParams.at(i); - else xml << " " << fConstantParams.at(i); - } - xml << "" << std::endl; - } + // Add the Preprocessed Functions + for (unsigned int i = 0; i < fFunctionObjects.size(); ++i) { + PreprocessFunction func = fFunctionObjects.at(i); + func.PrintXML(xml); + /* + xml << "" << std::endl; + */ + } - // Set the Parameters with new Constraint Terms - std::map::iterator ConstrItr; + xml << std::endl; - // Gamma - for( ConstrItr = fGammaSyst.begin(); ConstrItr != fGammaSyst.end(); ++ConstrItr ) { - xml << "second << "\">" << ConstrItr->first - << "" << std::endl; - } - // Uniform - for( ConstrItr = fUniformSyst.begin(); ConstrItr != fUniformSyst.end(); ++ConstrItr ) { - xml << "second << "\">" << ConstrItr->first - << "" << std::endl; - } - // LogNormal - for( ConstrItr = fLogNormSyst.begin(); ConstrItr != fLogNormSyst.end(); ++ConstrItr ) { - xml << "second << "\">" << ConstrItr->first - << "" << std::endl; - } - // NoSyst - for( ConstrItr = fNoSyst.begin(); ConstrItr != fNoSyst.end(); ++ConstrItr ) { - xml << "second << "\">" << ConstrItr->first - << "" << std::endl; - } + // Add the list of channels + for (unsigned int i = 0; i < fChannels.size(); ++i) { + xml << " " << "./"; + if (!directory.empty()) + xml << directory << "/"; + xml << GetName() << "_" << fChannels.at(i).GetName() << ".xml" << "" << std::endl; + } + xml << std::endl; + + // Open the Measurement, Set Lumi + xml << " " << std::endl; + + // Set the POI + xml << " "; + for (unsigned int i = 0; i < fPOI.size(); ++i) { + if (i == 0) + xml << fPOI.at(i); + else + xml << " " << fPOI.at(i); + } + xml << " " << std::endl; + + // Set the Constant Parameters + if (!fConstantParams.empty()) { + xml << " "; + for (unsigned int i = 0; i < fConstantParams.size(); ++i) { + if (i == 0) + xml << fConstantParams.at(i); + else + xml << " " << fConstantParams.at(i); + } + xml << "" << std::endl; + } - // Close the Measurement - xml << " " << std::endl << std::endl; + // Set the Parameters with new Constraint Terms + std::map::iterator ConstrItr; - // Close the combination - xml << "" << std::endl; + // Gamma + for (ConstrItr = fGammaSyst.begin(); ConstrItr != fGammaSyst.end(); ++ConstrItr) { + xml << "second << "\">" << ConstrItr->first + << "" << std::endl; + } + // Uniform + for (ConstrItr = fUniformSyst.begin(); ConstrItr != fUniformSyst.end(); ++ConstrItr) { + xml << "second << "\">" << ConstrItr->first + << "" << std::endl; + } + // LogNormal + for (ConstrItr = fLogNormSyst.begin(); ConstrItr != fLogNormSyst.end(); ++ConstrItr) { + xml << "second << "\">" + << ConstrItr->first << "" << std::endl; + } + // NoSyst + for (ConstrItr = fNoSyst.begin(); ConstrItr != fNoSyst.end(); ++ConstrItr) { + xml << "second << "\">" << ConstrItr->first + << "" << std::endl; + } - xml.close(); + // Close the Measurement + xml << " " << std::endl << std::endl; - // Now, make the xml files - // for the individual channels: + // Close the combination + xml << "" << std::endl; - std::string prefix = std::string(GetName()) + "_"; + xml.close(); - for( unsigned int i = 0; i < fChannels.size(); ++i ) { - fChannels.at(i).PrintXML( directory, prefix ); - } + // Now, make the xml files + // for the individual channels: + std::string prefix = std::string(GetName()) + "_"; - cxcoutPHF << "Finished printing XML files" << std::endl; + for (unsigned int i = 0; i < fChannels.size(); ++i) { + fChannels.at(i).PrintXML(directory, prefix); + } + cxcoutPHF << "Finished printing XML files" << std::endl; } - /// A measurement, once fully configured, can be saved into a ROOT /// file. This will persitify the Measurement object, along with any /// channels and samples that have been added to it. It can then be @@ -435,225 +406,1657 @@ void RooStats::HistFactory::Measurement::PrintXML( std::string directory, std::s /// Edit the measurement to point to this file /// and to point to each histogram in this file /// Then write the measurement itself. -void RooStats::HistFactory::Measurement::writeToFile( TFile* file ) +void Measurement::writeToFile(TFile *file) { - // Create a temporary measurement - // (This is the one that is actually written) - RooStats::HistFactory::Measurement outMeas( *this ); + // Create a temporary measurement + // (This is the one that is actually written) + Measurement outMeas(*this); - std::string OutputFileName = file->GetName(); + std::string OutputFileName = file->GetName(); - // Collect all histograms from file: - // HistCollector collector; + // Collect all histograms from file: + // HistCollector collector; + for (unsigned int chanItr = 0; chanItr < outMeas.fChannels.size(); ++chanItr) { - for( unsigned int chanItr = 0; chanItr < outMeas.fChannels.size(); ++chanItr ) { + // Go to the main directory + // in the file + file->cd(); + file->Flush(); - // Go to the main directory - // in the file - file->cd(); - file->Flush(); + // Get the name of the channel: + Channel &channel = outMeas.fChannels.at(chanItr); + std::string chanName = channel.GetName(); - // Get the name of the channel: - RooStats::HistFactory::Channel& channel = outMeas.fChannels.at( chanItr ); - std::string chanName = channel.GetName(); + if (!channel.CheckHistograms()) { + cxcoutEHF << "Measurement.writeToFile(): Channel: " << chanName << " has uninitialized histogram pointers" + << std::endl; + throw hf_exc(); + return; + } + // Get and cache the histograms for this channel: + // collector.CollectHistograms( channel ); + // Do I need this...? + // channel.CollectHistograms(); - if( ! channel.CheckHistograms() ) { - cxcoutEHF << "Measurement.writeToFile(): Channel: " << chanName - << " has uninitialized histogram pointers" << std::endl; - throw hf_exc(); - return; - } + // Make a directory to store the histograms + // for this channel - // Get and cache the histograms for this channel: - //collector.CollectHistograms( channel ); - // Do I need this...? - // channel.CollectHistograms(); + TDirectory *chanDir = file->mkdir((chanName + "_hists").c_str()); + if (chanDir == nullptr) { + cxcoutEHF << "Error: Cannot create channel " << (chanName + "_hists") << std::endl; + throw hf_exc(); + } + chanDir->cd(); - // Make a directory to store the histograms - // for this channel + // Save the data: + TDirectory *dataDir = chanDir->mkdir("data"); + if (dataDir == nullptr) { + cxcoutEHF << "Error: Cannot make directory " << chanDir << std::endl; + throw hf_exc(); + } + dataDir->cd(); - TDirectory* chanDir = file->mkdir( (chanName + "_hists").c_str() ); - if( chanDir == nullptr ) { - cxcoutEHF << "Error: Cannot create channel " << (chanName + "_hists") - << std::endl; - throw hf_exc(); - } - chanDir->cd(); + channel.fData.writeToFile(OutputFileName, GetDirPath(dataDir)); - // Save the data: - TDirectory* dataDir = chanDir->mkdir( "data" ); - if( dataDir == nullptr ) { - cxcoutEHF << "Error: Cannot make directory " << chanDir << std::endl; - throw hf_exc(); - } - dataDir->cd(); + /* + // Write the data file to this directory + TH1* hData = channel.data.GetHisto(); + hData->Write(); - channel.fData.writeToFile( OutputFileName, GetDirPath(dataDir) ); + // Set the location of the data + // in the output measurement - /* - // Write the data file to this directory - TH1* hData = channel.data.GetHisto(); - hData->Write(); + channel.data.InputFile = OutputFileName; + channel.data.HistoName = hData->GetName(); + channel.data.HistoPath = GetDirPath( dataDir ); + */ - // Set the location of the data - // in the output measurement + // Loop over samples: + + for (unsigned int sampItr = 0; sampItr < channel.GetSamples().size(); ++sampItr) { + + Sample &sample = channel.GetSamples().at(sampItr); + std::string sampName = sample.GetName(); + + cxcoutPHF << "Writing sample: " << sampName << std::endl; + + file->cd(); + chanDir->cd(); + TDirectory *sampleDir = chanDir->mkdir(sampName.c_str()); + if (sampleDir == nullptr) { + cxcoutEHF << "Error: Directory " << sampName << " not created properly" << std::endl; + throw hf_exc(); + } + std::string sampleDirPath = GetDirPath(sampleDir); + + if (!sampleDir) { + cxcoutEHF << "Error making directory: " << sampName << " in directory: " << chanName << std::endl; + throw hf_exc(); + } + + // Write the data file to this directory + sampleDir->cd(); + + sample.writeToFile(OutputFileName, sampleDirPath); + /* + TH1* hSample = sample.GetHisto(); + if( ! hSample ) { + std::cout << "Error getting histogram for sample: " + << sampName << std::endl; + throw -1; + } + sampleDir->cd(); + hSample->Write(); + + sample.InputFile = OutputFileName; + sample.HistoName = hSample->GetName(); + sample.HistoPath = sampleDirPath; + */ + + // Write the histograms associated with + // systematics + + /* THIS IS WHAT I"M COMMENTING + sample.GetStatError().writeToFile( OutputFileName, sampleDirPath ); + + // Must write all systematics that contain internal histograms + // (This is not all systematics) + + for( unsigned int i = 0; i < sample.GetHistoSysList().size(); ++i ) { + sample.GetHistoSysList().at(i).writeToFile( OutputFileName, sampleDirPath ); + } + for( unsigned int i = 0; i < sample.GetHistoFactorList().size(); ++i ) { + sample.GetHistoFactorList().at(i).writeToFile( OutputFileName, sampleDirPath ); + } + for( unsigned int i = 0; i < sample.GetShapeSysList().size(); ++i ) { + sample.GetShapeSysList().at(i).writeToFile( OutputFileName, sampleDirPath ); + } + END COMMENT */ + /* + sample.statError.writeToFile( OutputFileName, sampleDirPath ); + + // Now, get the Stat config histograms + if( sample.statError.HistoName != "" ) { + TH1* hStatError = sample.statError.GetErrorHist(); + if( ! hStatError ) { + std::cout << "Error getting stat error histogram for sample: " + << sampName << std::endl; + throw -1; + } + hStatError->Write(); - channel.data.InputFile = OutputFileName; - channel.data.HistoName = hData->GetName(); - channel.data.HistoPath = GetDirPath( dataDir ); - */ + sample.statError.InputFile = OutputFileName; + sample.statError.HistoName = hStatError->GetName(); + sample.statError.HistoPath = sampleDirPath; - // Loop over samples: + } + */ + } + } - for( unsigned int sampItr = 0; sampItr < channel.GetSamples().size(); ++sampItr ) { + // Finally, write the measurement itself: - RooStats::HistFactory::Sample& sample = channel.GetSamples().at( sampItr ); - std::string sampName = sample.GetName(); + cxcoutPHF << "Saved all histograms" << std::endl; - cxcoutPHF << "Writing sample: " << sampName << std::endl; + file->cd(); + outMeas.Write(); - file->cd(); - chanDir->cd(); - TDirectory* sampleDir = chanDir->mkdir( sampName.c_str() ); - if( sampleDir == nullptr ) { - cxcoutEHF << "Error: Directory " << sampName << " not created properly" << std::endl; - throw hf_exc(); - } - std::string sampleDirPath = GetDirPath( sampleDir ); + cxcoutPHF << "Saved Measurement" << std::endl; +} - if( ! sampleDir ) { - cxcoutEHF << "Error making directory: " << sampName - << " in directory: " << chanName - << std::endl; - throw hf_exc(); - } +/// Return the directory's path, +/// stripped of unnecessary prefixes +std::string Measurement::GetDirPath(TDirectory *dir) +{ - // Write the data file to this directory - sampleDir->cd(); + std::string path = dir->GetPath(); - sample.writeToFile( OutputFileName, sampleDirPath ); - /* - TH1* hSample = sample.GetHisto(); - if( ! hSample ) { - std::cout << "Error getting histogram for sample: " - << sampName << std::endl; - throw -1; - } - sampleDir->cd(); - hSample->Write(); + if (path.find(':') != std::string::npos) { + size_t index = path.find(':'); + path.replace(0, index + 1, ""); + } - sample.InputFile = OutputFileName; - sample.HistoName = hSample->GetName(); - sample.HistoPath = sampleDirPath; - */ + path = path + "/"; - // Write the histograms associated with - // systematics + return path; - /* THIS IS WHAT I"M COMMENTING - sample.GetStatError().writeToFile( OutputFileName, sampleDirPath ); + /* + if( path.find(":") != std::string::npos ) { + size_t index = path.find(":"); + SampleName.replace( 0, index, "" ); + } - // Must write all systematics that contain internal histograms - // (This is not all systematics) + // Remove the file: + */ +} - for( unsigned int i = 0; i < sample.GetHistoSysList().size(); ++i ) { - sample.GetHistoSysList().at(i).writeToFile( OutputFileName, sampleDirPath ); - } - for( unsigned int i = 0; i < sample.GetHistoFactorList().size(); ++i ) { - sample.GetHistoFactorList().at(i).writeToFile( OutputFileName, sampleDirPath ); - } - for( unsigned int i = 0; i < sample.GetShapeSysList().size(); ++i ) { - sample.GetShapeSysList().at(i).writeToFile( OutputFileName, sampleDirPath ); - } - END COMMENT */ +/// The most common way to add histograms to channels is to have them +/// stored in ROOT files and to give HistFactory the location of these +/// files. This means providing the path to the ROOT file and the path +/// and name of the histogram within that file. When providing these +/// in a script, HistFactory doesn't load the histogram from the file +/// right away. Instead, once all such histograms have been supplied, +/// one should run this method to open all ROOT files and to copy and +/// save all necessary histograms. +void Measurement::CollectHistograms() +{ + + for (unsigned int chanItr = 0; chanItr < fChannels.size(); ++chanItr) { + + Channel &chan = fChannels.at(chanItr); + + chan.CollectHistograms(); + } +} + +////////////////////////////////////////////////////////////////////////////// +/** \class RooStats::HistFactory::Sample + * \ingroup HistFactory + */ + +Sample::Sample() = default; + +Sample::~Sample() = default; + +// copy constructor (important for Python) +Sample::Sample(const Sample &other) + : fName(other.fName), + fInputFile(other.fInputFile), + fHistoName(other.fHistoName), + fHistoPath(other.fHistoPath), + fChannelName(other.fChannelName), + + fOverallSysList(other.fOverallSysList), + fNormFactorList(other.fNormFactorList), + fHistoSysList(other.fHistoSysList), + fHistoFactorList(other.fHistoFactorList), + fShapeSysList(other.fShapeSysList), + fShapeFactorList(other.fShapeFactorList), + + fStatError(other.fStatError), + fNormalizeByTheory(other.fNormalizeByTheory), + fStatErrorActivate(other.fStatErrorActivate), + fhNominal(other.fhNominal) +{ + if (other.fhCountingHist) { + SetValue(other.fhCountingHist->GetBinContent(1)); + } else { + fhCountingHist.reset(); + } +} + +Sample &Sample::operator=(const Sample &other) +{ + fName = other.fName; + fInputFile = other.fInputFile; + fHistoName = other.fHistoName; + fHistoPath = other.fHistoPath; + fChannelName = other.fChannelName; + + fOverallSysList = other.fOverallSysList; + fNormFactorList = other.fNormFactorList; + fHistoSysList = other.fHistoSysList; + fHistoFactorList = other.fHistoFactorList; + fShapeSysList = other.fShapeSysList; + fShapeFactorList = other.fShapeFactorList; + + fStatError = other.fStatError; + fNormalizeByTheory = other.fNormalizeByTheory; + fStatErrorActivate = other.fStatErrorActivate; + fhNominal = other.fhNominal; + + fhCountingHist.reset(); + + if (other.fhCountingHist) { + SetValue(other.fhCountingHist->GetBinContent(1)); + } else { + fhCountingHist.reset(); + } + + return *this; +} + +Sample::Sample(std::string SampName, std::string SampHistoName, std::string SampInputFile, std::string SampHistoPath) + : fName(SampName), + fInputFile(SampInputFile), + fHistoName(SampHistoName), + fHistoPath(SampHistoPath), + fNormalizeByTheory(true), + fStatErrorActivate(false) +{ +} + +Sample::Sample(std::string SampName) : fName(SampName), fNormalizeByTheory(true), fStatErrorActivate(false) {} + +const TH1 *Sample::GetHisto() const +{ + TH1 *histo = (TH1 *)fhNominal.GetObject(); + return histo; +} + +void Sample::writeToFile(std::string OutputFileName, std::string DirName) +{ + + const TH1 *histNominal = GetHisto(); + histNominal->Write(); + + // Set the location of the data + // in the output measurement + + fInputFile = OutputFileName; + fHistoName = histNominal->GetName(); + fHistoPath = DirName; + + // Write this sample's StatError + GetStatError().writeToFile(OutputFileName, DirName); + + // Must write all systematics that contain internal histograms + // (This is not all systematics) + for (unsigned int i = 0; i < GetHistoSysList().size(); ++i) { + GetHistoSysList().at(i).writeToFile(OutputFileName, DirName); + } + for (unsigned int i = 0; i < GetHistoFactorList().size(); ++i) { + GetHistoFactorList().at(i).writeToFile(OutputFileName, DirName); + } + for (unsigned int i = 0; i < GetShapeSysList().size(); ++i) { + GetShapeSysList().at(i).writeToFile(OutputFileName, DirName); + } + for (unsigned int i = 0; i < GetShapeFactorList().size(); ++i) { + GetShapeFactorList().at(i).writeToFile(OutputFileName, DirName); + } + + return; +} + +void Sample::SetValue(double val) +{ + + // For use in a number counting measurement + // Create a 1-bin histogram, + // fill it with this input value, + // and set this Sample's histogram to that hist + + std::string SampleHistName = fName + "_hist"; + + // Histogram has 1-bin (hard-coded) + fhCountingHist.reset(); + + fhCountingHist = std::make_unique(SampleHistName.c_str(), SampleHistName.c_str(), 1, 0, 1); + fhCountingHist->SetBinContent(1, val); + + // Set the histogram of the internally held data + // node of this channel to this newly created histogram + SetHisto(fhCountingHist.get()); +} + +void Sample::Print(std::ostream &stream) const +{ + + stream << "\t \t Name: " << fName << "\t \t Channel: " << fChannelName + << "\t NormalizeByTheory: " << (fNormalizeByTheory ? "True" : "False") + << "\t StatErrorActivate: " << (fStatErrorActivate ? "True" : "False") << std::endl; + + stream << "\t \t \t \t " + << "\t InputFile: " << fInputFile << "\t HistName: " << fHistoName << "\t HistoPath: " << fHistoPath + << "\t HistoAddress: " + << GetHisto() + // << "\t Type: " << GetHisto()->ClassName() + << std::endl; + + if (fStatError.GetActivate()) { + stream << "\t \t \t StatError Activate: " << fStatError.GetActivate() << "\t InputFile: " << fInputFile + << "\t HistName: " << fStatError.GetHistoName() << "\t HistoPath: " << fStatError.GetHistoPath() + << "\t HistoAddress: " << fStatError.GetErrorHist() << std::endl; + } + + /* + stream<< " NormalizeByTheory: "; + if(NormalizeByTheory) stream << "True"; + else stream << "False"; + + stream<< " StatErrorActivate: "; + if(StatErrorActivate) stream << "True"; + else stream << "False"; + */ +} + +void Sample::PrintXML(std::ofstream &xml) const +{ + + // Create the sample tag + xml << " " << std::endl; + + // Print Stat Error (if necessary) + fStatError.PrintXML(xml); + /* + if( fStatError.GetActivate() ) { + xml << " " << std::endl; + } + */ + + // Now, print the systematics: + for (unsigned int i = 0; i < fOverallSysList.size(); ++i) { + OverallSys sys = fOverallSysList.at(i); + sys.PrintXML(xml); + /* + xml << " " << std::endl; + */ + } + for (unsigned int i = 0; i < fNormFactorList.size(); ++i) { + NormFactor sys = fNormFactorList.at(i); + sys.PrintXML(xml); + /* + xml << " " << std::endl; + */ + } + for (unsigned int i = 0; i < fHistoSysList.size(); ++i) { + HistoSys sys = fHistoSysList.at(i); + sys.PrintXML(xml); /* - sample.statError.writeToFile( OutputFileName, sampleDirPath ); + xml << " " << std::endl; + */ } - hStatError->Write(); + for (unsigned int i = 0; i < fHistoFactorList.size(); ++i) { + HistoFactor sys = fHistoFactorList.at(i); + sys.PrintXML(xml); + /* + xml << " GetName(); - sample.statError.HistoPath = sampleDirPath; + << " InputFileLow=\"" << sys.GetInputFileLow() << "\" " + << " HistoNameLow=\"" << sys.GetHistoNameLow() << "\" " + << " HistoPathLow=\"" << sys.GetHistoPathLow() << "\" " - } + << " InputFileHigh=\"" << sys.GetInputFileHigh() << "\" " + << " HistoNameHigh=\"" << sys.GetHistoNameHigh() << "\" " + << " HistoPathHigh=\"" << sys.GetHistoPathHigh() << "\" " + << " /> " << std::endl; */ + } + for (unsigned int i = 0; i < fShapeSysList.size(); ++i) { + ShapeSys sys = fShapeSysList.at(i); + sys.PrintXML(xml); + /* + xml << " " << std::endl; + */ + } + for (unsigned int i = 0; i < fShapeFactorList.size(); ++i) { + ShapeFactor sys = fShapeFactorList.at(i); + sys.PrintXML(xml); + /* + xml << " " << std::endl; + */ + } - } + // Finally, close the tag + xml << " " << std::endl; +} +// Some helper functions +// (Not strictly necessary because +// methods are publicly accessible) - // Finally, write the measurement itself: +void Sample::ActivateStatError() +{ - cxcoutPHF << "Saved all histograms" << std::endl; + fStatError.Activate(true); + fStatError.SetUseHisto(false); +} - file->cd(); - outMeas.Write(); +void Sample::ActivateStatError(std::string StatHistoName, std::string StatInputFile, std::string StatHistoPath) +{ - cxcoutPHF << "Saved Measurement" << std::endl; + fStatError.Activate(true); + fStatError.SetUseHisto(true); + fStatError.SetInputFile(StatInputFile); + fStatError.SetHistoName(StatHistoName); + fStatError.SetHistoPath(StatHistoPath); } -/// Return the directory's path, -/// stripped of unnecessary prefixes -std::string RooStats::HistFactory::Measurement::GetDirPath( TDirectory* dir ) +void Sample::AddOverallSys(std::string SysName, double SysLow, double SysHigh) { + OverallSys sys; + sys.SetName(SysName); + sys.SetLow(SysLow); + sys.SetHigh(SysHigh); - std::string path = dir->GetPath(); + fOverallSysList.push_back(sys); +} - if( path.find(':') != std::string::npos ) { - size_t index = path.find(':'); - path.replace( 0, index+1, "" ); - } +void Sample::AddOverallSys(const OverallSys &Sys) +{ + fOverallSysList.push_back(Sys); +} - path = path + "/"; +void Sample::AddNormFactor(std::string const &SysName, double SysVal, double SysLow, double SysHigh) +{ - return path; + NormFactor norm; - /* - if( path.find(":") != std::string::npos ) { - size_t index = path.find(":"); - SampleName.replace( 0, index, "" ); - } + norm.SetName(SysName); + norm.SetVal(SysVal); + norm.SetLow(SysLow); + norm.SetHigh(SysHigh); - // Remove the file: - */ + fNormFactorList.push_back(norm); +} +void Sample::AddNormFactor(const NormFactor &Factor) +{ + fNormFactorList.push_back(Factor); } +void Sample::AddHistoSys(std::string SysName, std::string SysHistoNameLow, std::string SysHistoFileLow, + std::string SysHistoPathLow, std::string SysHistoNameHigh, std::string SysHistoFileHigh, + std::string SysHistoPathHigh) +{ -/// The most common way to add histograms to channels is to have them -/// stored in ROOT files and to give HistFactory the location of these -/// files. This means providing the path to the ROOT file and the path -/// and name of the histogram within that file. When providing these -/// in a script, HistFactory doesn't load the histogram from the file -/// right away. Instead, once all such histograms have been supplied, -/// one should run this method to open all ROOT files and to copy and -/// save all necessary histograms. -void RooStats::HistFactory::Measurement::CollectHistograms() { + HistoSys sys; + sys.SetName(SysName); + sys.SetHistoNameLow(SysHistoNameLow); + sys.SetHistoPathLow(SysHistoPathLow); + sys.SetInputFileLow(SysHistoFileLow); - for( unsigned int chanItr = 0; chanItr < fChannels.size(); ++chanItr) { + sys.SetHistoNameHigh(SysHistoNameHigh); + sys.SetHistoPathHigh(SysHistoPathHigh); + sys.SetInputFileHigh(SysHistoFileHigh); - RooStats::HistFactory::Channel& chan = fChannels.at( chanItr ); + fHistoSysList.push_back(sys); +} - chan.CollectHistograms(); +void Sample::AddHistoSys(const HistoSys &Sys) +{ + fHistoSysList.push_back(Sys); +} - } +void Sample::AddHistoFactor(std::string SysName, std::string SysHistoNameLow, std::string SysHistoFileLow, + std::string SysHistoPathLow, std::string SysHistoNameHigh, std::string SysHistoFileHigh, + std::string SysHistoPathHigh) +{ + + HistoFactor factor; + factor.SetName(SysName); + + factor.SetHistoNameLow(SysHistoNameLow); + factor.SetHistoPathLow(SysHistoPathLow); + factor.SetInputFileLow(SysHistoFileLow); + + factor.SetHistoNameHigh(SysHistoNameHigh); + factor.SetHistoPathHigh(SysHistoPathHigh); + factor.SetInputFileHigh(SysHistoFileHigh); + + fHistoFactorList.push_back(factor); +} + +void Sample::AddHistoFactor(const HistoFactor &Factor) +{ + fHistoFactorList.push_back(Factor); +} + +void Sample::AddShapeFactor(std::string SysName) +{ + + ShapeFactor factor; + factor.SetName(SysName); + fShapeFactorList.push_back(factor); +} +void Sample::AddShapeFactor(const ShapeFactor &Factor) +{ + fShapeFactorList.push_back(Factor); } +void Sample::AddShapeSys(std::string SysName, Constraint::Type SysConstraintType, std::string SysHistoName, + std::string SysHistoFile, std::string SysHistoPath) +{ + + ShapeSys sys; + sys.SetName(SysName); + sys.SetConstraintType(SysConstraintType); + sys.SetHistoName(SysHistoName); + sys.SetHistoPath(SysHistoPath); + sys.SetInputFile(SysHistoFile); + + fShapeSysList.push_back(sys); +} + +void Sample::AddShapeSys(const ShapeSys &Sys) +{ + fShapeSysList.push_back(Sys); +} + +//////////////////////////////////////////////////////////////////////////////// +/** \class RooStats::HistFactory::Channel + * \ingroup HistFactory + This class encapsulates all information for the statistical interpretation of one experiment. + It can be combined with other channels (e.g. for the combination of multiple experiments, or + to constrain nuisance parameters with information obtained in a control region). + A channel contains one or more samples which describe the contribution from different processes + to this measurement. +*/ + +Channel::Channel(std::string ChanName, std::string ChanInputFile) : fName(ChanName), fInputFile(ChanInputFile) +{ + // create channel with given name and input file +} + +// BadChannel = Channel(); +Channel BadChannel; +// BadChannel.Name = "BadChannel"; // = Channel(); //.Name = "BadChannel"; + +void Channel::AddSample(Sample sample) +{ + // add fully configured sample to channel + + sample.SetChannelName(GetName()); + fSamples.push_back(sample); +} + +void Channel::Print(std::ostream &stream) +{ + // print information of channel to given stream + + stream << "\t Channel Name: " << fName << "\t InputFile: " << fInputFile << std::endl; + + stream << "\t Data:" << std::endl; + fData.Print(stream); + + stream << "\t statErrorConfig:" << std::endl; + fStatErrorConfig.Print(stream); + + if (!fSamples.empty()) { + + stream << "\t Samples: " << std::endl; + for (unsigned int i = 0; i < fSamples.size(); ++i) { + fSamples.at(i).Print(stream); + } + } + + stream << "\t End of Channel " << fName << std::endl; +} + +void Channel::PrintXML(std::string const &directory, std::string const &prefix) const +{ + + // Create an XML file for this channel + cxcoutPHF << "Printing XML Files for channel: " << GetName() << std::endl; + + std::string XMLName = prefix + fName + ".xml"; + if (!directory.empty()) + XMLName = directory + "/" + XMLName; + + std::ofstream xml(XMLName.c_str()); + + // Add the time + xml << "" << std::endl; + + // Add the DOCTYPE + xml << " " << std::endl << std::endl; + + // Add the Channel + xml << " " << std::endl << std::endl; + + fData.PrintXML(xml); + for (auto const &data : fAdditionalData) { + data.PrintXML(xml); + } + + fStatErrorConfig.PrintXML(xml); + /* + xml << " " << std::endl << std::endl; + */ + + for (auto const &sample : fSamples) { + sample.PrintXML(xml); + xml << std::endl << std::endl; + } + + xml << std::endl; + xml << " " << std::endl; + xml.close(); + + cxcoutPHF << "Finished printing XML files" << std::endl; +} + +void Channel::SetData(std::string DataHistoName, std::string DataInputFile, std::string DataHistoPath) +{ + // set data for this channel by specifying the name of the histogram, + // the external ROOT file and the path to the histogram inside the ROOT file + + fData.SetHistoName(DataHistoName); + fData.SetInputFile(DataInputFile); + fData.SetHistoPath(DataHistoPath); +} + +void Channel::SetData(TH1 *hData) +{ + // set data directly to some histogram + fData.SetHisto(hData); +} + +void Channel::SetData(double val) +{ + + // For a NumberCounting measurement only + // Set the value of data in a particular channel + // + // Internally, this simply creates a 1-bin TH1F for you + + std::string DataHistName = fName + "_data"; + + // Histogram has 1-bin (hard-coded) + TH1F *hData = new TH1F(DataHistName.c_str(), DataHistName.c_str(), 1, 0, 1); + hData->SetBinContent(1, val); + + // Set the histogram of the internally held data + // node of this channel to this newly created histogram + SetData(hData); +} + +void Channel::SetStatErrorConfig(double StatRelErrorThreshold, Constraint::Type StatConstraintType) +{ + + fStatErrorConfig.SetRelErrorThreshold(StatRelErrorThreshold); + fStatErrorConfig.SetConstraintType(StatConstraintType); +} + +void Channel::SetStatErrorConfig(double StatRelErrorThreshold, std::string StatConstraintType) +{ + + fStatErrorConfig.SetRelErrorThreshold(StatRelErrorThreshold); + fStatErrorConfig.SetConstraintType(Constraint::GetType(StatConstraintType)); +} + +void Channel::CollectHistograms() +{ + + // Loop through all Samples and Systematics + // and collect all necessary histograms + + // Handles to open files for collecting histograms + std::map> fileHandles; + + // Get the Data Histogram: + + if (!fData.GetInputFile().empty()) { + fData.SetHisto(GetHistogram(fData.GetInputFile(), fData.GetHistoPath(), fData.GetHistoName(), fileHandles)); + } + + // Collect any histograms for additional Datasets + for (auto &data : fAdditionalData) { + if (!data.GetInputFile().empty()) { + data.SetHisto(GetHistogram(data.GetInputFile(), data.GetHistoPath(), data.GetHistoName(), fileHandles)); + } + } + + // Get the histograms for the samples: + for (unsigned int sampItr = 0; sampItr < fSamples.size(); ++sampItr) { + + Sample &sample = fSamples.at(sampItr); + + // Get the nominal histogram: + cxcoutDHF << "Collecting Nominal Histogram" << std::endl; + TH1 *Nominal = GetHistogram(sample.GetInputFile(), sample.GetHistoPath(), sample.GetHistoName(), fileHandles); + + sample.SetHisto(Nominal); + + // Get the StatError Histogram (if necessary) + if (sample.GetStatError().GetUseHisto()) { + sample.GetStatError().SetErrorHist(GetHistogram(sample.GetStatError().GetInputFile(), + sample.GetStatError().GetHistoPath(), + sample.GetStatError().GetHistoName(), fileHandles)); + } + + // Get the HistoSys Variations: + for (unsigned int histoSysItr = 0; histoSysItr < sample.GetHistoSysList().size(); ++histoSysItr) { + + HistoSys &histoSys = sample.GetHistoSysList().at(histoSysItr); + + histoSys.SetHistoLow(GetHistogram(histoSys.GetInputFileLow(), histoSys.GetHistoPathLow(), + histoSys.GetHistoNameLow(), fileHandles)); + + histoSys.SetHistoHigh(GetHistogram(histoSys.GetInputFileHigh(), histoSys.GetHistoPathHigh(), + histoSys.GetHistoNameHigh(), fileHandles)); + } // End Loop over HistoSys + + // Get the HistoFactor Variations: + for (unsigned int histoFactorItr = 0; histoFactorItr < sample.GetHistoFactorList().size(); ++histoFactorItr) { + + HistoFactor &histoFactor = sample.GetHistoFactorList().at(histoFactorItr); + + histoFactor.SetHistoLow(GetHistogram(histoFactor.GetInputFileLow(), histoFactor.GetHistoPathLow(), + histoFactor.GetHistoNameLow(), fileHandles)); + + histoFactor.SetHistoHigh(GetHistogram(histoFactor.GetInputFileHigh(), histoFactor.GetHistoPathHigh(), + histoFactor.GetHistoNameHigh(), fileHandles)); + } // End Loop over HistoFactor + + // Get the ShapeSys Variations: + for (unsigned int shapeSysItr = 0; shapeSysItr < sample.GetShapeSysList().size(); ++shapeSysItr) { + + ShapeSys &shapeSys = sample.GetShapeSysList().at(shapeSysItr); + + shapeSys.SetErrorHist( + GetHistogram(shapeSys.GetInputFile(), shapeSys.GetHistoPath(), shapeSys.GetHistoName(), fileHandles)); + } // End Loop over ShapeSys + + // Get any initial shape for a ShapeFactor + for (unsigned int shapeFactorItr = 0; shapeFactorItr < sample.GetShapeFactorList().size(); ++shapeFactorItr) { + + ShapeFactor &shapeFactor = sample.GetShapeFactorList().at(shapeFactorItr); + + // Check if we need an InitialShape + if (shapeFactor.HasInitialShape()) { + TH1 *hist = GetHistogram(shapeFactor.GetInputFile(), shapeFactor.GetHistoPath(), shapeFactor.GetHistoName(), + fileHandles); + shapeFactor.SetInitialShape(hist); + } + + } // End Loop over ShapeFactor + + } // End Loop over Samples +} + +bool Channel::CheckHistograms() const +{ + + // Check that all internal histogram pointers + // are properly configured (ie that they're not nullptr) + + if (fData.GetHisto() == nullptr && !fData.GetInputFile().empty()) { + cxcoutEHF << "Error: Data Histogram for channel " << GetName() << " is nullptr." << std::endl; + return false; + } + + // Get the histograms for the samples: + for (unsigned int sampItr = 0; sampItr < fSamples.size(); ++sampItr) { + + const Sample &sample = fSamples.at(sampItr); + + // Get the nominal histogram: + if (sample.GetHisto() == nullptr) { + cxcoutEHF << "Error: Nominal Histogram for sample " << sample.GetName() << " is nullptr." << std::endl; + return false; + } else { + + // Check if any bins are negative + std::vector NegativeBinNumber; + std::vector NegativeBinContent; + const TH1 *histNominal = sample.GetHisto(); + for (int ibin = 1; ibin <= histNominal->GetNbinsX(); ++ibin) { + if (histNominal->GetBinContent(ibin) < 0) { + NegativeBinNumber.push_back(ibin); + NegativeBinContent.push_back(histNominal->GetBinContent(ibin)); + } + } + if (!NegativeBinNumber.empty()) { + cxcoutWHF << "WARNING: Nominal Histogram " << histNominal->GetName() << " for Sample = " << sample.GetName() + << " in Channel = " << GetName() << " has negative entries in bin numbers = "; + + for (unsigned int ibin = 0; ibin < NegativeBinNumber.size(); ++ibin) { + if (ibin > 0) + std::cout << " , "; + std::cout << NegativeBinNumber[ibin] << " : " << NegativeBinContent[ibin]; + } + std::cout << std::endl; + } + } + + // Get the StatError Histogram (if necessary) + if (sample.GetStatError().GetUseHisto()) { + if (sample.GetStatError().GetErrorHist() == nullptr) { + cxcoutEHF << "Error: Statistical Error Histogram for sample " << sample.GetName() << " is nullptr." + << std::endl; + return false; + } + } + + // Get the HistoSys Variations: + for (unsigned int histoSysItr = 0; histoSysItr < sample.GetHistoSysList().size(); ++histoSysItr) { + + const HistoSys &histoSys = sample.GetHistoSysList().at(histoSysItr); + + if (histoSys.GetHistoLow() == nullptr) { + cxcoutEHF << "Error: HistoSyst Low for Systematic " << histoSys.GetName() << " in sample " + << sample.GetName() << " is nullptr." << std::endl; + return false; + } + if (histoSys.GetHistoHigh() == nullptr) { + cxcoutEHF << "Error: HistoSyst High for Systematic " << histoSys.GetName() << " in sample " + << sample.GetName() << " is nullptr." << std::endl; + return false; + } + + } // End Loop over HistoSys + + // Get the HistoFactor Variations: + for (unsigned int histoFactorItr = 0; histoFactorItr < sample.GetHistoFactorList().size(); ++histoFactorItr) { + + const HistoFactor &histoFactor = sample.GetHistoFactorList().at(histoFactorItr); + + if (histoFactor.GetHistoLow() == nullptr) { + cxcoutEHF << "Error: HistoSyst Low for Systematic " << histoFactor.GetName() << " in sample " + << sample.GetName() << " is nullptr." << std::endl; + return false; + } + if (histoFactor.GetHistoHigh() == nullptr) { + cxcoutEHF << "Error: HistoSyst High for Systematic " << histoFactor.GetName() << " in sample " + << sample.GetName() << " is nullptr." << std::endl; + return false; + } + + } // End Loop over HistoFactor + + // Get the ShapeSys Variations: + for (unsigned int shapeSysItr = 0; shapeSysItr < sample.GetShapeSysList().size(); ++shapeSysItr) { + + const ShapeSys &shapeSys = sample.GetShapeSysList().at(shapeSysItr); + + if (shapeSys.GetErrorHist() == nullptr) { + cxcoutEHF << "Error: HistoSyst High for Systematic " << shapeSys.GetName() << " in sample " + << sample.GetName() << " is nullptr." << std::endl; + return false; + } + + } // End Loop over ShapeSys + + } // End Loop over Samples + + return true; +} + +/// Open a file and copy a histogram +/// \param InputFile File where the histogram resides. +/// \param HistoPath Path of the histogram in the file. +/// \param HistoName Name of the histogram to retrieve. +/// \param lsof List of open files. Helps to prevent opening and closing a file hundreds of times. +TH1 *Channel::GetHistogram(std::string InputFile, std::string HistoPath, std::string HistoName, + std::map> &lsof) +{ + + cxcoutPHF << "Getting histogram " << InputFile << ":" << HistoPath << "/" << HistoName << std::endl; + + auto &inFile = lsof[InputFile]; + if (!inFile || !inFile->IsOpen()) { + inFile.reset(TFile::Open(InputFile.c_str())); + if (!inFile || !inFile->IsOpen()) { + cxcoutEHF << "Error: Unable to open input file: " << InputFile << std::endl; + throw hf_exc(); + } + cxcoutIHF << "Opened input file: " << InputFile << ": " << std::endl; + } + + TDirectory *dir = inFile->GetDirectory(HistoPath.c_str()); + if (dir == nullptr) { + cxcoutEHF << "Histogram path '" << HistoPath << "' wasn't found in file '" << InputFile << "'." << std::endl; + throw hf_exc(); + } + + // Have to read histograms via keys, to ensure that the latest-greatest + // name cycle is read from file. Otherwise, they might come from memory. + auto key = dir->GetKey(HistoName.c_str()); + if (key == nullptr) { + cxcoutEHF << "Histogram '" << HistoName << "' wasn't found in file '" << InputFile << "' in directory '" + << HistoPath << "'." << std::endl; + throw hf_exc(); + } + + std::unique_ptr hist(key->ReadObject()); + if (!hist) { + cxcoutEHF << "Histogram '" << HistoName << "' wasn't found in file '" << InputFile << "' in directory '" + << HistoPath << "'." << std::endl; + throw hf_exc(); + } + + TDirectory::TContext ctx{nullptr}; + TH1 *ptr = static_cast(hist->Clone()); + + if (!ptr) { + std::cerr << "Not all necessary info are set to access the input file. Check your config" << std::endl; + std::cerr << "filename: " << InputFile << "path: " << HistoPath << "obj: " << HistoName << std::endl; + throw hf_exc(); + } + +#ifdef DEBUG + std::cout << "Found Histogram: " << HistoName " at address: " << ptr << " with integral " << ptr->Integral() + << " and mean " << ptr->GetMean() << std::endl; +#endif + + // Done + return ptr; +} + +//////////////////////////////////////////////////////////////////////////////// +/** \class RooStats::HistFactory::Data + * \ingroup HistFactory + */ + +Data::Data(std::string HistoName, std::string InputFile, std::string HistoPath) + : fInputFile(InputFile), fHistoName(HistoName), fHistoPath(HistoPath) +{ +} + +TH1 *Data::GetHisto() +{ + return (TH1 *)fhData.GetObject(); +} + +const TH1 *Data::GetHisto() const +{ + return (TH1 *)fhData.GetObject(); +} + +void Data::Print(std::ostream &stream) +{ + + stream << "\t \t InputFile: " << fInputFile << "\t HistoName: " << fHistoName << "\t HistoPath: " << fHistoPath + << "\t HistoAddress: " << GetHisto() << std::endl; +} + +void Data::writeToFile(std::string OutputFileName, std::string DirName) +{ + + TH1 *histData = GetHisto(); + + if (histData != nullptr) { + + histData->Write(); + + // Set the location of the data + // in the output measurement + + fInputFile = OutputFileName; + fHistoName = histData->GetName(); + fHistoPath = DirName; + } +} + +void Data::PrintXML(std::ostream &xml) const +{ + + xml << " " << std::endl << std::endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/** + * \ingroup HistFactory + */ + +namespace { + +/// Replaces the XML special characters with their escape codes. +std::string escapeXML(const std::string &src) +{ + std::stringstream dst; + for (char ch : src) { + switch (ch) { + case '&': dst << "&"; break; + case '\'': dst << "'"; break; + case '"': dst << """; break; + case '<': dst << "<"; break; + case '>': dst << ">"; break; + default: dst << ch; break; + } + } + return dst.str(); +} + +} // namespace + +PreprocessFunction::PreprocessFunction(std::string const &name, std::string const &expression, + std::string const &dependents) + : fName(name), fExpression(expression), fDependents(dependents) +{ +} + +std::string PreprocessFunction::GetCommand() const +{ + return "expr::" + fName + "('" + fExpression + "',{" + fDependents + "})"; +} + +void PreprocessFunction::Print(std::ostream &stream) const +{ + stream << "\t \t Name: " << fName << "\t \t Expression: " << fExpression << "\t \t Dependents: " << fDependents + << std::endl; +} + +void PreprocessFunction::PrintXML(std::ostream &xml) const +{ + xml << "\n"; +} + +//////////////////////////////////////////////////////////////////////////////// +/** \class RooStats::HistFactory::Asimov + * \ingroup HistFactory + * TODO Here, we are missing some documentation. + */ + +void Asimov::ConfigureWorkspace(RooWorkspace *wspace) +{ + + // Here is where we set the values, and constantness + // of all parameters in the workspace before creating + // an asimov dataset + + /* + // Okay, y'all, first we're going to create a snapshot + // of the current state of the variables in the workspace + + std::string ListOfVariableNames = ""; + for( std::map< std::string, double >::iterator itr = fParamValsToSet.begin(); + itr != fParamValsToSet.end(); ++itr) { + // Extend the Variable Name list + ListOfVariableNames += "," + itr->first; + } + for( std::map< std::string, bool >::iterator itr = fParamsToFix.begin(); + itr != fParamsToFix.end(); ++itr) { + // Extend the Variable Name list + ListOfVariableNames += "," + itr->first; + } + + // Save a snapshot + std::string SnapShotName = "NominalParamValues"; + wspace->saveSnapshot(SnapShotName.c_str(), ListOfVariableNames.c_str()); + */ + + // + // First we set all parameters to their given values + // + + for (std::map::iterator itr = fParamValsToSet.begin(); itr != fParamValsToSet.end(); ++itr) { + + std::string param = itr->first; + double val = itr->second; + + // Try to get the variable in the workspace + RooRealVar *var = wspace->var(param); + if (!var) { + std::cout << "Error: Trying to set variable: " << var + << " to a specific value in creation of asimov dataset: " << fName + << " but this variable doesn't appear to exist in the workspace" << std::endl; + throw hf_exc(); + } + + // Check that the desired value is in the range of the variable + double inRange = var->inRange(val, nullptr); + if (!inRange) { + std::cout << "Error: Attempting to set variable: " << var << " to value: " << val << ", however it appears" + << " that this is not withn the variable's range: " + << "[" << var->getMin() << ", " << var->getMax() << "]" << std::endl; + throw hf_exc(); + } + + // Set its value + std::cout << "Configuring Asimov Dataset: Setting " << param << " = " << val << std::endl; + var->setVal(val); + } + + // + // Then, we set any variables to constant + // + + for (std::map::iterator itr = fParamsToFix.begin(); itr != fParamsToFix.end(); ++itr) { + + std::string param = itr->first; + bool isConstant = itr->second; + + // Try to get the variable in the workspace + RooRealVar *var = wspace->var(param); + if (!var) { + std::cout << "Error: Trying to set variable: " << var << " constant in creation of asimov dataset: " << fName + << " but this variable doesn't appear to exist in the workspace" << std::endl; + throw hf_exc(); + } + + std::cout << "Configuring Asimov Dataset: Setting " << param << " to constant " << std::endl; + var->setConstant(isConstant); + } + + return; +} + +/** \class RooStats::HistFactory::HistRef + * \ingroup HistFactory + * Internal class wrapping an histogram and managing its content. + * convenient for dealing with histogram pointers in the + * HistFactory class + */ + +/// constructor - use gives away ownerhip of the given pointer +HistRef::HistRef(TH1 *h) : fHist(h) {} + +HistRef::HistRef(const HistRef &other) +{ + if (other.fHist) + fHist.reset(CopyObject(other.fHist.get())); +} + +HistRef::HistRef(HistRef &&other) : fHist(std::move(other.fHist)) {} + +HistRef::~HistRef() = default; + +/// assignment operator (delete previous contained histogram) +HistRef &HistRef::operator=(const HistRef &other) +{ + if (this == &other) + return *this; + + fHist.reset(CopyObject(other.fHist.get())); + return *this; +} + +HistRef &HistRef::operator=(HistRef &&other) +{ + fHist = std::move(other.fHist); + return *this; +} + +TH1 *HistRef::CopyObject(const TH1 *h) +{ + // implementation of method copying the contained pointer + // (just use Clone) + if (!h) + return nullptr; + + TDirectory::TContext ctx{nullptr}; // Don't associate histogram with currently open file + return static_cast(h->Clone()); +} + +TH1 *HistRef::GetObject() const +{ + return fHist.get(); +} + +/// set the object - user gives away the ownerhisp +void HistRef::SetObject(TH1 *h) +{ + fHist.reset(h); +} + +/// operator= passing an object pointer : user gives away its ownerhisp +void HistRef::operator=(TH1 *h) +{ + SetObject(h); +} + +/// Release ownership of object. +TH1 *HistRef::ReleaseObject() +{ + return fHist.release(); +} + +// Constraints +std::string Constraint::Name(Constraint::Type type) +{ + + if (type == Constraint::Gaussian) + return "Gaussian"; + if (type == Constraint::Poisson) + return "Poisson"; + return ""; +} + +Constraint::Type Constraint::GetType(const std::string &Name) +{ + + if (Name.empty()) { + std::cout << "Error: Given empty name for ConstraintType" << std::endl; + throw hf_exc(); + } + + else if (Name == "Gaussian" || Name == "Gauss") { + return Constraint::Gaussian; + } + + else if (Name == "Poisson" || Name == "Pois") { + return Constraint::Poisson; + } + + else { + std::cout << "Error: Unknown name given for Constraint Type: " << Name << std::endl; + throw hf_exc(); + } +} + +// Norm Factor + +void NormFactor::Print(std::ostream &stream) const +{ + stream << "\t \t Name: " << fName << "\t Val: " << fVal << "\t Low: " << fLow << "\t High: " << fHigh << std::endl; +} + +void NormFactor::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl; +} + +// Overall Sys +void OverallSys::Print(std::ostream &stream) const +{ + stream << "\t \t Name: " << fName << "\t Low: " << fLow << "\t High: " << fHigh << std::endl; +} + +void OverallSys::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl; +} + +HistogramUncertaintyBase::HistogramUncertaintyBase() = default; + +HistogramUncertaintyBase::HistogramUncertaintyBase(const std::string &Name) + : fName(Name), fhLow(nullptr), fhHigh(nullptr) +{ +} + +HistogramUncertaintyBase::HistogramUncertaintyBase(HistogramUncertaintyBase &&) = default; + +HistogramUncertaintyBase &HistogramUncertaintyBase::operator=(HistogramUncertaintyBase &&) = default; + +HistogramUncertaintyBase::~HistogramUncertaintyBase() = default; + +void HistogramUncertaintyBase::Print(std::ostream &stream) const +{ + stream << "\t \t Name: " << fName << "\t HistoFileLow: " << fInputFileLow << "\t HistoNameLow: " << fHistoNameLow + << "\t HistoPathLow: " << fHistoPathLow << "\t HistoFileHigh: " << fInputFileHigh + << "\t HistoNameHigh: " << fHistoNameHigh << "\t HistoPathHigh: " << fHistoPathHigh << std::endl; +} + +void HistogramUncertaintyBase::writeToFile(const std::string &FileName, const std::string &DirName) +{ + + // This saves the histograms to a file and + // changes the name of the local file and histograms + + auto histLow = GetHistoLow(); + if (histLow == nullptr) { + std::cout << "Error: Cannot write " << GetName() << " to file: " << FileName << " HistoLow is nullptr" + << std::endl; + throw hf_exc(); + } + histLow->Write(); + fInputFileLow = FileName; + fHistoPathLow = DirName; + fHistoNameLow = histLow->GetName(); + + auto histHigh = GetHistoHigh(); + if (histHigh == nullptr) { + std::cout << "Error: Cannot write " << GetName() << " to file: " << FileName << " HistoHigh is nullptr" + << std::endl; + throw hf_exc(); + } + histHigh->Write(); + fInputFileHigh = FileName; + fHistoPathHigh = DirName; + fHistoNameHigh = histHigh->GetName(); + + return; +} + +void HistoSys::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl; +} + +// Shape Sys + +void ShapeSys::SetErrorHist(TH1 *hError) +{ + fhHigh.reset(hError); +} + +void ShapeSys::Print(std::ostream &stream) const +{ + stream << "\t \t Name: " << fName << "\t InputFile: " << fInputFileHigh << "\t HistoName: " << fHistoNameHigh + << "\t HistoPath: " << fHistoPathHigh << std::endl; +} + +void ShapeSys::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl; +} + +void ShapeSys::writeToFile(const std::string &FileName, const std::string &DirName) +{ + + auto histError = GetErrorHist(); + if (histError == nullptr) { + std::cout << "Error: Cannot write " << GetName() << " to file: " << FileName << " ErrorHist is nullptr" + << std::endl; + throw hf_exc(); + } + histError->Write(); + fInputFileHigh = FileName; + fHistoPathHigh = DirName; + fHistoNameHigh = histError->GetName(); + + return; +} + +// HistoFactor + +void HistoFactor::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl; +} + +// Shape Factor + +void ShapeFactor::SetInitialShape(TH1 *shape) +{ + fhHigh.reset(shape); +} + +void ShapeFactor::Print(std::ostream &stream) const +{ + + stream << "\t \t Name: " << fName << std::endl; + + if (!fHistoNameHigh.empty()) { + stream << "\t \t " + << " Shape Hist Name: " << fHistoNameHigh << " Shape Hist Path Name: " << fHistoPathHigh + << " Shape Hist FileName: " << fInputFileHigh << std::endl; + } + + if (fConstant) { + stream << "\t \t ( Constant ): " << std::endl; + } +} + +void ShapeFactor::writeToFile(const std::string &FileName, const std::string &DirName) +{ + + if (HasInitialShape()) { + auto histInitialShape = GetInitialShape(); + if (histInitialShape == nullptr) { + std::cout << "Error: Cannot write " << GetName() << " to file: " << FileName << " InitialShape is nullptr" + << std::endl; + throw hf_exc(); + } + histInitialShape->Write(); + fInputFileHigh = FileName; + fHistoPathHigh = DirName; + fHistoNameHigh = histInitialShape->GetName(); + } + + return; +} + +void ShapeFactor::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl; +} + +void StatError::SetErrorHist(TH1 *Error) +{ + fhHigh.reset(Error); +} + +// Stat Error Config +void StatErrorConfig::Print(std::ostream &stream) const +{ + stream << "\t \t RelErrorThreshold: " << fRelErrorThreshold + << "\t ConstraintType: " << Constraint::Name(fConstraintType) << std::endl; +} + +void StatErrorConfig::PrintXML(std::ostream &xml) const +{ + xml << " " << std::endl + << std::endl; +} + +// Stat Error +void StatError::Print(std::ostream &stream) const +{ + stream << "\t \t Activate: " << fActivate << "\t InputFile: " << fInputFileHigh << "\t HistoName: " << fHistoNameHigh + << "\t histoPath: " << fHistoPathHigh << std::endl; +} + +void StatError::PrintXML(std::ostream &xml) const +{ + + if (GetActivate()) { + xml << " " << std::endl; + } +} + +void StatError::writeToFile(const std::string &OutputFileName, const std::string &DirName) +{ + + if (fUseHisto) { + + std::string statErrorHistName = "statisticalErrors"; + + auto hStatError = GetErrorHist(); + if (hStatError == nullptr) { + std::cout << "Error: Stat Error error hist is nullptr" << std::endl; + throw hf_exc(); + } + hStatError->Write(statErrorHistName.c_str()); + + fInputFileHigh = OutputFileName; + fHistoNameHigh = statErrorHistName; + fHistoPathHigh = DirName; + } + + return; +} + +HistogramUncertaintyBase::HistogramUncertaintyBase(const HistogramUncertaintyBase &oth) + : fName{oth.fName}, + fInputFileLow{oth.fInputFileLow}, + fHistoNameLow{oth.fHistoNameLow}, + fHistoPathLow{oth.fHistoPathLow}, + fInputFileHigh{oth.fInputFileHigh}, + fHistoNameHigh{oth.fHistoNameHigh}, + fHistoPathHigh{oth.fHistoPathHigh}, + fhLow{oth.fhLow ? static_cast(oth.fhLow->Clone()) : nullptr}, + fhHigh{oth.fhHigh ? static_cast(oth.fhHigh->Clone()) : nullptr} +{ + if (fhLow) + fhLow->SetDirectory(nullptr); + if (fhHigh) + fhHigh->SetDirectory(nullptr); +} + +HistogramUncertaintyBase &HistogramUncertaintyBase::operator=(const HistogramUncertaintyBase &oth) +{ + fName = oth.fName; + fInputFileLow = oth.fInputFileLow; + fHistoNameLow = oth.fHistoNameLow; + fHistoPathLow = oth.fHistoPathLow; + fInputFileHigh = oth.fInputFileHigh; + fHistoNameHigh = oth.fHistoNameHigh; + fHistoPathHigh = oth.fHistoPathHigh; + + TDirectory::TContext ctx{nullptr}; // Don't associate clones to directories + fhLow.reset(oth.fhLow ? static_cast(oth.fhLow->Clone()) : nullptr); + fhHigh.reset(oth.fhHigh ? static_cast(oth.fhHigh->Clone()) : nullptr); + + return *this; +} + +void HistogramUncertaintyBase::SetHistoLow(TH1 *Low) +{ + Low->SetDirectory(nullptr); + fhLow.reset(Low); +} + +void HistogramUncertaintyBase::SetHistoHigh(TH1 *High) +{ + High->SetDirectory(nullptr); + fhHigh.reset(High); +} + +void Data::SetHisto(TH1 *Hist) +{ + fhData = Hist; + fHistoName = Hist->GetName(); +} + +void Sample::SetHisto(TH1 *histo) +{ + fhNominal = histo; + fHistoName = histo->GetName(); +} +} // namespace RooStats::HistFactory diff --git a/roofit/histfactory/src/PreprocessFunction.cxx b/roofit/histfactory/src/PreprocessFunction.cxx deleted file mode 100644 index 46a8b92b93dff..0000000000000 --- a/roofit/histfactory/src/PreprocessFunction.cxx +++ /dev/null @@ -1,64 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: Kyle Cranmer, George Lewis -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// -/** - * \ingroup HistFactory - */ - -#include - -#include - -namespace { - -/// Replaces the XML special characters with their escape codes. -std::string escapeXML(const std::string &src) -{ - std::stringstream dst; - for (char ch : src) { - switch (ch) { - case '&': dst << "&"; break; - case '\'': dst << "'"; break; - case '"': dst << """; break; - case '<': dst << "<"; break; - case '>': dst << ">"; break; - default: dst << ch; break; - } - } - return dst.str(); -} - -} // namespace - -RooStats::HistFactory::PreprocessFunction::PreprocessFunction(std::string const &name, std::string const &expression, - std::string const &dependents) - : fName(name), fExpression(expression), fDependents(dependents) -{ -} - -std::string RooStats::HistFactory::PreprocessFunction::GetCommand() const -{ - return "expr::" + fName + "('" + fExpression + "',{" + fDependents + "})"; -} - -void RooStats::HistFactory::PreprocessFunction::Print(std::ostream &stream) const -{ - stream << "\t \t Name: " << fName << "\t \t Expression: " << fExpression << "\t \t Dependents: " << fDependents - << std::endl; -} - -void RooStats::HistFactory::PreprocessFunction::PrintXML(std::ostream &xml) const -{ - xml << "\n"; -} diff --git a/roofit/histfactory/src/Sample.cxx b/roofit/histfactory/src/Sample.cxx deleted file mode 100644 index 2481c3ac8ca6b..0000000000000 --- a/roofit/histfactory/src/Sample.cxx +++ /dev/null @@ -1,436 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: Kyle Cranmer, George Lewis -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -/** \class RooStats::HistFactory::Sample - * \ingroup HistFactory - */ - -#include "TH1.h" -#include "RooStats/HistFactory/Sample.h" -#include "RooStats/HistFactory/HistFactoryException.h" - -RooStats::HistFactory::Sample::Sample() {} - -// copy constructor (important for Python) -RooStats::HistFactory::Sample::Sample(const Sample& other) : - fName(other.fName), fInputFile(other.fInputFile), - fHistoName(other.fHistoName), fHistoPath(other.fHistoPath), - fChannelName(other.fChannelName), - - fOverallSysList(other.fOverallSysList), - fNormFactorList(other.fNormFactorList), - fHistoSysList(other.fHistoSysList), - fHistoFactorList(other.fHistoFactorList), - fShapeSysList(other.fShapeSysList), - fShapeFactorList(other.fShapeFactorList), - - fStatError(other.fStatError), - fNormalizeByTheory(other.fNormalizeByTheory), - fStatErrorActivate(other.fStatErrorActivate), - fhNominal(other.fhNominal) - { - if( other.fhCountingHist ) { - SetValue( other.fhCountingHist->GetBinContent(1) ); - }else{ - fhCountingHist.reset(); - } - } - -RooStats::HistFactory::Sample& RooStats::HistFactory::Sample::operator=(const Sample& other) -{ - fName = other.fName; fInputFile = other.fInputFile; - fHistoName = other.fHistoName; fHistoPath = other.fHistoPath; - fChannelName = other.fChannelName; - - fOverallSysList = other.fOverallSysList; - fNormFactorList = other.fNormFactorList; - fHistoSysList = other.fHistoSysList; - fHistoFactorList = other.fHistoFactorList; - fShapeSysList = other.fShapeSysList; - fShapeFactorList = other.fShapeFactorList; - - fStatError = other.fStatError; - fNormalizeByTheory = other.fNormalizeByTheory; - fStatErrorActivate = other.fStatErrorActivate; - fhNominal = other.fhNominal; - - fhCountingHist.reset(); - - if( other.fhCountingHist ) { - SetValue( other.fhCountingHist->GetBinContent(1) ); - } else { - fhCountingHist.reset(); - } - - return *this; -} - - -RooStats::HistFactory::Sample::Sample(std::string SampName, std::string SampHistoName, std::string SampInputFile, std::string SampHistoPath) : - fName( SampName ), fInputFile( SampInputFile), - fHistoName( SampHistoName ), fHistoPath( SampHistoPath ), - fNormalizeByTheory(true), fStatErrorActivate(false) -{ -} - -RooStats::HistFactory::Sample::Sample(std::string SampName) - : fName(SampName), fNormalizeByTheory(true), fStatErrorActivate(false) -{ -} - -const TH1* RooStats::HistFactory::Sample::GetHisto() const { - TH1* histo = (TH1*) fhNominal.GetObject(); - return histo; -} - - -void RooStats::HistFactory::Sample::writeToFile( std::string OutputFileName, std::string DirName ) { - - const TH1* histNominal = GetHisto(); - histNominal->Write(); - - // Set the location of the data - // in the output measurement - - fInputFile = OutputFileName; - fHistoName = histNominal->GetName(); - fHistoPath = DirName; - - // Write this sample's StatError - GetStatError().writeToFile( OutputFileName, DirName ); - - // Must write all systematics that contain internal histograms - // (This is not all systematics) - for( unsigned int i = 0; i < GetHistoSysList().size(); ++i ) { - GetHistoSysList().at(i).writeToFile( OutputFileName, DirName ); - } - for( unsigned int i = 0; i < GetHistoFactorList().size(); ++i ) { - GetHistoFactorList().at(i).writeToFile( OutputFileName, DirName ); - } - for( unsigned int i = 0; i < GetShapeSysList().size(); ++i ) { - GetShapeSysList().at(i).writeToFile( OutputFileName, DirName ); - } - for( unsigned int i = 0; i < GetShapeFactorList().size(); ++i ) { - GetShapeFactorList().at(i).writeToFile( OutputFileName, DirName ); - } - - return; - -} - - -void RooStats::HistFactory::Sample::SetValue( double val ) { - - // For use in a number counting measurement - // Create a 1-bin histogram, - // fill it with this input value, - // and set this Sample's histogram to that hist - - std::string SampleHistName = fName + "_hist"; - - // Histogram has 1-bin (hard-coded) - fhCountingHist.reset(); - - fhCountingHist = std::make_unique( SampleHistName.c_str(), SampleHistName.c_str(), 1, 0, 1 ); - fhCountingHist->SetBinContent( 1, val ); - - // Set the histogram of the internally held data - // node of this channel to this newly created histogram - SetHisto( fhCountingHist.get() ); - -} - - - -void RooStats::HistFactory::Sample::Print( std::ostream& stream ) const { - - - stream << "\t \t Name: " << fName - << "\t \t Channel: " << fChannelName - << "\t NormalizeByTheory: " << (fNormalizeByTheory ? "True" : "False") - << "\t StatErrorActivate: " << (fStatErrorActivate ? "True" : "False") - << std::endl; - - stream << "\t \t \t \t " - << "\t InputFile: " << fInputFile - << "\t HistName: " << fHistoName - << "\t HistoPath: " << fHistoPath - << "\t HistoAddress: " << GetHisto() - // << "\t Type: " << GetHisto()->ClassName() - << std::endl; - - if( fStatError.GetActivate() ) { - stream << "\t \t \t StatError Activate: " << fStatError.GetActivate() - << "\t InputFile: " << fInputFile - << "\t HistName: " << fStatError.GetHistoName() - << "\t HistoPath: " << fStatError.GetHistoPath() - << "\t HistoAddress: " << fStatError.GetErrorHist() - << std::endl; - } - - - /* - stream<< " NormalizeByTheory: "; - if(NormalizeByTheory) stream << "True"; - else stream << "False"; - - stream<< " StatErrorActivate: "; - if(StatErrorActivate) stream << "True"; - else stream << "False"; - */ - - -} - -void RooStats::HistFactory::Sample::PrintXML( std::ofstream& xml ) const { - - - // Create the sample tag - xml << " " << std::endl; - - - // Print Stat Error (if necessary) - fStatError.PrintXML( xml ); - /* - if( fStatError.GetActivate() ) { - xml << " " << std::endl; - } - */ - - - // Now, print the systematics: - for( unsigned int i = 0; i < fOverallSysList.size(); ++i ) { - RooStats::HistFactory::OverallSys sys = fOverallSysList.at(i); - sys.PrintXML(xml); - /* - xml << " " << std::endl; - */ - } - for( unsigned int i = 0; i < fNormFactorList.size(); ++i ) { - RooStats::HistFactory::NormFactor sys = fNormFactorList.at(i); - sys.PrintXML(xml); - /* - xml << " " << std::endl; - */ - } - for( unsigned int i = 0; i < fHistoSysList.size(); ++i ) { - RooStats::HistFactory::HistoSys sys = fHistoSysList.at(i); - sys.PrintXML(xml); - /* - xml << " " << std::endl; - */ - } - for( unsigned int i = 0; i < fHistoFactorList.size(); ++i ) { - RooStats::HistFactory::HistoFactor sys = fHistoFactorList.at(i); - sys.PrintXML(xml); - /* - xml << " " << std::endl; - */ - } - for( unsigned int i = 0; i < fShapeSysList.size(); ++i ) { - RooStats::HistFactory::ShapeSys sys = fShapeSysList.at(i); - sys.PrintXML(xml); - /* - xml << " " << std::endl; - */ - } - for( unsigned int i = 0; i < fShapeFactorList.size(); ++i ) { - RooStats::HistFactory::ShapeFactor sys = fShapeFactorList.at(i); - sys.PrintXML(xml); - /* - xml << " " << std::endl; - */ - } - - // Finally, close the tag - xml << " " << std::endl; - -} - - -// Some helper functions -// (Not strictly necessary because -// methods are publicly accessible) - - -void RooStats::HistFactory::Sample::ActivateStatError() { - - fStatError.Activate( true ); - fStatError.SetUseHisto( false ); - -} - - -void RooStats::HistFactory::Sample::ActivateStatError( std::string StatHistoName, std::string StatInputFile, std::string StatHistoPath ) { - - - fStatError.Activate( true ); - fStatError.SetUseHisto( true ); - - fStatError.SetInputFile( StatInputFile ); - fStatError.SetHistoName( StatHistoName ); - fStatError.SetHistoPath( StatHistoPath ); - -} - - -void RooStats::HistFactory::Sample::AddOverallSys( std::string SysName, double SysLow, double SysHigh ) { - - RooStats::HistFactory::OverallSys sys; - sys.SetName( SysName ); - sys.SetLow( SysLow ); - sys.SetHigh( SysHigh ); - - fOverallSysList.push_back( sys ); - -} - -void RooStats::HistFactory::Sample::AddOverallSys( const OverallSys& Sys ) { - fOverallSysList.push_back(Sys); -} - -void RooStats::HistFactory::Sample::AddNormFactor( std::string const& SysName, double SysVal, double SysLow, double SysHigh ) { - - RooStats::HistFactory::NormFactor norm; - - norm.SetName( SysName ); - norm.SetVal( SysVal ); - norm.SetLow( SysLow ); - norm.SetHigh( SysHigh ); - - fNormFactorList.push_back( norm ); - -} - -void RooStats::HistFactory::Sample::AddNormFactor( const NormFactor& Factor ) { - fNormFactorList.push_back( Factor ); -} - - -void RooStats::HistFactory::Sample::AddHistoSys( std::string SysName, -std::string SysHistoNameLow, std::string SysHistoFileLow, std::string SysHistoPathLow, - std::string SysHistoNameHigh, std::string SysHistoFileHigh, std::string SysHistoPathHigh ) { - - RooStats::HistFactory::HistoSys sys; - sys.SetName( SysName ); - - sys.SetHistoNameLow( SysHistoNameLow ); - sys.SetHistoPathLow( SysHistoPathLow ); - sys.SetInputFileLow( SysHistoFileLow ); - - sys.SetHistoNameHigh( SysHistoNameHigh ); - sys.SetHistoPathHigh( SysHistoPathHigh ); - sys.SetInputFileHigh( SysHistoFileHigh ); - - fHistoSysList.push_back( sys ); - -} - -void RooStats::HistFactory::Sample::AddHistoSys( const HistoSys& Sys ) { - fHistoSysList.push_back( Sys ); -} - - -void RooStats::HistFactory::Sample::AddHistoFactor( std::string SysName, std::string SysHistoNameLow, std::string SysHistoFileLow, std::string SysHistoPathLow, - std::string SysHistoNameHigh, std::string SysHistoFileHigh, std::string SysHistoPathHigh ) { - - RooStats::HistFactory::HistoFactor factor; - factor.SetName( SysName ); - - factor.SetHistoNameLow( SysHistoNameLow ); - factor.SetHistoPathLow( SysHistoPathLow ); - factor.SetInputFileLow( SysHistoFileLow ); - - factor.SetHistoNameHigh( SysHistoNameHigh ); - factor.SetHistoPathHigh( SysHistoPathHigh ); - factor.SetInputFileHigh( SysHistoFileHigh ); - - fHistoFactorList.push_back( factor ); - -} - -void RooStats::HistFactory::Sample::AddHistoFactor( const HistoFactor& Factor ) { - fHistoFactorList.push_back(Factor); -} - - -void RooStats::HistFactory::Sample::AddShapeFactor( std::string SysName ) { - - RooStats::HistFactory::ShapeFactor factor; - factor.SetName( SysName ); - fShapeFactorList.push_back( factor ); - -} - - -void RooStats::HistFactory::Sample::AddShapeFactor( const ShapeFactor& Factor ) { - fShapeFactorList.push_back(Factor); -} - - -void RooStats::HistFactory::Sample::AddShapeSys( std::string SysName, Constraint::Type SysConstraintType, std::string SysHistoName, std::string SysHistoFile, std::string SysHistoPath ) { - - RooStats::HistFactory::ShapeSys sys; - sys.SetName( SysName ); - sys.SetConstraintType( SysConstraintType ); - - sys.SetHistoName( SysHistoName ); - sys.SetHistoPath( SysHistoPath ); - sys.SetInputFile( SysHistoFile ); - - fShapeSysList.push_back( sys ); - -} - -void RooStats::HistFactory::Sample::AddShapeSys( const ShapeSys& Sys ) { - fShapeSysList.push_back(Sys); -} diff --git a/roofit/histfactory/src/Systematics.cxx b/roofit/histfactory/src/Systematics.cxx deleted file mode 100644 index 58923420c8423..0000000000000 --- a/roofit/histfactory/src/Systematics.cxx +++ /dev/null @@ -1,327 +0,0 @@ -// @(#)root/roostats:$Id$ -// Author: Kyle Cranmer, George Lewis -/************************************************************************* - * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. * - * All rights reserved. * - * * - * For the licensing terms see $ROOTSYS/LICENSE. * - * For the list of contributors see $ROOTSYS/README/CREDITS. * - *************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// - -/* -BEGIN_HTML -

-

-END_HTML -*/ -// - - -#include "RooStats/HistFactory/Systematics.h" -#include "RooStats/HistFactory/HistFactoryException.h" - - -// Constraints -std::string RooStats::HistFactory::Constraint::Name( Constraint::Type type ) { - - if( type == Constraint::Gaussian ) return "Gaussian"; - if( type == Constraint::Poisson ) return "Poisson"; - return ""; -} - -RooStats::HistFactory::Constraint::Type RooStats::HistFactory::Constraint::GetType( const std::string& Name ) { - - if( Name.empty() ) { - std::cout << "Error: Given empty name for ConstraintType" << std::endl; - throw hf_exc(); - } - - else if ( Name == "Gaussian" || Name == "Gauss" ) { - return Constraint::Gaussian; - } - - else if ( Name == "Poisson" || Name == "Pois" ) { - return Constraint::Poisson; - } - - else { - std::cout << "Error: Unknown name given for Constraint Type: " << Name << std::endl; - throw hf_exc(); - } - -} - -// Norm Factor -RooStats::HistFactory::NormFactor::NormFactor() : fVal(1.0), - fLow(1.0), fHigh(1.0) {} - -void RooStats::HistFactory::NormFactor::Print( std::ostream& stream ) const { - stream << "\t \t Name: " << fName - << "\t Val: " << fVal - << "\t Low: " << fLow - << "\t High: " << fHigh - << std::endl; -} - -void RooStats::HistFactory::NormFactor::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl; -} - -// Overall Sys -void RooStats::HistFactory::OverallSys::Print( std::ostream& stream ) const { - stream << "\t \t Name: " << fName - << "\t Low: " << fLow - << "\t High: " << fHigh - << std::endl; -} - -void RooStats::HistFactory::OverallSys::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl; -} - - -void RooStats::HistFactory::HistogramUncertaintyBase::Print( std::ostream& stream ) const { - stream << "\t \t Name: " << fName - << "\t HistoFileLow: " << fInputFileLow - << "\t HistoNameLow: " << fHistoNameLow - << "\t HistoPathLow: " << fHistoPathLow - << "\t HistoFileHigh: " << fInputFileHigh - << "\t HistoNameHigh: " << fHistoNameHigh - << "\t HistoPathHigh: " << fHistoPathHigh - << std::endl; -} - -void RooStats::HistFactory::HistogramUncertaintyBase::writeToFile( const std::string& FileName, - const std::string& DirName ) { - - // This saves the histograms to a file and - // changes the name of the local file and histograms - - auto histLow = GetHistoLow(); - if( histLow==nullptr ) { - std::cout << "Error: Cannot write " << GetName() - << " to file: " << FileName - << " HistoLow is nullptr" - << std::endl; - throw hf_exc(); - } - histLow->Write(); - fInputFileLow = FileName; - fHistoPathLow = DirName; - fHistoNameLow = histLow->GetName(); - - auto histHigh = GetHistoHigh(); - if( histHigh==nullptr ) { - std::cout << "Error: Cannot write " << GetName() - << " to file: " << FileName - << " HistoHigh is nullptr" - << std::endl; - throw hf_exc(); - } - histHigh->Write(); - fInputFileHigh = FileName; - fHistoPathHigh = DirName; - fHistoNameHigh = histHigh->GetName(); - - return; - -} - - -void RooStats::HistFactory::HistoSys::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl; -} - -// Shape Sys - -void RooStats::HistFactory::ShapeSys::Print( std::ostream& stream ) const { - stream << "\t \t Name: " << fName - << "\t InputFile: " << fInputFileHigh - << "\t HistoName: " << fHistoNameHigh - << "\t HistoPath: " << fHistoPathHigh - << std::endl; -} - - -void RooStats::HistFactory::ShapeSys::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl; -} - - -void RooStats::HistFactory::ShapeSys::writeToFile( const std::string& FileName, - const std::string& DirName ) { - - auto histError = GetErrorHist(); - if( histError==nullptr ) { - std::cout << "Error: Cannot write " << GetName() - << " to file: " << FileName - << " ErrorHist is nullptr" - << std::endl; - throw hf_exc(); - } - histError->Write(); - fInputFileHigh = FileName; - fHistoPathHigh = DirName; - fHistoNameHigh = histError->GetName(); - - return; - -} - - - - -// HistoFactor - -void RooStats::HistFactory::HistoFactor::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl; -} - - -// Shape Factor -void RooStats::HistFactory::ShapeFactor::Print( std::ostream& stream ) const { - - stream << "\t \t Name: " << fName << std::endl; - - if( !fHistoNameHigh.empty() ) { - stream << "\t \t " - << " Shape Hist Name: " << fHistoNameHigh - << " Shape Hist Path Name: " << fHistoPathHigh - << " Shape Hist FileName: " << fInputFileHigh - << std::endl; - } - - if( fConstant ) { stream << "\t \t ( Constant ): " << std::endl; } - -} - - -void RooStats::HistFactory::ShapeFactor::writeToFile( const std::string& FileName, - const std::string& DirName ) { - - if( HasInitialShape() ) { - auto histInitialShape = GetInitialShape(); - if( histInitialShape==nullptr ) { - std::cout << "Error: Cannot write " << GetName() - << " to file: " << FileName - << " InitialShape is nullptr" - << std::endl; - throw hf_exc(); - } - histInitialShape->Write(); - fInputFileHigh = FileName; - fHistoPathHigh = DirName; - fHistoNameHigh = histInitialShape->GetName(); - } - - return; - -} - - -void RooStats::HistFactory::ShapeFactor::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl; -} - - -// Stat Error Config -void RooStats::HistFactory::StatErrorConfig::Print( std::ostream& stream ) const { - stream << "\t \t RelErrorThreshold: " << fRelErrorThreshold - << "\t ConstraintType: " << Constraint::Name( fConstraintType ) - << std::endl; -} - -void RooStats::HistFactory::StatErrorConfig::PrintXML( std::ostream& xml ) const { - xml << " " << std::endl << std::endl; - -} - - -// Stat Error -void RooStats::HistFactory::StatError::Print( std::ostream& stream ) const { - stream << "\t \t Activate: " << fActivate - << "\t InputFile: " << fInputFileHigh - << "\t HistoName: " << fHistoNameHigh - << "\t histoPath: " << fHistoPathHigh - << std::endl; -} - -void RooStats::HistFactory::StatError::PrintXML( std::ostream& xml ) const { - - if( GetActivate() ) { - xml << " " << std::endl; - } - -} - - -void RooStats::HistFactory::StatError::writeToFile( const std::string& OutputFileName, - const std::string& DirName ) { - - if( fUseHisto ) { - - std::string statErrorHistName = "statisticalErrors"; - - auto hStatError = GetErrorHist(); - if( hStatError == nullptr ) { - std::cout << "Error: Stat Error error hist is nullptr" << std::endl; - throw hf_exc(); - } - hStatError->Write(statErrorHistName.c_str()); - - fInputFileHigh = OutputFileName; - fHistoNameHigh = statErrorHistName; - fHistoPathHigh = DirName; - - } - - return; - -} diff --git a/roofit/histfactory/test/testHistFactory.cxx b/roofit/histfactory/test/testHistFactory.cxx index 8e144b9891af4..f66f1ce0a0b39 100644 --- a/roofit/histfactory/test/testHistFactory.cxx +++ b/roofit/histfactory/test/testHistFactory.cxx @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/roofit/histfactory/test/testHistFactoryPlotting.cxx b/roofit/histfactory/test/testHistFactoryPlotting.cxx index 0f6b91ac50d2e..cef2daa975037 100644 --- a/roofit/histfactory/test/testHistFactoryPlotting.cxx +++ b/roofit/histfactory/test/testHistFactoryPlotting.cxx @@ -3,7 +3,6 @@ #include #include -#include #include #include