diff --git a/DataQuality/dqm_algorithms/cmt/Makefile b/DataQuality/dqm_algorithms/cmt/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c2c9dbbed79a7894e694cf7a0c7d1bf0756334c3 --- /dev/null +++ b/DataQuality/dqm_algorithms/cmt/Makefile @@ -0,0 +1,4 @@ +include $(CMTROOT)/src/Makefile.header + +include $(CMTROOT)/src/constituents.make + diff --git a/DataQuality/dqm_algorithms/cmt/requirements b/DataQuality/dqm_algorithms/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..5cfe75e4e99f8ed252a740ac306e9831f2d1c783 --- /dev/null +++ b/DataQuality/dqm_algorithms/cmt/requirements @@ -0,0 +1,70 @@ +package dqm_algorithms +author Peter Onyisi <ponyisi@utexas.edu> + +############################################################################## +public +############################################################################## + +use AtlasPolicy AtlasPolicy-* +use AtlasROOT AtlasROOT-* External +# DRQ: It's important that the AtlasBoost dependency comes before the DQM_Core one since the +# latter overrides the Boost version in a way that's incompatible with the ATLAS offline +use AtlasBoost AtlasBoost-* External +use DQM_Core DQM_Core-* External + +# online options (only when building against AtlasHLT) +macro online_use "" AtlasHLT_scripts "HLTtdaq HLTtdaq-* HLT/HLTExternal" +use $(online_use) + +############################################################################## +private +############################################################################## + +use AtlasReflex AtlasReflex-* External -no_auto_imports + +macro_append ers_linkopts "$(tdaqc_linkopts) -lers " +# online options (only when building against AtlasHLT) +macro_append AtlasCxxPolicy_pp_cppflags "" AtlasHLT_scripts "-DONLINE" + +############################################################################## +# libraries +############################################################################## + +library dqm_algorithms "../src/*.cxx \ + ../tools/AlgorithmHelper.cxx \ + ../tools/SimpleAlgorithmConfig.cxx" +apply_pattern installed_library + +library dqm_tools "../tools/DumpConfig.cxx" +macro_append dqm_tools_dependencies " dqm_algorithms" +apply_pattern named_installed_library library=dqm_tools + +library dqm_summaries "../summary/*.cxx" +macro_append dqm_summaries_dependencies " dqm_tools" +apply_pattern named_installed_library library=dqm_summaries + +############################################################################# +# dictionaries +############################################################################# + +# Uncomment the following lines if you want to use the workbench + +apply_pattern lcgdict dict=dqm_algorithms selectionfile=../dqm_algorithms/selection.xml \ + headerfiles=../dqm_algorithms/dqm_algorithmsDict.h + +apply_pattern lcgdict dict=dqm_tools selectionfile=../dqm_algorithms/tools/selection.xml \ + headerfiles=../dqm_algorithms/tools/dqm_toolsDict.h + +############################################################################# +# applications +############################################################################# + +application dqm_print_algorithms "../test/print_algorithms.cpp" +macro_append dqm_print_algorithmslinkopts "$(Boost_linkopts) $(Boost_linkopts_program_options)" +alias dqm_print_algorithms dqm_print_algorithms.exe +macro_append dqm_print_algorithms_dependencies " dqm_summaries" + +application dqm_print_summarymakers "../test/print_summarymakers.cpp" +macro_append dqm_print_summarymakerslinkopts "$(Boost_linkopts) $(Boost_linkopts_program_options)" +alias dqm_print_summarymakers dqm_print_summarymakers.exe +macro_append dqm_print_summarymakers_dependencies " dqm_summaries" diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference.h new file mode 100644 index 0000000000000000000000000000000000000000..17133f39e0f40d7ed8d679bde18a3999c6a363a4 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference.h file declares the dqm_algorithms::AddReference class. + * \author andrea.dotti@cern.ch + */ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_H +#define DQM_ALGORITHMS_ADDREFERENCE_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct AddReference : public dqm_core::Algorithm + { + AddReference(const std::string& name ); + AddReference* clone(); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + dqm_core::Result* execute(const std::string& , const TObject& , const dqm_core::AlgorithmConfig& ); + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_All_Bins_Filled.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_All_Bins_Filled.h new file mode 100644 index 0000000000000000000000000000000000000000..ee90c08f65c534e654ff4fdaa98b0fc4ce80705a --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_All_Bins_Filled.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_All_Bins_Filled.h file declares the dqm_algorithms::AddReference_All_Bins_Filled class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_ALL_BINS_FILLED_H +#define DQM_ALGORITHMS_ADDREFERENCE_ALL_BINS_FILLED_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_All_Bins_Filled : public AddReference + { + AddReference_All_Bins_Filled(): AddReference("All_Bins_Filled") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_ALL_BINS_FILLED_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_BinContentComp.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_BinContentComp.h new file mode 100644 index 0000000000000000000000000000000000000000..a5ca448a932bd1c3c1ea10c9ae731205724a9a2f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_BinContentComp.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_BinContentComp.h file declares the dqm_algorithms::AddReference_BinContentComp class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINCONTENTCOMP_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINCONTENTCOMP_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_BinContentComp : public AddReference + { + AddReference_BinContentComp(): AddReference("BinContentComp") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINCONTENTCOMP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_Diff_FromAvg.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_Diff_FromAvg.h new file mode 100644 index 0000000000000000000000000000000000000000..6ef3e7874c9cfb441fa5bcdd33946b114073ce84 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_Diff_FromAvg.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_Diff_FromAvg.h file declares the dqm_algorithms::AddReference_Bins_Diff_FromAvg class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_DIFF_FROMAVG_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_DIFF_FROMAVG_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_Diff_FromAvg : public AddReference + { + AddReference_Bins_Diff_FromAvg(): AddReference("Bins_Diff_FromAvg") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_DIFF_FROMAVG_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_Equal_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_Equal_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..87d8df6b448e4fc42c119eebd4c978a08a62a1a2 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_Equal_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_Equal_Threshold.h file declares the dqm_algorithms::AddReference_Bins_Equal_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_EQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_EQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_Equal_Threshold : public AddReference + { + AddReference_Bins_Equal_Threshold(): AddReference("Bins_Equal_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_EQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_GreaterThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_GreaterThanEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..0db9c137222a43e7986fe4532defe31bb84db61d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_GreaterThanEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_GreaterThanEqual_Threshold.h file declares the dqm_algorithms::AddReference_Bins_GreaterThanEqual_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_GREATERTHANEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_GREATERTHANEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_GreaterThanEqual_Threshold : public AddReference + { + AddReference_Bins_GreaterThanEqual_Threshold(): AddReference("Bins_GreaterThanEqual_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_GREATERTHANEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_GreaterThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_GreaterThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..b32471f858650405f46444f0664f4d31e83ce344 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_GreaterThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_GreaterThan_Threshold.h file declares the dqm_algorithms::AddReference_Bins_GreaterThan_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_GREATERTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_GREATERTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_GreaterThan_Threshold : public AddReference + { + AddReference_Bins_GreaterThan_Threshold(): AddReference("Bins_GreaterThan_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_GREATERTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_LessThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_LessThanEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..ba2164f878a1c1d8ae977ecf4874d38745ef2347 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_LessThanEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_LessThanEqual_Threshold.h file declares the dqm_algorithms::AddReference_Bins_LessThanEqual_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_LESSTHANEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_LESSTHANEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_LessThanEqual_Threshold : public AddReference + { + AddReference_Bins_LessThanEqual_Threshold(): AddReference("Bins_LessThanEqual_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_LESSTHANEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_LessThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_LessThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..8272d497e1cde7e467c3f6d3a65bad6a8b310b22 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_LessThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_LessThan_Threshold.h file declares the dqm_algorithms::AddReference_Bins_LessThan_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_LESSTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_LESSTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_LessThan_Threshold : public AddReference + { + AddReference_Bins_LessThan_Threshold(): AddReference("Bins_LessThan_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_LESSTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_NotEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_NotEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..f810be3222b6368e1c41b2bfd34e27e39558563d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AddReference_Bins_NotEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference_Bins_NotEqual_Threshold.h file declares the dqm_algorithms::AddReference_Bins_NotEqual_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_ADDREFERENCE_BINS_NOTEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_ADDREFERENCE_BINS_NOTEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/AddReference.h> + +namespace dqm_algorithms +{ + struct AddReference_Bins_NotEqual_Threshold : public AddReference + { + AddReference_Bins_NotEqual_Threshold(): AddReference("Bins_NotEqual_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_ADDREFERENCE_BINS_NOTEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/All_Bins_Filled.h b/DataQuality/dqm_algorithms/dqm_algorithms/All_Bins_Filled.h new file mode 100644 index 0000000000000000000000000000000000000000..499956cc7c463df56b14c05a495cf6eb5f88019e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/All_Bins_Filled.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file All_Bins_Filled.h file declares the dqm_algorithms::All_Bins_Filled class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_ALL_BINS_FILLED_H +#define DQM_ALGORITHMS_ALL_BINS_FILLED_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheck.h> + +namespace dqm_algorithms +{ + struct All_Bins_Filled : public BasicHistoCheck + { + All_Bins_Filled(): BasicHistoCheck("All_Bins_Filled") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_ALL_BINS_FILLED_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/AveragePrint.h b/DataQuality/dqm_algorithms/dqm_algorithms/AveragePrint.h new file mode 100644 index 0000000000000000000000000000000000000000..0b79c0a474c2814b597987b220aa505a90f5a148 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/AveragePrint.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_AVERAGEPRINT_H +#define DQM_ALGORITHMS_AVERAGEPRINT_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + + class AveragePrint : public dqm_core::Algorithm { + public: + + AveragePrint(); + + virtual ~AveragePrint(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, + const TObject& data, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + + protected: + + std::string name; + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_AVERAGEPRINT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BasicGraphCheck.h b/DataQuality/dqm_algorithms/dqm_algorithms/BasicGraphCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..202a6eccdd8d0db9d086ab2cd0076e1312d823dd --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BasicGraphCheck.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicGraphCheck.h file declares the dqm_core::BasicGraphCheck class. + * \author Peter Onyisi following Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BASICGRAPHCHECK_H +#define DQM_ALGORITHMS_BASICGRAPHCHECK_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BasicGraphCheck : public dqm_core::Algorithm + { + BasicGraphCheck(const std::string & name); + + //overwrites virtual functions + BasicGraphCheck * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BasicHistoCheck.h b/DataQuality/dqm_algorithms/dqm_algorithms/BasicHistoCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..34f94a642a9c3006c100e064a23ca03f9ff8491e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BasicHistoCheck.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicHistoCheck.h file declares the dqm_core::BasicHistoCheck class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BASICHISTOCHECK_H +#define DQM_ALGORITHMS_BASICHISTOCHECK_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BasicHistoCheck : public dqm_core::Algorithm + { + BasicHistoCheck(const std::string & name); + + //overwrites virtual functions + BasicHistoCheck * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_BASICHISTOCHECK_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BasicHistoCheckModuleStatus.h b/DataQuality/dqm_algorithms/dqm_algorithms/BasicHistoCheckModuleStatus.h new file mode 100644 index 0000000000000000000000000000000000000000..c3fad61973a33502d93a3ad6d0a58e83dbc6b57a --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BasicHistoCheckModuleStatus.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicHistoCheck.h file declares the dqm_core::BasicHistoCheck class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BASICHISTOCHECKMODULESTATUS_H +#define DQM_ALGORITHMS_BASICHISTOCHECKMODULESTATUS_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BasicHistoCheckModuleStatus : public dqm_core::Algorithm + { + BasicHistoCheckModuleStatus(const std::string & name); + + //overwrites virtual functions + BasicHistoCheckModuleStatus * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_BASICHISTOCHECKMODULESTATUS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BasicStatCheck.h b/DataQuality/dqm_algorithms/dqm_algorithms/BasicStatCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..3182347c8db48e3578624c02cdfedb8216669f70 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BasicStatCheck.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicStatCheck.h file declares the dqm_algorithms::BasicStatCheck class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BASICSTATCHECK_H +#define DQM_ALGORITHMS_BASICSTATCHECK_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BasicStatCheck : public dqm_core::Algorithm + { + BasicStatCheck(const std::string & name); + + //overwrites virtual functions + BasicStatCheck * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_BASICSTATCHECK_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinContentComp.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinContentComp.h new file mode 100644 index 0000000000000000000000000000000000000000..c5cd92e965634d237ecf77c98bda5fcf53eefb99 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinContentComp.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinContentComp.h file declares the dqm_algorithms::BinContentComp class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINCONTENTCOMP_H +#define DQM_ALGORITHMS_BINCONTENTCOMP_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BinContentComp : public dqm_core::Algorithm + { + BinContentComp(); + + ~BinContentComp(); + + //overwrites virtual functions + BinContentComp * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_BINCONTENTCOMP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinContentDump.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinContentDump.h new file mode 100644 index 0000000000000000000000000000000000000000..a8cf8828d3346149e76bf882643eca2334183eaa --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinContentDump.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_BINCONTENTDUMP_H +#define DQM_ALGORITHMS_BINCONTENTDUMP_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BinContentDump : public dqm_core::Algorithm + { + BinContentDump(); + + ~BinContentDump(); + + //overwrites virtual functions + BinContentDump * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_BINCONTENTDUMP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinDump.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinDump.h new file mode 100644 index 0000000000000000000000000000000000000000..422d4944676efef557396c569745f5a09691b7ad --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinDump.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_BINDUMP_H +#define DQM_ALGORITHMS_BINDUMP_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class BinDump : public dqm_core::Algorithm { +public: + + BinDump(); + + virtual ~BinDump(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_BINDUMP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinPrint.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinPrint.h new file mode 100644 index 0000000000000000000000000000000000000000..1362ef00cf6bd96c59ce0df80411ecc68a1b5b12 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinPrint.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_BINPRINT_H +#define DQM_ALGORITHMS_BINPRINT_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + + class BinPrint : public dqm_core::Algorithm { + public: + + BinPrint(); + + virtual ~BinPrint(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, + const TObject& data, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + + protected: + + std::string name; + + int NbinsX; + int NbinsY; + int UnMask_All; + int UseValue; + int TypeValue; + double Value; + int UseMaskValue; + double MaskValue; + + int UseValue_GetFromMap(const std::map<std::string, double> & params); + int TypeValue_GetFromMap(const std::map<std::string, double> & params); + double Value_GetFromMap(const std::map<std::string, double> & params); + int UseMaskValue_GetFromMap(const std::map<std::string, double> & params); + double MaskValue_GetFromMap(const std::map<std::string, double> & params); + std::vector<bool> Mask1D_GetFromMap(const std::map<std::string, double> & params); + std::vector< std::vector<bool> > Mask2D_GetFromMap(const std::map<std::string, double> & params); + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_BINPRINT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinThresh.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinThresh.h new file mode 100644 index 0000000000000000000000000000000000000000..cab50618ae8203e47528b07f929afe1f30e5414e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinThresh.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_BINTHRESH_H +#define DQM_ALGORITHMS_BINTHRESH_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +namespace dqm_algorithms { + + class BinThresh : public dqm_core::Algorithm { + public: + + BinThresh(); + + virtual ~BinThresh(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, + const TObject& data, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + + protected: + struct mask_limits { + bool Mask; + double WarningValue; + double ErrorValue; + }; + + protected: + + std::string name; + + //Histogram configuration parameters + int NbinsX; + int NbinsY; + + int Publish_GetFromMap(const std::map<std::string, double> & params); + int TypePublish_GetFromMap(const std::map<std::string, double> & params); + int UseValue_GetFromMap(const std::map<std::string, double> & params); + int TypeValue_GetFromMap(const std::map<std::string, double> & params); + int BinMinEntries_GetFromMap(const std::map<std::string, double> & params); + std::vector<BinThresh::mask_limits> Limits1D_GetFromMap( const std::map<std::string, double> & params, + const std::map<std::string, double> & warning_params, + const std::map<std::string, double> & error_params ); + std::vector< std::vector<BinThresh::mask_limits> > Limits2D_GetFromMap( const std::map< std::string, double> & params, + const std::map< std::string, double> & warning_params, + const std::map< std::string, double> & error_params ); + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_BINTHRESH_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinThreshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinThreshold.h new file mode 100644 index 0000000000000000000000000000000000000000..21b5144991f1b003c838ec98f40842d6e9d18cc8 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinThreshold.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinThreshold.h file declares the dqm_algorithms::BinThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINTHRESHOLD_H +#define DQM_ALGORITHMS_BINTHRESHOLD_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BinThreshold : public dqm_core::Algorithm + { + BinThreshold(const std::string & name); + + //overwrites virtual functions + BinThreshold * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + bool CompareBinThreshold( const std::string & objname, double bincontent, double threshold ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_BINTHRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffByStrips.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffByStrips.h new file mode 100644 index 0000000000000000000000000000000000000000..2e97cbd2a0072060c7c0622b6d583de092034a0f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffByStrips.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsDiffByStrips.h file declares the dqm_algorithms::BinContentComp class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINSDIFFBYSTRIPS_H +#define DQM_ALGORITHMS_BINSDIFFBYSTRIPS_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BinsDiffByStrips : public dqm_core::Algorithm + { + BinsDiffByStrips(); + + ~BinsDiffByStrips(); + + //overwrites virtual functions + BinsDiffByStrips * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + void find_n(std::string, int&); + }; +} + +#endif // DQM_ALGORITHMS_BINSDIFFBYSTRIPS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffFromStripMedian.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffFromStripMedian.h new file mode 100644 index 0000000000000000000000000000000000000000..8a213fe9c4f9de5d68936256aea0765f66d2629d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffFromStripMedian.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* BinsDiffFromStripMedian.h +// Author: FENG TIAN (columbia university) + Email: Feng.Tian@cern.ch +*/ + +#ifndef BinsDiffFromStripMedian_H +#define BinsDiffFromStripMedian_H + +#include <dqm_core/Algorithm.h> +#include <vector> +#include <iostream> +#include <string> +enum color{green,yellow,red}; +class bin; +class colorbin; +class colorcluster; + +namespace dqm_algorithms +{ + struct BinsDiffFromStripMedian : public dqm_core::Algorithm + { + BinsDiffFromStripMedian(); + + ~BinsDiffFromStripMedian(); + + //overwrites virtual functions + BinsDiffFromStripMedian * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + void FindStripMedian(std::vector<double> onestrip,std::vector<double>& stripsMedian); + // void MakeTag(colorbin,std::string&); + colorcluster MakeCluster(const int r0,const int r2,bin & onebin, std::vector<std::vector< +colorbin> > & ColorBinMap); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +class bin{ + public: + double m_eta; + double m_phi; + int m_ix; + int m_iy; + double m_value; + double m_outstandingRatio; +} ; + +class colorbin{ + public: + double m_eta; + double m_phi; + int m_ix; + int m_iy; + double m_value; + color m_color; + bool m_status; // true: not in cluster ; false: in cluster +}; +class colorcluster{ + public: + double m_eta; + double m_phi; + double m_radius; + double m_value; + double m_color; + int m_size; +}; + + +#endif // BinsDiffFromStripMedian_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffFromStripMedianOnline.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffFromStripMedianOnline.h new file mode 100644 index 0000000000000000000000000000000000000000..004f3efd958aa63dd91c7dbc9ff88e691edc2cbd --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinsDiffFromStripMedianOnline.h @@ -0,0 +1,83 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* BinsDiffFromStripMedianOnline.h +// Author: FENG TIAN (columbia university) + Email: Feng.Tian@cern.ch +*/ + +#ifndef BinsDiffFromStripMedianOnline_H +#define BinsDiffFromStripMedianOnline_H + +#include <dqm_core/Algorithm.h> +#include "dqm_algorithms/BinsDiffFromStripMedian.h" +#include <vector> +#include <iostream> +#include <string> + +//class binOnline; +//class colorbinOnline; +//class colorclusterOnline; + +namespace dqm_algorithms +{ + struct BinsDiffFromStripMedianOnline : public dqm_core::Algorithm + { + class binOnline; + class colorbinOnline; + class colorclusterOnline; + + BinsDiffFromStripMedianOnline(); + + ~BinsDiffFromStripMedianOnline(); + + //overwrites virtual functions + BinsDiffFromStripMedianOnline * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + void FindStripMedianOnline(const std::string & ,std::vector<double> onestrip,std::vector<double>& stripsMedian); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + colorclusterOnline MakeClusterOnline(const std::string & name,const int r0,const int r2,binOnline & onebin, std::vector<std::vector<colorbinOnline> > & ColorBinMap); + + void AddToList(const int r0,const int r2,int i,int j,std::vector<std::vector<colorbinOnline> > & ColorBinMap, std::vector<colorbinOnline>& LookAtList); + double CalEta(std::vector<colorbinOnline>& LookAtList); + double CalPhi(std::vector<colorbinOnline>& LookAtList); + double CalVal(std::vector<colorbinOnline>& LookAtList); + double CalR(std::vector<colorbinOnline>& LookAtList,double eta, double phi); + + class binOnline{ + public: + double m_eta; + double m_phi; + int m_ix; + int m_iy; + double m_value; + double m_outstandingRatio; + friend bool operator<(const binOnline &left, const binOnline &right) {return left.m_outstandingRatio > right.m_outstandingRatio;} + } ; + + class colorbinOnline{ + public: + double m_eta; + double m_phi; + int m_ix; + int m_iy; + double m_value; + color m_color; + bool m_status; // true: not in cluster ; false: in cluster + }; + + class colorclusterOnline{ + public: + double m_eta; + double m_phi; + double m_radius; + double m_value; + color m_color; + int m_size; + }; + + }; +} +#endif // BinsDiffFromStripMedianOnline_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinsFilledOutRange.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinsFilledOutRange.h new file mode 100644 index 0000000000000000000000000000000000000000..5064bdf38f42e72f9bb8e41568be6b7b1da0d6c7 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinsFilledOutRange.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsFilledOutRange.h file declares the dqm_algorithms::BinsFilledOutRange class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINSFILLEDOUTRANGE_H +#define DQM_ALGORITHMS_BINSFILLEDOUTRANGE_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BinsFilledOutRange : public dqm_core::Algorithm + { + BinsFilledOutRange(); + + ~BinsFilledOutRange(); + + //overwrites virtual functions + BinsFilledOutRange * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_BINSFILLEDOUTRANGE_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinsOutOfRange.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinsOutOfRange.h new file mode 100644 index 0000000000000000000000000000000000000000..634e2df67fa15abf3c4e97da08df65f45fe42595 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinsOutOfRange.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* BinsOutOfRange.h +// Author: FENG TIAN (columbia university) + Email: Feng.Tian@cern.ch +*/ + +#ifndef BinsOutOfRange_H +#define BinsOutOfRange_H + +#include <dqm_core/Algorithm.h> +#include <vector> +#include <iostream> +#include <string> +class bin3; +namespace dqm_algorithms +{ + struct BinsOutOfRange: public dqm_core::Algorithm + { + BinsOutOfRange(); + + ~BinsOutOfRange(); + + //overwrites virtual functions + BinsOutOfRange * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +class bin3{ + public: + double m_eta; + double m_phi; + int m_ix; + int m_iy; + double m_value; +} ; + + +#endif // BinsOutOfRange_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinsSymmetric.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinsSymmetric.h new file mode 100644 index 0000000000000000000000000000000000000000..d47281119aeeeaeb64fe0c9161c0c1f77761a108 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinsSymmetric.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsSymmetric.h file declares the dqm_algorithms::BinsSymmetric class. + * \author Michele Petteni +*/ + +#ifndef DQM_ALGORITHMS_BINSSYMMETRIC_H +#define DQM_ALGORITHMS_BINSSYMMETRIC_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BinsSymmetric : public dqm_core::Algorithm + { + BinsSymmetric(); + + ~BinsSymmetric(); + + //overwrites virtual functions + BinsSymmetric * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + }; +} + +#endif // DQM_ALGORITHMS_BINSSYMMETRIC_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_Diff_FromAvg.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_Diff_FromAvg.h new file mode 100644 index 0000000000000000000000000000000000000000..8095065b92b1010b028657de921d0bef0deef4bd --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_Diff_FromAvg.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Bins_Diff_FromAvg.h file declares the dqm_algorithms::BinContentComp class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_DIFF_FROMAVG_H +#define DQM_ALGORITHMS_BINS_DIFF_FROMAVG_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct Bins_Diff_FromAvg : public dqm_core::Algorithm + { + Bins_Diff_FromAvg(); + + ~Bins_Diff_FromAvg(); + + //overwrites virtual functions + Bins_Diff_FromAvg * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_BINS_DIFF_FROMAVG_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_Equal_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_Equal_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..291503726559a087d6e3217444921ae9033c12c1 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_Equal_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsEqualThreshold.h file declares the dqm_algorithms::BinsEqualThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_EQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_EQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_Equal_Threshold : public BinThreshold + { + Bins_Equal_Threshold(): BinThreshold("Equal") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_EQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanAbs_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanAbs_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..1a46a54c6982b67ea865f2fc58d1ba5265a83bfa --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanAbs_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Bins_GreaterThanAbs_Threshold.h file declares the dqm_algorithms::Bins_GreaterThanAbs_Threshold class. + * \author Evan Wulf +*/ + +#ifndef DQM_ALGORITHMS_BINS_GREATERTHANABS_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_GREATERTHANABS_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_GreaterThanAbs_Threshold : public BinThreshold + { + Bins_GreaterThanAbs_Threshold(): BinThreshold("GreaterThanAbs") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_GREATERTHANABS_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..7b1d3bdb9c4ad6b3410121d304f06fbc1de2f26f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Bins_GreaterThanEqual_Threshold.h file declares the dqm_algorithms::Bins_GreaterThanEqual_Threshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_GREATERTHANEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_GREATERTHANEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_GreaterThanEqual_Threshold : public BinThreshold + { + Bins_GreaterThanEqual_Threshold(): BinThreshold("GreaterThanEqual") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_GREATERTHANEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanNonZeroMedian_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanNonZeroMedian_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..6e6bd68084e77f1d91114b1622c62e8438038326 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThanNonZeroMedian_Threshold.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*file Bins_GreaterThan_NonZeroMedian.h author Justin Griffiths based of template dqm_algorithms:: +BinsGreaterThanThreshold class author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_GREATERTHANNONZEROMEDIAN_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_GREATERTHANNONZEROMEDIAN_THRESHOLD_H + +#include "dqm_core/Algorithm.h" +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms { + + + struct Bins_GreaterThanNonZeroMedian_Threshold : public BinThreshold + { + Bins_GreaterThanNonZeroMedian_Threshold(): BinThreshold("GreaterThanNonZeroMedian") {}; + }; + + + +} //dqm_algorithms + +#endif // DQM_ALGORITHMS_BINS_GREATERTHANNONZEROMEDIAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..6c7ce4c2029800fe41a928bfaee95e5e7b37c17d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_GreaterThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsGreaterThanThreshold.h file declares the dqm_algorithms::BinsGreaterThanThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_GREATERTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_GREATERTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_GreaterThan_Threshold : public BinThreshold + { + Bins_GreaterThan_Threshold(): BinThreshold("GreaterThan") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_GREATERTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanAbs_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanAbs_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..ba2abbceb2525ba4912a34450960bcc620169027 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanAbs_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsLessThanThreshold.h file declares the dqm_algorithms::BinsLessThanThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_LESSTHANABS_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_LESSTHANABS_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_LessThanAbs_Threshold : public BinThreshold + { + Bins_LessThanAbs_Threshold(): BinThreshold("LessThanAbs") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_LESSTHANABS_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..c1ed2d67b2860083e6d10980890dc31e120e40c6 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsLessThanEqualThreshold.h file declares the dqm_algorithms::BinsLessThanEqualThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_LESSTHANEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_LESSTHANEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_LessThanEqual_Threshold : public BinThreshold + { + Bins_LessThanEqual_Threshold(): BinThreshold("LessThanEqual") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_LESSTHANEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanNonZeroMedian_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanNonZeroMedian_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..2aab54f5f241d2047b094d54e051f821baded53b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThanNonZeroMedian_Threshold.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*file Bins_LessThan_NonZeroMedian.h author Justin Griffiths based of template dqm_algorithms:: +BinsLessThanThreshold class author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_LESSTHANNONZEROMEDIAN_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_LESSTHANNONZEROMEDIAN_THRESHOLD_H + +#include "dqm_core/Algorithm.h" +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms { + + + struct Bins_LessThanNonZeroMedian_Threshold : public BinThreshold + { + Bins_LessThanNonZeroMedian_Threshold(): BinThreshold("LessThanNonZeroMedian") {}; + }; + + + +} //dqm_algorithms + +#endif // DQM_ALGORITHMS_BINS_LESSTHANNONZEROMEDIAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..6b86089ec85b0c0226c96cf32fb2bc37f01b5d45 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_LessThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsLessThanThreshold.h file declares the dqm_algorithms::BinsLessThanThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_LESSTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_LESSTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_LessThan_Threshold : public BinThreshold + { + Bins_LessThan_Threshold(): BinThreshold("LessThan") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_LESSTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Bins_NotEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_NotEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..b237d9f102806bccadf2e0a9ec7db83645b8214f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Bins_NotEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsNotEqualThreshold.h file declares the dqm_algorithms::BinsNotEqualThreshold class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_BINS_NOTEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_BINS_NOTEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BinThreshold.h> + +namespace dqm_algorithms +{ + struct Bins_NotEqual_Threshold : public BinThreshold + { + Bins_NotEqual_Threshold(): BinThreshold("NotEqual") {}; + + }; +} + +#endif // DQM_ALGORITHMS_BINS_NOTEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BlackBin.h b/DataQuality/dqm_algorithms/dqm_algorithms/BlackBin.h new file mode 100644 index 0000000000000000000000000000000000000000..527d5b467d0b735ac084865f934435c58d7e9b80 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BlackBin.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BlackBin.h file declares the dqm_algorithms::BlackBin class. + * \author Martin White +*/ + +#ifndef DQM_ALGORITHMS_BLACKBIN_H +#define DQM_ALGORITHMS_BLACKBIN_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BlackBin : public dqm_core::Algorithm + { + BlackBin(); + + //overwrites virtual functions + BlackBin * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_BLACKBIN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BlackBin1D.h b/DataQuality/dqm_algorithms/dqm_algorithms/BlackBin1D.h new file mode 100644 index 0000000000000000000000000000000000000000..25bb92383d7629b4865efaff213989b15dcaa799 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/BlackBin1D.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BlackBin.h file declares the dqm_algorithms::BlackBin class. + * \author Martin White +*/ + +#ifndef DQM_ALGORITHMS_BLACKBIN1D_H +#define DQM_ALGORITHMS_BLACKBIN1D_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct BlackBin1D : public dqm_core::Algorithm + { + BlackBin1D(); + + //overwrites virtual functions + BlackBin1D * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_BLACKBIN1D_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/CSCNoisyDead.h b/DataQuality/dqm_algorithms/dqm_algorithms/CSCNoisyDead.h new file mode 100644 index 0000000000000000000000000000000000000000..481286f88b22ba6596bddc1c20ee3cdd829bda33 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/CSCNoisyDead.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file CSCNoisyDead.h file declares the dqm_algorithms::CSCNoisyDead class. + * \author J.Veatch +*/ + +#ifndef DQM_ALGORITHMS_CSCNOISYDEAD_H +#define DQM_ALGORITHMS_CSCNOISYDEAD_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct CSCNoisyDead : public dqm_core::Algorithm + { + CSCNoisyDead(); + + ~CSCNoisyDead(); + + //overwrites virtual functions + CSCNoisyDead * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_CSCNOISYDEAD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/CheckHisto_Mean.h b/DataQuality/dqm_algorithms/dqm_algorithms/CheckHisto_Mean.h new file mode 100644 index 0000000000000000000000000000000000000000..4e8646ac3d74e0503ab57c49674abb88cbc8fe6c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/CheckHisto_Mean.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file CheckHisto_Mean.h file declares the dqm_algorithms::CheckHisto_Mean class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHECKHISTO_MEAN_H +#define DQM_ALGORITHMS_CHECKHISTO_MEAN_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicStatCheck.h> + +namespace dqm_algorithms +{ + struct CheckHisto_Mean : public BasicStatCheck + { + CheckHisto_Mean(): BasicStatCheck("Mean") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_CHECKHISTO_MEAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/CheckHisto_RMS.h b/DataQuality/dqm_algorithms/dqm_algorithms/CheckHisto_RMS.h new file mode 100644 index 0000000000000000000000000000000000000000..e49fba1211eae8b45d642bd1590090e5a8896ae7 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/CheckHisto_RMS.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file CheckHisto_RMS.h file declares the dqm_algorithms::CheckHisto_RMS class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHECKHISTO_RMS_H +#define DQM_ALGORITHMS_CHECKHISTO_RMS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicStatCheck.h> + +namespace dqm_algorithms +{ + struct CheckHisto_RMS : public BasicStatCheck + { + CheckHisto_RMS(): BasicStatCheck("RMS") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_CHECKHISTO_RMS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/CheckMean.h b/DataQuality/dqm_algorithms/dqm_algorithms/CheckMean.h new file mode 100644 index 0000000000000000000000000000000000000000..6d02733a6753635da92b9e09838b558a4f3ffd5c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/CheckMean.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_CHECKMEAN_H +#define DQM_ALGORITHMS_CHECKMEAN_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class CheckMean : public dqm_core::Algorithm { +public: + + CheckMean(); + + virtual ~CheckMean(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& data, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +protected: + + virtual double getWarningLimit( const dqm_core::AlgorithmConfig& config, std::string limitName ); + virtual double getErrorLimit( const dqm_core::AlgorithmConfig& config, std::string limitName ); + + std::string name; + std::string limitName; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_CHECKMEAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test.h new file mode 100644 index 0000000000000000000000000000000000000000..d28e8a1fc4a0d1582111cf01e7800567de5d26f6 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test.h file declares the dqm_algorithms::Chi2Test class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_H +#define DQM_ALGORITHMS_CHI2TEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct Chi2Test : public dqm_core::Algorithm + { + Chi2Test( const std::string & name ); + + Chi2Test * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + std::string option; + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_2D.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_2D.h new file mode 100644 index 0000000000000000000000000000000000000000..e9dc884b23e34e0bcbd69d58efcc308452429168 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_2D.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_2D.h file declares the dqm_algorithms::Chi2Test_2D class. + * \author Ian Moult +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_2D_H +#define DQM_ALGORITHMS_CHI2TEST_2D_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct Chi2Test_2D : public dqm_core::Algorithm + { + Chi2Test_2D (); + + Chi2Test_2D * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + std::string option; + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_2D_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Chi2.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Chi2.h new file mode 100644 index 0000000000000000000000000000000000000000..1c2a950a89b9ad41c5a26e329619a072f1dd1b66 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Chi2.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Prob.h file declares the dqm_algorithms::Chi2Test_Prob class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_CHI2_H +#define DQM_ALGORITHMS_CHI2TEST_CHI2_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/Chi2Test.h> + +namespace dqm_algorithms +{ + struct Chi2Test_Chi2 : public Chi2Test + { + Chi2Test_Chi2(): Chi2Test("Chi2") {}; + + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_CHI2_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Chi2_per_NDF.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Chi2_per_NDF.h new file mode 100644 index 0000000000000000000000000000000000000000..46ae38e07808c3a89c7efb1fa35e86f86431aeea --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Chi2_per_NDF.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Chi2_per_NDF.h file declares the dqm_algorithms::Chi2Test_Chi2_per_NDF class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_CHI2_PER_NDF_H +#define DQM_ALGORITHMS_CHI2TEST_CHI2_PER_NDF_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/Chi2Test.h> + +namespace dqm_algorithms +{ + struct Chi2Test_Chi2_per_NDF : public Chi2Test + { + Chi2Test_Chi2_per_NDF(): Chi2Test("Chi2_per_NDF") {}; + + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_CHI2_PER_NDF_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Prob.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Prob.h new file mode 100644 index 0000000000000000000000000000000000000000..525df20dfcb50b225d7a87493cd4df3aa6aa5c95 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Prob.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Prob.h file declares the dqm_algorithms::Chi2Test_Prob class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_PROB_H +#define DQM_ALGORITHMS_CHI2TEST_PROB_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/Chi2Test.h> + +namespace dqm_algorithms +{ + struct Chi2Test_Prob : public Chi2Test + { + Chi2Test_Prob(): Chi2Test("Prob") {}; + + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_PROB_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_ProbUW.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_ProbUW.h new file mode 100644 index 0000000000000000000000000000000000000000..7973a68746dbed0fca5eff95b0930b252932e445 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_ProbUW.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Prob.h file declares the dqm_algorithms::Chi2Test_Prob class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_PROBUW_H +#define DQM_ALGORITHMS_CHI2TEST_PROBUW_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/Chi2Test.h> + +namespace dqm_algorithms +{ + struct Chi2Test_ProbUW : public Chi2Test + { + Chi2Test_ProbUW(): Chi2Test("ProbUW") {}; + + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_PROBUW_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_ProbWW.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_ProbWW.h new file mode 100644 index 0000000000000000000000000000000000000000..f294b951942115c5fa1ba095c9f973654c5dfba8 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_ProbWW.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Prob.h file declares the dqm_algorithms::Chi2Test_Prob class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_PROBWW_H +#define DQM_ALGORITHMS_CHI2TEST_PROBWW_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/Chi2Test.h> + +namespace dqm_algorithms +{ + struct Chi2Test_ProbWW : public Chi2Test + { + Chi2Test_ProbWW(): Chi2Test("ProbWW") {}; + + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_PROBWW_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Scatterplot.h b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Scatterplot.h new file mode 100644 index 0000000000000000000000000000000000000000..f2ccca2f39f437a13a3eaa236e6df1d4e2bf8647 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Chi2Test_Scatterplot.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Scatterplot.h file declares the dqm_algorithms::Chi2Test_Scatterplot class. + * \author Ian Moult +*/ + +#ifndef DQM_ALGORITHMS_CHI2TEST_SCATTERPLOT_H +#define DQM_ALGORITHMS_CHI2TEST_SCATTERPLOT_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct Chi2Test_Scatterplot : public dqm_core::Algorithm + { + Chi2Test_Scatterplot (); + + Chi2Test_Scatterplot * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + std::string option; + }; +} + +#endif // DQM_ALGORITHMS_CHI2TEST_SCATTERPLOT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/ChiComp.h b/DataQuality/dqm_algorithms/dqm_algorithms/ChiComp.h new file mode 100644 index 0000000000000000000000000000000000000000..356bc0a658837e6e42ea34a561f9d6d0572cba39 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/ChiComp.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file ChiComp.h file declares the dqm_algorithms::ChiComp class. + * \author Pier-Olivier DeViveiros - inspired by the other dqm algorithms +*/ + +#ifndef DQM_ALGORITHMS_CHICOMP_H +#define DQM_ALGORITHMS_CHICOMP_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct ChiComp : public dqm_core::Algorithm + { + ChiComp( const std::string & name ); + + ChiComp * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + std::string option; + }; +} + +#endif // DQM_ALGORITHMS_CHICOMP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/CorrelationYX.h b/DataQuality/dqm_algorithms/dqm_algorithms/CorrelationYX.h new file mode 100644 index 0000000000000000000000000000000000000000..0302cbe813d39365797060d945a6c26a868eabde --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/CorrelationYX.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_CORRELATIONYX_H +#define DQM_ALGORITHMS_CORRELATIONYX_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + + class CorrelationYX : public dqm_core::Algorithm { + public: + + CorrelationYX(); + + virtual ~CorrelationYX(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + + private: + std::string name; + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_CORRELATIONYX_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/CountsBinsGreaterThan.h b/DataQuality/dqm_algorithms/dqm_algorithms/CountsBinsGreaterThan.h new file mode 100644 index 0000000000000000000000000000000000000000..1668937dc1ffbdf71bb84d2795d434e51030cff1 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/CountsBinsGreaterThan.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_COUNTSBINSGREATERTHAN_H +#define DQM_ALGORITHMS_COUNTSBINSGREATERTHAN_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + + class CountsBinsGreaterThan : public dqm_core::Algorithm { + public: + + CountsBinsGreaterThan(); + + virtual ~CountsBinsGreaterThan(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + + private: + std::string name; + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_COUNTSBINSGREATERTHAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideBin.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideBin.h new file mode 100644 index 0000000000000000000000000000000000000000..cb9420c19c9c47c29997ca6d8024b60871633f56 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideBin.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideBin.h file declares the dqm_algorithms::DivideBin class. + * \author Martin White +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEBIN_H +#define DQM_ALGORITHMS_DIVIDEBIN_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct DivideBin : public dqm_core::Algorithm + { + DivideBin(); + + //overwrites virtual functions + DivideBin * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEBIN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference.h new file mode 100644 index 0000000000000000000000000000000000000000..132391aea8b86f83db06d9824e3bde0f7cfdb494 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference.h file declares the dqm_algorithms::DivideReference class. + * \author andrea.dotti@cern.ch + */ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct DivideReference : public dqm_core::Algorithm + { + DivideReference(const std::string& name ); + DivideReference* clone(); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + dqm_core::Result* execute(const std::string& , const TObject& , const dqm_core::AlgorithmConfig& ); + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_All_Bins_Filled.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_All_Bins_Filled.h new file mode 100644 index 0000000000000000000000000000000000000000..9d1ca140cca127c7de131c1e6565d7227375685c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_All_Bins_Filled.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_All_Bins_Filled.h file declares the dqm_algorithms::DivideReference_All_Bins_Filled class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_ALL_BINS_FILLED_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_ALL_BINS_FILLED_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_All_Bins_Filled : public DivideReference + { + DivideReference_All_Bins_Filled(): DivideReference("All_Bins_Filled") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_ALL_BINS_FILLED_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_BinContentComp.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_BinContentComp.h new file mode 100644 index 0000000000000000000000000000000000000000..cf8e11b43b1cb3b1836c41927bb67da78638303f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_BinContentComp.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_BinContentComp.h file declares the dqm_algorithms::DivideReference_BinContentComp class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINCONTENTCOMP_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINCONTENTCOMP_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_BinContentComp : public DivideReference + { + DivideReference_BinContentComp(): DivideReference("BinContentComp") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINCONTENTCOMP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_Diff_FromAvg.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_Diff_FromAvg.h new file mode 100644 index 0000000000000000000000000000000000000000..48fa5a21750a1965a121b582cb2d54e23668f3a7 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_Diff_FromAvg.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_Diff_FromAvg.h file declares the dqm_algorithms::DivideReference_Bins_Diff_FromAvg class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_DIFF_FROMAVG_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_DIFF_FROMAVG_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_Diff_FromAvg : public DivideReference + { + DivideReference_Bins_Diff_FromAvg(): DivideReference("Bins_Diff_FromAvg") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_DIFF_FROMAVG_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_Equal_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_Equal_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..e9922dc9c877bd490434ae6bf3a1a207761f6d39 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_Equal_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_Equal_Threshold.h file declares the dqm_algorithms::DivideReference_Bins_Equal_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_EQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_EQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_Equal_Threshold : public DivideReference + { + DivideReference_Bins_Equal_Threshold(): DivideReference("Bins_Equal_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_EQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_GreaterThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_GreaterThanEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..991a936b19f36236fac082e375e93dd809e79064 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_GreaterThanEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_GreaterThanEqual_Threshold.h file declares the dqm_algorithms::DivideReference_Bins_GreaterThanEqual_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_GREATERTHANEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_GREATERTHANEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_GreaterThanEqual_Threshold : public DivideReference + { + DivideReference_Bins_GreaterThanEqual_Threshold(): DivideReference("Bins_GreaterThanEqual_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_GREATERTHANEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_GreaterThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_GreaterThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..6be44d7b630d3cd29cf32e9695167adb69038b50 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_GreaterThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_GreaterThan_Threshold.h file declares the dqm_algorithms::DivideReference_Bins_GreaterThan_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_GREATERTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_GREATERTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_GreaterThan_Threshold : public DivideReference + { + DivideReference_Bins_GreaterThan_Threshold(): DivideReference("Bins_GreaterThan_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_GREATERTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_LessThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_LessThanEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..1058cf960bc2112eb1ec77f3bd7411f3839437e5 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_LessThanEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_LessThanEqual_Threshold.h file declares the dqm_algorithms::DivideReference_Bins_LessThanEqual_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_LESSTHANEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_LESSTHANEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_LessThanEqual_Threshold : public DivideReference + { + DivideReference_Bins_LessThanEqual_Threshold(): DivideReference("Bins_LessThanEqual_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_LESSTHANEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_LessThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_LessThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..32f8bfa7c6a2ef85fb5e875a9f8965adffd19a4e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_LessThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_LessThan_Threshold.h file declares the dqm_algorithms::DivideReference_Bins_LessThan_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_LESSTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_LESSTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_LessThan_Threshold : public DivideReference + { + DivideReference_Bins_LessThan_Threshold(): DivideReference("Bins_LessThan_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_LESSTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_NotEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_NotEqual_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..3e4f3069d7cf664ff303ecbc3879c3ac46e69699 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/DivideReference_Bins_NotEqual_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference_Bins_NotEqual_Threshold.h file declares the dqm_algorithms::DivideReference_Bins_NotEqual_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_NOTEQUAL_THRESHOLD_H +#define DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_NOTEQUAL_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/DivideReference.h> + +namespace dqm_algorithms +{ + struct DivideReference_Bins_NotEqual_Threshold : public DivideReference + { + DivideReference_Bins_NotEqual_Threshold(): DivideReference("Bins_NotEqual_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_DIVIDEREFERENCE_BINS_NOTEQUAL_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/GatherData.h b/DataQuality/dqm_algorithms/dqm_algorithms/GatherData.h new file mode 100644 index 0000000000000000000000000000000000000000..6a79eba2bba4039ba585b984598032cc03628f6e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/GatherData.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_GATHERDATA_H +#define DQM_ALGORITHMS_GATHERDATA_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class GatherData : public dqm_core::Algorithm { +public: + + GatherData(); + + virtual ~GatherData(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& data, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +protected: + + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_GATHERDATA_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/GraphPrint.h b/DataQuality/dqm_algorithms/dqm_algorithms/GraphPrint.h new file mode 100644 index 0000000000000000000000000000000000000000..80b1f5e6376c75886151d2f82bf458dfb85b8204 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/GraphPrint.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file GraphPrint.h file declares the dqm_algorithms::GraphPrint class. + * \author Jahred Adelman +*/ +#ifndef DQM_ALGORITHMS_GRAPHPRINT_H +#define DQM_ALGORITHMS_GRAPHPRINT_H +#include <string> +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + class GraphPrint : public dqm_core::Algorithm + { + public: + GraphPrint(); + virtual GraphPrint* clone(); + virtual dqm_core::Result* execute(const std::string &, + const TObject & obj, + const dqm_core::AlgorithmConfig & conf ); + virtual ~GraphPrint(); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_GRAPHTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/GraphTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/GraphTest.h new file mode 100644 index 0000000000000000000000000000000000000000..251e097dab18d2b17582a4602fea38aec0e7c2ab --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/GraphTest.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file GraphTest.h file declares the dqm_algorithms::GraphTest class. + * \author Haleh Hadavand +*/ +#ifndef DQM_ALGORITHMS_GRAPHTEST_H +#define DQM_ALGORITHMS_GRAPHTEST_H +#include <string> +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + /*! \class tile_dq::GraphTest + * GraphTest DQ algorithm: check validity of a TGraph (or TH1) + * This test can be used to perform a test on a TGraph with (or without) + * error bars, in case asymmmetric. + * The algorithm accepts also TH1 as input, in such a case + * the histogram with be translated into a TGraph object (without error bars) + * It performs two tests: + * 1- It checks that each point in the TGraph has "small" error bars + * 2- It checks that each point is "close" to a reference value + * For test 2 a reference TGraph has to be provided (in this way + * each point may have a different reference value). The (x,y) + * coordinates of the point are compared with the reference point + * coordinates (x_r,y_r) and REFERENCE point error bars defining + * the maximum allowed distance. i.e. + * the point is good if: + * x_r - f*x_err < x < x_r + f*x_err + * and + * y_r - f*y_err < y < y_r + f*y_err + * "f" is a factor that can be used to specify different limits for Green and Red + * thresholds. + * If, for a specific reference point, the error bars along one coordinate are set to + * zero the test 2 is NOT performed for that point (this can be used to exclude, for + * example, a dead channel through the reference graph). + * The algorithms can work also with TGraphAsymmErrors object, so high and low errors + * can always be specified separately. + * The parameters that can be set, separetely, for Green and Red thresholds are: + * XErrHigh : Maximum (higher) error bar length x coord. + * XErrLow : Maximum (lower) error bar length x coord. + * YErrHigh : Maximum (higher) error bar length y coord. + * YErrLow : Maximum (lower) error bar length y coord. + * DistFactor : The factor "f" used in second part of the test + * Detailed example in workbench macro: TestGraphTest.C + */ + class GraphTest : public dqm_core::Algorithm + { + public: + GraphTest(); + virtual GraphTest* clone(); + virtual dqm_core::Result* execute(const std::string &, + const TObject & obj, + const dqm_core::AlgorithmConfig & conf ); + virtual ~GraphTest(); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_GRAPHTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/GrubbsOutlierTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/GrubbsOutlierTest.h new file mode 100644 index 0000000000000000000000000000000000000000..fc166236cbf68a4e6dfada22e352fa66c4cc92e9 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/GrubbsOutlierTest.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file GrubbsOutlierTest.h + * \author Venkatesh Kaushik <venkat.kaushik@cern.ch> + * \identify outlier-bins in 1d histogram +*/ + +#ifndef DQM_ALGORITHMS_GRUBBSOUTLIERTEST_H +#define DQM_ALGORITHMS_GRUBBSOUTLIERTEST_H + +#include <dqm_core/Algorithm.h> +#include <vector> + +namespace dqm_algorithms +{ + + struct GrubbsOutlierTest : public dqm_core::Algorithm + { + GrubbsOutlierTest(const std::string &name); + + GrubbsOutlierTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + int GrubbsTest(std::vector<float>& vec, std::vector<size_t>&binIndices, float signLevel); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_GRUBBSOUTLIERTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/HLTMETComponents.h b/DataQuality/dqm_algorithms/dqm_algorithms/HLTMETComponents.h new file mode 100644 index 0000000000000000000000000000000000000000..7b68d0ef3f18082d35a633f363cb256e06b88733 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/HLTMETComponents.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* Algorithm: dqm_algorithms::HLTMETComponents + * Author : Venkatesh Kaushik <venkat.kaushik@cern.ch> + * Date : Mar 6 2010 + */ + + +#ifndef DQM_ALGORITHMS_HLTMETCOMPONENTS_H +#define DQM_ALGORITHMS_HLTMETCOMPONENTS_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct HLTMETComponents : public dqm_core::Algorithm + { + HLTMETComponents(); + + //overwrites virtual functions + HLTMETComponents * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_HLTMETCOMPONENTS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/HLTMETStatus.h b/DataQuality/dqm_algorithms/dqm_algorithms/HLTMETStatus.h new file mode 100644 index 0000000000000000000000000000000000000000..085601b3422b747fd1426e5d30b61010b7fdccab --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/HLTMETStatus.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* Algorithm: dqm_algorithms::HLTMETStatus + * Author : Venkatesh Kaushik <venkat.kaushik@cern.ch> + * Date : Feb 21 2010 + */ + + +#ifndef DQM_ALGORITHMS_HLTMETSTATUS_H +#define DQM_ALGORITHMS_HLTMETSTATUS_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct HLTMETStatus : public dqm_core::Algorithm + { + HLTMETStatus(); + + //overwrites virtual functions + HLTMETStatus * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_HLTMETSTATUS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Effective_Empty.h b/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Effective_Empty.h new file mode 100644 index 0000000000000000000000000000000000000000..7c1dbae68c9417819243809b58261bc1b96d9625 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Effective_Empty.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Histogram_Not_Empty.h file declares the dqm_algorithms::Histogram_Not_Empty class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_HISTOGRAM_EFFECTIVE_EMPTY_H +#define DQM_ALGORITHMS_HISTOGRAM_EFFECTIVE_EMPTY_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheck.h> + +namespace dqm_algorithms +{ + struct Histogram_Effective_Empty : public BasicHistoCheck + { + Histogram_Effective_Empty(): BasicHistoCheck("Histogram_Effective_Empty") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_HISTOGRAM_EFFECTIVE_EMPTY_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Empty.h b/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Empty.h new file mode 100644 index 0000000000000000000000000000000000000000..f12aaf54a6e1fc4e6f0bc2d899c6732710514657 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Empty.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Histogram_Not_Empty.h file declares the dqm_algorithms::Histogram_Not_Empty class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_HISTOGRAM_EMPTY_H +#define DQM_ALGORITHMS_HISTOGRAM_EMPTY_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheck.h> + +namespace dqm_algorithms +{ + struct Histogram_Empty : public BasicHistoCheck + { + Histogram_Empty(): BasicHistoCheck("Histogram_Empty") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_HISTOGRAM_EMPTY_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Not_Empty.h b/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Not_Empty.h new file mode 100644 index 0000000000000000000000000000000000000000..fe2cf7222bf33e8793e3efc9141d037f4e0f8c76 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Histogram_Not_Empty.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Histogram_Not_Empty.h file declares the dqm_algorithms::Histogram_Not_Empty class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_HISTOGRAM_NOT_EMPTY_H +#define DQM_ALGORITHMS_HISTOGRAM_NOT_EMPTY_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheck.h> + +namespace dqm_algorithms +{ + struct Histogram_Not_Empty : public BasicHistoCheck + { + Histogram_Not_Empty(): BasicHistoCheck("Histogram_Not_Empty") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_HISTOGRAM_NOT_EMPTY_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/IterativeGaussianFit.h b/DataQuality/dqm_algorithms/dqm_algorithms/IterativeGaussianFit.h new file mode 100644 index 0000000000000000000000000000000000000000..bc3afac4acb7b6a78505b59892957c65e9f132f9 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/IterativeGaussianFit.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_ITERATIVEGAUSSIANFIT_H +#define DQM_ALGORITHMS_ITERATIVEGAUSSIANFIT_H + +#include "dqm_core/Algorithm.h" +#include <string> + +namespace dqm_core { class AlgorithmConfig; } +class TObject; + +namespace dqm_algorithms +{ + +class IterativeGaussianFit: public dqm_core::Algorithm +{ +public: + explicit IterativeGaussianFit(const std::string &name); + virtual ~IterativeGaussianFit(); + +public: + virtual IterativeGaussianFit *clone(); + virtual dqm_core::Result *execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + const std::string m_name; +}; + +} // namespace + +#endif // DQM_ALGORITHMS_ITERATIVEGAUSSIANFIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest.h new file mode 100644 index 0000000000000000000000000000000000000000..f6afb401d659304fc6260c79a472662e0b330e39 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file JarqueBeraTest.h file declares the dqm_algorithms::JarqueBeraTest class, implementing the Jarque-Bera statistical test. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_JARQUEBERATEST_H +#define DQM_ALGORITHMS_JARQUEBERATEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct JarqueBeraTest : public dqm_core::Algorithm + { + JarqueBeraTest( const std::string & name ); + + JarqueBeraTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + }; + +} + +#endif // DQM_ALGORITHMS_JARQUEBERATEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest_JB.h b/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest_JB.h new file mode 100644 index 0000000000000000000000000000000000000000..9e4f96bcb3c8ca08880fc096e0ab18d0266ad7a1 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest_JB.h @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file JarqueBearTest_JB.h file declares the dqm_algorithms::JarqueBearTest_JB class. + * \author andrea.dotti@cen.ch +*/ + +#ifndef DQM_ALGORITHMS_JARQUEBERATEST_JB_H +#define DQM_ALGORITHMS_JARQUEBERATEST_JB_H + +#include <dqm_algorithms/JarqueBeraTest.h> + +namespace dqm_algorithms +{ + struct JarqueBeraTest_JB : public JarqueBeraTest + { + JarqueBeraTest_JB() : JarqueBeraTest("JB") {} ; + }; +} + +#endif // DQM_ALGORITHMS_JARQUEBERATEST_JB_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest_Prob.h b/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest_Prob.h new file mode 100644 index 0000000000000000000000000000000000000000..af51ab4d36096b30c6a6e724dcf538e7d830994e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/JarqueBeraTest_Prob.h @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file JarqueBearTest_Prob.h file declares the dqm_algorithms::JarqueBearTest_Prob class. + * \author andrea.dotti@cen.ch +*/ + +#ifndef DQM_ALGORITHMS_JARQUEBERATEST_PROB_H +#define DQM_ALGORITHMS_JARQUEBERATEST_PROB_H + +#include <dqm_algorithms/JarqueBeraTest.h> + +namespace dqm_algorithms +{ + struct JarqueBeraTest_Prob : public JarqueBeraTest + { + JarqueBeraTest_Prob() : JarqueBeraTest("Prob") {} ; + }; +} + +#endif // DQM_ALGORITHMS_JARQUEBERATEST_PROB_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KillBinsByStrip.h b/DataQuality/dqm_algorithms/dqm_algorithms/KillBinsByStrip.h new file mode 100644 index 0000000000000000000000000000000000000000..ab6ca152184bca264836c3a64d845b63f26050e5 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KillBinsByStrip.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* KillBinsByStrip.h + Author: Olivier Simard (CEA-Saclay) + Email: Olivier.Simard@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_KILLBINSBYSTRIP_H +#define DQM_ALGORITHMS_KILLBINSBYSTRIP_H + +#include <dqm_core/Algorithm.h> +#include <math.h> +#include <vector> +#include <iostream> +#include <string> +class bin2; + +namespace dqm_algorithms +{ + struct KillBinsByStrip : public dqm_core::Algorithm + { + KillBinsByStrip(); + + ~KillBinsByStrip(); + + // overwrites virtual functions + KillBinsByStrip* clone(); + dqm_core::Result* execute(const std::string&,const TObject&,const dqm_core::AlgorithmConfig&); + //void MakeTag(bin2,std::string&); // not yet implemented + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} +class bin2 { + public: + double m_eta; + double m_phi; + int m_ix; + int m_iy; + double m_value; + double m_deviation; +}; +#endif // DQM_ALGORITHMS_KILLBINSBYSTRIP_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest.h new file mode 100644 index 0000000000000000000000000000000000000000..72e9e6b27b9da39137d961cc5171ed7b647dec4f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KolmogorovTest.h file declares the dqm_algorithms::KolmogorovTest class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_KOLMOGOROVTEST_H +#define DQM_ALGORITHMS_KOLMOGOROVTEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct KolmogorovTest : public dqm_core::Algorithm + { + KolmogorovTest( const std::string & name ); + + KolmogorovTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + std::string option; + }; +} + +#endif // DQM_ALGORITHMS_KOLMOGOROVTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_MaxDist.h b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_MaxDist.h new file mode 100644 index 0000000000000000000000000000000000000000..fea3db5fd3826abe37a74c7b15f736ae65f91174 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_MaxDist.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KolmogorovTest_MaxDist.h file declares the dqm_algorithms::KolmogorovTest_MaxDist class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_KOLMOGOROVTEST_MAXDIST_H +#define DQM_ALGORITHMS_KOLMOGOROVTEST_MAXDIST_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KolmogorovTest.h> + +namespace dqm_algorithms +{ + struct KolmogorovTest_MaxDist : public KolmogorovTest + { + KolmogorovTest_MaxDist(): KolmogorovTest("MaxDist") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KOLMOGOROVTEST_MAXDIST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_MaxDistPlusNorm.h b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_MaxDistPlusNorm.h new file mode 100644 index 0000000000000000000000000000000000000000..3e3b2a7b5ef43a643b8b5a26744095c1f38e5fbf --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_MaxDistPlusNorm.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KolmogorovTest_MaxDistPlusNorm.h file declares the dqm_algorithms::KolmogorovTest_MaxDistPlusNorm class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_KOLMOGOROVTEST_MAXDISTPLUSNORM_H +#define DQM_ALGORITHMS_KOLMOGOROVTEST_MAXDISTPLUSNORM_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KolmogorovTest.h> + +namespace dqm_algorithms +{ + struct KolmogorovTest_MaxDistPlusNorm : public KolmogorovTest + { + KolmogorovTest_MaxDistPlusNorm(): KolmogorovTest("MaxDistPlusNorm") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KOLMOGOROVTEST_MAXDISTPLUSNORM_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_Norm.h b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_Norm.h new file mode 100644 index 0000000000000000000000000000000000000000..1791ba262a79c27f958cdf9ef38ab7c1421ab2e5 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_Norm.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KolmogorovTest_Norm.h file declares the dqm_algorithms::KolmogorovTest_Norm class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_KOLMOGOROVTEST_NORM_H +#define DQM_ALGORITHMS_KOLMOGOROVTEST_NORM_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KolmogorovTest.h> + +namespace dqm_algorithms +{ + struct KolmogorovTest_Norm : public KolmogorovTest + { + KolmogorovTest_Norm(): KolmogorovTest("Norm") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KOLMOGOROVTEST_NORM_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_Prob.h b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_Prob.h new file mode 100644 index 0000000000000000000000000000000000000000..2c58a116baf9ab442d36adf2cdc6e1cd667940e2 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KolmogorovTest_Prob.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KolmogorovTest_Prob.h file declares the dqm_algorithms::KolmogorovTest_Prob class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_KOLMOGOROVTEST_PROB_H +#define DQM_ALGORITHMS_KOLMOGOROVTEST_PROB_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KolmogorovTest.h> + +namespace dqm_algorithms +{ + struct KolmogorovTest_Prob : public KolmogorovTest + { + KolmogorovTest_Prob(): KolmogorovTest("Prob") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KOLMOGOROVTEST_PROB_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest.h new file mode 100644 index 0000000000000000000000000000000000000000..2b4139da4094da78e0b43eea3535dcf3280fd090 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KurtosisTest.h file declares the dqm_algorithms::KurtosisTest class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_KURTOSISTEST_H +#define DQM_ALGORITHMS_KURTOSISTEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct KurtosisTest : public dqm_core::Algorithm + { + KurtosisTest(const std::string & name); + + //overwrites virtual functions + KurtosisTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + bool CompareKurtosisTest( const std::string& type, double value , double threshold ); + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_KURTOSISTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_GreaterThan.h b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_GreaterThan.h new file mode 100644 index 0000000000000000000000000000000000000000..cbdbf37b31fbd4bb798b41aac91ea4879972cdca --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_GreaterThan.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KurtosisTest_GreaterThan.h file declares the dqm_algorithms::KurtosisTest_GreaterThan class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_KURTOSISTEST_GREATERTHAN_H +#define DQM_ALGORITHMS_KURTOSISTEST_GREATERTHAN_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KurtosisTest.h> + +namespace dqm_algorithms +{ + struct KurtosisTest_GreaterThan : public KurtosisTest + { + KurtosisTest_GreaterThan(): KurtosisTest("GreaterThan") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KURTOSISTEST_GREATERTHAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_GreaterThanAbs.h b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_GreaterThanAbs.h new file mode 100644 index 0000000000000000000000000000000000000000..828b07aad101b4fb7a96454f928aa12e54af0260 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_GreaterThanAbs.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KurtosisTest_GreaterThanAbs.h file declares the dqm_algorithms::KurtosisTest_GreaterThanAbs class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_KURTOSISTEST_GREATERTHANABS_H +#define DQM_ALGORITHMS_KURTOSISTEST_GREATERTHANABS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KurtosisTest.h> + +namespace dqm_algorithms +{ + struct KurtosisTest_GreaterThanAbs : public KurtosisTest + { + KurtosisTest_GreaterThanAbs(): KurtosisTest("GreaterThanAbs") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KURTOSISTEST_GREATERTHANABS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_LessThan.h b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_LessThan.h new file mode 100644 index 0000000000000000000000000000000000000000..3a96ffc4be35addc16fce71781bd0bfeb0c03a94 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_LessThan.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KurtosisTest_LessThan.h file declares the dqm_algorithms::KurtosisTest_LessThan class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_KURTOSISTEST_LESSTHAN_H +#define DQM_ALGORITHMS_KURTOSISTEST_LESSTHAN_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KurtosisTest.h> + +namespace dqm_algorithms +{ + struct KurtosisTest_LessThan : public KurtosisTest + { + KurtosisTest_LessThan(): KurtosisTest("LessThan") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KURTOSISTEST_LESSTHAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_LessThanAbs.h b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_LessThanAbs.h new file mode 100644 index 0000000000000000000000000000000000000000..c27779447cfa6ca48c0ab2e7589109f6aa4cb9b2 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/KurtosisTest_LessThanAbs.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KurtosisTest_LessThanAbs.h file declares the dqm_algorithms::KurtosisTest_LessThanAbs class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_KURTOSISTEST_LESSTHANABS_H +#define DQM_ALGORITHMS_KURTOSISTEST_LESSTHANABS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/KurtosisTest.h> + +namespace dqm_algorithms +{ + struct KurtosisTest_LessThanAbs : public KurtosisTest + { + KurtosisTest_LessThanAbs(): KurtosisTest("LessThanAbs") {}; + + }; +} + +#endif // DQM_ALGORITHMS_KURTOSISTEST_LESSTHANABS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/L1Calo_OutlierAndFlatnessTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/L1Calo_OutlierAndFlatnessTest.h new file mode 100644 index 0000000000000000000000000000000000000000..294e6bc34bccdc774b1f30be8a1e957a248521a6 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/L1Calo_OutlierAndFlatnessTest.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file L1Calo_OutlierAndFlatnessTest.h file declares the dqm_algorithms::L1Calo_OutlierAndFlatnessTest class. + * \author Steffen Schaepe +*/ + +#ifndef DQM_ALGORITHMS_L1CALO_OUTLIERANDFLATNESSTEST_H +#define DQM_ALGORITHMS_L1CALO_OUTLIERANDFLATNESSTEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + class L1Calo_OutlierAndFlatnessTest : public dqm_core::Algorithm { + public: + L1Calo_OutlierAndFlatnessTest(const std::string & name); + + //overwrites virtual functions + L1Calo_OutlierAndFlatnessTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + + unsigned int counterSkip; + static const unsigned int counterSkipMax = 6; + dqm_core::Result LastResult; + }; +} + +#endif // DQM_ALGORITHMS_L1CALO_OUTLIERANDFLATNESSTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/LastBinThreshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/LastBinThreshold.h new file mode 100644 index 0000000000000000000000000000000000000000..4b99bbb08ac8864bdcea9d37faf966d270927b04 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/LastBinThreshold.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_LASTBINTHRESHOLD_H +#define DQM_ALGORITHMS_LASTBINTHRESHOLD_H + +#include "dqm_core/Algorithm.h" +#include <string> + +namespace dqm_core { class AlgorithmConfig; } +class TObject; + +namespace dqm_algorithms +{ + +class LastBinThreshold: public dqm_core::Algorithm +{ +public: + explicit LastBinThreshold(const std::string &name); + virtual ~LastBinThreshold(); + +public: + virtual LastBinThreshold *clone(); + virtual dqm_core::Result *execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + void getParameters(const std::string &name, const dqm_core::AlgorithmConfig &config); + void getThresholds(const std::string &name, const dqm_core::AlgorithmConfig &config); + inline bool exceeds(double value, double threshold) const; + +private: + // optional parameters + int m_nBinsToWatch; // how many bins to watch (default = 1), returning worst-case result of those bins + int m_nBinsToExceed; // how many bins have to exceed the threshold (default = 1), less will be ignored + bool m_greaterThan; // greater-than or less-than comparison against thresholds? (default = true) + bool m_valueThresholds; // thresholds set w.r.t num entries per bin (false) or w.r.t to X-axis value? (default = false) + int m_getEntries; // search the rightmost non-zero bin (default) + // or just use GetEntries() + // or search the rightmost bin regardless of the bin content + // neither MinStat nor xmin/xmax makes sense for this kind of algorithm, I assume + + // thresholds + double m_grn; + double m_red; + + // other properties + const std::string m_name; +}; + +} // namespace + +#endif // DQM_ALGORITHMS_LASTBINTHRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTADCSpectrum.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTADCSpectrum.h new file mode 100644 index 0000000000000000000000000000000000000000..ae1c7420ec1f2da5cf2c6202a95d65fa30106bda --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTADCSpectrum.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTADCSPECTRUM_H +#define DQM_ALGORITHMS_MDTADCSPECTRUM_H + +#include <string> +#include "TObject.h" +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class MDTADCSpectrum : public dqm_core::Algorithm { +public: + + MDTADCSpectrum(); + + virtual ~MDTADCSpectrum(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTADCSPECTRUM_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTChi2.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTChi2.h new file mode 100644 index 0000000000000000000000000000000000000000..ed0c428e6af871bf13090ec2dd53e975b1a02804 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTChi2.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTCHI2_H +#define DQM_ALGORITHMS_MDTCHI2_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +class TF1; +class TH1; +class TAxis; + +namespace dqm_algorithms { + +class MDTChi2 : public dqm_core::Algorithm { +public: + + MDTChi2(); + + virtual ~MDTChi2(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTCHI2_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTCluster.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTCluster.h new file mode 100644 index 0000000000000000000000000000000000000000..5fea0884662a188ba05dc6a3863730bf94cf9fed --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTCluster.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTCLUSTER_H +#define DQM_ALGORITHMS_MDTCLUSTER_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +namespace dqm_algorithms { + +class MDTCluster : public dqm_core::Algorithm { +public: + + MDTCluster(); + + virtual ~MDTCluster(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTCLUSTER_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTMLOverview.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTMLOverview.h new file mode 100644 index 0000000000000000000000000000000000000000..ba8cfc5a6d17de842288a111a61924fd4b85f92b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTMLOverview.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTMLOVERVIEW_H +#define DQM_ALGORITHMS_MDTMLOVERVIEW_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +class TF1; +class TH1; +class TAxis; + +namespace dqm_algorithms { + +class MDTMLOverview : public dqm_core::Algorithm { +public: + + MDTMLOverview(); + + virtual ~MDTMLOverview(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTMLOVERVIEW_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTMultiplicity.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTMultiplicity.h new file mode 100644 index 0000000000000000000000000000000000000000..5c06ed7ef3100b46565999387563e9be0722a40d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTMultiplicity.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTMULTIPLICITY_H +#define DQM_ALGORITHMS_MDTMULTIPLICITY_H + +#include <string> +#include "TObject.h" +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class MDTMultiplicity : public dqm_core::Algorithm { +public: + + MDTMultiplicity(); + + virtual ~MDTMultiplicity(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTMULTIPLICITY_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview.h new file mode 100644 index 0000000000000000000000000000000000000000..c36a479cf9300d2cfb94c7fc04a42fe46659038e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTOVERVIEW_H +#define DQM_ALGORITHMS_MDTOVERVIEW_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +class TF1; +class TH1; +class TAxis; + +namespace dqm_algorithms { + +class MDTOverview : public dqm_core::Algorithm { +public: + + MDTOverview(const std::string & name); + + virtual ~MDTOverview(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name_; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTOVERVIEW_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview_Global.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview_Global.h new file mode 100644 index 0000000000000000000000000000000000000000..863dacbd094e433bb124a8929840bf6745870ddd --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview_Global.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTOVERVIEW_GLOBAL_H +#define DQM_ALGORITHMS_MDTOVERVIEW_GLOBAL_H + +#include "dqm_core/Algorithm.h" +#include "dqm_algorithms/MDTOverview.h" + +namespace dqm_algorithms { + + struct MDTOverview_Global : public MDTOverview + { + MDTOverview_Global(): MDTOverview( "MDTOverview_Global" ) {}; + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTOVERVIEW_GLOBAL_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview_Station.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview_Station.h new file mode 100644 index 0000000000000000000000000000000000000000..81b588e2d5c500b81c76411f23d2379611b92864 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTOverview_Station.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTOVERVIEW_STATION_H +#define DQM_ALGORITHMS_MDTOVERVIEW_STATION_H + +#include "dqm_core/Algorithm.h" +#include "dqm_algorithms/MDTOverview.h" + +namespace dqm_algorithms { + + struct MDTOverview_Station : public MDTOverview + { + MDTOverview_Station(): MDTOverview( "MDTOverview_Station" ) {}; + }; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTOVERVIEW_STATION_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTPercentUnderThresh.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTPercentUnderThresh.h new file mode 100644 index 0000000000000000000000000000000000000000..7014123f6e7b6aeb78e0f748bd19a028a79126a0 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTPercentUnderThresh.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTPERCENTUNDERTHRESH_H +#define DQM_ALGORITHMS_MDTPERCENTUNDERTHRESH_H + + +#include <string> +#include "TObject.h" +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class MDTPercentUnderThresh : public dqm_core::Algorithm { +public: + + MDTPercentUnderThresh(); + + virtual ~MDTPercentUnderThresh(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTPERCENTUNDERTHRESH_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTTDCOfflineSpectrum.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTDCOfflineSpectrum.h new file mode 100644 index 0000000000000000000000000000000000000000..60b56ec1e603f46cbb44d2dd3ef62b0ba3cef1ee --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTDCOfflineSpectrum.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file MDTTDCOfflineSpectrum.h author Elena Solfaroli and Valerio Consorti. + * \ Adapted for dqm_algorithms by Justin Griffiths and adapted for MDTOffline Sept 09 +*/ + +#ifndef DQM_ALGORITHMS_MDTTDCOFFLINESPECTRUM_H +#define DQM_ALGORITHMS_MDTTDCOFFLINESPECTRUM_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + + struct MDTTDCOfflineSpectrum : public dqm_core::Algorithm + { + MDTTDCOfflineSpectrum(const std::string &name); + + MDTTDCOfflineSpectrum * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_MDTTDCOFFLINESPECTRUM_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTTDCSpectrum.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTDCSpectrum.h new file mode 100644 index 0000000000000000000000000000000000000000..ff53eccf855348b00cdc237bfc55aa51c82c9d01 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTDCSpectrum.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTTDCSPECTRUM_H +#define DQM_ALGORITHMS_MDTTDCSPECTRUM_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +class TF1; +class TH1; +class TAxis; + +namespace dqm_algorithms { + +class MDTTDCSpectrum : public dqm_core::Algorithm { +public: + + MDTTDCSpectrum(); + + virtual ~MDTTDCSpectrum(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTTDCSPECTRUM_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTTubeCheck.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTubeCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..619d72614c8310983ecb39302ff07f96a206f4a7 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTubeCheck.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTTUBECHECK_H +#define DQM_ALGORITHMS_MDTTUBECHECK_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +class TF1; +class TH1; +class TAxis; + +namespace dqm_algorithms { + +class MDTTubeCheck : public dqm_core::Algorithm { +public: + + MDTTubeCheck(); + + virtual ~MDTTubeCheck(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTTUBECHECK_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDTTubeCheckError.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTubeCheckError.h new file mode 100644 index 0000000000000000000000000000000000000000..f8fdfd2fbbbc47057f0f183fb8f49209debadc7d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDTTubeCheckError.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_MDTTUBECHECKERROR_H +#define DQM_ALGORITHMS_MDTTUBECHECKERROR_H + +#include <string> + +#include "dqm_core/Algorithm.h" + +class TF1; +class TH1; +class TAxis; + +namespace dqm_algorithms { + +class MDTTubeCheckError : public dqm_core::Algorithm { +public: + + MDTTubeCheckError(); + + virtual ~MDTTubeCheckError(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_MDTTUBECHECKERROR_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MDT_OccupancyHoleFinder.h b/DataQuality/dqm_algorithms/dqm_algorithms/MDT_OccupancyHoleFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..38f1f40b83024765800236d895dc1790b2047263 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MDT_OccupancyHoleFinder.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*file MDT_OccupancyHoleFinder imp author Justin Griffiths +*/ + +#ifndef DQM_ALGORITHMS_MDT_OCCUPANCYHOLEFINDER_H +#define DQM_ALGORITHMS_MDT_OCCUPANCYHOLEFINDER_H + +#include "dqm_core/Algorithm.h" +#include <dqm_algorithms/OccupancyHoleFinder.h> + +namespace dqm_algorithms { + + + struct MDT_OccupancyHoleFinder : public OccupancyHoleFinder + { + MDT_OccupancyHoleFinder(): OccupancyHoleFinder("MDT") { + }; + }; + + + +} //dqm_algorithms + +#endif // DQM_ALGORITHMS_MDT_OCCUPANCYHOLEFINDER_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/MaskedBinRow.h b/DataQuality/dqm_algorithms/dqm_algorithms/MaskedBinRow.h new file mode 100644 index 0000000000000000000000000000000000000000..ff13ff66ecb15ced891587fc00f947b954255a9e --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/MaskedBinRow.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file MaskedBinRow.h file declares the dqm_algorithms::MaskedBinRow class. + * \author R. Calkins +*/ + +#ifndef DQM_ALGORITHMS_MASKEDBINROW_H +#define DQM_ALGORITHMS_MASKEDBINROW_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct MaskedBinRow : public dqm_core::Algorithm + { + MaskedBinRow(); + + ~MaskedBinRow(); + + //overwrites virtual functions + MaskedBinRow * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_MASKEDBINROW_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/ModuleStatus_All_Bins_Filled.h b/DataQuality/dqm_algorithms/dqm_algorithms/ModuleStatus_All_Bins_Filled.h new file mode 100644 index 0000000000000000000000000000000000000000..c72237da9330ea48b320a23c1487b328828e426c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/ModuleStatus_All_Bins_Filled.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file All_Bins_Filled.h file declares the dqm_algorithms::All_Bins_Filled class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_MODULESTATUS_ALL_BINS_FILLED_H +#define DQM_ALGORITHMS_MODULESTATUS_ALL_BINS_FILLED_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheckModuleStatus.h> + +namespace dqm_algorithms +{ + struct ModuleStatus_All_Bins_Filled : public BasicHistoCheckModuleStatus + { + ModuleStatus_All_Bins_Filled(): BasicHistoCheckModuleStatus("ModuleStatus_All_Bins_Filled") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_MODULESTATUS_ALL_BINS_FILLED_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/No_OverFlows.h b/DataQuality/dqm_algorithms/dqm_algorithms/No_OverFlows.h new file mode 100644 index 0000000000000000000000000000000000000000..72d241b62bbb0f08d6209bd2b47a904d46b795ad --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/No_OverFlows.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file No_OverFlows.h file declares the dqm_algorithms::No_OverFlows class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_NO_OVERFLOWS_H +#define DQM_ALGORITHMS_NO_OVERFLOWS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheck.h> + +namespace dqm_algorithms +{ + struct No_OverFlows : public BasicHistoCheck + { + No_OverFlows(): BasicHistoCheck("No_OverFlows") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_NO_OVERFLOWS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/No_UnderFlows.h b/DataQuality/dqm_algorithms/dqm_algorithms/No_UnderFlows.h new file mode 100644 index 0000000000000000000000000000000000000000..0ef268f36c8428e9b820d288ae85532ac4f31f2c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/No_UnderFlows.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file No_UnderFlows.h file declares the dqm_algorithms::No_UnderFlows class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_NO_UNDERFLOWS_H +#define DQM_ALGORITHMS_NO_UNDERFLOWS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/BasicHistoCheck.h> + +namespace dqm_algorithms +{ + struct No_UnderFlows : public BasicHistoCheck + { + No_UnderFlows(): BasicHistoCheck("No_UnderFlows") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_NO_UNDERFLOWS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/OccupancyHoleFinder.h b/DataQuality/dqm_algorithms/dqm_algorithms/OccupancyHoleFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..102f8f8fc6a3ac472bd6bb81840ac1ce0be767e3 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/OccupancyHoleFinder.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_OCCUPANCYHOLEFINDER_H +#define DQM_ALGORITHMS_OCCUPANCYHOLEFINDER_H + +#include <dqm_core/Algorithm.h> + +class TH1; +class TH2; + +namespace dqm_algorithms +{ + struct OccupancyHoleFinder : public dqm_core::Algorithm + { + OccupancyHoleFinder(const std::string & name); + ~OccupancyHoleFinder(); + + //overwrites virtual functions + OccupancyHoleFinder * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + //return histogram with median in each vertical strip + TH1* getMedian(const TH2* histo); + //Have this function call your own function based on name + //See MDT_OccupancyHoleFinder.h as an example + std::string getChamberName(const TH2* histo, int biny); + //Called when calling derived instance 'MDT_OccupancyHoleFinder.h' + std::string getMDTChamberName(const TH2* histo, int biny); + private: + std::string m_name; + }; +} + +#endif // DQM_ALGORITHMS_OCCUPANCYHOLEFINDER_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/OutlierAndFlatnessTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/OutlierAndFlatnessTest.h new file mode 100644 index 0000000000000000000000000000000000000000..e425770e934ad63d28fecf676486fcb7f6ed3045 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/OutlierAndFlatnessTest.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file OutlierAndFlatnessTest.h file declares the dqm_algorithms::OutlierAndFlatnessTest class. + * \author Steffen Schaepe +*/ + +#ifndef DQM_ALGORITHMS_OUTLIERANDFLATNESSTEST_H +#define DQM_ALGORITHMS_OUTLIERANDFLATNESSTEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + class OutlierAndFlatnessTest : public dqm_core::Algorithm { + public: + OutlierAndFlatnessTest(const std::string & name); + + //overwrites virtual functions + OutlierAndFlatnessTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_OUTLIERANDFLATNESSTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/PassInput.h b/DataQuality/dqm_algorithms/dqm_algorithms/PassInput.h new file mode 100644 index 0000000000000000000000000000000000000000..d35613f66104ab35e372cf86a334f5eeb666dbc3 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/PassInput.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Bins_Diff_FromAvg.h file declares the dqm_algorithms::BinContentComp class. + * \author Evan Wulf +*/ + +#ifndef DQM_ALGORITHMS_PASSINPUT_H +#define DQM_ALGORITHMS_PASSINPUT_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct PassInput : public dqm_core::Algorithm + { + PassInput(); + + ~PassInput(); + + //overwrites virtual functions + PassInput * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + }; +} + +#endif // DQM_ALGORITHMS_PASSINPUT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking.h b/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking.h new file mode 100644 index 0000000000000000000000000000000000000000..9a032d95fedf95ac21c19c523cb0b531e8d888ca --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file ReferenceMasking.h file declares the dqm_algorithms::ReferenceMasking class. + * \author andrea.dotti@cern.ch + */ + +#ifndef DQM_ALGORITHMS_REFERENCEMASKING_H +#define DQM_ALGORITHMS_REFERENCEMASKING_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct ReferenceMasking : public dqm_core::Algorithm + { + ReferenceMasking(const std::string& name ); + ReferenceMasking* clone(); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + dqm_core::Result* execute(const std::string& , const TObject& , const dqm_core::AlgorithmConfig& ); + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_REFERENCEMASKING_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking_Bins_Diff_FromAvg.h b/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking_Bins_Diff_FromAvg.h new file mode 100644 index 0000000000000000000000000000000000000000..048c0ac68901f55c3ab11b74ef179e13f07f70d8 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking_Bins_Diff_FromAvg.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file ReferenceMasking_Bins_Diff_FromAvg.h file declares the dqm_algorithms::ReferenceMasking_Bins_Diff_FromAvg class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_REFERENCEMASKING_BINS_DIFF_FROMAVG_H +#define DQM_ALGORITHMS_REFERENCEMASKING_BINS_DIFF_FROMAVG_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/ReferenceMasking.h> + +namespace dqm_algorithms +{ + struct ReferenceMasking_Bins_Diff_FromAvg : public ReferenceMasking + { + ReferenceMasking_Bins_Diff_FromAvg(): ReferenceMasking("Bins_Diff_FromAvg") {}; + + }; +} + +#endif // DQM_ALGORITHMS_REFERENCEMASKING_BINS_DIFF_FROMAVG_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking_Bins_GreaterThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking_Bins_GreaterThan_Threshold.h new file mode 100644 index 0000000000000000000000000000000000000000..1dd4a305acbee2f99bb99d2820f00c64c149d71c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/ReferenceMasking_Bins_GreaterThan_Threshold.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file ReferenceMasking_Bins_GreaterThan_Threshold.h file declares the dqm_algorithms::ReferenceMasking_Bins_GreaterThan_Threshold class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_REFERENCEMASKING_BINS_GREATERTHAN_THRESHOLD_H +#define DQM_ALGORITHMS_REFERENCEMASKING_BINS_GREATERTHAN_THRESHOLD_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/ReferenceMasking.h> + +namespace dqm_algorithms +{ + struct ReferenceMasking_Bins_GreaterThan_Threshold : public ReferenceMasking + { + ReferenceMasking_Bins_GreaterThan_Threshold(): ReferenceMasking("Bins_GreaterThan_Threshold") {}; + + }; +} + +#endif // DQM_ALGORITHMS_REFERENCEMASKING_BINS_GREATERTHAN_THRESHOLD_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/RepeatAlgorithm.h b/DataQuality/dqm_algorithms/dqm_algorithms/RepeatAlgorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..c8470e14638007c98467d6ad11ab344bd8f2950b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/RepeatAlgorithm.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef dqaRepeatAlgorithm_h +#define dqaRepeatAlgorithm_h + +#include <string> +#include <vector> + +#include "dqm_core/Algorithm.h" + +namespace dqm_algorithms { + +class RepeatAlgorithm : public dqm_core::Algorithm { +public: + + RepeatAlgorithm( const RepeatAlgorithm& other ); + RepeatAlgorithm(); + + virtual ~RepeatAlgorithm(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, const TObject& data, + const dqm_core::AlgorithmConfig& config ); + dqm_core::AlgorithmConfig* ConfigureSubAlg(const dqm_core::AlgorithmConfig& config, TObject* reference); + + using Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +protected: + + std::shared_ptr<dqm_core::Algorithm> subalg_; + +}; + +} //namespace dqi + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/RootFit.h b/DataQuality/dqm_algorithms/dqm_algorithms/RootFit.h new file mode 100644 index 0000000000000000000000000000000000000000..834bab97b97e06b31bf8627eca205051cd15485b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/RootFit.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file RootFit.h file declares the dqm_algorithms::RootFit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_ROOTFIT_H +#define DQM_ALGORITHMS_ROOTFIT_H + +#include <dqm_core/Algorithm.h> +#include <TF1.h> +#include <TCanvas.h> + +namespace dqm_algorithms +{ + struct RootFit : public dqm_core::Algorithm + { + RootFit( const std::string & name ); + + ~RootFit(); + RootFit * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + std::auto_ptr<TF1> func; + }; +} + +#endif // DQM_ALGORITHMS_ROOTFIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/RootFitGraph.h b/DataQuality/dqm_algorithms/dqm_algorithms/RootFitGraph.h new file mode 100644 index 0000000000000000000000000000000000000000..29cd1ca10c098d0654de7c6cb718e96cdff0be36 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/RootFitGraph.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file RootFitGraph.h file declares the dqm_algorithms::RootFitGraph class. + * \author Akimasa Ishikawa (akimasa.ishikawa@cern.ch) 15th Apr 2010 +*/ + +#ifndef DQM_ALGORITHMS_ROOTFITGRAPH_H +#define DQM_ALGORITHMS_ROOTFITGRAPH_H + +#include <dqm_core/Algorithm.h> +#include <TF1.h> +#include <TCanvas.h> + +namespace dqm_algorithms +{ + struct RootFitGraph : public dqm_core::Algorithm + { + RootFitGraph( const std::string & name ); + + ~RootFitGraph(); + RootFitGraph * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + std::auto_ptr<TF1> func; + }; +} + +#endif // DQM_ALGORITHMS_ROOTFITGRAPH_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SCTTrackTiming.h b/DataQuality/dqm_algorithms/dqm_algorithms/SCTTrackTiming.h new file mode 100644 index 0000000000000000000000000000000000000000..6eac10a04bdb605fdf4b2a27b02316ffc08134d3 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SCTTrackTiming.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_SCTTRACKTIMING_H +#define DQM_ALGORITHMS_SCTTRACKTIMING_H + +#include <string> + +#include "dqm_core/Algorithm.h" + + +namespace dqm_algorithms { + +class SCTTrackTiming : public dqm_core::Algorithm { +public: + + SCTTrackTiming(); + + virtual ~SCTTrackTiming(); + virtual dqm_core::Algorithm* clone(); + virtual dqm_core::Result* execute( const std::string& name, + const TObject& data, + const dqm_core::AlgorithmConfig& config ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + +protected: + + std::string name; + + int NbinsX; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_SCTTRACKTIMING_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SideBand.h b/DataQuality/dqm_algorithms/dqm_algorithms/SideBand.h new file mode 100644 index 0000000000000000000000000000000000000000..5a8cf609008f84c93f1af801722a981a5544c9f4 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SideBand.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SideBand.h file declares the dqm_algorithms::SideBand class. + * \author Andrea Dotti +*/ + +#ifndef DQM_ALGORITHMS_SIDEBAND_H +#define DQM_ALGORITHMS_SIDEBAND_H + +#include <string> +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + /*! \class tile_dq::SideBand + * SideBand DQ algorithm: check number of entries outside range + * This test can be used to chek, for a 1D histogram, the entries + * outside a region. + * The test is perfrormed evaluating the integral of the histogram + * thus real numbers as bin content are accepted. + * The parameters that can be set are: + * UseUnderFlow : if != 0 include also underflow bin + * UseOverFlow : if != 0 include also overflow bin + * Min : Specify Lower limit (-999999 means full range) + * Max : Specify Upper limit (-999999 means full range) + * Thresholds are specified through the key-word "Threshold" + * Detailed example in workbench macro: TestSideBand.C + * + * There are two variants of this algorithms that you can select with + * Constructor parameter name: + * "SideBand_Absolute" in which the integral is checked in value + * "SideBand_Relative" in which the integral is checked as ratio with + * respect to total integral. + */ + class SideBand : public dqm_core::Algorithm + { + public: + SideBand(const std::string & name ); + virtual SideBand* clone(); + virtual dqm_core::Result* execute(const std::string &, + const TObject & obj, + const dqm_core::AlgorithmConfig & conf ); + virtual ~SideBand() {}; + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + private: + std::string name_; + }; + +} + +#endif // DQM_ALGORITHMS_SIDEBAND_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SideBand_Absolute.h b/DataQuality/dqm_algorithms/dqm_algorithms/SideBand_Absolute.h new file mode 100644 index 0000000000000000000000000000000000000000..b544fe68c6a070c59986f5b76febbd9bb44cccd2 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SideBand_Absolute.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SideBand_Absolute.h file declares the dqm_algorithms::SideBand_Absolute class. + * \author Andrea Dotti +*/ + +#ifndef DQM_ALGORITHMS_SIDEBAND_ABSOLUTE_H +#define DQM_ALGORITHMS_SIDEBAND_ABSOLUTE_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/SideBand.h> + +namespace dqm_algorithms +{ + struct SideBand_Absolute : public SideBand + { + SideBand_Absolute(): SideBand("SideBand_Absolute") {}; + + }; + +} + +#endif // DQM_ALGORITHMS_SIDEBAND_ABSOLUTE_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SideBand_Relative.h b/DataQuality/dqm_algorithms/dqm_algorithms/SideBand_Relative.h new file mode 100644 index 0000000000000000000000000000000000000000..4e2a61beaac522e6705c0973570700b5cd45236c --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SideBand_Relative.h @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SideBand_Relative.h file declares the dqm_algorithms::SideBand_Relative class. + * \author Andrea Dotti +*/ + +#ifndef DQM_ALGORITHMS_SIDEBAND_RELATIVE_H +#define DQM_ALGORITHMS_SIDEBAND_RELATIVE_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/SideBand.h> + +namespace dqm_algorithms +{ + struct SideBand_Relative : public SideBand + { + SideBand_Relative(): SideBand("SideBand_Relative") {}; + + }; + +} + +#endif // DQM_ALGORITHMS_SIDEBAND_RELATIVE_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_doublegaus_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_doublegaus_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..07197b2a798901fa0f9f7b2654e9ba62624c3ba0 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_doublegaus_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_doublegaus_Fit.h file declares the dqm_algorithms::algorithm::Simple_doublegaus_Fit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_DOUBLEGAUS_FIT_H +#define DQM_ALGORITHMS_SIMPLE_DOUBLEGAUS_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_doublegaus_Fit : public RootFit + { + Simple_doublegaus_Fit(): RootFit("doublegaus") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_DOUBLEGAUS_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_erf_Fit_Graph.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_erf_Fit_Graph.h new file mode 100644 index 0000000000000000000000000000000000000000..7717d51591a26ba22bcc72ede27f2b4e5d12335f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_erf_Fit_Graph.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_erf_Fit_Graph.h file declares the dqm_algorithms::algorithm::Simple_erf_Fit_Graph class. + * \author Akimasa Ishikawa (akimasa.ishikawa@cern.ch) +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_ERF_FIT_GRAPH_H +#define DQM_ALGORITHMS_SIMPLE_ERF_FIT_GRAPH_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFitGraph.h> + +namespace dqm_algorithms +{ + struct Simple_erf_Fit_Graph : public RootFitGraph + { + Simple_erf_Fit_Graph(): RootFitGraph("erf") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_ERF_FIT_GRAPH_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_fermi_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_fermi_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..2099788eea984d9420369d7c1839bf56f11ded82 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_fermi_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_fermi_Fit.h file declares the dqm_algorithms::algorithm::Simple_fermi_Fit class. \n Format copied from Simple_gaus_Fit.h + * \author Matt King +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_FERMI_FIT_H +#define DQM_ALGORITHMS_SIMPLE_FERMI_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_fermi_Fit : public RootFit + { + Simple_fermi_Fit(): RootFit("fermi") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_FERMI_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_fermi_Fit_Graph.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_fermi_Fit_Graph.h new file mode 100644 index 0000000000000000000000000000000000000000..e02c525f9ffb80b966b22c2e85bae719bf478336 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_fermi_Fit_Graph.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_erf_Fit_Graph.h file declares the dqm_algorithms::algorithm::Simple_fermi_Fit_Graph class. \n Format copied from Simple_gaus_Fit.h + * \author Matt King and Akimasa Ishikawa +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_FERMI_FIT_GRAPH_H +#define DQM_ALGORITHMS_SIMPLE_FERMI_FIT_GRAPH_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFitGraph.h> + +namespace dqm_algorithms +{ + struct Simple_fermi_Fit_Graph : public RootFitGraph + { + Simple_fermi_Fit_Graph(): RootFitGraph("fermi") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_FERMI_FIT_GRAPH_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gaus_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gaus_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..eded47d869910e1f72b3dcf026680696c1f9dee1 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gaus_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_gaus_Fit.h file declares the dqm_algorithms::algorithm::Simple_gaus_Fit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_GAUS_FIT_H +#define DQM_ALGORITHMS_SIMPLE_GAUS_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_gaus_Fit : public RootFit + { + Simple_gaus_Fit(): RootFit("gaus") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_GAUS_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gausplusexpo_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gausplusexpo_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..07acd3f2021203d54ba05e59570288e185c232b8 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gausplusexpo_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_gausplusexpo_Fit.h file declares the dqm_algorithms::algorithm::Simple_gausplusexpo_Fit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_GAUSPLUSEXPO_FIT_H +#define DQM_ALGORITHMS_SIMPLE_GAUSPLUSEXPO_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_gausplusexpo_Fit : public RootFit + { + Simple_gausplusexpo_Fit(): RootFit("gausplusexpo") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_GAUSPLUSEXPO_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gauspluspol1_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gauspluspol1_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..00468a06c47d8deed412251c15dc221ba61e7519 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_gauspluspol1_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_gauspluspol1_Fit.h file declares the dqm_algorithms::Simple_gauspluspol1_Fit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_GAUSPLUSPOL1_FIT_H +#define DQM_ALGORITHMS_SIMPLE_GAUSPLUSPOL1_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_gauspluspol1_Fit : public RootFit + { + Simple_gauspluspol1_Fit(): RootFit("gauspluspol1") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_GAUSPLUSPOL1_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_landau_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_landau_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..2fd26a051e054b8333b7e71aff48bc7fd0a1e2c9 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_landau_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_landau_Fit.h file declares the dqm_algorithms::Simple_landau_Fit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_LANDAU_FIT_H +#define DQM_ALGORITHMS_SIMPLE_LANDAU_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_landau_Fit : public RootFit + { + Simple_landau_Fit(): RootFit("landau") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_LANDAU_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_pol1_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_pol1_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..9dd2f5a72aa30b3cfd15f2840962f489ee92d102 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_pol1_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_pol1_Fit.h file declares the dqm_algorithms::Simple_pol1_Fit class. + * \author Haleh Hadavand +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_POL1_FIT_H +#define DQM_ALGORITHMS_SIMPLE_POL1_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_pol1_Fit : public RootFit + { + Simple_pol1_Fit(): RootFit("pol1") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_POL1_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/Simple_sinusoid_Fit.h b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_sinusoid_Fit.h new file mode 100644 index 0000000000000000000000000000000000000000..7c47f89de350c679fc23c92dc9655d2f3db13217 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/Simple_sinusoid_Fit.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Simple_sinusoid_Fit.h file declares the dqm_algorithms::algorithm::Simple_sinusoid_Fit class. + * \author Cristobal Cuenca Almenar, November 29th 2009 +*/ + +#ifndef DQM_ALGORITHMS_SIMPLE_SINUSOID_FIT_H +#define DQM_ALGORITHMS_SIMPLE_SINUSOID_FIT_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/RootFit.h> + +namespace dqm_algorithms +{ + struct Simple_sinusoid_Fit : public RootFit + { + Simple_sinusoid_Fit(): RootFit("sinusoid") {}; + + + }; + +} + +#endif // DQM_ALGORITHMS_SIMPLE_SINUSOID_FIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest.h b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest.h new file mode 100644 index 0000000000000000000000000000000000000000..065a7b33dae02986b56e6ca04d02b44b21786f34 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SkewnessTest.h file declares the dqm_algorithms::SkewnessTest class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_SKEWNESSTEST_H +#define DQM_ALGORITHMS_SKEWNESSTEST_H + +#include <dqm_core/Algorithm.h> + +namespace dqm_algorithms +{ + struct SkewnessTest : public dqm_core::Algorithm + { + SkewnessTest(const std::string & name); + + //overwrites virtual functions + SkewnessTest * clone( ); + dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & ); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + bool CompareSkewnessTest( const std::string& type, double value , double threshold ); + private: + std::string name_; + }; +} + +#endif // DQM_ALGORITHMS_SKEWNESSTEST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_GreaterThan.h b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_GreaterThan.h new file mode 100644 index 0000000000000000000000000000000000000000..1e6c54a33ea49ea32f3d9637f43f5c1edf09c701 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_GreaterThan.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SkewnessTest_GreaterThan.h file declares the dqm_algorithms::SkewnessTest_GreaterThan class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_SKEWNESSTEST_GREATERTHAN_H +#define DQM_ALGORITHMS_SKEWNESSTEST_GREATERTHAN_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/SkewnessTest.h> + +namespace dqm_algorithms +{ + struct SkewnessTest_GreaterThan : public SkewnessTest + { + SkewnessTest_GreaterThan(): SkewnessTest("GreaterThan") {}; + + }; +} + +#endif // DQM_ALGORITHMS_SKEWNESSTEST_GREATERTHAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_GreaterThanAbs.h b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_GreaterThanAbs.h new file mode 100644 index 0000000000000000000000000000000000000000..a13d086a41430ac726e675279cda8b5c53c71da8 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_GreaterThanAbs.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SkewnessTest_GreaterThanAbs.h file declares the dqm_algorithms::SkewnessTest_GreaterThanAbs class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_SKEWNESSTEST_GREATERTHANABS_H +#define DQM_ALGORITHMS_SKEWNESSTEST_GREATERTHANABS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/SkewnessTest.h> + +namespace dqm_algorithms +{ + struct SkewnessTest_GreaterThanAbs : public SkewnessTest + { + SkewnessTest_GreaterThanAbs(): SkewnessTest("GreaterThanAbs") {}; + + }; +} + +#endif // DQM_ALGORITHMS_SKEWNESSTEST_GREATERTHANABS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_LessThan.h b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_LessThan.h new file mode 100644 index 0000000000000000000000000000000000000000..7df15be0e286b43945e42e812dd3cb3319899e34 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_LessThan.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SkewnessTest_LessThan.h file declares the dqm_algorithms::SkewnessTest_LessThan class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_SKEWNESSTEST_LESSTHAN_H +#define DQM_ALGORITHMS_SKEWNESSTEST_LESSTHAN_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/SkewnessTest.h> + +namespace dqm_algorithms +{ + struct SkewnessTest_LessThan : public SkewnessTest + { + SkewnessTest_LessThan(): SkewnessTest("LessThan") {}; + + }; +} + +#endif // DQM_ALGORITHMS_SKEWNESSTEST_LESSTHAN_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_LessThanAbs.h b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_LessThanAbs.h new file mode 100644 index 0000000000000000000000000000000000000000..3c888d4ec38a03e17d72ed75c3b1ef8cc6ca5558 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/SkewnessTest_LessThanAbs.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SkewnessTest_LessThanAbs.h file declares the dqm_algorithms::SkewnessTest_LessThanAbs class. + * \author andrea.dotti@cern.ch +*/ + +#ifndef DQM_ALGORITHMS_SKEWNESSTEST_LESSTHANABS_H +#define DQM_ALGORITHMS_SKEWNESSTEST_LESSTHANABS_H + +#include <dqm_core/Algorithm.h> +#include <dqm_algorithms/SkewnessTest.h> + +namespace dqm_algorithms +{ + struct SkewnessTest_LessThanAbs : public SkewnessTest + { + SkewnessTest_LessThanAbs(): SkewnessTest("LessThanAbs") {}; + + }; +} + +#endif // DQM_ALGORITHMS_SKEWNESSTEST_LESSTHANABS_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/TRTAvgEventSizeCheck.h b/DataQuality/dqm_algorithms/dqm_algorithms/TRTAvgEventSizeCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..4235bc25dbc395845d13b5f5960c5961a14cd67d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/TRTAvgEventSizeCheck.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifdef ONLINE // can only be built in an online environment + +#ifndef DQM_ALGORITHMS_TRTAVGEVENTSIZECHECK_H +#define DQM_ALGORITHMS_TRTAVGEVENTSIZECHECK_H + +#include "dqm_core/Algorithm.h" + +namespace dqm_algorithms { + +class TRTAvgEventSizeCheck : public dqm_core::Algorithm +{ +public: + TRTAvgEventSizeCheck(); + TRTAvgEventSizeCheck *clone(); + dqm_core::Result *execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + +private: + boost::posix_time::ptime lastCollisionsSeen_; +}; + +} // namespace + +#endif // DQM_ALGORITHMS_TRTAVGEVENTSIZECHECK_H +#endif // ONLINE diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/TRTCheckPeakSimple.h b/DataQuality/dqm_algorithms/dqm_algorithms/TRTCheckPeakSimple.h new file mode 100644 index 0000000000000000000000000000000000000000..9a9d27016c45f2fd8d89efb60d0cbc022d1c0635 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/TRTCheckPeakSimple.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file TRTCheckPeakSimple.h file declares the dqm_algorithms::TRTCheckPeakSimple class. + * \author Peter Cwetanski +*/ + +#ifndef DQM_ALGORITHMS_TRTCHECKPEAKSIMPLE_H +#define DQM_ALGORITHMS_TRTCHECKPEAKSIMPLE_H + +#include "dqm_core/Algorithm.h" + +#include <string> + +namespace dqm_algorithms +{ + +class TRTCheckPeakSimple: public dqm_core::Algorithm +{ +public: + TRTCheckPeakSimple(); + + virtual ~TRTCheckPeakSimple(); + virtual dqm_core::Algorithm *clone(); + virtual dqm_core::Result *execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_TRTCHECKPEAKSIMPLE_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/TRTHistogramHasNonZeroEntries.h b/DataQuality/dqm_algorithms/dqm_algorithms/TRTHistogramHasNonZeroEntries.h new file mode 100644 index 0000000000000000000000000000000000000000..1be908f49581cc0b69910a8468aff9caa7856252 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/TRTHistogramHasNonZeroEntries.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file TRTHistogramHasNonZeroEntries.h file declares the dqm_algorithms::TRTHistogramHasNonZeroEntries class. + * \author Peter Cwetanski +*/ + +#ifndef DQM_ALGORITHMS_TRTHISTOGRAMHASNONZEROENTRIES_H +#define DQM_ALGORITHMS_TRTHISTOGRAMHASNONZEROENTRIES_H + +#include "dqm_core/Algorithm.h" + +#include <string> + +namespace dqm_algorithms +{ + +class TRTHistogramHasNonZeroEntries: public dqm_core::Algorithm +{ +public: + TRTHistogramHasNonZeroEntries(); + + virtual ~TRTHistogramHasNonZeroEntries(); + virtual dqm_core::Algorithm *clone(); + virtual dqm_core::Result *execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &); + using dqm_core::Algorithm::printDescription; + virtual void printDescription(std::ostream& out); + +private: + std::string name; +}; + +} //namespace dqm_algorithms + +#endif // DQM_ALGORITHMS_TRTHISTOGRAMHASNONZEROENTRIES_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/TripleGaussCollFit.h b/DataQuality/dqm_algorithms/dqm_algorithms/TripleGaussCollFit.h new file mode 100644 index 0000000000000000000000000000000000000000..afa368a39792c54a0157527fe9233909f24a6168 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/TripleGaussCollFit.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_TRIPLEGAUSSCOLLFIT_H +#define DQM_ALGORITHMS_TRIPLEGAUSSCOLLFIT_H + +#include <dqm_core/Algorithm.h> +#include <string> +#include <TF1.h> + +namespace dqm_algorithms { + + class TripleGaussCollFit : public dqm_core::Algorithm { + + public: + TripleGaussCollFit (const std::string& _name); + ~TripleGaussCollFit(); + + dqm_core::Result* execute (const std::string& s, const TObject& object, const dqm_core::AlgorithmConfig& cfg); + using dqm_core::Algorithm::printDescription; + void printDescription(std::ostream& out); + TripleGaussCollFit* clone(); + + private: + std::string name; + TF1* gaus3_fn; + void fitSingle(TH1* hist1D); + + }; // end class +} //end namespace + + +#endif // DQM_ALGORITHMS_TRIPLEGAUSSCOLLFIT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h b/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h new file mode 100644 index 0000000000000000000000000000000000000000..31a69bdbdeb20803d896064f69e5971f1e196324 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h @@ -0,0 +1,151 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_DQM_ALGORITHMSDICT_H +#define DQM_ALGORITHMS_DQM_ALGORITHMSDICT_H + +#include "dqm_algorithms/AddReference.h" +#include "dqm_algorithms/AddReference_All_Bins_Filled.h" +#include "dqm_algorithms/AddReference_BinContentComp.h" +#include "dqm_algorithms/AddReference_Bins_Diff_FromAvg.h" +#include "dqm_algorithms/AddReference_Bins_Equal_Threshold.h" +#include "dqm_algorithms/AddReference_Bins_GreaterThanEqual_Threshold.h" +#include "dqm_algorithms/AddReference_Bins_GreaterThan_Threshold.h" +#include "dqm_algorithms/AddReference_Bins_LessThanEqual_Threshold.h" +#include "dqm_algorithms/AddReference_Bins_LessThan_Threshold.h" +#include "dqm_algorithms/AddReference_Bins_NotEqual_Threshold.h" +#include "dqm_algorithms/All_Bins_Filled.h" +#include "dqm_algorithms/AveragePrint.h" +#include "dqm_algorithms/BasicGraphCheck.h" +#include "dqm_algorithms/BasicHistoCheck.h" +#include "dqm_algorithms/BasicHistoCheckModuleStatus.h" +#include "dqm_algorithms/BasicStatCheck.h" +#include "dqm_algorithms/BinContentComp.h" +#include "dqm_algorithms/BinContentDump.h" +#include "dqm_algorithms/OccupancyHoleFinder.h" +#include "dqm_algorithms/MDT_OccupancyHoleFinder.h" +#include "dqm_algorithms/BinDump.h" +#include "dqm_algorithms/BinPrint.h" +#include "dqm_algorithms/BinThresh.h" +#include "dqm_algorithms/BinThreshold.h" +#include "dqm_algorithms/BinsDiffByStrips.h" +#include "dqm_algorithms/BinsDiffFromStripMedian.h" +#include "dqm_algorithms/BinsDiffFromStripMedianOnline.h" +#include "dqm_algorithms/BinsFilledOutRange.h" +#include "dqm_algorithms/BinsOutOfRange.h" +#include "dqm_algorithms/BinsSymmetric.h" +#include "dqm_algorithms/Bins_Diff_FromAvg.h" +#include "dqm_algorithms/Bins_Equal_Threshold.h" +#include "dqm_algorithms/Bins_GreaterThanAbs_Threshold.h" +#include "dqm_algorithms/Bins_GreaterThanEqual_Threshold.h" +#include "dqm_algorithms/Bins_GreaterThanNonZeroMedian_Threshold.h" +#include "dqm_algorithms/Bins_GreaterThan_Threshold.h" +#include "dqm_algorithms/Bins_LessThanAbs_Threshold.h" +#include "dqm_algorithms/Bins_LessThanEqual_Threshold.h" +#include "dqm_algorithms/Bins_LessThanNonZeroMedian_Threshold.h" +#include "dqm_algorithms/Bins_LessThan_Threshold.h" +#include "dqm_algorithms/Bins_NotEqual_Threshold.h" +#include "dqm_algorithms/BlackBin.h" +#include "dqm_algorithms/BlackBin1D.h" +#include "dqm_algorithms/CheckHisto_Mean.h" +#include "dqm_algorithms/CheckHisto_RMS.h" +#include "dqm_algorithms/CheckMean.h" +#include "dqm_algorithms/Chi2Test.h" +#include "dqm_algorithms/Chi2Test_2D.h" +#include "dqm_algorithms/Chi2Test_Chi2.h" +#include "dqm_algorithms/Chi2Test_Chi2_per_NDF.h" +#include "dqm_algorithms/Chi2Test_Prob.h" +#include "dqm_algorithms/Chi2Test_ProbUW.h" +#include "dqm_algorithms/Chi2Test_ProbWW.h" +#include "dqm_algorithms/Chi2Test_Scatterplot.h" +#include "dqm_algorithms/ChiComp.h" +#include "dqm_algorithms/CorrelationYX.h" +#include "dqm_algorithms/CountsBinsGreaterThan.h" +#include "dqm_algorithms/CSCNoisyDead.h" +#include "dqm_algorithms/DivideBin.h" +#include "dqm_algorithms/DivideReference.h" +#include "dqm_algorithms/DivideReference_All_Bins_Filled.h" +#include "dqm_algorithms/DivideReference_BinContentComp.h" +#include "dqm_algorithms/DivideReference_Bins_Diff_FromAvg.h" +#include "dqm_algorithms/DivideReference_Bins_Equal_Threshold.h" +#include "dqm_algorithms/DivideReference_Bins_GreaterThanEqual_Threshold.h" +#include "dqm_algorithms/DivideReference_Bins_GreaterThan_Threshold.h" +#include "dqm_algorithms/DivideReference_Bins_LessThanEqual_Threshold.h" +#include "dqm_algorithms/DivideReference_Bins_LessThan_Threshold.h" +#include "dqm_algorithms/DivideReference_Bins_NotEqual_Threshold.h" +#include "dqm_algorithms/GatherData.h" +#include "dqm_algorithms/GraphPrint.h" +#include "dqm_algorithms/GraphTest.h" +#include "dqm_algorithms/GrubbsOutlierTest.h" +#include "dqm_algorithms/HLTMETComponents.h" +#include "dqm_algorithms/HLTMETStatus.h" +#include "dqm_algorithms/Histogram_Effective_Empty.h" +#include "dqm_algorithms/Histogram_Empty.h" +#include "dqm_algorithms/Histogram_Not_Empty.h" +#include "dqm_algorithms/IterativeGaussianFit.h" +#include "dqm_algorithms/JarqueBeraTest.h" +#include "dqm_algorithms/JarqueBeraTest_JB.h" +#include "dqm_algorithms/JarqueBeraTest_Prob.h" +#include "dqm_algorithms/KillBinsByStrip.h" +#include "dqm_algorithms/KolmogorovTest.h" +#include "dqm_algorithms/KolmogorovTest_MaxDist.h" +#include "dqm_algorithms/KolmogorovTest_MaxDistPlusNorm.h" +#include "dqm_algorithms/KolmogorovTest_Norm.h" +#include "dqm_algorithms/KolmogorovTest_Prob.h" +#include "dqm_algorithms/KurtosisTest.h" +#include "dqm_algorithms/KurtosisTest_GreaterThan.h" +#include "dqm_algorithms/KurtosisTest_GreaterThanAbs.h" +#include "dqm_algorithms/KurtosisTest_LessThan.h" +#include "dqm_algorithms/KurtosisTest_LessThanAbs.h" +#include "dqm_algorithms/LastBinThreshold.h" +#include "dqm_algorithms/L1Calo_OutlierAndFlatnessTest.h" +#include "dqm_algorithms/MDTADCSpectrum.h" +#include "dqm_algorithms/MDTChi2.h" +#include "dqm_algorithms/MDTCluster.h" +#include "dqm_algorithms/MDTMLOverview.h" +#include "dqm_algorithms/MDTMultiplicity.h" +#include "dqm_algorithms/MDTOverview.h" +#include "dqm_algorithms/MDTOverview_Global.h" +#include "dqm_algorithms/MDTOverview_Station.h" +#include "dqm_algorithms/MDTPercentUnderThresh.h" +#include "dqm_algorithms/MDTTDCOfflineSpectrum.h" +#include "dqm_algorithms/MDTTDCSpectrum.h" +#include "dqm_algorithms/MDTTubeCheck.h" +#include "dqm_algorithms/MDTTubeCheckError.h" +#include "dqm_algorithms/MaskedBinRow.h" +#include "dqm_algorithms/ModuleStatus_All_Bins_Filled.h" +#include "dqm_algorithms/No_OverFlows.h" +#include "dqm_algorithms/No_UnderFlows.h" +#include "dqm_algorithms/OutlierAndFlatnessTest.h" +#include "dqm_algorithms/PassInput.h" +#include "dqm_algorithms/ReferenceMasking.h" +#include "dqm_algorithms/ReferenceMasking_Bins_Diff_FromAvg.h" +#include "dqm_algorithms/ReferenceMasking_Bins_GreaterThan_Threshold.h" +#include "dqm_algorithms/RepeatAlgorithm.h" +#include "dqm_algorithms/RootFit.h" +#include "dqm_algorithms/RootFitGraph.h" +#include "dqm_algorithms/SCTTrackTiming.h" +#include "dqm_algorithms/SideBand.h" +#include "dqm_algorithms/SideBand_Absolute.h" +#include "dqm_algorithms/SideBand_Relative.h" +#include "dqm_algorithms/Simple_doublegaus_Fit.h" +#include "dqm_algorithms/Simple_erf_Fit_Graph.h" +#include "dqm_algorithms/Simple_fermi_Fit.h" +#include "dqm_algorithms/Simple_fermi_Fit_Graph.h" +#include "dqm_algorithms/Simple_gaus_Fit.h" +#include "dqm_algorithms/Simple_gausplusexpo_Fit.h" +#include "dqm_algorithms/Simple_gauspluspol1_Fit.h" +#include "dqm_algorithms/Simple_landau_Fit.h" +#include "dqm_algorithms/Simple_pol1_Fit.h" +#include "dqm_algorithms/Simple_sinusoid_Fit.h" +#include "dqm_algorithms/SkewnessTest.h" +#include "dqm_algorithms/SkewnessTest_GreaterThan.h" +#include "dqm_algorithms/SkewnessTest_GreaterThanAbs.h" +#include "dqm_algorithms/SkewnessTest_LessThan.h" +#include "dqm_algorithms/SkewnessTest_LessThanAbs.h" +#include "dqm_algorithms/TRTCheckPeakSimple.h" +#include "dqm_algorithms/TRTHistogramHasNonZeroEntries.h" +#include "dqm_algorithms/TripleGaussCollFit.h" + +#endif // DQM_ALGORITHMS_DQM_ALGORITHMSDICT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml b/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..252db24810af3d13c059298175de01cdcee8cd42 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml @@ -0,0 +1,145 @@ +<lcgdict> + <namespace name="dqm_algorithms"/> + <class name="dqm_algorithms::AddReference"/> + <class name="dqm_algorithms::AddReference_All_Bins_Filled"/> + <class name="dqm_algorithms::AddReference_BinContentComp"/> + <class name="dqm_algorithms::AddReference_Bins_Diff_FromAvg"/> + <class name="dqm_algorithms::AddReference_Bins_Equal_Threshold"/> + <class name="dqm_algorithms::AddReference_Bins_GreaterThanEqual_Threshold"/> + <class name="dqm_algorithms::AddReference_Bins_GreaterThan_Threshold"/> + <class name="dqm_algorithms::AddReference_Bins_LessThanEqual_Threshold"/> + <class name="dqm_algorithms::AddReference_Bins_LessThan_Threshold"/> + <class name="dqm_algorithms::AddReference_Bins_NotEqual_Threshold"/> + <class name="dqm_algorithms::All_Bins_Filled"/> + <class name="dqm_algorithms::AveragePrint"/> + <class name="dqm_algorithms::BasicGraphCheck"/> + <class name="dqm_algorithms::BasicHistoCheck"/> + <class name="dqm_algorithms::BasicHistoCheckModuleStatus"/> + <class name="dqm_algorithms::BasicStatCheck"/> + <class name="dqm_algorithms::BinContentComp"/> + <class name="dqm_algorithms::BinContentDump"/> + <class name="dqm_algorithms::OccupancyHoleFinder"/> + <class name="dqm_algorithms::MDT_OccupancyHoleFinder"/> + <class name="dqm_algorithms::BinDump"/> + <class name="dqm_algorithms::BinPrint"/> + <class name="dqm_algorithms::BinThresh"/> + <class name="dqm_algorithms::BinThreshold"/> + <class name="dqm_algorithms::BinsDiffByStrips"/> + <class name="dqm_algorithms::BinsDiffFromStripMedian"/> + <class name="dqm_algorithms::BinsDiffFromStripMedianOnline"/> + <class name="dqm_algorithms::BinsFilledOutRange"/> + <class name="dqm_algorithms::BinsOutOfRange"/> + <class name="dqm_algorithms::BinsSymmetric"/> + <class name="dqm_algorithms::Bins_Diff_FromAvg"/> + <class name="dqm_algorithms::Bins_Equal_Threshold"/> + <class name="dqm_algorithms::Bins_GreaterThanAbs_Threshold"/> + <class name="dqm_algorithms::Bins_GreaterThanEqual_Threshold"/> + <class name="dqm_algorithms::Bins_GreaterThanNonZeroMedian_Threshold"/> + <class name="dqm_algorithms::Bins_GreaterThan_Threshold"/> + <class name="dqm_algorithms::Bins_LessThanAbs_Threshold"/> + <class name="dqm_algorithms::Bins_LessThanEqual_Threshold"/> + <class name="dqm_algorithms::Bins_LessThanNonZeroMedian_Threshold"/> + <class name="dqm_algorithms::Bins_LessThan_Threshold"/> + <class name="dqm_algorithms::Bins_NotEqual_Threshold"/> + <class name="dqm_algorithms::BlackBin"/> + <class name="dqm_algorithms::BlackBin1D"/> + <class name="dqm_algorithms::CheckHisto_Mean"/> + <class name="dqm_algorithms::CheckHisto_RMS"/> + <class name="dqm_algorithms::CheckMean"/> + <class name="dqm_algorithms::Chi2Test"/> + <class name="dqm_algorithms::Chi2Test_2D"/> + <class name="dqm_algorithms::Chi2Test_Chi2"/> + <class name="dqm_algorithms::Chi2Test_Chi2_per_NDF"/> + <class name="dqm_algorithms::Chi2Test_Prob"/> + <class name="dqm_algorithms::Chi2Test_ProbUW"/> + <class name="dqm_algorithms::Chi2Test_ProbWW"/> + <class name="dqm_algorithms::Chi2Test_Scatterplot"/> + <class name="dqm_algorithms::ChiComp"/> + <class name="dqm_algorithms::CorrelationYX"/> + <class name="dqm_algorithms::CountsBinsGreaterThan"/> + <class name="dqm_algorithms::CSCNoisyDead"/> + <class name="dqm_algorithms::DivideBin"/> + <class name="dqm_algorithms::DivideReference"/> + <class name="dqm_algorithms::DivideReference_All_Bins_Filled"/> + <class name="dqm_algorithms::DivideReference_BinContentComp"/> + <class name="dqm_algorithms::DivideReference_Bins_Diff_FromAvg"/> + <class name="dqm_algorithms::DivideReference_Bins_Equal_Threshold"/> + <class name="dqm_algorithms::DivideReference_Bins_GreaterThanEqual_Threshold"/> + <class name="dqm_algorithms::DivideReference_Bins_GreaterThan_Threshold"/> + <class name="dqm_algorithms::DivideReference_Bins_LessThanEqual_Threshold"/> + <class name="dqm_algorithms::DivideReference_Bins_LessThan_Threshold"/> + <class name="dqm_algorithms::DivideReference_Bins_NotEqual_Threshold"/> + <class name="dqm_algorithms::GatherData"/> + <class name="dqm_algorithms::GraphPrint"/> + <class name="dqm_algorithms::GraphTest"/> + <class name="dqm_algorithms::GrubbsOutlierTest"/> + <class name="dqm_algorithms::HLTMETComponents"/> + <class name="dqm_algorithms::HLTMETStatus"/> + <class name="dqm_algorithms::Histogram_Effective_Empty"/> + <class name="dqm_algorithms::Histogram_Empty"/> + <class name="dqm_algorithms::Histogram_Not_Empty"/> + <class name="dqm_algorithms::IterativeGaussianFit"/> + <class name="dqm_algorithms::JarqueBeraTest"/> + <class name="dqm_algorithms::JarqueBeraTest_JB"/> + <class name="dqm_algorithms::JarqueBeraTest_Prob"/> + <class name="dqm_algorithms::KillBinsByStrip"/> + <class name="dqm_algorithms::KolmogorovTest"/> + <class name="dqm_algorithms::KolmogorovTest_MaxDist"/> + <class name="dqm_algorithms::KolmogorovTest_MaxDistPlusNorm"/> + <class name="dqm_algorithms::KolmogorovTest_Norm"/> + <class name="dqm_algorithms::KolmogorovTest_Prob"/> + <class name="dqm_algorithms::KurtosisTest"/> + <class name="dqm_algorithms::KurtosisTest_GreaterThan"/> + <class name="dqm_algorithms::KurtosisTest_GreaterThanAbs"/> + <class name="dqm_algorithms::KurtosisTest_LessThan"/> + <class name="dqm_algorithms::KurtosisTest_LessThanAbs"/> + <class name="dqm_algorithms::LastBinThreshold"/> + <class name="dqm_algorithms::L1Calo_OutlierAndFlatnessTest"/> + <class name="dqm_algorithms::MDTADCSpectrum"/> + <class name="dqm_algorithms::MDTChi2"/> + <class name="dqm_algorithms::MDTCluster"/> + <class name="dqm_algorithms::MDTMLOverview"/> + <class name="dqm_algorithms::MDTMultiplicity"/> + <class name="dqm_algorithms::MDTOverview"/> + <class name="dqm_algorithms::MDTOverview_Global"/> + <class name="dqm_algorithms::MDTOverview_Station"/> + <class name="dqm_algorithms::MDTPercentUnderThresh"/> + <class name="dqm_algorithms::MDTTDCOfflineSpectrum"/> + <class name="dqm_algorithms::MDTTDCSpectrum"/> + <class name="dqm_algorithms::MDTTubeCheck"/> + <class name="dqm_algorithms::MDTTubeCheckError"/> + <class name="dqm_algorithms::MaskedBinRow"/> + <class name="dqm_algorithms::ModuleStatus_All_Bins_Filled"/> + <class name="dqm_algorithms::No_OverFlows"/> + <class name="dqm_algorithms::No_UnderFlows"/> + <class name="dqm_algorithms::OutlierAndFlatnessTest"/> + <class name="dqm_algorithms::PassInput"/> + <class name="dqm_algorithms::ReferenceMasking"/> + <class name="dqm_algorithms::ReferenceMasking_Bins_Diff_FromAvg"/> + <class name="dqm_algorithms::ReferenceMasking_Bins_GreaterThan_Threshold"/> + <class name="dqm_algorithms::RepeatAlgorithm"/> + <class name="dqm_algorithms::RootFit"/> + <class name="dqm_algorithms::RootFitGraph"/> + <class name="dqm_algorithms::SCTTrackTiming"/> + <class name="dqm_algorithms::SideBand"/> + <class name="dqm_algorithms::SideBand_Absolute"/> + <class name="dqm_algorithms::SideBand_Relative"/> + <class name="dqm_algorithms::Simple_doublegaus_Fit"/> + <class name="dqm_algorithms::Simple_erf_Fit_Graph"/> + <class name="dqm_algorithms::Simple_fermi_Fit"/> + <class name="dqm_algorithms::Simple_fermi_Fit_Graph"/> + <class name="dqm_algorithms::Simple_gaus_Fit"/> + <class name="dqm_algorithms::Simple_gausplusexpo_Fit"/> + <class name="dqm_algorithms::Simple_gauspluspol1_Fit"/> + <class name="dqm_algorithms::Simple_landau_Fit"/> + <class name="dqm_algorithms::Simple_pol1_Fit"/> + <class name="dqm_algorithms::Simple_sinusoid_Fit"/> + <class name="dqm_algorithms::SkewnessTest"/> + <class name="dqm_algorithms::SkewnessTest_GreaterThan"/> + <class name="dqm_algorithms::SkewnessTest_GreaterThanAbs"/> + <class name="dqm_algorithms::SkewnessTest_LessThan"/> + <class name="dqm_algorithms::SkewnessTest_LessThanAbs"/> + <class name="dqm_algorithms::TRTCheckPeakSimple"/> + <class name="dqm_algorithms::TRTHistogramHasNonZeroEntries"/> + <class name="dqm_algorithms::TripleGaussCollFit"/> +</lcgdict> diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/AlwaysGreenSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/AlwaysGreenSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..4f04034b1a10bd9f8fa946a936f3e8ae43427af4 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/AlwaysGreenSummary.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlwaysGreenSummary.h + * \author Akimasa Ishikawa (akimasa.ishikawa@cern.ch) +*/ + + +#ifndef DQM_ALGORITHMS_ALWAYS_GREEN_SUMMARY_H +#define DQM_ALGORITHMS_ALWAYS_GREEN_SUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + struct AlwaysGreenSummary : public dqm_core::SummaryMaker + { + AlwaysGreenSummary(); + ~AlwaysGreenSummary(); + + AlwaysGreenSummary * clone(); + dqm_core::Result * execute( const std::string & , const dqm_core::Result & result, const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/AlwaysUndefinedSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/AlwaysUndefinedSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..c22e114775145c58233ab0cdd5f677ab66f4f03b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/AlwaysUndefinedSummary.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlwaysUndefinedSummary.h + * \author Akimasa Ishikawa (akimasa.ishikawa@cern.ch) +*/ + + +#ifndef DQM_ALGORITHMS_ALWAYS_GREEN_SUMMARY_H +#define DQM_ALGORITHMS_ALWAYS_GREEN_SUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + struct AlwaysUndefinedSummary : public dqm_core::SummaryMaker + { + AlwaysUndefinedSummary(); + ~AlwaysUndefinedSummary(); + + AlwaysUndefinedSummary * clone(); + dqm_core::Result * execute( const std::string & , const dqm_core::Result & result, const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/BinwiseSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/BinwiseSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..69ca1bde15af39419e458f43d82cce826da6a872 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/BinwiseSummary.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinwiseSummary.h file declares the dqm_algorithms::summary::BinwiseSummary class, a simple summary maker which combines the binwise status from the appropriate algorithms in it's region, masking according to the Role=Mask histogram, and produces a dq result based on these and the other parameters in the region a la WorstCaseSummary + * \author Evan Wulf +*/ + + + +#ifndef DQM_ALGORITHMS_BINWISESUMMARY_H +#define DQM_ALGORITHMS_BINWISESUMMARY_H + +#include <dqm_core/SummaryMaker.h> + + +namespace dqm_algorithms +{ + namespace summary + { + struct BinwiseSummary : public dqm_core::SummaryMaker + { + BinwiseSummary(); + ~BinwiseSummary(); + BinwiseSummary* clone(); + dqm_core::Result* execute( const std::string & name, const dqm_core::Result & , const dqm_core::ParametersMap & ); + }; + } +} + +#endif //#ifndef DQM_ALGORITHMS_BINWISESUMMARY_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/DivideByHist.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/DivideByHist.h new file mode 100644 index 0000000000000000000000000000000000000000..6c4ffc6924df0ea8c015e4fb3478a3fc2f854a93 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/DivideByHist.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideByHist.h file declares the dqm_algorithms::summary::DivideByHist class, a summary maker which divides the histogram from the result of one algorithm by a histogram from the result of another and then runs a test on the resulting histogram, as specified by the algorithm input + * \author Evan Wulf +*/ + + + +#ifndef DQM_ALGORITHMS_DIVIDEBYHIST_H +#define DQM_ALGORITHMS_DIVIDEBYHIST_H + +#include <dqm_core/SummaryMaker.h> + + +namespace dqm_algorithms +{ + namespace summary + { + struct DivideByHist : public dqm_core::SummaryMaker + { + DivideByHist(); + ~DivideByHist(); + DivideByHist* clone(); + dqm_core::Result* execute( const std::string & name, const dqm_core::Result & , const dqm_core::ParametersMap & ); + dqm_core::Result* execute( const std::string & name, const std::multimap<std::string,TObject*> & inputs, const dqm_core::AlgorithmConfig& config ); + }; + } +} + +#endif //#ifndef DQM_ALGORITHMS_DIVIDEBYHIST_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/FractionSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/FractionSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..33bef556ce0a976417580876ed29db791041da3f --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/FractionSummary.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file FractionSummary.h file declares the dqm_algorithms::summary::NeutralSumamry class. + * \author Andrea Dotti, added by R. Calkins +*/ + +#ifndef DQM_ALGORITHMS_FRACTION_SUMMARY_H +#define DQM_ALGORITHMS_FRACTION_SUMMARY_H + +#include <map> +#include <dqm_core/Parameter.h> +#include <dqm_core/SummaryMaker.h> +#include <dqm_core/Result.h> +#include <boost/thread/mutex.hpp> + +namespace dqm_algorithms +{ + namespace summary + { + /*! \class FractionSummary interface + * Declares the FractionSummary SummaryMaker. + * Information about number of Red/Green/Yellow is attached to tags of the result + */ + class FractionSummary : public dqm_core::SummaryMaker + { + public: + FractionSummary() ; + FractionSummary* clone(); + virtual dqm_core::Result * execute( const std::string& , const dqm_core::Result&, const dqm_core::ParametersMap& map); + private: + float m_fractionRed; + float m_fractionYellow; + }; + } +} + +#endif // DQM_ALGORITHMS_GENERIC_SUMMARY_H + diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/JetWorstCaseSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/JetWorstCaseSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..071be042c5fe2b26d83b9b0064be5cce4aaf7a86 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/JetWorstCaseSummary.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file JetWorstCaseSummary.h file declares the dqm_algorithms::summary::JetWorstCaseSummary class. + */ + + +#ifndef DQM_ALGORITHMS_JETWORSTCASESUMMARY_H +#define DQM_ALGORITHMS_JETWORSTCASESUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + /*! A simple summary + This summary maker calculates result for a region for Jet Monitoring as the worst result + of childs. If at least one child is red or yellow the summary result will be yellow. + Green if there are no red and yellow childs. + Childs with undefined state will not be considered. + Summary will result in undefined state if all childs are in + Undefined state + */ + struct JetWorstCaseSummary : public dqm_core::SummaryMaker + { + JetWorstCaseSummary(); + ~JetWorstCaseSummary(); + JetWorstCaseSummary* clone(); + dqm_core::Result* execute( const std::string & , const dqm_core::Result & , const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/MDTWorstCaseSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/MDTWorstCaseSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..84d1610d5d0085c15af227618110237cb3945044 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/MDTWorstCaseSummary.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file MDTWorstCaseSummary.h file declares the dqm_algorithms::summary::MDTWorstCaseSummary class. + */ + + +#ifndef DQM_ALGORITHMS_MDTWORSTCASESUMMARY_H +#define DQM_ALGORITHMS_MDTWORSTCASESUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + /*! A simple summary + Compute the MDT Coverage to ML Granularity per region (BA,BC,EA,EC) + based on four separate plots in four different layers (Inner, Middle, Outer, Extra) + returns green if > 90 %, red if less than 90%, and undefined if enough of the plots + failed the MinStat requirement + */ + struct MDTWorstCaseSummary : public dqm_core::SummaryMaker + { + MDTWorstCaseSummary(); + ~MDTWorstCaseSummary(); + MDTWorstCaseSummary* clone(); + dqm_core::Result* execute( const std::string & , const dqm_core::Result & , const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/PercentSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/PercentSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..0574f2b252d8e3c1bb532cc3e959b0281ba4bd14 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/PercentSummary.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//! \file PercentSummary.h file declares the dqm_algorithms::summary::PercentSummary class. +//! Valerio Consorti valerio.consorti@roma1.infn.it + + +#ifndef DQM_ALGORITHMS_PERCENT_SUMMARY_H +#define DQM_ALGORITHMS_PERCENT_SUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + struct PercentSummary : public dqm_core::SummaryMaker + { + PercentSummary(); + ~PercentSummary(); + + PercentSummary * clone(); + dqm_core::Result * execute( const std::string & , const dqm_core::Result & result, const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/SimpleSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/SimpleSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..9ef9e86f24cd7a29a334ef05985c1bcab4fc6d8a --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/SimpleSummary.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SimpleSummary.h file declares the dqm_algorithms::summary::SimpleSummary class. + * \author Haleh Hadavand +*/ + + +#ifndef DQM_ALGORITHMS_SIMPLE_SUMMARY_H +#define DQM_ALGORITHMS_SIMPLE_SUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + struct SimpleSummary : public dqm_core::SummaryMaker + { + SimpleSummary(); + ~SimpleSummary(); + + SimpleSummary * clone(); + dqm_core::Result * execute( const std::string & , const dqm_core::Result & result, const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstCaseSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstCaseSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..e07e760e539b00e6ff6c6febf0aeb4c38cc0662d --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstCaseSummary.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file WorstCaseSummary.h file declares the dqm_algorithms::summary::WorstCaseSummary class. + * \author Andrea Dotti +*/ + + + +#ifndef DQM_ALGORITHMS_WORSTCASESUMMARY_H +#define DQM_ALGORITHMS_WORSTCASESUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + /*! A simple summary + This summary maker calculates result for a region as the worst result + of childs. If at least one child is red the summary result will be red. + Yellow if at least one child is yellow and none is red. + Green if there are no red and yellow childs. + Childs with undefined state will not be considered. + Summary will result in undefined state if all childs are in + Undefined state + */ + struct WorstCaseSummary : public dqm_core::SummaryMaker + { + WorstCaseSummary(); + ~WorstCaseSummary(); + WorstCaseSummary* clone(); + dqm_core::Result* execute( const std::string & , const dqm_core::Result & , const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstCaseYellow.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstCaseYellow.h new file mode 100644 index 0000000000000000000000000000000000000000..18b913c3e2737257f7e71ad13cc8c735500f36c1 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstCaseYellow.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file WorstCaseYellow.h alternative to worst case summary. Ensures that correctable errors do not determine summary status. + * \author Andrea Dotti +*/ + + + +#ifndef DQM_ALGORITHMS_WORSTCASEYELLOW_H +#define DQM_ALGORITHMS_WORSTCASEYELLOW_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + /*! Restricted summary. The worst case output is yellow. This is useful when assessing correctable distributions. + */ + struct WorstCaseYellow : public dqm_core::SummaryMaker + { + WorstCaseYellow(); + ~WorstCaseYellow(); + WorstCaseYellow* clone(); + dqm_core::Result* execute( const std::string & , const dqm_core::Result & , const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstWBlackSummary.h b/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstWBlackSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..f08a1c7b2d9d790a982abe9dbfd6245fa65ee17b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/summary/WorstWBlackSummary.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file WorstWBlackSummary.h file declares the dqm_algorithms::summary::WorstWBlackSummary class. + * \author Andrea Dotti +*/ + + + +#ifndef DQM_ALGORITHMS_WORSTCASESUMMARY_H +#define DQM_ALGORITHMS_WORSTCASESUMMARY_H + +#include <dqm_core/SummaryMaker.h> + +namespace dqm_algorithms +{ + namespace summary + { + /*! A simple summary + This summary maker calculates result for a region as the worst result + of childs. If at least one child is red the summary result will be red. + Yellow if at least one child is yellow and none is red. + Green if there are no red and yellow childs. + Childs with undefined state will not be considered. + Summary will result in undefined state if all childs are in + Undefined state + */ + struct WorstWBlackSummary : public dqm_core::SummaryMaker + { + WorstWBlackSummary(); + ~WorstWBlackSummary(); + WorstWBlackSummary* clone(); + dqm_core::Result* execute( const std::string & , const dqm_core::Result & , const dqm_core::ParametersMap & ); + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/tools/AlgorithmHelper.h b/DataQuality/dqm_algorithms/dqm_algorithms/tools/AlgorithmHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..72cb1b6bdd998f7bda3115a3468efd57b13b127b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/tools/AlgorithmHelper.h @@ -0,0 +1,179 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlgorithmHelper.cpp does basic functions to get dqm_core::Results from algorithms + * \author Haleh Hadavand + */ + +#ifndef DQM_ALGORITHMS_TOOLS_ALGORITHMHELPER_H +#define DQM_ALGORITHMS_TOOLS_ALGORITHMHELPER_H + +#include <dqm_core/Result.h> +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_core/exceptions.h> + +#include <map> +#include <vector> +#include <deque> +#include <list> +#include <utility> + +#include <TH1.h> +#include <TObject.h> +#include <TClass.h> +#include <boost/thread/once.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread.hpp> +#include <boost/utility.hpp> +#include <iostream> + +class TF1; +class TAxis; + +namespace dqm_algorithms +{ + namespace tools + { + enum AxisType { XYAxes, XAxis, YAxis, XYZAxes, XZAxes, YZAxes, ZAxis }; + + enum Topology { Rectangle, CylinderX, CylinderY, Torus }; + + //Structure to hold the essence of a 2D histogram bin, and be sortable: + struct binContainer { + double value; + double error; + int test; + int ix; + int iy; + double x; + double y; + //Comparison function, for sorting + inline static bool comp(const binContainer &lhs, const binContainer &rhs) { return fabs(lhs.value) < fabs(rhs.value); } + }; + + struct binCluster { + double value; + double error; + double x; + double y; + double radius; + int n; + int ixmin; + int ixmax; + int iymin; + int iymax; + inline static bool comp(const binCluster &lhs, const binCluster &rhs) { return fabs(lhs.value) < fabs(rhs.value); } + }; + + std::map<std::string, double > GetFitParams(const TF1 * func); + + std::map<std::string, double > GetFitParamErrors(const TF1 * func); + + dqm_core::Result * MakeComparisons( const std::map<std::string,double> & algparams, + const std::map<std::string,double> & gthreshold, + const std::map<std::string,double> & rthreshold ); + + dqm_core::Result * CompareWithErrors( const std::map<std::string,double> & algparams, + const std::map<std::string,double> & paramErrors, + const std::map<std::string,double> & gthreshold, + const std::map<std::string,double> & rthreshold, double minSig); + + dqm_core::Result * GetFitResult (const TF1 * func, const dqm_core::AlgorithmConfig & config, double minSig = 0) ; + + double GetFirstFromMap(const std::string ¶mName, const std::map<std::string, double > ¶ms); + // mandatory: throws an exception if the parameter is not found + + double GetFirstFromMap(const std::string ¶mName, const std::map<std::string, double > ¶ms, double defaultValue); + // optional: returns defaultValue if the parameter is not found + + std::vector<int> GetBinRange(const TH1* histogram, const std::map<std::string, double > & params); + + void PublishBin(const TH1 * histogram, int xbin, int ybin, double content, dqm_core::Result *result); + + TH1* DivideByHistogram(const TH1* hNumerator, const TH1* hDenominator); + + void ModifyHistogram(TH1 * histogram, const dqm_core::AlgorithmConfig & config); + + std::string ExtractAlgorithmName(const dqm_core::AlgorithmConfig& config); + + dqm_core::Result * ExecuteNamedAlgorithm(const std::string & name, const TObject & object, + const dqm_core::AlgorithmConfig & config); + + TH1* BookHistogramByExample(const TH1* histogram, const std::string& title, const std::string& name, AxisType axisType); + + template <class T> + const T & GetFromMap( const std::string & pname, const std::map<std::string,T> & params ) + { + typename std::map<std::string,T>::const_iterator it = params.find( pname ); + if ( it != params.end() ){ + return it->second; + }else { + throw dqm_core::BadConfig( ERS_HERE, "None", pname ); + } + } + + /** Helper function used to handle complex reference histograms + * This function gets as input a reference object and checks if it is a + * collection of references, in this case extracts and returns the first element. + \param inputReference : the original reference object + \param firstReference : the first element of the reference object, + If the input reference is a TCollection, otherwise + the inputReference itself + \param secondReference : the remaining reference(s), if the input collection + has 2 elements the secondReference is a TObject, + otherwise it is of the same class as the + inputReference + \throw dqm_core::BadRefHist : in case of wrong references + */ + void handleReference( const TObject& inputReference , TObject*& firstReference , TObject*& secondReference); + + // Function to find outliers in input; iterates over values nIteration times, recalculating mean each time and + // removing values that are beyond threshold * scale, where: + // + // scale = ( sum_in[ abs( value - mean )^ exponent ] / (Nin - 1 - SBCF * Nout) ) ^ ( 1 / exponent ). + // + // If all bins are in, and the exponent is two, this is just and unbiased estimator of the standard variance. + // SBCF, or the Scale Bias Correction Factor, is an empirical quantity intended to correct for the bias induced from the + // bin exclusion process (in a sense, the act of excluding bins could be thought of as decreasing the number of degrees + // of freedom). In practice, the SBCF serves to impose an upper bound on the fraction of bins that can be excluded. + + + void findOutliers( std::vector<binContainer>& input, double& mean, double& scale, int& nIn, int nIterations, + double exponent, double threshold, double SBCF = 1., double nStop = 8. ); + + void findOutliersUsingErrors( std::vector<binContainer>& input, double& mean, double& meanError, int& nIn, + double mindiff = 0, int minNin = 4); + + // Method for building a cluster: + binCluster buildCluster( binContainer& seed, const std::vector<std::vector<binContainer*> >& binMap, + const std::vector<double>& xValues, const std::vector<double>& yValues, + double threhold, int topology = CylinderX); + + // Method for mapping binContainer object by their relative positions: + std::vector<std::vector<binContainer*> > + makeBinMap(std::vector<dqm_algorithms::tools::binContainer>& bins, int ixmax, int iymax, int topology = CylinderX); + + dqm_core::Result::Status + WorstCaseAddStatus(dqm_core::Result::Status baseStatus, dqm_core::Result::Status addedStatus, float weight = 1.0); + + dqm_core::Result::Status + BestCaseAddStatus(dqm_core::Result::Status baseStatus, dqm_core::Result::Status addedStatus, float weight = 1.0); + + std::pair<double,double> CalcBinsProbChisq(std::vector<double> inputval,std::vector<double> inputerr, + double x0, double x0_err); + std::pair<double,double> CalcBinsProbChisq(std::vector<double> inputval,std::vector<double> inputerr, + std::vector<double> x0,std::vector<double> x0_err); + + void MergePastMinStat(std::vector<std::vector<tools::binContainer> >& strips, int minStat); + + void MakeBinTag( const binContainer& bin, std::string & tag ); + + void FormatToSize( double value, int size, std::string & str, bool showSign = true ); + + } +} + + +#endif // #ifndef DQM_ALGORITHMS_TOOLS_ALGORITHMHELPER_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/tools/DumpConfig.h b/DataQuality/dqm_algorithms/dqm_algorithms/tools/DumpConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..28913085800541cf3360a93464e446cffbdb63f8 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/tools/DumpConfig.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlgorithmHelper.cpp does basic functions to get dqm_core::Results from algorithms + * \author Haleh Hadavand + */ +#ifndef DQM_ALGORITHMS_TEST_DUMPCONFIG_H +#define DQM_ALGORITHMS_TEST_DUMPCONFIG_H + +#include <map> +#include <iostream> +#include <fstream> +#include <dqm_core/test/DummyAlgorithmConfig.h> + +namespace dqm_algorithms +{ + namespace tools + { + class DumpConfig{ + public: + DumpConfig(std::string ParameterName,dqm_core::test::DummyAlgorithmConfig & config, std::string algorithmname, std::string histogramname, std::string reffilename="", std::string refhistogramname="", float weight=1.,std::string regionname="" ); + ~DumpConfig(); + + void DumpOnlineConfig(std::string filename,bool dumpAgent=true); + void DumpOfflineConfig(std::string filename); + + private: + void WriteThresholdFromMap(std::map<std::string,double> object,std::string ParameterName,std::string Name); + void DumpThresholds(); + void DumpParams(); + void DumpRegion(); + void DumpAgent(); + + ofstream _myfile; + std::map<std::string,double> params; + std::map<std::string,double> gthresh; + std::map<std::string,double> rthresh; + std::vector<std::string> red_id; + std::vector<std::string> green_id; + std::vector<std::string> param_id; + + std::string _ParameterName; + dqm_core::test::DummyAlgorithmConfig _config; + std::string _regionname; + std::string _algorithmname; + std::string _histogramname; + std::string _refhistogramname; + std::string _reffilename; + float _weight; + + }; + } +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/tools/SimpleAlgorithmConfig.h b/DataQuality/dqm_algorithms/dqm_algorithms/tools/SimpleAlgorithmConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..2305118a10a4e7cd7322e8bdf074af4c4f723b53 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/tools/SimpleAlgorithmConfig.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SimpleAlgorithmConfig Defines the class SimpleAlgorithmConfig a concrete simple implementation of dqm_core::AlgorithmConfig + * \author andrea.dotti@cern.ch + */ + +#ifndef DQM_ALGORITHMS_TOOLS_SIMPLEALGORITHMCONFIG +#define DQM_ALGORITHMS_TOOLS_SIMPLEALGORITHMCONFIG +#include <TObject.h> +#include <dqm_core/AlgorithmConfig.h> +namespace dqm_algorithms +{ + namespace tools + { + /*! \brief This class provides a simple implementation of the DQMF abstract AlgorithmConfig interface + which can be used in dqm_algorithms (see AddReference algorithms). + \ingroup public + */ + class SimpleAlgorithmConfig : public dqm_core::AlgorithmConfig + { + public: + ///Default constructor + SimpleAlgorithmConfig(); + SimpleAlgorithmConfig(TObject *ref); +#ifndef __MAKECINT__ + ///Copy constructor + SimpleAlgorithmConfig(const AlgorithmConfig& conf); +#endif + + ///Getters, interface defines in AlgorithmConfig + virtual TObject * getReference() const; + virtual const std::map<std::string, double>& getParameters() const; + virtual const std::map<std::string, double>& getGreenThresholds() const; + virtual const std::map<std::string, double>& getRedThresholds() const; + ///Setters + void setReference(TObject* ref); + void addParameter(std::string,double);//< Adds a new parameter to the list of current params + void addGreenThreshold(std::string,double);//< Adds a new threshold to the list of current params + void addRedThreshold(std::string,double);//< Adds a new threshold to the list of current params + private: + TObject* ref_; + std::map<std::string,double> param_; + std::map<std::string,double> green_; + std::map<std::string,double> red_; + }; + } + +} + +#endif diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/tools/dqm_toolsDict.h b/DataQuality/dqm_algorithms/dqm_algorithms/tools/dqm_toolsDict.h new file mode 100644 index 0000000000000000000000000000000000000000..d01f0312e21c0880b0b18316984dbe205a60521b --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/tools/dqm_toolsDict.h @@ -0,0 +1,11 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DQM_ALGORITHMS_DQM_TOOLSDICT_H +#define DQM_ALGORITHMS_DQM_TOOLSDICT_H + +#include "dqm_algorithms/tools/DumpConfig.h" +#include "dqm_algorithms/tools/SimpleAlgorithmConfig.h" + +#endif // DQM_ALGORITHMS_DQM_TOOLSDICT_H diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/tools/selection.xml b/DataQuality/dqm_algorithms/dqm_algorithms/tools/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..1b0d800f062badf5b570a4fc6f9281f8142933e4 --- /dev/null +++ b/DataQuality/dqm_algorithms/dqm_algorithms/tools/selection.xml @@ -0,0 +1,5 @@ +<lcgdict> + <namespace name="dqm_algorithms::tools"/> + <class name="dqm_algorithms::tools::DumpConfig"/> + <class name="dqm_algorithms::tools::SimpleAlgorithmConfig"/> +</lcgdict> diff --git a/DataQuality/dqm_algorithms/share/HOWTo_make_DQMDQ.txt b/DataQuality/dqm_algorithms/share/HOWTo_make_DQMDQ.txt new file mode 100644 index 0000000000000000000000000000000000000000..fdc5e0fe1287adb98a9a4ccc364871c329796748 --- /dev/null +++ b/DataQuality/dqm_algorithms/share/HOWTo_make_DQMDQ.txt @@ -0,0 +1,30 @@ +Function: +Creates a DQMF configuration for histograms in a given directory in a root file applying the same algorithm to all histograms. One may dump +different DQThresholds and DQAlgorithmParameters for each histograms associated to a DQParamter as well to modify in oks_data_editor or in an editor. + +Example: +./make_DQMDB.pl -c 1 (-i root_dumpfile) (-r Region) -o test_2060.data.xml -s 0 -d CaloClusterVecMon/Energy -a Simple_gaus_Fit --red Mean=7 --green Mean=3 --red Sigma=1 --green Sigma=-0.1 --param xmin=-1 --param xmax=1 + +Options: +bool -c: 1: Dump a txt file which contains a list of histograms from the given root file + 0: don't dump the file instead use the existing one provided by -i option + +string -i: Optional:Input file containing list of histograms in a root file + +string -o: Output file to put DQMF configuration + +bool -s: 1: Create new DQAlgorithmParameters and DQThreshold objects for each DQParameter, or histogram. Values are default one filled in at command + line but can be modified by user. + 0: Use same DQAlgorithmParamters and DQThresholds +string -d: Directory in root file from which you would like to use histograms to make DQParameters + +string -a: Algorithm name you dqm_print_algorithms command to see list of available algorithm names + +string -r: Optional: Region name to which include all DQParameters. + +--red String=float : Use this structure to set RedThresholds example: --red Mean=7 + +--green String=float:Use this structure to set GreenThresholds example: --green Mean=2 + +--param String=float:Use this structure to set DQAlgorithmParameters example: --param xmin=7 + diff --git a/DataQuality/dqm_algorithms/share/Test.root b/DataQuality/dqm_algorithms/share/Test.root new file mode 100644 index 0000000000000000000000000000000000000000..6a5445539b4c180bd20afc7339178230792da0d3 Binary files /dev/null and b/DataQuality/dqm_algorithms/share/Test.root differ diff --git a/DataQuality/dqm_algorithms/share/inspect.C b/DataQuality/dqm_algorithms/share/inspect.C new file mode 100644 index 0000000000000000000000000000000000000000..dd1cf2024f77087645cc770b7a0818d9480018f4 --- /dev/null +++ b/DataQuality/dqm_algorithms/share/inspect.C @@ -0,0 +1,35 @@ +#include<iostream.h> +#include<vector.h> +#include<string.h> + +std::vector<std::string> inspect(){ + std::string pwd(gDirectory->GetPath()); + gDirectory->cd(); // go home + std::vector<std::string> s = traversedir( gDirectory ); + gDirectory->cd( pwd.c_str()); + return s; + } + +std::vector<std::string> traversedir( TDirectory *dir) { + std::vector<std::string> histograms; + TIter nextkey( dir->GetListOfKeys() ); + TKey *key, *oldkey=0; + while ( (key = (TKey*)nextkey() )) { + TObject *obj = key->ReadObj(); + if ( obj->IsA()->InheritsFrom( "TH1" ) ) { + std::string fullname(gDirectory->GetPath()); + fullname +="/"; + fullname += obj->GetName(); + histograms.push_back(fullname); + std::cout<<fullname<<std::endl; + } else if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) { + std::string pwdd(gDirectory->GetPath()); + gDirectory->cd(obj->GetName()); + std::vector<std::string> r = traversedir(gDirectory); + // append it to the list + gDirectory->cd(pwdd.c_str()); + //copy(r.begin(), r.end(), histograms.end()); + } + } + return histograms; + } diff --git a/DataQuality/dqm_algorithms/share/make_DQMDB.pl b/DataQuality/dqm_algorithms/share/make_DQMDB.pl new file mode 100755 index 0000000000000000000000000000000000000000..2f766075162e3af2b03fe89ef2432bf24be433ee --- /dev/null +++ b/DataQuality/dqm_algorithms/share/make_DQMDB.pl @@ -0,0 +1,171 @@ +#!/usr/local/bin/perl -w +use strict; +use Getopt::Long; +use Cwd; + +my $int=0; +my $outputfile = ""; +my $rootfile = ""; +my $inputfile = ""; +my $Region=""; +my $createrootdump; +my $first=1; +my $c; +my $index; +my $dir; +my $createnewvalues=1; +my $algorithm; +my %opt = (); +my $optparam = (); +my $optred = (); +my $optgreen = (); +&GetOptions(\%opt, "param=f%", "green=f%", "red=f%", 'c=i',\$createrootdump,'o=s', \$outputfile,'i=s',\$inputfile, 'f=s',\$rootfile, 's=i',\$createnewvalues, 'd=s', \$dir, 'a=s', \$algorithm, 'r=s', \$Region ); + +$optgreen=$opt{"green"}; +$optred=$opt{"red"}; +$optparam=$opt{"param"}; +my $gcount += scalar keys %$optgreen; +my $rcount += scalar keys %$optred; +my $pcount += scalar keys %$optparam; + +open(G,">dump_$outputfile") || die "ups"; +$c=-e "inspect.C" ; +if (!$c){ +print "need file inspect.C\n"; +exit 0; +} + +if ($inputfile eq ""){ + $inputfile="root_dump.txt"; +} + +system "which root"; +if ($createrootdump){ + print "creating root file dump\n"; + system "root -b $rootfile -q inspect.C |sort > $inputfile"; +}; +if (!($createrootdump) && !(-e $inputfile) ){ + print "creating root file\n"; + system "root -b $rootfile -q inspect.C |sort > $inputfile"; +} +open(F,"<".$inputfile) || die "cannot open $inputfile"; +while(<F>){ + chomp $_; + if ($_=~/$rootfile:($dir\/.*)/ || $_=~/$rootfile:(\/$dir\/.*)/ || $_=~/$rootfile:($dir.*)/){ + print "$_\n"; + ++$int; + if ($createnewvalues) { + $index=$int; + }else { + $index=1; + } + print G "\<obj class=\"DQParameter\" id=\"Param_$int\"\> \n"; + print G "\<attr name=\"InputDataSource\" type=\"string\"\>\"$1\"\<\/attr\> \n"; + print G "\<attr name=\"Weight\" type=\"float\"\>1\<\/attr\> \n"; + print G "\<rel name=\"Algorithm\">\"DQAlgorithm\" \"$algorithm\"\<\/rel\> \n"; + print G "\<attr name=\"Action\" type=\"string\"\>\"\"\<\/attr\> \n"; + if ($pcount != 0 ){ + print G "\<rel name=\"AlgorithmParameters\" num=\"$pcount\"\> \n"; + while ( my ($pkey, $pvalue) = each(%$optparam) ) { + print G " \"DQAlgorithmParameter\" \"param-$pkey-$index\" \n"; + } + print G "\<\/rel\> \n"; + print G "\<rel name=\"References\" num=\"0\"\> <\/rel\>\n"; + }else { + print G "\<rel name=\"AlgorithmParameters\" num=\"0\"\> \n"; + print G "\<\/rel\> \n"; + print G "\<rel name=\"References\" num=\"0\"\> <\/rel\>\n"; + } + if ($gcount != 0 ){ + print G "\<rel name=\"GreenThresholds\" num=\"$gcount\"\>\n"; + while ( my ($pkey, $pvalue) = each(%$optgreen) ) { + print G " \"DQThreshold\" \"GreenTh-$pkey-$index\" \n"; + } + print G "\<\/rel\>\n"; + }else { + print G "\<rel name=\"GreenThresholds\" num=\"0\"\>\n"; + print G "\<\/rel\>\n"; + } + + if ($rcount != 0 ){ + print G "\<rel name=\"RedThresholds\" num=\"$rcount\"\>\n"; + while ( my ($pkey, $pvalue) = each(%$optred) ) { + print G " \"DQThreshold\" \"RedTh-$pkey-$index\" \n"; + } + print G "\<\/rel\>\n"; + }else { + print G "\<rel name=\"RedThresholds\" num=\"0\"\>\n"; + print G "\<\/rel\>\n"; + } + print G "\<\/obj\> \n"; + print G "\n \n"; + + if ($createnewvalues || $first) { + if ($gcount !=0 ){ + while ( my ($pkey, $pvalue) = each(%$optgreen) ) { + print G" \<obj class\=\"DQThreshold\" id\=\"GreenTh\-$pkey\-$int\"\> \n"; + print G" \<attr name=\"Name\" type=\"string\"\>\"$pkey\"\<\/attr\> \n"; + print G" \<attr name=\"Value\" type\=\"double\"\>$pvalue\<\/attr\> \n"; + print G "\<\/obj\> \n"; + print G "\n \n"; + } + } + if ($rcount !=0 ){ + while ( my ($pkey, $pvalue) = each(%$optred) ) { + print G" \<obj class\=\"DQThreshold\" id\=\"RedTh\-$pkey\-$int\"\> \n"; + print G" \<attr name=\"Name\" type=\"string\"\>\"$pkey\"\<\/attr\> \n"; + print G" \<attr name=\"Value\" type\=\"double\"\>$pvalue\<\/attr\> \n"; + print G "\<\/obj\> \n"; + print G "\n \n"; + } + } + + if ($pcount !=0 ){ + while ( my ($pkey, $pvalue) = each(%$optparam) ) { + print G "\<obj class=\"DQAlgorithmParameter\" id\=\"param\-$pkey\-$int\"\> \n"; + print G "\<attr name\=\"Name\" type\=\"string\"\>\"$pkey\"\<\/attr\> \n"; + print G "\<attr name\=\"Value\" type\=\"double\"\ num\=\"1\">$pvalue\<\/attr\> \n"; + print G "\<\/obj\> \n"; + print G "\n \n"; + } + } + $first=0; + + } + + + + } +} +close(F); + if ($Region ne "" ) { + print G "\<obj class=\"DQRegion\" id=\"$Region\"\> \n"; + print G "\<attr name=\"InputDataSource\" type=\"string\">\"\"\<\/attr\> \n"; + print G "\<attr name=\"Weight\" type=\"float\"\>1\<\/attr\> \n"; + print G "\<attr name=\"Action\" type=\"string\"\>\"\"\<\/attr\> \n"; + print G "\<rel name=\"Algorithm\"\>\"DQAlgorithm\" \"SimpleSummary\"\<\/rel\>\n"; + print G "\<rel name=\"AlgorithmParameters\" num=\"0\"\>\<\/rel\>\n"; + print G "\<rel name=\"References\" num=\"0\"\>\<\/rel\>\n"; + print G "\<rel name=\"GreenThresholds\" num=\"0\"\>\<\/rel\>\n"; + print G "\<rel name=\"RedThresholds\" num=\"0\">\<\/rel\> \n"; + print G "\<rel name=\"DQRegions\" num=\"0\">\<\/rel\> \n"; + print G "\<rel name=\"DQParameters\" num=\"$int\"\> \n"; + for (my $i=1 ; $i < ($int+1) ; $i++) { + print G "\"DQParameter\" \"Param_$i\" \n"; + } + print G "\<\/rel\>\n"; + print G "\<\/obj\>\n"; + } +print G "</oks-data>\n"; + +close(G); +system "cat oks-xml-header.txt dump_$outputfile > $outputfile"; +if ($createrootdump == 1){ +print "*****DQM DB file $outputfile created from root file $rootfile*****\n"; +}else { +print "*****DQM DB file $outputfile created from input file $inputfile*****\n"; +} +if ($Region ne "" ){ +print "*****This file has a Region called $Region*****\n"; +} +print "*****This file has $int Parameters*****\n"; diff --git a/DataQuality/dqm_algorithms/share/oks-xml-header.txt b/DataQuality/dqm_algorithms/share/oks-xml-header.txt new file mode 100644 index 0000000000000000000000000000000000000000..b29c886a9841155393b8f3dbf48874c22bbbf47b --- /dev/null +++ b/DataQuality/dqm_algorithms/share/oks-xml-header.txt @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="ASCII"?> + +<!-- oks-data version 2.0 --> + + +<!DOCTYPE oks-data [ + <!ELEMENT oks-data (info, (include)?, (obj)+)> + <!ELEMENT info EMPTY> + <!ATTLIST info + name CDATA #REQUIRED + type CDATA #REQUIRED + num-of-includes CDATA #REQUIRED + num-of-items CDATA #REQUIRED + oks-format CDATA #FIXED "extended" + oks-version CDATA #REQUIRED + created-by CDATA #REQUIRED + created-on CDATA #REQUIRED + creation-time CDATA #REQUIRED + last-modified-by CDATA #REQUIRED + last-modified-on CDATA #REQUIRED + last-modification-time CDATA #REQUIRED + > + <!ELEMENT include (file)+> + <!ELEMENT file EMPTY> + <!ATTLIST file + path CDATA #REQUIRED + > + <!ELEMENT obj (attr | rel)*> + <!ATTLIST obj + class CDATA #REQUIRED + id CDATA #REQUIRED + > + <!ELEMENT attr (#PCDATA)*> + <!ATTLIST attr + name CDATA #REQUIRED + type (bool|s8|u8|s16|u16|s32|u32|float|double|date|time|string|uid|enum|-) "-" + num CDATA "-1" + > + <!ELEMENT rel (#PCDATA)*> + <!ATTLIST rel + name CDATA #REQUIRED + num CDATA "-1" + > +]> + +<oks-data> + +<info name="" type="" num-of-includes="3" num-of-items="15" oks-format="extended" oks-version="oks-03-06-02 built "Jan 24 2007"" created-by="" created-on="" creation-time="1/4/07 1:00:00" last-modified-by="hadavand" last-modified-on="pcatlas3206.cern.ch" last-modification-time="17/4/07 14:11:08"/> + +<include> + <file path="dqm_config/schema/DQM.schema.xml"/> + <file path="dqm_config/data/DQM_algorithms.data.xml"/> +</include> + diff --git a/DataQuality/dqm_algorithms/src/AddReference.cxx b/DataQuality/dqm_algorithms/src/AddReference.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1b0b1b099a2c7f1c997252a27c768cf9ba25c8d3 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/AddReference.cxx @@ -0,0 +1,134 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AddReference.cxx checks an histogram with a specified algorithm, after summing to input histograms the reference histogram + * \author andrea.dotti@cern.ch + */ + +#include <dqm_algorithms/AddReference.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TClass.h> +#include <TObjArray.h> +#include <dqm_core/AlgorithmManager.h> + +namespace { + static dqm_algorithms::AddReference AllBins_Filled("All_Bins_Filled"); + static dqm_algorithms::AddReference BinsDiffFromAvg("Bins_Diff_FromAvg"); + static dqm_algorithms::AddReference b1("Bins_GreaterThan_Threshold"); + static dqm_algorithms::AddReference b2("Bins_GreaterThanEqual_Threshold"); + static dqm_algorithms::AddReference b3("Bins_LessThan_Threshold"); + static dqm_algorithms::AddReference b4("Bins_LessThanEqual_Threshold"); + static dqm_algorithms::AddReference b5("Bins_Equal_Threshold"); + static dqm_algorithms::AddReference b6("Bins_NotEqual_Threshold"); + static dqm_algorithms::AddReference b7("BinContentComp"); +} + +dqm_algorithms::AddReference::AddReference(const std::string& name ) : name_(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("AddReference_"+name,this); +} + +dqm_algorithms::AddReference* +dqm_algorithms::AddReference::clone() +{ + return new AddReference(name_); +} + +dqm_core::Result* +dqm_algorithms::AddReference::execute(const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)(object.Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEffectiveEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + delete histogram; + return result; + } + + double coeff = dqm_algorithms::tools::GetFirstFromMap("Coeff",config.getParameters(), 1); + + TObject* ro = config.getReference(); + TObject* firstReference = 0; + TObject* secondReference= 0; + try { + dqm_algorithms::tools::handleReference( *ro , firstReference , secondReference ); + } + catch ( dqm_core::Exception& ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + TH1* refhist = dynamic_cast<TH1*>(firstReference); + if ( refhist == 0 ) + { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + +if ((histogram->GetDimension() != refhist->GetDimension()) || + (histogram->GetNbinsX() != refhist->GetNbinsX()) || + (histogram->GetNbinsY() != refhist->GetNbinsY()) || + refhist->GetNbinsZ() != histogram->GetNbinsZ() ) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + ERS_DEBUG(2,"Doing: histogram + ("<<coeff<<")*reference"); + histogram->Add( refhist , coeff ); + + //Now prepare to run the real algorithm... + ERS_DEBUG(2,"Running algorithm: "<<name_); + dqm_core::Algorithm* subalgorithm; + try { + subalgorithm = dqm_core::AlgorithmManager::instance().getAlgorithm( name_ ); + } + catch ( dqm_core::AlgorithmNotFound& ex ) + { + ERS_DEBUG(2,"Cannot find algorithm:"+name_); + throw dqm_core::BadConfig(ERS_HERE,name,"Cannot Find sub-algorithm:"+name_); + } + dqm_core::Result* result = subalgorithm->execute( name , *histogram , config); + ERS_DEBUG(2,"Sub algorithm returns:"<<*result); + //Add modified histogram to result + TObject* robject = result->getObject(); + if ( !robject ) //No object defined, add this + { + ERS_DEBUG(2,"Adding modified histogram in result"); + result->object_.reset(histogram); + } + else //Transform the object_ in TObjArray (if needed) and add this result + { + ERS_DEBUG(2,"Result already have an associated TObject, appending modified histogram"); + if ( robject->IsA()->InheritsFrom("TObjArray") ) //It is already an array add it... + { + static_cast<TObjArray*>(robject)->Add( histogram ); + //Check in again + result->object_.reset( robject ); + } + else + { + TObjArray* array = new TObjArray( 2 ); + array->AddAt( robject , 0 ); + array->AddAt( histogram , 1 ); + //Check in again + result->object_.reset( array ); + } + ERS_DEBUG(2,"Result now have a TObjArray of size:"<<static_cast<TObjArray*>(result->getObject())->GetEntries()); + } + return result; +} + + +void dqm_algorithms::AddReference::printDescription(std::ostream& out) { + out<<"AddReference_"+name_+" : Performst the "+name_+" algorithm after adding to the input histogram the reference. I.e. performing: histogram += c*Reference. Adds to the output TObject list the modified input histogram."<<std::endl; + out<<"Optional Parameter : MinStat : Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter : Coeff : The multiplication coefficient c, for reference. Default c=+1"<<std::endl; + +} diff --git a/DataQuality/dqm_algorithms/src/AveragePrint.cxx b/DataQuality/dqm_algorithms/src/AveragePrint.cxx new file mode 100644 index 0000000000000000000000000000000000000000..427209f29cf9de1b0fb41daa5223073cf6da551d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/AveragePrint.cxx @@ -0,0 +1,133 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_algorithms/AveragePrint.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TH1.h> +#include <TProfile.h> +#include <TClass.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/Result.h" + +static dqm_algorithms::AveragePrint staticInstance; + +namespace dqm_algorithms { + + // ********************************************************************* + // Public Methods + // ********************************************************************* + + void + AveragePrint:: + printDescription(std::ostream& out) + { + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Prints out the average of the histogram or profile bins\n"; + message += " In the case of a TProfile each bin is weighted by its fraction of the entries\n"; + message += " Overflow (and Underflow) bins are not included\n"; + message += "\n"; + + out << message; + } + + AveragePrint:: + AveragePrint() + : name("AveragePrint") + { + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); + } + + + AveragePrint:: + ~AveragePrint() + { + } + + + dqm_core::Algorithm* + AveragePrint:: + clone() + { + return new AveragePrint(*this); + } + + + dqm_core::Result* + AveragePrint:: + execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& /*config*/) + { + //No status flags are set + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Undefined; + + if (!data.IsA()->InheritsFrom("TH1")) { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + TH1* h = (TH1*)&data; // h cannot be null + if (h->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2 "); + } + + //********** + // Profile case + //********** + if ( data.IsA()->InheritsFrom("TProfile") ) { + TProfile* hp = (TProfile*)&data; + //ASSUME: dimension = 1 + double Average_value = 0.; + double Total_entries = 0; + int NbinsX = h->GetNbinsX(); + for(int binX = 0; binX < NbinsX; binX++) { + double Bin_entries = hp->GetBinEntries(binX + 1); + double Bin_value = Bin_entries * (hp->GetBinContent(binX + 1)); + Total_entries += Bin_entries; + Average_value += Bin_value; + } + Average_value = Average_value / Total_entries; + std::string Average_name = Form("%s_Average", name.c_str()); + result->tags_[Average_name.c_str()] = Average_value; + } + + //********** + // 1D Histogram case + //********** + if((! data.IsA()->InheritsFrom("TProfile")) && h->GetDimension() == 1) { + double Average_value = 0.; + int NbinsX = h->GetNbinsX(); + for(int binX = 0; binX < NbinsX; binX++) { + Average_value += h->GetBinContent(binX + 1); + } + std::string Average_name = Form("%s_Average", name.c_str()); + result->tags_[Average_name.c_str()] = Average_value; + } + + //********** + // 2D Histogram case + //********** + if((! data.IsA()->InheritsFrom("TProfile")) && h->GetDimension() == 2) { + double Average_value = 0.; + int NbinsX = h->GetNbinsX(); + int NbinsY = h->GetNbinsY(); + for(int binX = 0; binX < NbinsX; binX++) { + for(int binY = 0; binY < NbinsY; binY++) { + Average_value += h->GetBinContent(binY + 1, binY + 1); + } + } + std::string Average_name = Form("%s_Average", name.c_str()); + result->tags_[Average_name.c_str()] = Average_value; + } + + return result; + } + +} diff --git a/DataQuality/dqm_algorithms/src/BasicGraphCheck.cxx b/DataQuality/dqm_algorithms/src/BasicGraphCheck.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4a0cc4982af00d10435a14747d7533886bff4c4d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BasicGraphCheck.cxx @@ -0,0 +1,95 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicGraphCheck.cxx checks basic histogram quanitites like over/underflow; if filled and returns dqm_core::Result + * \author Peter Onyisi, following Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BasicGraphCheck.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TGraph.h> +#include <TClass.h> +#include <ers/ers.h> + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::BasicGraphCheck GraphFilling( "Graph_Not_Empty" ); + dqm_algorithms::BasicGraphCheck GraphEmpty( "Graph_Empty" ); + +} + + +dqm_algorithms::BasicGraphCheck::BasicGraphCheck( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +dqm_algorithms::BasicGraphCheck * +dqm_algorithms::BasicGraphCheck::clone() +{ + + return new BasicGraphCheck( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::BasicGraphCheck::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TGraph * graph; + + if( object.IsA()->InheritsFrom( "TGraph" ) ) { + graph = (TGraph*)&object; + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TGraph" ); + } + + double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1 ); + + if (graph->GetN() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientN"] = graph->GetN(); + return result; + } + + if (name_ == "Graph_Not_Empty") { + if (graph->GetN() != 0) { + ERS_DEBUG(1, "Graph " <<graph->GetName()<<" is Not Empty"); + return new dqm_core::Result(dqm_core::Result::Green); + }else { + ERS_DEBUG(1, "Graph " <<graph->GetName()<<" is Empty"); + return new dqm_core::Result(dqm_core::Result::Red); + } + } else if (name_ == "Graph_Empty") { + if (graph->GetN() == 0) { + ERS_DEBUG(1, "Graph " <<graph->GetName()<<" is Empty"); + return new dqm_core::Result(dqm_core::Result::Green); + }else { + ERS_DEBUG(1, "Graph " <<graph->GetName()<<" is Not Empty"); + return new dqm_core::Result(dqm_core::Result::Red); + } + } else { + return new dqm_core::Result(); + } + + +} + +void +dqm_algorithms::BasicGraphCheck::printDescription(std::ostream& out) +{ + if ( name_ == "Graph_Not_Empty"){ + out<<"Graph_Not_Empty: Checks that graph is not empty\n"<<std::endl; + } else if ( name_ == "Graph_Empty"){ + out<<"Graph_Empty: Checks that graph is empty\n"<<std::endl; + } + + out<<"Optional Parameter: MinStat: Minimum graph statistics needed to perform Algorithm\n"<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/src/BasicHistoCheck.cxx b/DataQuality/dqm_algorithms/src/BasicHistoCheck.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0e38420473b500439d1a774f1df716dbacd8d55d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BasicHistoCheck.cxx @@ -0,0 +1,239 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicHistoCheck.cxx checks basic histogram quanitites like over/underflow; if filled and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BasicHistoCheck.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::BasicHistoCheck Filling( "Histogram_Not_Empty" ); + dqm_algorithms::BasicHistoCheck OverFlow( "No_OverFlows" ); + dqm_algorithms::BasicHistoCheck UnderFlow( "No_UnderFlows" ); + dqm_algorithms::BasicHistoCheck BinsFilled( "All_Bins_Filled" ); + + dqm_algorithms::BasicHistoCheck Empty( "Histogram_Empty" ); + dqm_algorithms::BasicHistoCheck EffectiveEmpty( "Histogram_Effective_Empty" ); +} + + +dqm_algorithms::BasicHistoCheck::BasicHistoCheck( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +dqm_algorithms::BasicHistoCheck * +dqm_algorithms::BasicHistoCheck::clone() +{ + + return new BasicHistoCheck( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::BasicHistoCheck::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 3 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 3 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + if (name_ == "Histogram_Not_Empty") { + if (histogram->GetEntries() != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Not Empty"); + return new dqm_core::Result(dqm_core::Result::Green); + }else { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Empty"); + return new dqm_core::Result(dqm_core::Result::Red); + } + } else if (name_ == "No_OverFlows" ) { + const unsigned int binsx = histogram->GetNbinsX()+1; + const unsigned int binsy = histogram->GetNbinsY()+1; + const unsigned int binsz = histogram->GetNbinsZ()+1; + switch (histogram->GetDimension()){ + case 1: + if (histogram->GetBinContent(binsx) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has OverFlows X"); + return new dqm_core::Result(dqm_core::Result::Red); + } + break; + case 2: + for (unsigned int i(0); i <= binsx; ++i) + if (histogram->GetBinContent(i,binsy) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has OverFlows Y"); + return new dqm_core::Result(dqm_core::Result::Red); + } + for (unsigned int i(0); i <= binsy; ++i) + if (histogram->GetBinContent(binsx,i) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has OverFlows X"); + return new dqm_core::Result(dqm_core::Result::Red); + } + break; + case 3: + for (unsigned int i(0); i <= binsx; ++i) + for (unsigned int j(0); j <= binsy; ++j) + if (histogram->GetBinContent(i,j,binsz) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has OverFlows Z"); + return new dqm_core::Result(dqm_core::Result::Red); + } + for (unsigned int i(0); i <= binsx; ++i) + for (unsigned int j(0); j <= binsz; ++j) + if (histogram->GetBinContent(i,binsy,j) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has OverFlows Y"); + return new dqm_core::Result(dqm_core::Result::Red); + } + for (unsigned int i(0); i <= binsz; ++i) + for (unsigned int j(0); j <= binsy; ++j) + if (histogram->GetBinContent(binsx,j,i) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has OverFlows X"); + return new dqm_core::Result(dqm_core::Result::Red); + } + break; + default: + throw dqm_core::BadConfig( ERS_HERE, name, "Something is wrong with the Dimension of the Histogram"); + } + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" does NOT have OverFlows"); + return new dqm_core::Result(dqm_core::Result::Green); + }else if (name_ == "No_UnderFlows") { + const unsigned int binsx = histogram->GetNbinsX()+1; + const unsigned int binsy = histogram->GetNbinsY()+1; + const unsigned int binsz = histogram->GetNbinsZ()+1; + switch (histogram->GetDimension()){ + case 1: + if (histogram->GetBinContent(0) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has UnderFlows X"); + return new dqm_core::Result(dqm_core::Result::Red); + } + break; + case 2: + for (unsigned int i(0); i <= binsx; ++i) + if (histogram->GetBinContent(i,0) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has UnderFlows Y"); + return new dqm_core::Result(dqm_core::Result::Red); + } + for (unsigned int i(0); i <= binsy; ++i) + if (histogram->GetBinContent(0,i) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has UnderFlows X"); + return new dqm_core::Result(dqm_core::Result::Red); + } + break; + case 3: + for (unsigned int i(0); i <= binsx; ++i) + for (unsigned int j(0); j <= binsy; ++j) + if (histogram->GetBinContent(i,j,0) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has UnderFlows Z"); + return new dqm_core::Result(dqm_core::Result::Red); + } + for (unsigned int i(0); i <= binsx; ++i) + for (unsigned int j(0); j <= binsz; ++j) + if (histogram->GetBinContent(i,0,j) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has UnderFlows Y"); + return new dqm_core::Result(dqm_core::Result::Red); + } + for (unsigned int i(0); i <= binsz; ++i) + for (unsigned int j(0); j <= binsy; ++j) + if (histogram->GetBinContent(0,j,i) != 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has UnderFlows X"); + return new dqm_core::Result(dqm_core::Result::Red); + } + break; + default: + throw dqm_core::BadConfig( ERS_HERE, name, "Something is wrong with the Dimension of the Histogram"); + } + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" does NOT have UnderFlows"); + return new dqm_core::Result(dqm_core::Result::Green); + } else if ( name_ == "All_Bins_Filled" ) { + const unsigned int binsx = histogram->GetNbinsX(); + const unsigned int binsy = histogram->GetNbinsY(); + const unsigned int binsz = histogram->GetNbinsZ(); + for ( unsigned int i(1); i <= binsx; ++i ) { + for ( unsigned int j(1); j <= binsy; ++j ) { + for ( unsigned int k(1); k<= binsz; ++k ) { + double content= histogram -> GetBinContent(i,j); + if ( content == 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has empty bins"); + return new dqm_core::Result(dqm_core::Result::Red); + } + } + } + } + + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has all filled bins"); + return new dqm_core::Result(dqm_core::Result::Green); + + + } else if (name_ == "Histogram_Empty") { + if (histogram->GetEntries() == 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Empty"); + return new dqm_core::Result(dqm_core::Result::Green); + }else { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Not Empty"); + return new dqm_core::Result(dqm_core::Result::Red); + } + } else if (name_ == "Histogram_Effective_Empty") { + if (histogram->GetEffectiveEntries() == 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Empty"); + return new dqm_core::Result(dqm_core::Result::Green); + }else { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Not Empty"); + return new dqm_core::Result(dqm_core::Result::Red); + } + + + } else { + return new dqm_core::Result(); + } + + +} + +void +dqm_algorithms::BasicHistoCheck::printDescription(std::ostream& out) +{ + if ( name_ == "All_Bins_Filled"){ + out<<"All_Bins_Filled: Checks that all bins of histogram are filled\n"<<std::endl; + } else if ( name_ == "Histogram_Not_Empty"){ + out<<"Histogram_Not_Empty: Checks that histogram is not empty\n"<<std::endl; + }else if ( name_ == "No_UnderFlows"){ + out<<"No_UnderFlows: Checks that histogram has no Underflows"<<std::endl; + }else if ( name_ == "No_OverFlows"){ + out<<"No_OverFlows: Checks that histogram has no Overflows"<<std::endl; + + + } else if ( name_ == "Histogram_Empty"){ + out<<"Histogram_Empty: Checks that histogram is empty\n"<<std::endl; + } else if ( name_ == "Histogram_Effective_Empty"){ + out<<"Histogram_Not_Empty:\tChecks that histogram has no effective entries\n\t\t\t(see ROOT doc -> TH1 -> GetEffectiveEntries())\n"<<std::endl; + } + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/src/BasicHistoCheckModuleStatus.cxx b/DataQuality/dqm_algorithms/src/BasicHistoCheckModuleStatus.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6116068798bc5b1348c30bf3b291fe109847ed58 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BasicHistoCheckModuleStatus.cxx @@ -0,0 +1,119 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicHistoCheck.cxx checks basic histogram quanitites like over/underflow; if filled and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BasicHistoCheckModuleStatus.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::BasicHistoCheckModuleStatus BinsFilled( "ModuleStatus_All_Bins_Filled" ); + +} + + +dqm_algorithms::BasicHistoCheckModuleStatus::BasicHistoCheckModuleStatus( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +dqm_algorithms::BasicHistoCheckModuleStatus * +dqm_algorithms::BasicHistoCheckModuleStatus::clone() +{ + + return new BasicHistoCheckModuleStatus( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::BasicHistoCheckModuleStatus::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 3 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 3 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + + + if ( name_ == "ModuleStatus_All_Bins_Filled" ) { + unsigned int nbinsX_filled = 0; + const unsigned int binsx = histogram->GetNbinsX(); + //const unsigned int binsy = histogram->GetNbinsY(); + //const unsigned int binsz = histogram->GetNbinsZ(); + for ( unsigned int i(1); i <= binsx; ++i ) { + //for ( unsigned int j(1); j <= binsy; ++j ) { + //for ( unsigned int k(1); k<= binsz; ++k ) { + double content= histogram -> GetBinContent(i); + if ( content == 0) { + // ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has empty bins"); +// return new dqm_core::Result(dqm_core::Result::Red); + + nbinsX_filled++; + } + + } + + if(histogram->GetEffectiveEntries() == 0){ + + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" does not have all filled bins"); + return new dqm_core::Result(dqm_core::Result::Disabled); + + } + + + if(nbinsX_filled >0 && nbinsX_filled < binsx){ + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has empty bins"); + return new dqm_core::Result(dqm_core::Result::Red); + } + + + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" has all filled bins"); + return new dqm_core::Result(dqm_core::Result::Green); + + } + + else { + return new dqm_core::Result(); + } + + +} + +void +dqm_algorithms::BasicHistoCheckModuleStatus::printDescription(std::ostream& out) +{ + if ( name_ == "All_Bins_Filled"){ + out<<"All_Bins_Filled: Checks that all bins of histogram are filled\n"<<std::endl; + } + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/src/BasicStatCheck.cxx b/DataQuality/dqm_algorithms/src/BasicStatCheck.cxx new file mode 100644 index 0000000000000000000000000000000000000000..cda82fec1fde0e7c7534c1d021c2cc6d914e3701 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BasicStatCheck.cxx @@ -0,0 +1,126 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BasicStatCheck.cxx checks basic histogram quanitites like over/underflow; if filled and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BasicStatCheck.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <ers/ers.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> + + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::BasicStatCheck Mean ( "Mean" ); + dqm_algorithms::BasicStatCheck RMS ( "RMS" ); +} + + +dqm_algorithms::BasicStatCheck::BasicStatCheck( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("CheckHisto_"+name, this); +} + +dqm_algorithms::BasicStatCheck * +dqm_algorithms::BasicStatCheck::clone() +{ + + return new BasicStatCheck( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::BasicStatCheck::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const double subtractfromxmean = dqm_algorithms::tools::GetFirstFromMap( "SubtractFromXMean", config.getParameters(), 0); + const double subtractfromymean = dqm_algorithms::tools::GetFirstFromMap( "SubtractFromYMean", config.getParameters(), 0); + const unsigned int publishType = static_cast<unsigned int>(dqm_algorithms::tools::GetFirstFromMap( "PublishType", config.getParameters(), 3)); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + histogram->GetXaxis()->SetRange(range[0], range[1]); + histogram->GetYaxis()->SetRange(range[2], range[3]); + + std::map<std::string, double> params; + if (name_ == "Mean") { + params["XMean"]=histogram->GetMean(1) - subtractfromxmean; + params["YMean"]=histogram->GetMean(2) - subtractfromymean; + ERS_DEBUG(1,"XMean Value " <<histogram->GetMean(1)<<" YMean Value " <<histogram->GetMean(2)); + } else if (name_ == "RMS" ) { + params["XRMS"]=histogram->GetRMS(1); + params["YRMS"]=histogram->GetRMS(2); + ERS_DEBUG(1,"XRMS Value " <<histogram->GetRMS(1)<<" YRMS Value "<<histogram->GetRMS(2)); + }else { + return new dqm_core::Result(); + } + + dqm_core::Result* result; + + try { + result = dqm_algorithms::tools::MakeComparisons(params, config.getGreenThresholds(), config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + if (name_ == "Mean") { + if (publishType & 0x01) result->tags_["XMean"] = params["XMean"]; + if (publishType & 0x02) result->tags_["YMean"] = params["YMean"]; + } else if (name_ == "RMS") { + if (publishType & 0x01) result->tags_["XRMS"] = params["XRMS"]; + if (publishType & 0x02) result->tags_["YRMS"] = params["YRMS"]; + } + + return result; +} + +void +dqm_algorithms::BasicStatCheck::printDescription(std::ostream& out) +{ + if (name_ == "Mean") { + out<<"CheckHisto_Mean: Checks that X and Y Mean of histo are within specified thresholds\n"<<std::endl; + out<<"Green/Red Threshold: XMean or AbsXMean: X Mean value to give Green/Red result; AbsXMean checks the absolute value"<<std::endl; + out<<"Green/Red Threshold: YMean or AbsYMean: Y Mean value to give Green/Red result; AbsYMean checks the absolute value\n"<<std::endl; + }else if (name_ == "RMS"){ + out<<"CheckHisto_RMS: Checks that X and Y RMS of histo are within specified thresholds\n"<<std::endl; + out<<"Green/Red Threshold: XRMS: X RMS value to give Green/Red result"<<std::endl; + out<<"Green/Red Threshold: YRMS: Y RMS value to give Green/Red result\n"<<std::endl; + } + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: ymin: minimum y range"<<std::endl; + out<<"Optional Parameter: ymax: maximum y range"<<std::endl; + out<<"Optional Parameter: SubtractFromXMean: value subtracted from XMean before test is applied: allows using AbsXMean for non-zero expected mean"<<std::endl; + out<<"Optional Parameter: SubtractFromYMean: value subtracted from YMean before test is applied: allows using AbsYMean for non-zero expected mean"<<std::endl; + out<<"Optional Parameter: PublishType: 0 = publish no results, 1 = publish X result, 2 = publish Y result, 3 = publish both results (default)."<<std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/BinContentComp.cxx b/DataQuality/dqm_algorithms/src/BinContentComp.cxx new file mode 100644 index 0000000000000000000000000000000000000000..33a911d0d00deb791c37f3aca76e2399f3c4b8df --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinContentComp.cxx @@ -0,0 +1,253 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinContentComp.cxx compares bins of histogram wrt to reference histogram and counts number of bins N Sigma away from ref; returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinContentComp.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> +#include <ers/ers.h> + + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::BinContentComp myInstance; + + +dqm_algorithms::BinContentComp::BinContentComp() +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( "BinContentComp", this ); +} + +dqm_algorithms::BinContentComp::~BinContentComp() +{ +} + +dqm_algorithms::BinContentComp * +dqm_algorithms::BinContentComp::clone() +{ + return new BinContentComp(); +} + + +dqm_core::Result * +dqm_algorithms::BinContentComp::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + TH1 * refhist; + + if(object.IsA()->InheritsFrom( "TH1" )) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1"); + } + + double value=-99999; + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch (dqm_core::BadConfig &ex ) { + refhist=0; + try { + value = dqm_algorithms::tools::GetFirstFromMap( "Value", config.getParameters() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + } + if ( ! refhist ) { + try { + value = dqm_algorithms::tools::GetFirstFromMap( "Value", config.getParameters() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + } else { + + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Dimension" ); + } + + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } +} + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + const bool ignorezero = (bool) dqm_algorithms::tools::GetFirstFromMap( "Ignore0", config.getParameters(), 0); + bool greaterthan = (bool) dqm_algorithms::tools::GetFirstFromMap( "GreaterThan", config.getParameters(), 0); + bool lessthan = (bool) dqm_algorithms::tools::GetFirstFromMap( "LessThan", config.getParameters(), 0); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0); + const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const bool normref = (bool) dqm_algorithms::tools::GetFirstFromMap( "NormRef", config.getParameters(), 0); + const double maxdiffabs = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffAbs", config.getParameters(), -1); + const double maxdiffrel = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffRel", config.getParameters(), -1); + const double fixerr = dqm_algorithms::tools::GetFirstFromMap( "FixedError", config.getParameters(), 0); + const bool increferr = (bool) dqm_algorithms::tools::GetFirstFromMap( "IncludeRefError", config.getParameters(), 0); + + if (greaterthan && lessthan) { + ERS_INFO("Both GreaterThan and LessThan parameters set: Will check for for both"); + greaterthan = false; + lessthan = false; + } + + double bin_threshold; + double gthreshold; + double rthreshold; + try { + bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "NSigma", config.getParameters() ); + rthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + int count = 0; + + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + + dqm_core::Result* result = new dqm_core::Result(); + double refcont =0; + TH1* resulthisto; + if (histogram->InheritsFrom("TH2")) { + resulthisto=(TH1*)(histogram->Clone()); + } else if (histogram->InheritsFrom("TH1")) { + resulthisto=(TH1*)(histogram->Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + resulthisto->Reset(); + + if (refhist && normref) { + double ratio=histogram->GetEntries()/refhist->GetEntries(); + refhist->Scale(ratio); + } + + for ( int i = range[0]; i <= range[1]; ++i ) { + for ( int j = range[2]; j <= range[3]; ++j ) { + if ( ! refhist ){ + refcont=value; + } else { + refcont = refhist->GetBinContent(i,j); + } + + double histerr = histogram->GetBinError(i,j); + double inputerr=0; + + + if (increferr && refhist ) { + double referr = refhist->GetBinError(i,j); + inputerr = sqrt(pow(histerr,2)+pow(referr,2)); + } else { + inputerr = histerr; + } + + if (fixerr) { + inputerr = fixerr; + } + + double inputcont = histogram->GetBinContent(i,j); + double diff=inputcont - refcont; + double reldiff=1; + if(refcont!=0) reldiff=diff/refcont; + else if(diff==0) reldiff=0; + if (ignorezero && refcont==0) continue; + if (inputerr !=0){ + double sigma=diff/inputerr; + if (greaterthan && diff < 0. ) continue; + if (lessthan && diff > 0. ) continue; + + if ( (fabs(sigma) > bin_threshold) && (fabs(diff) > maxdiffabs) && (fabs(reldiff) > maxdiffrel) ){ + resulthisto->SetBinContent(i,j,inputcont); + ++count; + if (publish && count<maxpublish){ + dqm_algorithms::tools::PublishBin(histogram,i,j,inputcont,result); + } + } + } + } + } + + if (value == -99999) { + ERS_DEBUG(1, "Number of bins " << bin_threshold << " Sigma away from reference is " << count); + }else { + ERS_DEBUG(1, "Number of bins " << bin_threshold << " Sigma away from "<<value<<" is " << count); + } + + ERS_DEBUG(1, "Green threshold: "<< gthreshold << " bin(s); Red threshold : " << rthreshold << " bin(s) "); + + + result->tags_["NBins"] = count; + result->object_ = (std::auto_ptr<TObject>)(TObject*)(resulthisto); + + if (gthreshold > rthreshold) { + if ( count >= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } else { + if ( count <= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count < rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } + return result; + +} +void +dqm_algorithms::BinContentComp::printDescription(std::ostream& out) +{ + + out<<"BinContentComp: Checks number of bins N sigma away from reference histogram bin value or given Value\n"<<std::endl; + + out<<"Mandatory Parameter: NSigma: Number of sigma each bin must be within reference histogram value\n"<<std::endl; + out<<"Mandatory Parameter (If no reference): Value: Value to compare each bin\n"<<std::endl; + + + out<<"Mandatory Green/Red Threshold: NBins: number of bins N sigma away from reference histogram bin to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: Ignore0: Ignore bins which have zero entries in reference histogram"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: ymin: minimum y range"<<std::endl; + out<<"Optional Parameter: ymax: maximum y range\n"<<std::endl; + out<<"Optional Parameter: GreaterThan: check only for bins which are GreaterThan average (set to 1)"<<std::endl; + out<<"Optional Parameter: LessThan: check only for bins which are LessThan average (set to 1)"<<std::endl; + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (set to 1)"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: NormRef: Normalize reference histogram to checked histogram statistics before checking bin contents (set to 1)"<<std::endl; + out<<"Optional Parameter: MaxDiffAbs: test fails if NBins more than NSigma away and NBins more than MaxDiffAbs (absolut difference) away"<<std::endl; + out<<"Optional Parameter: MaxDiffRel: test fails if NBins more than NSigma away and NBins more than MaxDiffRel (relative difference) away\n"<<std::endl; + out<<"Optional Parameter: FixedError: override the histogram errors with this value"<<std::endl; + out<<"Optional Parameter: IncludeRefError: use both the histogram and reference histogram errors in calculation"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/BinContentDump.cxx b/DataQuality/dqm_algorithms/src/BinContentDump.cxx new file mode 100644 index 0000000000000000000000000000000000000000..579c22b3d2c3a24cfa6bf08abe8251b8350f5ca7 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinContentDump.cxx @@ -0,0 +1,88 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinContentDump.cxx dumps contents of all bins in a histogram (preferably char labeled TH1). Method to store quantities in db; returns dqm_core::Result + * \author Justin Griffiths + */ + +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_algorithms/BinContentDump.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "TH1.h" +#include "TClass.h" +#include "ers/ers.h" + +#include <string> +#include <sstream> + +static dqm_algorithms::BinContentDump myInstance; + +dqm_algorithms::BinContentDump::BinContentDump() +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BinContentDump", this); +} + +dqm_algorithms::BinContentDump::~BinContentDump() +{ +} + +dqm_algorithms::BinContentDump *dqm_algorithms::BinContentDump::clone() +{ + return new BinContentDump(); +} + +dqm_core::Result *dqm_algorithms::BinContentDump::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + TH1 *histogram; + + if (object.IsA()->InheritsFrom("TH1")) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2"); + } + } else { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), -1); + const unsigned int publishType = static_cast<unsigned int>(dqm_algorithms::tools::GetFirstFromMap("PublishType", config.getParameters(), 1)); + // const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap("MaxPublish", config.getParameters(), 20); + + if (histogram->GetEntries() < minstat) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Green); + + for (int i = 1; i <= histogram->GetNbinsX(); ++i) { + const double binContent = histogram->GetBinContent(i); + const double binError = histogram->GetBinError(i); + std::string label = histogram->GetXaxis()->GetBinLabel(i); + + // Check if user has defined a minimum value on this bin + const double undefined = -99999; + const double binThreshold = dqm_algorithms::tools::GetFirstFromMap(label.c_str(), config.getParameters(), undefined); + if ((binThreshold != undefined) && (binContent < binThreshold)) result->status_ = dqm_core::Result::Red; + + if (label.empty()) { + std::ostringstream oss; + oss << "Bin_" << i; + label = oss.str(); + } + + if (publishType & 0x01) result->tags_[label] = binContent; + if (publishType & 0x02) result->tags_[label + "Error"] = binError; + } + return result; +} +void dqm_algorithms::BinContentDump::printDescription(std::ostream& out) +{ + out << "BinContentDump: Dumps the contents of all bins, labelled either with their bin label or with \"Bin_N\". Returns green status.\n" + "Optional parameters: <label>: The bin with this label must be greater than the given value, otherwise the algorithm returns red status.\n" + "Optional parameter: PublishType: What to publish. 0 = nothing, 1 = bin contents (default), 2 = bin errors, 3 = both\n" + "Thresholds: None." << std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/BinDump.cxx b/DataQuality/dqm_algorithms/src/BinDump.cxx new file mode 100644 index 0000000000000000000000000000000000000000..27d5b6a709ad547912ed34c2b9ee546593410364 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinDump.cxx @@ -0,0 +1,221 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: BinDump.cxx,v 1.2 2009/02/07 09:37:17 Remi Lafaye +// ********************************************************************** + +#include "dqm_algorithms/BinDump.h" + +#include <cmath> +#include <iostream> +#include <map> +#include <algorithm> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "ers/ers.h" + + +static dqm_algorithms::BinDump staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +BinDump:: +BinDump() + : name("BinDump") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +BinDump:: +~BinDump() +{ +} + + +dqm_core::Algorithm* +BinDump:: +clone() +{ + return new BinDump(*this); +} + + +dqm_core::Result* +BinDump:: +execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + int binStart, binEnd; + int method; + double gmin; + double rmin; + try { + binStart = (int) dqm_algorithms::tools::GetFirstFromMap("BinStart", config.getParameters() ); + binEnd = (int) dqm_algorithms::tools::GetFirstFromMap("BinEnd", config.getParameters() ); + method = (int) dqm_algorithms::tools::GetFirstFromMap("Method", config.getParameters() ); + rmin = dqm_algorithms::tools::GetFromMap( "NEntries", config.getRedThresholds()); + gmin = dqm_algorithms::tools::GetFromMap( "NEntries", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + if (rmin < gmin) { + std::swap(rmin, gmin); + } + + double count = 0; + int nbinx = histogram -> GetNbinsX(); + int nbiny = histogram -> GetNbinsY(); + if(binStart>binEnd) { + binStart= 1; + binEnd = histogram -> GetNbinsX(); + } + int binSize = binEnd-binStart+1; + + std::vector<double> contents(binSize); + //contents.resize(binSize); + for(int i=0;i<binSize;i++) { + int binx = binStart+i; + contents[i]=0; + for ( int j = 1; j <= nbiny; ++j ) { + double content= histogram -> GetBinContent(binx,j); + contents[i]+=content; + count+=content; + } + } + + ERS_DEBUG(1,"Number of entries for bins is " +<< count ); + ERS_DEBUG(1,"Green: "<< gmin << " entries; Red: " << rmin << " entries "); + + + TAxis *axis = histogram->GetXaxis(); + dqm_core::Result* result = new dqm_core::Result(); + if(axis) { + for(int i=0;i<binSize;i++) { + char tag[256]; + const char *label; + if(binStart+i==0) sprintf(tag,"Underflows"); + else if(binStart+i==nbinx+1) sprintf(tag,"Overflows"); + else { + label=axis->GetBinLabel(binStart+i); + // remove space in names to help handy.py + if(label) { + int l=strlen(label); + int j=0; + + char *mylabel=new char[l+1]; + if(mylabel) { + for(int k=0;k<l;k++) + if(label[k]!=' ') mylabel[j++]=label[k]; + mylabel[j]='\0'; + if (mylabel[0]!=0) sprintf(tag,"%s",mylabel); + else sprintf(tag,"Bin%d",binStart+i); + delete[] mylabel; + } + else sprintf(tag,"Bin%d",binStart+i); + } + else sprintf(tag,"Bin%d",binStart+i); + } + result->tags_[tag] = contents[i]; + } + } else { + for(int i=0;i<binSize;i++) { + char tag[256]; + if(binStart+i==0) sprintf(tag,"Underflows"); + else if(binStart+i==nbinx+1) sprintf(tag,"Overflows"); + else sprintf(tag,"Bin%d",binStart+i); + result->tags_[tag] = contents[i]; + } + } + + if(method==0) { // Check on bin sums + if ( count <= gmin ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rmin ) { + result->status_ = dqm_core::Result::Red; + } else { + result->status_ = dqm_core::Result::Yellow; + } + result->tags_["Total"] = count; + } + else if(method>0) { // Check on maximum bin + count = 0; + for(int i=0;i<binSize;i++) { + if(contents[i]>count) count = contents[i]; + } + if ( count <= gmin ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rmin ) { + result->status_ = dqm_core::Result::Red; + } else { + result->status_ = dqm_core::Result::Yellow; + } + result->tags_["Highest"] = count; + } + else if(method<0) { // Check on minimum bin + count = 1e30; + for(int i=0;i<binSize;i++) { + if(contents[i]<count) count = contents[i]; + } + if ( count <= gmin ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rmin ) { + result->status_ = dqm_core::Result::Red; + } else { + result->status_ = dqm_core::Result::Yellow; + } + result->tags_["Lowest"] = count; + } + + return result; +} + + +void +BinDump:: +printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Check the number of entries in listed bins\n"; + message += "Parameters: BinStart first bin to be checked (0=underflows)\n"; + message += " BinEnd last bin to be checked (nbin+1=overflows)\n"; + message += " Method=0 check is performed on bin sum\n"; + message += " Method<0 check is performed on lowest bin\n"; + message += " Method>0 check is performed on highest bin\n"; + message += " Nentries Green/Red minimums"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/BinPrint.cxx b/DataQuality/dqm_algorithms/src/BinPrint.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3e2842d34053b84ea4fc0f8abbdbeabcfae0df56 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinPrint.cxx @@ -0,0 +1,395 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: BinPrint.cxx,v 1.3 2009-01-22 13:53:56 ponyisi Exp $ +// ********************************************************************** + +#include "dqm_algorithms/BinPrint.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TH1.h> +#include <TClass.h> + +#include "dqm_core/exceptions.h" +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/Result.h" + +static dqm_algorithms::BinPrint staticInstance; + +namespace dqm_algorithms { + + // ********************************************************************* + // Public Methods + // ********************************************************************* + + void + BinPrint:: + printDescription(std::ostream& out) + { + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Extracts bin contents from a TProfile, TH1, TH2 object without performing\n"; + message += " any assessment; the status is always \"Undefined\"\n"; + message += "Optional Parameter: UnMask_All Default = -1\n"; + message += " <0: Only unmask bins when Mask_## = 0\n"; + message += " >=0: Unmask all bins and only mask bins when Mask_## = 1\n"; + message += " # >= 0: Maximum number of bins printed is #\n"; + message += " This setting is combined so that large bin lists do not occur accidentaly.\n"; + message += "Optional Parameter: UseValue: Default = 0\n"; + message += " 0: Print all unmasked bins\n"; + message += " 1: Print bin contents >= Value\n"; + message += " >1: Print bin contents > Value\n"; + message += " -1: Print bin contents <= Value\n"; + message += " <-1: Print bin contents < Value\n"; + message += "Optional Parameter: Value:\n"; + message += "Optional Parameter: UseMaskValue: Default = 0\n"; + message += " 0: Mask no bins\n"; + message += " 1: Change Mask for all >= MaskValue\n"; + message += " >1: Change Mask for all > Mask Value\n"; + message += " -1: Change Mask for all <= MaskValue\n"; + message += " <-1: Change Mask for all < Mask Value\n"; + message += " NOTE: The same boundaries apply to the mask\n"; + message += "Optional Parameter: MaskValue:\n"; + message += " Example of Printing values from 0. <= x <= 1.\n"; + message += " UseValue = 1\n"; + message += " Value = 0. ## x >= 0.\n"; + message += " UseMaskValue = 2\n"; + message += " MaskValue = 1. ## x <= 1.\n"; + message += " Example of Printing values outside of the range above\n"; + message += " UseValue = 2\n"; + message += " Value = 1.\n"; + message += " ## By Value Only: x > 1.0\n"; + message += " UseMaskValue = -2\n"; + message += " MaskValue = 0.\n"; + message += " ## Including Mask: x < 0.0\n"; + message += "Optional Parameter: TypeValue: Default = 0\n"; + message += " 0: Value is compared to total entries in bin\n"; + message += " 1: Value is compared to fraction of entries in histogram appearing in bin\n"; + message += " This also determines how the bin contents will be listed if published.\n"; + message += "1D Histogram Configuration:\n"; + message += "Optional Parameters: Mask_#\n"; + message += " 0: UnMask bin\n"; + message += " 1: Mask bin\n"; + message += " Example of Printing all but the first bin\n"; + message += " ***In algorithm declaration\n"; + message += " UnMask_All = 3\n"; + message += " Mask_1 = 1\n"; + message += "2D Histogram Configuration:\n"; + message += "Optional Parameters: Mask_#_#\n"; + message += " 0: UnMask bin\n"; + message += " 1: Mask bin\n"; + message += " Example of masking the X = 1, Y = 2 bin:\n"; + message += " ***In algorithm declaration\n"; + message += " UnMask_All = 3\n"; + message += " Mask_1_2 = 1\n"; + message += "\n"; + message += "Optional Parameters: PrintError\n"; + message += " 1: Print Corresponding Bin Error\n"; + + out << message; + } + + BinPrint:: + BinPrint() + : name("BinPrint") + , NbinsX(-1) + , NbinsY(-1) + , UnMask_All(-1) + , UseValue(0) + + { + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); + } + + + BinPrint:: + ~BinPrint() + { + } + + + dqm_core::Algorithm* + BinPrint:: + clone() + { + return new BinPrint(*this); + } + + + dqm_core::Result* + BinPrint:: + execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config) + { + //No status flags are set + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Undefined; + //Histogram dimension default = no dimensions + NbinsX = -1; + NbinsY = -1; + + if (!data.IsA()->InheritsFrom("TH1")) { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + TH1* h = (TH1*)&data; // h cannot be null + if (h->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2 "); + } + + //Get optional parameters + int Npublished = 0; + UseValue = UseValue_GetFromMap(config.getParameters()); + TypeValue = TypeValue_GetFromMap(config.getParameters()); + Value = Value_GetFromMap(config.getParameters()); + UseMaskValue = UseMaskValue_GetFromMap(config.getParameters()); + MaskValue = MaskValue_GetFromMap(config.getParameters()); + const int Error = (int) dqm_algorithms::tools::GetFirstFromMap( "PrintError", config.getParameters(), 0); + //out<<Error<<"Error"<<std::endl; + //********** + // 1D Histogram case + //********** + if (h->GetDimension() == 1) { + NbinsX = h->GetNbinsX(); + + //Get bin mask + std::vector<bool> Mask; + Mask = Mask1D_GetFromMap(config.getParameters()); + + //Rescale Value if fractional definition is used + double h_entries = h->GetEntries(); + if ( TypeValue > 0.5 ) Value = Value * h_entries; + + //Check all bins + for (int bin = 0; bin < NbinsX; bin++) { + double bincon = h->GetBinContent(bin + 1); + double ebincon = h->GetBinError(bin + 1); + //out<<"here"<<Mask[bin]<<std::endl; + //if( !Mask[bin] ) { + if( Mask[bin] ) { + bool do_printbin = false; + if(UseValue == 0) do_printbin = true; + if( (UseValue == 1 && bincon >= Value) || + (UseValue > 1 && bincon > Value) || + (UseValue == -1 && bincon <= Value) || + (UseValue < -1 && bincon < Value) + ) do_printbin = true; + if( (UseMaskValue == 1 && bincon >= MaskValue) || + (UseMaskValue > 1 && bincon > MaskValue) || + (UseMaskValue == -1 && bincon <= MaskValue) || + (UseMaskValue < -1 && bincon < MaskValue) + ) do_printbin = ! do_printbin; + if(do_printbin) { + //out<<"bin with name " << bincon<<std::endl; + Npublished++; + if ( UnMask_All < 0 || + Npublished <= UnMask_All ) { + double binvalX = h->GetXaxis()->GetBinCenter(bin + 1); + std::string binname = Form("%s_Bin(%u | %.*e)", name.c_str(), bin, 2, binvalX); + std::string sigbinname = Form("%s_EBin(%u | %.*e)", name.c_str(), bin, 2, binvalX); + //ERS_DEBUG(1, "bin with name " << binname <<" and value "<< bincon); + //out<<"bin with name " << binname <<" and value "<< bincon<<std::endl; + //out<<"bin with name " << sigbinname <<" and value "<< ebincon<<std::endl; + //From() ~ printf() (s ~ string, u ~ unsigned int, .*e ~ scientific) + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + if (Error ==1 ) result->tags_[sigbinname.c_str()] = ebincon ; + } else { + result->tags_[binname.c_str()] = bincon; + if (Error ==1 ) result->tags_[sigbinname.c_str()] = ebincon ; + } + } + } + } + } + } + + //********** + // 2D Histogram case + //********** + if (h->GetDimension() == 2) { + NbinsX = h->GetNbinsX(); + NbinsY = h->GetNbinsY(); + + //Get bin mask + std::vector< std::vector<bool> > Mask; + Mask = Mask2D_GetFromMap(config.getParameters()); + + //Rescale Value if fractional definition is used + double h_entries = h->GetEntries(); + if ( TypeValue > 0.5 ) Value = Value * h_entries; + + //Check all bins + for (int binX = 0; binX < NbinsX; binX++) { + for (int binY = 0; binY < NbinsY; binY++) { + double bincon = h->GetBinContent(binX + 1, binY + 1); + double ebincon = h->GetBinError(binX + 1, binY + 1); + if( !Mask[binX][binY] ) { + bool do_printbin = false; + if(UseValue == 0) do_printbin = true; + if( (UseValue == 1 && bincon >= Value) || + (UseValue > 1 && bincon > Value) || + (UseValue == -1 && bincon <= Value) || + (UseValue < -1 && bincon < Value) + ) do_printbin = true; + if( (UseMaskValue == 1 && bincon >= MaskValue) || + (UseMaskValue > 1 && bincon > MaskValue) || + (UseMaskValue == -1 && bincon <= MaskValue) || + (UseMaskValue < -1 && bincon < MaskValue) + ) do_printbin = ! do_printbin; + if(do_printbin) { + Npublished++; + if ( UnMask_All < 0 || + Npublished <= UnMask_All ) { + double binvalX = h->GetXaxis()->GetBinCenter(binX + 1); + double binvalY = h->GetYaxis()->GetBinCenter(binY + 1); + std::string binname = Form("%s_Bin((%u,%u) | %.*e,%.*e)", name.c_str(), binX, binY, 2, binvalX, 2, binvalY); + std::string sigbinname = Form("%s_EBin((%u,%u) | %.*e,%.*e)", name.c_str(), binX, binY, 2, binvalX, 2, binvalY); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + result->tags_[sigbinname.c_str()] = ebincon; + } else { + } + result->tags_[binname.c_str()] = bincon; + result->tags_[sigbinname.c_str()] = ebincon; + } + } + } + } + } + } + + //Append statement if all warnings or errors were not printed + if ( UnMask_All >= 0 && + Npublished > UnMask_All ) { + std::string pub_excess = Form("%s_PROBLEM_Publishable_UnPrinted",name.c_str()); + result->tags_[pub_excess.c_str()] = Npublished - UnMask_All; + } + + return result; + } + + + // ********************************************************************* + // Protected Methods + // ********************************************************************* + + int BinPrint::UseValue_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("UseValue"); + if ( it != params.end() ){ + return((int) it->second); + } else { + return(0); + } + } + + int BinPrint::TypeValue_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("TypeValue"); + if ( it != params.end() ){ + return((int) it->second); + } else { + return(0); + } + } + + double BinPrint::Value_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("Value"); + if ( it != params.end() ){ + return(it->second); + } else { + return(0.0); + } + } + + int BinPrint::UseMaskValue_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("UseMaskValue"); + if ( it != params.end() ){ + return((int) it->second); + } else { + return(0); + } + } + + double BinPrint::MaskValue_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("MaskValue"); + if ( it != params.end() ){ + return(it->second); + } else { + return(0.0); + } + } + + std::vector<bool> BinPrint::Mask1D_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator mask_map_bin; + + //Make default mask + bool default_Mask = true; + UnMask_All = -1; + //Get UnMask_All configuration + mask_map_bin = params.find("UnMask_All"); + if ( mask_map_bin != params.end() ) { + if(mask_map_bin->second > 0.5) { + UnMask_All = (int) mask_map_bin->second; + default_Mask = false; + } + } + std::vector<bool> Mask(NbinsX, default_Mask); + + //Get specific mask settings + for ( int bin = 0; bin < NbinsX; bin++ ) { + std::string mask_bin = Form("Mask_%d", bin + 1); + mask_map_bin = params.find(mask_bin.c_str()); + if ( mask_map_bin != params.end() ) { + if(mask_map_bin->second > 0.5) Mask[bin] = true; + else Mask[bin] = false; + } + } + + return(Mask); + } + + std::vector< std::vector<bool> > BinPrint::Mask2D_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator mask_map_bin; + + //Make default mask + bool default_Mask = true; + UnMask_All = -1; + //Get UnMask_All configuration + mask_map_bin = params.find("UnMask_All"); + if ( mask_map_bin != params.end() ) { + if(mask_map_bin->second > 0.5) { + UnMask_All = (int) mask_map_bin->second; + default_Mask = false; + } + } + std::vector< std::vector<bool> > Mask(NbinsX, std::vector<bool>(NbinsY, default_Mask)); + + //Get specific mask settings + for ( int binX = 0; binX < NbinsX; binX++ ) { + for ( int binY = 0; binY < NbinsY; binY++ ) { + std::string mask_bin = Form("Mask_%d_%d", binX + 1, binY + 1); + mask_map_bin = params.find(mask_bin.c_str()); + if ( mask_map_bin != params.end() ) { + if(mask_map_bin->second > 0.5) Mask[binX][binY] = true; + else Mask[binX][binY] = false; + } + } + } + + return(Mask); + } + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/BinThresh.cxx b/DataQuality/dqm_algorithms/src/BinThresh.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d2af82344d224ea627f817f9cb57be65246226fa --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinThresh.cxx @@ -0,0 +1,660 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_algorithms/BinThresh.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TH1.h> +#include <TProfile.h> +#include <TClass.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/Result.h" + +static dqm_algorithms::BinThresh staticInstance; + +namespace dqm_algorithms { + + // ********************************************************************* + // Public Methods + // ********************************************************************* + + void + BinThresh:: + printDescription(std::ostream& out) + { + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Defines a warning and an error threshold for individual bins.\n"; + message += " The status is the worst case summary of individual bin comparisons.\n"; + message += " Some of the parameter names depend on whether the histogram is 1D or 2D.\n"; + message += "Mandatory Parameter: UseValue:\n"; + message += " 1: Flag bin contents >= Value\n"; + message += " >1: Flag bin contents > Value\n"; + message += " -1: Flag bin contents <= Value\n"; + message += " <-1: Flag bin contents < Value\n"; + message += "Mandatory Parameter: TypeValue:\n"; + message += " 0: Value is compared to total entries in bin\n"; + message += " 1: Value is compared to fraction of entries in histogram appearing in bin\n"; + message += " This also determines how the bin contents will be listed if published.\n"; + message += "Optional Parameter: Publish: Default = -1\n"; + message += " -1: Print no values\n"; + message += " 0: Print the number of bins exceeding their threshold\n"; + message += " # > 0: Print bins exceeding their thresholds individually\n"; + message += " At most # bins are printed, and the excess is also listed\n"; + message += "Optional Parameter: TypePublish: Default = 0\n"; + message += " 0: Print only bins exceeding their error threshold Values\n"; + message += " 1: Print only bins exceeding their error or warning threshold Values\n"; + message += " 2: Print all unmasked bins\n"; + message += "Profile Configuration:\n"; + message += "Optional Parameter: BinMinEntries: Default = 0\n"; + message += " Minimum number of entries in a TProfile (1D only) for a bin to be checked against thresolds\n"; + message += " If a bin does not have a sufficient number of entries it also will not be printed\n"; + message += "1D Histogram Configuration:\n"; + message += "Limits: Value_#\n"; + message += " Arguments are given for individual bins.\n"; + message += " To make a single threshold check, set Warning:Value == Error:Value\n"; + message += " Example of asserting the thresholds for a 3 bin histogram with the 2nd bin masked\n"; + message += " ***In thresholds declaration:\n"; + message += " limits Value_1 {\n"; + message += " warning = 0.0\n"; + message += " error = 0.5\n"; + message += " }\n"; + message += " limits Value_3 {\n"; + message += " warning = 2.0\n"; + message += " error = 2.5\n"; + message += " }\n"; + message += "Limits: Value_All\n"; + message += " Unmasks and sets thresholds uniformly for all bins.\n"; + message += " Example of alternative declaration of the 3 bins histogram thresholds and masking above:\n"; + message += " ***In algorithm declaration\n"; + message += " Mask_2 = 1\n"; + message += " ***In thresholds declaration:\n"; + message += " limits Value_All {\n"; + message += " warning = 0.0\n"; + message += " error = 0.5\n"; + message += " }\n"; + message += " limits Value_3 {\n"; + message += " warning = 2.0\n"; + message += " error = 2.5\n"; + message += " }\n"; + message += "Optional Parameters: Mask_# Default = See Note below.\n"; + message += " 1: Mask bin\n"; + message += "2D Histogram Configuration:\n"; + message += "Limits: Value_#_#\n"; + message += " Arguments are given for individual bins.\n"; + message += " Example of setting the X = 1, Y = 2 bin thresholds:\n"; + message += " ***In thresholds declaration:\n"; + message += " limits Value_1_2 {\n"; + message += " warning = 2.0\n"; + message += " error = 2.5\n"; + message += " }\n"; + message += "Optional Parameters: Mask_#_# Default = See Note below.\n"; + message += " 1: Mask bin\n"; + message += " Example of masking the X = 1, Y = 2 bin:\n"; + message += " ***In algorithm declaration\n"; + message += " Mask_1_2 = 1\n"; + message += "Note Mask_## = 1 has precedence over the unmasking from a Value_## declaration\n"; + message += "and that Value_## settings take precedence over the Value_All settings.\n"; + message += "The un-masking option Mask_## = 0 is ignored in order to avoid unmasking an unconfigured bin."; + + out << message << std::endl; + } + + BinThresh:: + BinThresh() + : name("BinThresh") + , NbinsX(-1) + , NbinsY(-1) + { + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); + + //NOTE: name will yield the entire directory structure + //leading up to the algorithm instance. + //This directory structure is used by other features such as result->tag. + } + + + BinThresh:: + ~BinThresh() + { + } + + + dqm_core::Algorithm* + BinThresh:: + clone() + { + return new BinThresh(*this); + } + + + dqm_core::Result* + BinThresh:: + execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config) + { + dqm_core::Result* result = new dqm_core::Result(); + + //Worst Case Summary default = Good + int NWarnings = 0; + int NErrors = 0; + int NGoodPrint = 0; + //Histogram dimension default = no dimensions + NbinsX = -1; + NbinsY = -1; + + //Get data + if (!data.IsA()->InheritsFrom("TH1")) { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + TH1* h = (TH1*)&data; // h cannot be null + if (h->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2 "); + } + + //Get optional parameters + int Publish = Publish_GetFromMap(config.getParameters()); + int TypePublish = TypePublish_GetFromMap(config.getParameters()); + int BinMinEntries = BinMinEntries_GetFromMap(config.getParameters()); + + //Get mandatory parameters + int UseValue; + int TypeValue; + try { + UseValue = UseValue_GetFromMap(config.getParameters()); + TypeValue = TypeValue_GetFromMap(config.getParameters()); + } + catch (dqm_core::Exception & ex) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + if ( UseValue == 0 ) ERS_INFO("UseValue == 0 is meaningless"); + + //********** + // Profile case + //********** + if ( data.IsA()->InheritsFrom("TProfile") ) { + TProfile* hp = (TProfile*)&data; + //ASSUME: dimension = 1 + NbinsX = hp->GetNbinsX(); + + //Get threshold limits & masks + std::vector<BinThresh::mask_limits> Limits; + try { + Limits = Limits1D_GetFromMap(config.getParameters(), config.getGreenThresholds(), config.getRedThresholds()); + } + catch (dqm_core::Exception & ex) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + //CHECK + //Verify threshold limit consistencies + for(int bin = 0; bin < NbinsX; bin++) { + if ((UseValue > 0 && Limits[bin].WarningValue > Limits[bin].ErrorValue) || + (UseValue < 0 && Limits[bin].WarningValue < Limits[bin].ErrorValue)) { + //Masked thresholds might be used for a different algorithm configuration + if ( !Limits[bin].Mask ) { + std::string problem_message = Form("Incompatible Warning and Error Values in bin_%d : Warning = %e -> Error = %e", bin + 1, Limits[bin].WarningValue, Limits[bin].ErrorValue); + ERS_INFO(problem_message.c_str()); + } + } + } + + //Rescale Thresholds to test fractional distribution + double h_entries = hp->GetEntries(); + if ( TypeValue ) { + for (int bin = 0; bin < NbinsX; bin++) { + Limits[bin].WarningValue = Limits[bin].WarningValue * h_entries; + Limits[bin].ErrorValue = Limits[bin].ErrorValue * h_entries; + } + } + + //Check all bins + for (int bin = 0; bin < NbinsX; bin++) { + double bincon = hp->GetBinContent(bin + 1); + if ( !Limits[bin].Mask && hp->GetBinEntries(bin + 1) >= BinMinEntries ) { + //Check for and Print errors + if ((UseValue == 1 && bincon >= Limits[bin].ErrorValue) || + (UseValue > 1 && bincon > Limits[bin].ErrorValue) || + (UseValue == -1 && bincon <= Limits[bin].ErrorValue) || + (UseValue < -1 && bincon < Limits[bin].ErrorValue) ) { + NErrors++; + if ( NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Errors + double binval = hp->GetXaxis()->GetBinCenter(bin + 1); + //Give bin number as well as bin center + //Use scientific notation (e) to be compatible with all axis scales + //Include 2 digits after decimal (.*, with *=2) so that partitions up to 1000 are covered. + //If using fractional thresholds, then print fractional values. + std::string binname = Form("%s_ErrorBin(%u | %.*e)", name.c_str(), bin, 2, binval); + //From() ~ printf() (s ~ string, u ~ unsigned int, .*e ~ scientific) + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + //Check for and Print warnings, if no Errors found + else if ((UseValue == 1 && bincon >= Limits[bin].WarningValue) || + (UseValue > 1 && bincon > Limits[bin].WarningValue) || + (UseValue == -1 && bincon <= Limits[bin].WarningValue) || + (UseValue < -1 && bincon < Limits[bin].WarningValue) ) { + NWarnings++; + if ( TypePublish >= 1 && NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Warnings + float binval = hp->GetXaxis()->GetBinCenter(bin + 1); + //Use scientific notation (e) to be compatible with all axis scales + //Include 2 digits after decimal (.*, with *=2) so that partitions up to 1000 are covered. + //If using fractional thresholds, then print fractional values. + std::string binname = Form("%s_WarningBin(%u | %.*e)", name.c_str(), bin, 2, binval); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + //Print remaining bins + else { + NGoodPrint++; + if ( TypePublish >= 2 && NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Good Bins + float binval = hp->GetXaxis()->GetBinCenter(bin + 1); + //Use scientific notation (e) to be compatible with all axis scales + //Include 2 digits after decimal (.*, with *=2) so that partitions up to 1000 are covered. + //If using fractional thresholds, then print fractional values. + std::string binname = Form("%s_GoodBin(%u | %.*e)", name.c_str(), bin, 2, binval); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + } + } + } + + //********** + // 1D Histogram case + //********** + if ( (! data.IsA()->InheritsFrom("TProfile")) && h->GetDimension() == 1 ) { + NbinsX = h->GetNbinsX(); + + //Get threshold limits & masks + std::vector<BinThresh::mask_limits> Limits; + try { + Limits = Limits1D_GetFromMap(config.getParameters(), config.getGreenThresholds(), config.getRedThresholds()); + } + catch (dqm_core::Exception & ex) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + //CHECK + //Verify threshold limit consistencies + for(int bin = 0; bin < NbinsX; bin++) { + if ((UseValue > 0 && Limits[bin].WarningValue > Limits[bin].ErrorValue) || + (UseValue < 0 && Limits[bin].WarningValue < Limits[bin].ErrorValue)) { + //Masked thresholds might be used for a different algorithm configuration + if ( !Limits[bin].Mask ) { + std::string problem_message = Form("Incompatible Warning and Error Values in bin_%d : Warning = %e -> Error = %e", bin + 1, Limits[bin].WarningValue, Limits[bin].ErrorValue); + ERS_INFO(problem_message.c_str()); + } + } + } + + //Rescale Thresholds to test fractional distribution + double h_entries = h->GetEntries(); + if ( TypeValue ) { + for (int bin = 0; bin < NbinsX; bin++) { + Limits[bin].WarningValue = Limits[bin].WarningValue * h_entries; + Limits[bin].ErrorValue = Limits[bin].ErrorValue * h_entries; + } + } + + //Check all bins + for (int bin = 0; bin < NbinsX; bin++) { + double bincon = h->GetBinContent(bin + 1); + if ( !Limits[bin].Mask ) { + //Check for and Print errors + if ((UseValue == 1 && bincon >= Limits[bin].ErrorValue) || + (UseValue > 1 && bincon > Limits[bin].ErrorValue) || + (UseValue == -1 && bincon <= Limits[bin].ErrorValue) || + (UseValue < -1 && bincon < Limits[bin].ErrorValue) ) { + NErrors++; + if ( NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Errors + double binval = h->GetXaxis()->GetBinCenter(bin + 1); + //Give bin number as well as bin center + //Use scientific notation (e) to be compatible with all axis scales + //Include 2 digits after decimal (.*, with *=2) so that partitions up to 1000 are covered. + //If using fractional thresholds, then print fractional values. + std::string binname = Form("%s_ErrorBin(%u | %.*e)", name.c_str(), bin, 2, binval); + //From() ~ printf() (s ~ string, u ~ unsigned int, .*e ~ scientific) + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + //Check for and Print warnings, if no Errors found + else if ((UseValue == 1 && bincon >= Limits[bin].WarningValue) || + (UseValue > 1 && bincon > Limits[bin].WarningValue) || + (UseValue == -1 && bincon <= Limits[bin].WarningValue) || + (UseValue < -1 && bincon < Limits[bin].WarningValue) ) { + NWarnings++; + if ( TypePublish >= 1 && NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Warnings + float binval = h->GetXaxis()->GetBinCenter(bin + 1); + //Use scientific notation (e) to be compatible with all axis scales + //Include 2 digits after decimal (.*, with *=2) so that partitions up to 1000 are covered. + //If using fractional thresholds, then print fractional values. + std::string binname = Form("%s_WarningBin(%u | %.*e)", name.c_str(), bin, 2, binval); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + //Print remaining bins + else { + NGoodPrint++; + if ( TypePublish >= 2 && NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Good Bins + float binval = h->GetXaxis()->GetBinCenter(bin + 1); + //Use scientific notation (e) to be compatible with all axis scales + //Include 2 digits after decimal (.*, with *=2) so that partitions up to 1000 are covered. + //If using fractional thresholds, then print fractional values. + std::string binname = Form("%s_GoodBin(%u | %.*e)", name.c_str(), bin, 2, binval); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + } + } + } + + //********** + // 2D Histogram case + //********** + if ( (! data.IsA()->InheritsFrom("TProfile")) && h->GetDimension() == 2 ) { + NbinsX = h->GetNbinsX(); + NbinsY = h->GetNbinsY(); + + //Get threshold limits & masks + std::vector< std::vector<BinThresh::mask_limits> > Limits; + try { + Limits = Limits2D_GetFromMap(config.getParameters(), config.getGreenThresholds(), config.getRedThresholds()); + } + catch (dqm_core::Exception & ex) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + //CHECK + //Verify threshold limit consistencies + for(int binX = 0; binX < NbinsX; binX++) { + for(int binY = 0; binY < NbinsY; binY++) { + if ( (UseValue > 0 && Limits[binX][binY].WarningValue > Limits[binX][binY].ErrorValue) || + (UseValue < 0 && Limits[binX][binY].WarningValue < Limits[binX][binY].ErrorValue)) { + //Masked thresholds might be used for a different algorithm configuration + if ( !Limits[binX][binY].Mask ) { + std::string problem_message = Form("Incompatible Warning and Error Values in bin_%d_%d : Warning = %e -> Error = %e", binX + 1, binY + 1, Limits[binX][binY].WarningValue, Limits[binX][binY].ErrorValue); + ERS_INFO(problem_message.c_str()); + } + } + }} + + //Rescale Thresholds to test fractional distribution + double h_entries = h->GetEntries(); + if ( TypeValue ) { + for (int binX = 0; binX < NbinsX; binX++) { + for (int binY = 0; binY < NbinsY; binY++) { + Limits[binX][binY].WarningValue = Limits[binX][binY].WarningValue * h_entries; + Limits[binX][binY].ErrorValue = Limits[binX][binY].ErrorValue * h_entries; + }} + } + + //Check all bins + for (int binX = 0; binX < NbinsX; binX++) { + for (int binY = 0; binY < NbinsY; binY++) { + double bincon = h->GetBinContent(binX + 1, binY + 1); + if ( !Limits[binX][binY].Mask ) { + //Check for and Print errors + if ( (UseValue == 1 && bincon >= Limits[binX][binY].ErrorValue) || + (UseValue > 1 && bincon > Limits[binX][binY].ErrorValue) || + (UseValue == -1 && bincon <= Limits[binX][binY].ErrorValue) || + (UseValue < -1 && bincon < Limits[binX][binY].ErrorValue) ) { + NErrors++; + if ( NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Errors + float binvalX = h->GetXaxis()->GetBinCenter(binX + 1); + float binvalY = h->GetYaxis()->GetBinCenter(binY + 1); + std::string binname = Form("%s_ErrorBin((%u,%u) | %.*e,%.*e)", name.c_str(), binX, binY, 2, binvalX, 2, binvalY); + //From() ~ printf() (s ~ string, u ~ unsigned int, .*e ~ scientific) + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + //Check for and Print warnings + else if ( (UseValue == 1 && bincon >= Limits[binX][binY].WarningValue) || + (UseValue > 1 && bincon > Limits[binX][binY].WarningValue) || + (UseValue == -1 && bincon <= Limits[binX][binY].WarningValue) || + (UseValue < -1 && bincon < Limits[binX][binY].WarningValue) ) { + NWarnings++; + if ( TypePublish >= 1 && NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Warnings + float binvalX = h->GetXaxis()->GetBinCenter(binX + 1); + float binvalY = h->GetYaxis()->GetBinCenter(binY + 1); + std::string binname = Form("%s_WarningBin((%u,%u) | %.*e,%.*e)", name.c_str(), binX, binY, 2, binvalX, 2, binvalY); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + //Print remaining bins + else { + NGoodPrint++; + if ( TypePublish >= 2 && NErrors + NWarnings + NGoodPrint <= Publish ) { //Publish Good Bins + float binvalX = h->GetXaxis()->GetBinCenter(binX + 1); + float binvalY = h->GetYaxis()->GetBinCenter(binY + 1); + std::string binname = Form("%s_GoodBin((%u,%u) | %.*e,%.*e)", name.c_str(), binX, binY, 2, binvalX, 2, binvalY); + if ( TypeValue > 0.5 ) { + result->tags_[binname.c_str()] = (bincon / h_entries); + } else { + result->tags_[binname.c_str()] = bincon; + } + } + } + } + }} + } + + //Print Number of Errors & Warnings + if ( Publish >= 0 ) { + std::string pub_error = Form("%s_Bin_Errors", name.c_str()); + result->tags_[pub_error.c_str()] = NErrors; + if ( TypePublish >= 1 ) { + std::string pub_warning = Form("%s_Bin_Warnings", name.c_str()); + result->tags_[pub_warning.c_str()] = NWarnings; + } + } + + //Set Flag as worst case summary of all bins + if ( (NErrors == 0) && (NWarnings == 0) ) result->status_ = dqm_core::Result::Green; + if ( (NErrors == 0) && (NWarnings > 0) ) result->status_ = dqm_core::Result::Yellow; + if ( (NErrors > 0) ) result->status_ = dqm_core::Result::Red; + + return(result); + } + + // ********************************************************************* + // Protected Methods + // ********************************************************************* + + int BinThresh::Publish_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("Publish"); + if ( it != params.end() ) { + return((int) it->second); + }else { + return(0); + } + } + + int BinThresh::TypePublish_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("TypePublish"); + if ( it != params.end() ) { + if ( it->second > 1.5 ) return(2); + else if ( it->second > 0.5 ) return(1); + else return(0); + }else { + return(0); + } + } + + int BinThresh::UseValue_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("UseValue"); + if ( it != params.end() ) { + return((int) it->second); + }else { + return(0); + } + } + + int BinThresh::TypeValue_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("TypeValue"); + if ( it != params.end() ) { + if ( it->second > 0.5 ) return(1); + else return(0); + }else { + return(0); + } + } + + int BinThresh::BinMinEntries_GetFromMap(const std::map<std::string, double> & params) + { + std::map<std::string, double>::const_iterator it = params.find("BinMinEntries"); + if ( it != params.end() ) { + return((int) it->second); + }else { + return(0); + } + } + + std::vector<BinThresh::mask_limits> BinThresh::Limits1D_GetFromMap( const std::map<std::string, double> & params, + const std::map<std::string, double> & warning_params, + const std::map<std::string, double> & error_params ) + { + std::map<std::string, double>::const_iterator warning_map_bin; + std::map<std::string, double>::const_iterator error_map_bin; + std::map<std::string, double>::const_iterator mask_map_bin; + + //Make Default Limit Values & Masking + BinThresh::mask_limits default_Limits; + default_Limits.WarningValue = 0.0; + default_Limits.ErrorValue = 0.0; + default_Limits.Mask = true; + + //Check for Value_All thresholds to use for all bins + warning_map_bin = warning_params.find("Value_All"); + error_map_bin = error_params.find("Value_All"); + if ( warning_map_bin != warning_params.end() && + error_map_bin != error_params.end() ) { + default_Limits.WarningValue = warning_map_bin->second; + default_Limits.ErrorValue = error_map_bin->second; + default_Limits.Mask = false; + } + + //Make default threshold & mask + std::vector<BinThresh::mask_limits> Limits(NbinsX, default_Limits); + + //Get specific bin limits and unmasked bins + for ( int bin = 0; bin < NbinsX; bin++ ) { + std::string value_bin = Form("Value_%d", bin + 1); + //Get thresholds for bin + warning_map_bin = warning_params.find(value_bin.c_str()); + error_map_bin = error_params.find(value_bin.c_str()); + if ( warning_map_bin != warning_params.end() && + error_map_bin != error_params.end() ) { + Limits[bin].WarningValue = warning_map_bin->second; + Limits[bin].ErrorValue = error_map_bin->second; + Limits[bin].Mask = false; + } + + //Mask out specified bins + //The masking that is explicitly defined takes precedence over the implied masking from the thresholds + std::string mask_bin = Form("Mask_%d", bin + 1); + mask_map_bin = params.find(mask_bin.c_str()); + if ( mask_map_bin != params.end() ) { + if(mask_map_bin->second > 0.5) Limits[bin].Mask = true; + //UnMasking should never be necessary + } + } + + return(Limits); + } + + std::vector< std::vector<BinThresh::mask_limits> > BinThresh::Limits2D_GetFromMap( const std::map<std::string, double> & params, + const std::map<std::string, double> & warning_params, + const std::map<std::string, double> & error_params ) + { + std::map<std::string, double>::const_iterator warning_map_bin; + std::map<std::string, double>::const_iterator error_map_bin; + std::map<std::string, double>::const_iterator mask_map_bin; + + //Make Default Limit Values & Masking + BinThresh::mask_limits default_Limits; + default_Limits.WarningValue = 0.0; + default_Limits.ErrorValue = 0.0; + default_Limits.Mask = true; + + //Check for Value_All thresholds to use for all bins + warning_map_bin = warning_params.find("Value_All"); + error_map_bin = error_params.find("Value_All"); + if ( warning_map_bin != warning_params.end() && + error_map_bin != error_params.end() ) { + default_Limits.WarningValue = warning_map_bin->second; + default_Limits.ErrorValue = error_map_bin->second; + default_Limits.Mask = false; + } + + //Make default threshold & mask + std::vector< std::vector<BinThresh::mask_limits> > Limits(NbinsX, std::vector<BinThresh::mask_limits>(NbinsY, default_Limits)); + + //Get specific bin limits and unmasked bins + for ( int binX = 0; binX < NbinsX; binX++ ) { + for ( int binY = 0; binY < NbinsY; binY++ ) { + std::string value_bin = Form("Value_%d_%d", binX + 1, binY + 1); + //Get thresholds for bin + warning_map_bin = warning_params.find(value_bin.c_str()); + error_map_bin = error_params.find(value_bin.c_str()); + if ( warning_map_bin != warning_params.end() && + error_map_bin != error_params.end() ) { + Limits[binX][binY].WarningValue = warning_map_bin->second; + Limits[binX][binY].ErrorValue = error_map_bin->second; + Limits[binX][binY].Mask = false; + } + + //Mask out specified bins + //The masking that is explicitly defined takes precedence over the implied masking from the thresholds + std::string mask_bin = Form("Mask_%d_%d", binX + 1, binY + 1); + mask_map_bin = params.find(mask_bin.c_str()); + if ( mask_map_bin != params.end() ) { + if(mask_map_bin->second > 0.5) Limits[binX][binY].Mask = true; + //UnMasking should never be necessary + } + }} + + return(Limits); + } + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/BinThreshold.cxx b/DataQuality/dqm_algorithms/src/BinThreshold.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ea11070c8cb3161053dfbde80a633eb87d718701 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinThreshold.cxx @@ -0,0 +1,212 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinThreshold.cxx checks bins wrt to a threshold value and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinThreshold.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +#include <iostream> + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::BinThreshold GreaterThan( "GreaterThan" ); + dqm_algorithms::BinThreshold GreaterThanAbs( "GreaterThanAbs" ); + dqm_algorithms::BinThreshold GreaterThanNonZeroMedian( "GreaterThanNonZeroMedian" ); + dqm_algorithms::BinThreshold GreaterThanEqual( "GreaterThanEqual" ); + dqm_algorithms::BinThreshold LessThan( "LessThan" ); + dqm_algorithms::BinThreshold LessThanAbs( "LessThanAbs" ); + dqm_algorithms::BinThreshold LessThanNonZeroMedian( "LessThanNonZeroMedian" ); + dqm_algorithms::BinThreshold LessThanEqual( "LessThanEqual" ); + dqm_algorithms::BinThreshold Equal( "Equal" ); + dqm_algorithms::BinThreshold NotEqual( "NotEqual" ); +} + + +dqm_algorithms::BinThreshold::BinThreshold( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("Bins_"+name+"_Threshold", this); +} + +dqm_algorithms::BinThreshold * +dqm_algorithms::BinThreshold::clone() +{ + + return new BinThreshold( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::BinThreshold::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0); + const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double bin_threshold; + double gthreshold; + double rthreshold; + try { + bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "BinThreshold", config.getParameters() ); + rthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + int count = 0; + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + dqm_core::Result* result = new dqm_core::Result(); + TH1* resulthisto; + if (histogram->InheritsFrom("TH2")) { + resulthisto=(TH1*)(histogram->Clone()); + } else if (histogram->InheritsFrom("TH1")) { + resulthisto=(TH1*)(histogram->Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + resulthisto->Reset(); + if(name_.find("Median")!=std::string::npos){ + std::vector<double> bin_vals; + for ( int i = range[0]; i <= range[1]; ++i ) { + for ( int j = range[2]; j <= range[3]; ++j ) { + if(histogram -> GetBinContent(i,j) > 0) bin_vals . push_back( histogram -> GetBinContent(i,j) ); + } + } + std::sort(bin_vals.begin(), bin_vals.end()); + unsigned bin_vals_size = bin_vals.size(); + double median = 0; + if(bin_vals_size%2==0 && bin_vals_size>1) median = (bin_vals.at(bin_vals_size/2-1)+bin_vals.at(bin_vals_size/2))/2; + else if(bin_vals_size%2==1 && bin_vals_size>1) median = bin_vals.at(bin_vals_size/2-1); + else if(bin_vals_size==1) median = bin_vals.at(0); + + double min_bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "MinBinThreshold", config.getParameters() , -99999); + double max_bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "MaxBinTrheshold", config.getParameters() , -99999); + bin_threshold=median*bin_threshold; + + bin_threshold = std::max(bin_threshold, min_bin_threshold); + if(max_bin_threshold > -1 ) bin_threshold = std::min(bin_threshold, max_bin_threshold); + + result->tags_["Effective_BinThreshold"] = bin_threshold; + } + + for ( int i = range[0]; i <= range[1]; ++i ) { + for ( int j = range[2]; j <= range[3]; ++j ) { + double content= histogram -> GetBinContent(i,j); + if ( CompareBinThreshold(name_, content, bin_threshold )) { + ++count; + resulthisto->SetBinContent(i,j,content); + if (publish && count< maxpublish){ + dqm_algorithms::tools::PublishBin(histogram,i,j,content,result); + } + } + } + } + + ERS_DEBUG(1,"Number of bins " << name_ << " treshold of " << bin_threshold << " is " << count ); + ERS_DEBUG(1,"Green threshold: "<< gthreshold << " bin(s); Red threshold : " << rthreshold << " bin(s) "); + + int TotalBins = (int) dqm_algorithms::tools::GetFirstFromMap( "TotalBins", config.getParameters() , -99999); + if(TotalBins > -10){ + if(TotalBins < 0) TotalBins = histogram->GetNbinsX()*histogram->GetNbinsY()*histogram->GetNbinsZ(); + int effectiveCount = count - (histogram->GetNbinsX()*histogram->GetNbinsY()*histogram->GetNbinsZ() - TotalBins); + if(name_.find("LessThan")!=std::string::npos) result->tags_["NBins_%"] = 100.*effectiveCount/TotalBins; + else result->tags_["NBins_%"] = 100.*count/TotalBins; + } + + result->tags_["NBins"] = count; + result->object_ = (std::auto_ptr<TObject>)(TObject*)(resulthisto); + if (gthreshold > rthreshold) { + if ( count >= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } else { + if ( count <= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count < rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } + + return result; + +} + +bool +dqm_algorithms::BinThreshold::CompareBinThreshold(const std::string & type, double bincontent, double threshold) { + + if (type == "GreaterThan") return (bincontent > threshold); + if (type == "GreaterThanAbs") return (fabs(bincontent) > threshold); + if (type == "GreaterThanNonZeroMedian") return (bincontent > threshold); + if (type == "LessThan") return (bincontent < threshold); + if (type == "LessThanAbs") return (fabs(bincontent) < threshold); + if (type == "LessThanNonZeroMedian") return (bincontent < threshold); + if (type == "LessThanEqual") return (bincontent <= threshold); + if (type == "GreaterThanEqual") return (bincontent >= threshold); + if (type == "Equal") return (bincontent == threshold); + if (type == "NotEqual") return (bincontent != threshold); + + return 0; +} + + +void +dqm_algorithms::BinThreshold::printDescription(std::ostream& out) +{ + + out<<"Bins_"+name_+"_Threshold: Checks for number of bins "+name_+" threshold value\n"<<std::endl; + + out<<"Mandatory Parameter: BinThreshold: Look for bins "+name_+" BinTreshold; Count number of bins satifying requirement \n"<<std::endl; + + out<<"Mandatory Green/Red Threshold: NBins: Number of bins satifying "+name_+" BinThreshold constraint to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (set to 1)\n"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: ymin: minimum y range"<<std::endl; + out<<"Optional Parameter: ymax: maximum y range\n"<<std::endl; + + +} + diff --git a/DataQuality/dqm_algorithms/src/BinsDiffByStrips.cxx b/DataQuality/dqm_algorithms/src/BinsDiffByStrips.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5edbe9ad653fceaf7c184ae708c800be72eea219 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinsDiffByStrips.cxx @@ -0,0 +1,1063 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsDiffByStrips.cxx calculates average bin value for a strip of bins and finds bins that are outliers from that strip. DQ decision based on worst bin only, not number of bad bins. + * \author Evan Wulf + */ + + + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinsDiffByStrips.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <TH1.h> +#include <TH1F.h> +#include <TH2F.h> +#include <TClass.h> +#include <TObjArray.h> +#include <TMath.h> + +#include <math.h> +#include <string> + +using namespace std; + +static dqm_algorithms::BinsDiffByStrips myInstance; + +dqm_algorithms::BinsDiffByStrips::BinsDiffByStrips( ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BinsDiffByStrips", this); + TH1::AddDirectory(false); +} + +dqm_algorithms::BinsDiffByStrips::~BinsDiffByStrips() +{ +} + +dqm_algorithms::BinsDiffByStrips * +dqm_algorithms::BinsDiffByStrips::clone() +{ + + return new BinsDiffByStrips(); +} + + +dqm_core::Result * +dqm_algorithms::BinsDiffByStrips::execute(const std::string & name, + const TObject& object, + const dqm_core::AlgorithmConfig& config ){ + + dqm_core::Result* result = new dqm_core::Result(); + + //========================================================================== + //-- Input Histogram Retrieval -- + //========================================================================== + // Retrieve input object, test if it is a valid 2D histogram: + + TH1* histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() != 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension != 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //========================================================================== + //-- Algorithm Configuration -- + //========================================================================== + // Loading of parameters, thresholds from config, + + // Thresholds: + //------------------- + double gthreshold; + double rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + // Configuration Parameters: + //------------------------------- + + + // Parameters giving the minimum number(fraction) of bins with a certain status to change the histogram level result + // (If the histogram status is not determined by a Chi-Squared test): + const int nRedBinsToRedStatus = (int) dqm_algorithms::tools::GetFirstFromMap("NBinsRedToRedStatus", config.getParameters(), 1); + const double redFracToRedStatus = dqm_algorithms::tools::GetFirstFromMap("RedFractionToRedStatus", config.getParameters(), 0.01); + const int nYellowBinsToYellowStatus = (int) dqm_algorithms::tools::GetFirstFromMap("NBinsYellowToYellowStatus", config.getParameters(), 1); + const double yellowFracToYellowStatus = dqm_algorithms::tools::GetFirstFromMap("YellowFractionToYellowStatus", config.getParameters(), 0.05); + const double greenFracToGreenStatus = dqm_algorithms::tools::GetFirstFromMap("GreenFractionToGreenStatus", config.getParameters(), 0.5); + + // Minimum statistics for test: + const double minStat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + if ( histogram->GetEntries() < minStat ) { + result->status_ = dqm_core::Result::Undefined; + return result; + } + + // Parameter for exclusion of bins from consideration: + const double ignoreValue = dqm_algorithms::tools::GetFirstFromMap( "ignoreval", config.getParameters(), -99999); + const double minError = dqm_algorithms::tools::GetFirstFromMap( "minError", config.getParameters(), /*0.00001*/ -1); + + // Parameter giving the range of the histogram to be tested: + vector<int> range; + try{ + range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + const bool yStrips = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "useStripsOfConstantY", config.getParameters(), 0)); + + // Parameter giving minimal statistical significance for bin test results: + const double sigmaThresh = dqm_algorithms::tools::GetFirstFromMap("SigmaThresh", config.getParameters(), 5); + // Tag publishing options: + const bool publish = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0)); + const bool publishRed = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "PublishRedBins", config.getParameters(), 0)); + int maxPublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 50); + if (maxPublish > 999) maxPublish=999; + + // Clustering options: + const bool clusterResults = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "ClusterResults", config.getParameters(), 1)); + const double seedThreshold = dqm_algorithms::tools::GetFirstFromMap( "SeedThreshold", config.getParameters(), rthreshold); + const double growthThreshold = dqm_algorithms::tools::GetFirstFromMap( "GrowthThreshold", config.getParameters(), gthreshold); + const int topology = static_cast<int>(dqm_algorithms::tools::GetFirstFromMap( "Topology", config.getParameters(), tools::CylinderX)); + + // Test Directionality: exclude bins over(under) average by setting to a value other than 1: + const bool greaterThan = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "GreaterThan", config.getParameters(), 0)); + const bool lessThan = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "LessThan", config.getParameters(), 0)); + bool findBinsOverAvg = true; + bool findBinsUnderAvg = true; + + if (!lessThan && greaterThan) { + findBinsUnderAvg = false; + } + else if (!greaterThan && lessThan) { + findBinsOverAvg = false; + } + + + + // Master switch: trust errors and make this algorithm a test of whether that trust is warranted: (changes three defaults and final test) + const bool testConsistencyWithErrors = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("TestConsistencyWithErrors", config.getParameters(), 0)); + + // Switch to use the mean error instead of the variance as the yard stick by which deviations are measured: + const bool useMeanErrorForScale = (testConsistencyWithErrors || static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("UseMeanErrorForScale", config.getParameters(), 0))); + + // Switch to decide whether to do a Chi-Squared test: + const bool doChiSquaredTest = (testConsistencyWithErrors || static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("DoChiSquaredTest", config.getParameters(), 0))); + + // Minimum bins required before(after) removal of outliers for testing of a strip to proceed: + + //minimum number of bins left after skimming for bins in this strip to be tested: + int minBinsBeforeSkimming = (int) dqm_algorithms::tools::GetFirstFromMap("MinBinsBeforeSkimming", config.getParameters(), -1); + if (minBinsBeforeSkimming < 3) { + if ( !testConsistencyWithErrors ) minBinsBeforeSkimming = 50; + else minBinsBeforeSkimming = 8; + } + //minimum number of bins left after skimming for bins in this strip to be tested: + int minBinsAfterSkimming = (int) dqm_algorithms::tools::GetFirstFromMap("MinBinsAfterSkimming", config.getParameters(), -1); + if (minBinsAfterSkimming < 2) { + if ( !testConsistencyWithErrors ) minBinsAfterSkimming = 8; + else minBinsAfterSkimming = 3; + } + + // What to do if minimum bin requirement is not met: mark all bins as "Undefined" or add them all to the next strip: + const bool combineStripsBeforeSkimming = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("CombineStripsBeforeSkimming", config.getParameters(), 1)); + + // Parameter to declare a bin as green regardless of its relative deviation: (Also will exclude this bin from any clustering of bad bins) + double absDiffGreenThresh = dqm_algorithms::tools::GetFirstFromMap("AbsDiffGreenThresh", config.getParameters(), 0); + + // double maxdiffabs = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffAbs", config.getParameters(), -1); + // double maxdiffrel = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffRel", config.getParameters(), -1); + + + + // Parameters for configuring the iterative oulier identification process: + + // Switch to use error based outlier identification: + const bool findOutliersUsingErrors = (testConsistencyWithErrors || static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("FindOutliersUsingErrors", config.getParameters(), 0))); + + // Switch to configure non error based outlier identification: (id based on shape of distribution) + int nIter = (int) dqm_algorithms::tools::GetFirstFromMap( "nIterations", config.getParameters(), 100); //Defines a maximum: iteration will terminate on stabilization. + double iterThresh = dqm_algorithms::tools::GetFirstFromMap("IterDeviationThresh", config.getParameters(), 2.075); + double iVarExp = dqm_algorithms::tools::GetFirstFromMap("IterVariationExponent", config.getParameters(), 0.275); + double isbf = dqm_algorithms::tools::GetFirstFromMap("IterScaleBiasCorrectionFactor", config.getParameters(), 0.4); + double ibc = dqm_algorithms::tools::GetFirstFromMap("IterBreakConstant", config.getParameters(), 25); + +// empty ratio + double emptyRatio = dqm_algorithms::tools::GetFirstFromMap("EmptyRatio", +config.getParameters(), 0.3); + double outstandingRatio = dqm_algorithms::tools::GetFirstFromMap("OutstandingRatio",config.getParameters(), 50); +//test_begin +/* +out<<"histogram Name: "<<histogram->GetName()<<std::endl; +out<<"nIter : "<<nIter<<std::endl; +out<<"iterThresh: "<<iterThresh<<std::endl; +out<<"iVarExp : "<<iVarExp<<std::endl; +out<<"isbf: "<<isbf<<std::endl; +out<<"ibc: "<<ibc<<std::endl; +*/ +//test_end + //======================================================= + //-- Setup -- + //======================================================= + //Prepare for testing + + int ixmax = range[1] - range[0] + 1; + int iymax = range[3] - range[2] + 1; + + int ismax = ixmax; + int inmax = iymax; + if( yStrips) { + ismax = iymax; + inmax = ixmax; + } + + //Build vectors to store the axis information more efficiently, keeping to Root's use of overflow bins to keep things + //intuitive, aswell as temporary arrays to facilitate booking of results histograms: + vector<double> xBinCenters; + vector<double> yBinCenters; + double * xBinEdges = new double[ixmax+1]; + double * yBinEdges = new double[iymax+1]; + + //X-Axis: + xBinCenters.push_back( histogram->GetXaxis()->GetBinLowEdge(range[0]) ); //Underflow bin + for ( int i = range[0]; i <= range[1]; i++ ) { + xBinCenters.push_back( histogram->GetXaxis()->GetBinCenter(i) ); + xBinEdges[i-range[0]] = histogram->GetXaxis()->GetBinLowEdge(i); + } + xBinEdges[ixmax] = histogram->GetXaxis()->GetBinUpEdge(range[1]); + xBinCenters.push_back( xBinEdges[ixmax] ); //Overflow bin + + //Y-Axis: + yBinCenters.push_back( histogram->GetYaxis()->GetBinLowEdge(range[2]) ); //Underflow bin + + for ( int j = range[2]; j <= range[3]; j++ ) { + yBinCenters.push_back( histogram->GetYaxis()->GetBinCenter(j) ); + yBinEdges[j-range[2]] = histogram->GetYaxis()->GetBinLowEdge(j); + } + yBinEdges[iymax] = histogram->GetYaxis()->GetBinUpEdge(range[3]); + yBinCenters.push_back( yBinEdges[iymax] ); //Overflow bin + + double * sBinEdges = xBinEdges; + if( yStrips ) { + sBinEdges = yBinEdges; + } + + //Book result histograms: + TH2F* inputBins = new TH2F("inputBins", histogram->GetTitle(), ixmax, xBinEdges, iymax, yBinEdges); + TH2F* binwiseStatus = new TH2F("binewiseStatus", "BinsDiffByStrips Status Results per Bin", ixmax, xBinEdges, + iymax, yBinEdges); + TH2F* binDeviations = new TH2F("binDeviations","Input bin content normalized by skimmed average and variance per strip", + ixmax, xBinEdges, iymax, yBinEdges); + TH1F* stripAverages = new TH1F("stripAverages", "Average Value from Cells in Strip After Removal of Outliers", + ismax, sBinEdges); + TH1F* stripVariances = new TH1F("stripVariances","Standard Variance of Cells in Strip After Removal of Outliers", + ismax, sBinEdges); + + delete[] xBinEdges; + delete[] yBinEdges; + //Intialize result variables: + double maxDeviation = 0; + std::vector <tools::binContainer> yellowBins; + std::vector <tools::binContainer> redBins; + int nBinsRed = 0; + int nBinsYellow = 0; + int nBinsGreen = 0; + int nBinsUndefined = 0; + int nBinsDisabled = 0; + + + //=============================================================================================== + //-- Test -- + //=============================================================================================== + // Examination of bin values, filling of result histograms, and determination of dq result: + + vector<vector<tools::binContainer> > strips; +//test_change begin +vector<tools::binContainer> AllBinInOneStrip; +double emptyBinCounter=0; +int name_flag = 0; +//test_change end + //Loop to process histogram and pack it into a vector of strip vectors: + for ( int is = 1; is <= ismax; is++ ) { + vector<tools::binContainer> inputs; + + int ix = is; + int iy = 1; + if ( yStrips ) { + iy = is; + ix = 1; + } + for ( int in = 1; in <= inmax; in++ ) { + + if ( yStrips ) { + ix = in; + } + else { + iy = in; + } + + int bin = histogram->GetBin(ix + range[0]-1,iy + range[2]-1); + double value = histogram->GetBinContent(bin); + double error = histogram->GetBinError(bin); + inputBins->SetBinContent(ix,iy,value); + inputBins->SetBinError(ix,iy,error); +//test_change begin + if(value==0) emptyBinCounter++; +//test_change end +tools::binContainer binContent_tmp = {value,error,1,ix,iy,xBinCenters[ix],yBinCenters[iy] }; +AllBinInOneStrip.push_back(binContent_tmp); + if( (value != ignoreValue) && (error > minError) ){ + tools::binContainer binContent = {value,error,1,ix,iy,xBinCenters[ix],yBinCenters[iy] }; + + inputs.push_back(binContent); +// AllBinInOneStrip.push_back(binContent); + } + else { + nBinsDisabled++; + binwiseStatus->SetBinContent(ix,iy,dqm_core::Result::Disabled); + } + } + + // If there are not enough bins in this strip and we are not combining strips, then + // all the active bins in this strip should be considered undefined and ignored. + if( (!combineStripsBeforeSkimming) && ((int)inputs.size() < minBinsBeforeSkimming) ) { + nBinsUndefined += inputs.size(); + } + else if(inputs.size() != 0) { + strips.push_back(inputs); + } + } + + //If combine strips before skimming is on, combine the strips with the fewest active bins with their neighbors. + if( combineStripsBeforeSkimming ) { + tools::MergePastMinStat(strips,minBinsBeforeSkimming); + } + + + //Vectors to store values for chi-squared test, if one is performed: (could one be performed on deviations alone?) + vector<double> inputValues; + vector<double> inputErrors; + vector<double> stripAveragesVector; + vector<double> stripErrors; + + vector<tools::binContainer> deviations; + //Loop over strips: + for( vector<vector<tools::binContainer> >::iterator stripItr = strips.begin(); stripItr != strips.end(); ++stripItr ) { +//test_change begin +//out<<"************ im here 1************"<<std::endl; +//test_change end + if ( stripItr->empty() ) { +//out<<" this strip is empty"<<std::endl; + continue; + } + + //Find outliers and average when outliers are exluded: + double stripAvg = 0; + double iScale = 0; + int nIn = 0; + int nTot = stripItr->size(); + if( findOutliersUsingErrors ) { + tools::findOutliersUsingErrors(*stripItr, stripAvg, iScale, nIn, absDiffGreenThresh); + } + else { + tools::findOutliers(*stripItr, stripAvg, iScale, nIn, nIter, iVarExp , iterThresh, isbf, ibc); + } + + // Check if there are enough bins after outliers skimming for any bins from this strip to be flagged, + // if not, either label them all as undefined (error = -1) or combine with the next strip: + // (Note: in the second case we do not reset binContent.test: + // outliers found here will be excluded in the first iteration when they are processed with the next strip) +//test_change begin +//out<<"iScal: "<<iScale<<std::endl; +//out<<"stripAvg: "<<stripAvg<<std::endl; +//out<<"nIn: "<<nIn<<std::endl; +//out<<"minBinsAfterSkimming: "<<minBinsAfterSkimming<<std::endl; +//test_change end + if ( (nIn < minBinsAfterSkimming) ) { + for (vector<tools::binContainer>::const_iterator it = stripItr->begin(); it != stripItr->end(); ++it) { + tools::binContainer deviationContainer = { 0, -3, -13, it->ix, it->iy, it->x, it->y }; + deviations.push_back(deviationContainer); + } + continue; //Next strip; + } + + + double stripVariance = 0; + double stripVarianceError = 0; + double stripAvgError = 0; + double err2Sum = 0; +// out<<"useMeanErrorForScale : "<<useMeanErrorForScale<<std::endl; + + if( !useMeanErrorForScale ) { +// out<<"********** im here 2 *************"<<std::endl; + // We will now calculate the variance with two methods, one using the the number of bins in (nIn), the number out, + // and range from above, and one looking at the standard variance of the nIn bins in inputs marked as good by + // findOutliers. We will then take a weighted average of the two measures as our final estimate of the variance of + // the underlying, outlier free population. + + // Get range and measures of distribution: + double S2 = 0; + double sumSquaredDiffFromAvg = 0; + double sumCompensator = 0; + double err2DiffSum = 0; + double err2Diff2Sum = 0; + double min = 0; + double max = 0; + nIn = 0; + + + for (vector<tools::binContainer>::const_iterator it = stripItr->begin(); it != stripItr->end(); ++it) { + //it->test will evaluate as true iff tools::findOutliers determined it was sufficiently close to the mean + // to not be a variance spoiling outlier: + + if(it->test){ + if( nIn == 0 ) { + min = it->value; + max = it->value; + } + if( it->value > max ) max = it->value; + if( it->value < min ) min = it->value; + nIn++; + + double diffFromAvg = it->value - stripAvg; + sumSquaredDiffFromAvg += pow( diffFromAvg, 2); + sumCompensator += ( diffFromAvg ); //Use to compensate for floating point issues if they should crop up: + // (would be zero if precision was perfect) + + double inputErr2 = pow(it->error,2.); + err2Sum += inputErr2; + err2DiffSum += inputErr2 * diffFromAvg; + err2Diff2Sum += inputErr2 * pow( diffFromAvg, 2); + } + } + + // Record the range + double range = max - min; + + + //Method 1: ErfInverse: + double countingVariance = 0; + double countingWeight = 0; +// out<<"nTot: "<<nTot<<std::endl; +// out<<"range: "<< range<<" max: "<<max<<" min: "<<min<<std::endl; + if( (nTot != 0) && (range != 0) && ((nTot - nIn) != 0) ) { + double erfin = TMath::ErfInverse( (1.0 * nIn) / nTot ); + double erfin2 = pow(erfin,2); +// out<<"erfin: "<<erfin<<std::endl; +// out<<"erfin2: "<<erfin2<<std::endl; + if( erfin2 != 0 ) { + countingVariance = range / (erfin * 2 * sqrt(2)); + countingWeight = 8 * pow(erfin2 / (range * exp(erfin2)),2) * pow(1.0 * nTot,3.) / (TMath::Pi() * nIn * (nTot - nIn)); + } + } + + //Method 2: Compensated Bounded Variance: + double boundedVariance = 0; + double boundedWeight = 0; + double sumWeights = 0; + if(nIn > 2) { + S2 = (sumSquaredDiffFromAvg - (pow(sumCompensator,2)/nIn) )/(nIn - 1); + boundedVariance = sqrt(S2); + double boundEffect = 1; + double U = 0; + if( countingVariance != 0 ) { + U = range / (2 * countingVariance); + } + else if( boundedVariance != 0 ) { + U = range / (2 * boundedVariance); + } + if( U != 0 ) { + boundEffect = TMath::Erf( U / 2 ) ; + } + if(boundEffect != 0) { + boundedVariance = boundedVariance / boundEffect; + } + double boundedErr2 = 0; + if (S2 != 0) { + boundedErr2 = ( pow( err2Diff2Sum / (pow(nIn-1,2.) * S2), 2) + pow( boundedVariance*(1 - boundEffect)/2,2) ); + } + if( boundedErr2 != 0 ) { + boundedWeight = 1/boundedErr2; + } + sumWeights = ( countingWeight + boundedWeight ); + stripVariance = 0; + if(sumWeights != 0) { + //Recalculate boundEffect and rederive boundedVariance using preliminary combined strip variance: + stripVariance = (countingVariance * countingWeight + boundedVariance * boundedWeight ) / sumWeights; + if(stripVariance != 0 ) { + boundEffect = TMath::Erf( range / (4 * stripVariance) ); + if( boundEffect != 0 ) { + boundedVariance = sqrt(S2) / boundEffect; + boundedErr2 = ( pow( err2Diff2Sum / (pow(nIn-1,2.) * S2), 2) + pow( boundedVariance*(1 - boundEffect)/2,2) ); + } + } + } +//test_change begin +//out<<"iScale: "<<iScale<<std::endl; +//test_change end + + } + else if ( iScale != 0 ){ + //Use the iScale as a last resort, as method 1 is not very good with nIn <= 2 either, but give it a big error + boundedVariance = iScale; + boundedWeight = pow(iScale, -2); + } + + // Make final Combination of the two variance estimations, weighted with their errors: + sumWeights = ( countingWeight + boundedWeight ); + stripVariance = 0; +//test_change begin +//out<<"countingWeight: "<<countingWeight<<std::endl; +//out<<"boundedWeight: "<<boundedWeight<<std::endl; +//out<<"sumWeights: "<<sumWeights<<std::endl; +//test_change end + if(sumWeights != 0) { + stripVariance = (countingVariance * countingWeight + boundedVariance * boundedWeight ) / sumWeights; + stripVarianceError = 1/sqrt(sumWeights); +//test_change begin +// out<<"stripVariance: "<<stripVariance<<std::endl; +// out<<"stripVariance Error: "<<stripVarianceError<<std::endl; + +//test_change end + } + } + else if (nIn > 2) { + // Just calculate error based quantities and use these: + for (vector<tools::binContainer>::const_iterator it = stripItr->begin(); it != stripItr->end(); ++it) { + //it->test will evaluate as true iff tools::findOutliers determined it was sufficiently close to the mean + // to not be a variance spoiling outlier: + if(it->test){ + err2Sum += pow(it->error,2.); + } + } + stripVariance = sqrt( err2Sum / nIn ); //<- what we would expect the variance to be if the errors are correct + stripVarianceError = stripVariance / sqrt( nIn ); + } + + + // Calculate error on the mean: + stripAvgError = sqrt(err2Sum)/nIn; + + int is = 0; + if (yStrips) { + is = stripItr->front().iy; + } + else { + is = stripItr->front().ix; + } + + // Store final skimmed Average and Variance found for this strip: + stripAverages->SetBinContent(is,stripAvg); + stripAverages->SetBinError(is,stripAvgError); + stripVariances->SetBinContent(is,stripVariance); + stripVariances->SetBinError(is,stripVarianceError); + + + if(doChiSquaredTest) { + for (vector<tools::binContainer>::const_iterator it = stripItr->begin(); it != stripItr->end(); ++it) { + inputValues.push_back( it->value ); + inputErrors.push_back( 0. ); + stripAveragesVector.push_back( stripAvg ); + stripErrors.push_back( stripVariance ); + } + } + + //Now find the deviation from the strip average, in multiples of the strip variance, for each bin in this strip: + for (vector<tools::binContainer>::const_iterator it = stripItr->begin(); it != stripItr->end(); ++it) { +//out<<"********** im here 5 *************"<<std::endl; + double deviation = 0; + double deviationError = -1; + double diffFromAvg = it->value - stripAvg; +/* if(it->iy==26 && it->ix==71) { + out<<"bin value: "<<it->value<<std::endl; + out<<"bin error: "<<it->error<<std::endl; + out<<"stripAvg: "<<stripAvg<<std::endl; + out<<"stripAvgError: "<<stripAvgError<<std::endl; + out<<"diffFromAvg: "<<diffFromAvg<<std::endl; + out<<"stripVariance: "<<stripVariance<<std::endl; + out<<"stripVarianceError: "<<stripVarianceError<<std::endl; + } +*/ +// test_change begin + if(stripVariance > 0.00001){ + deviation = diffFromAvg / stripVariance; +// if(it->iy==26 && it->ix==71) out<<"deviation: "<<deviation<<std::endl; + if ( nIn > 1 ) { + deviationError = sqrt( (( pow(it->error,2) + pow(stripAvgError,2) ) / pow(stripVariance,2)) + + ( pow(diffFromAvg,2) * pow(stripVarianceError,2) / pow(stripVariance,4)) ); +/* if(it->iy==26 && it->ix==71) { + out<<"deviationError: "<<deviationError<<std::endl; + out<<" eta & phi: "<<it->x << " "<< it->y<<std::endl; + } +*/ + } + } + else {deviation=0; + deviationError=0; + if( (it->test==0) && (fabs(it->value)/fabs(stripAvg)) > outstandingRatio ) { + name_flag = 1; + // out<<"outstandingRatio "<<outstandingRatio<<std::endl; + } + } //test_change + int binStatus = 0; + if ( fabs(diffFromAvg) < (absDiffGreenThresh + sqrt(pow(it->error,2) + (err2Sum/nIn))) ) { + binStatus = 3; + } + //Save bin for future processing and tests: + tools::binContainer deviationContainer = { deviation , deviationError, binStatus, it->ix, it->iy, it->x, it->y }; + deviations.push_back(deviationContainer); + //Write bin to result histogram: + int bin = binDeviations->GetBin(it->ix,it->iy); + binDeviations->SetBinContent(bin,deviation); +// binDeviations->SetBinError(bin,deviation); + binDeviations->SetBinError(bin,deviationError); // i change this + } + } + + + //If clustering of results is turned on, cluster the bins according to their deviation: + vector<tools::binCluster> clusters; + vector<tools::binCluster> redClusters; + vector<tools::binCluster> yellowClusters; + if(clusterResults) { + + //First sort the bins: + std::sort( deviations.begin(), deviations.end(), dqm_algorithms::tools::binContainer::comp ); + + //Now map the deviations according to ix, iy, + vector<vector<tools::binContainer*> > binMap = makeBinMap(deviations, ixmax, iymax, topology); + //Now do the clustering: + for (vector<tools::binContainer>::iterator it = deviations.begin(); it != deviations.end(); ++it) { + if( (it->value > seedThreshold + it->error) && !it->test ) { + tools::binCluster cluster = tools::buildCluster(*it,binMap,xBinCenters,yBinCenters,growthThreshold,topology); + if(cluster.n > 1) { + // Only keep clusters with more than 1 bin + clusters.push_back(cluster); + } + else { + // Unmark this bin: it is not in a cluster + it->test = 0; + } + } + } + + + //Score each cluster based on the significance of its total deviation: (Using the same criteria to be used for bins) + for( vector<tools::binCluster>::const_iterator it = clusters.begin(); it != clusters.end(); ++it) { + double fabsDeviation = fabs(it->value); + double significanceBound = sigmaThresh * it->error; + bool overAvg = ( it->value >= 0 ); + if ( (findBinsOverAvg && overAvg) || (findBinsUnderAvg && !overAvg) ) { + if ( fabsDeviation > (gthreshold + significanceBound) ) { + if ( fabsDeviation > (rthreshold + significanceBound) ) { + nBinsRed += it->n; + if (publish || publishRed) { + redClusters.push_back(*it); + } + continue; + } + nBinsYellow += it->n; + if (publish) { + yellowClusters.push_back(*it); + } + } + } + } + } + + tools::binContainer maxDevBin = { 0, -999.9, 0, 0, 0, 0, 0 }; + + // Now score each bin based on the significance of its deviation: + for (vector<tools::binContainer>::const_iterator it = deviations.begin(); it != deviations.end(); ++it) { + int bin = binwiseStatus->GetBin(it->ix,it->iy); + //Check for bins with no defined deviation / deviation error + if ( it->error < 0 ) { + binwiseStatus->SetBinContent(bin,dqm_core::Result::Undefined); + nBinsUndefined++; + continue; + } + //Check if this is the maximum deviation so far: + if (fabs(it->value) > fabs(maxDeviation) ) { // i change the maxDeviation to + // fabs(maxDeviation) + maxDeviation = it->value; + maxDevBin = *it; + } + //Check if this bin was marked as green by a prior test: + if ( it->test == 3 ) { + binwiseStatus->SetBinContent(bin,dqm_core::Result::Green); + nBinsGreen++; + continue; + } + + + double fabsDeviation = fabs(it->value); + double significanceBound = sigmaThresh * it->error; + + //Flag Green bins: + if ( fabsDeviation < (gthreshold - significanceBound ) ) { + binwiseStatus->SetBinContent(bin,dqm_core::Result::Green); + nBinsGreen++; + continue; + } + bool overAvg = ( it->value >= 0 ); + if ( (findBinsOverAvg && overAvg) || (findBinsUnderAvg && !overAvg) ) { + if ( fabsDeviation > (gthreshold + significanceBound) ) { + if ( fabsDeviation > (rthreshold + significanceBound) ) { + + binwiseStatus->SetBinContent(bin,dqm_core::Result::Red); + + //Only publish and count red bins here if they were not grouped in any cluster of bad bins: + if( it->test != 10 ) { + // Using map machinery to ensure proper ordering: worst bins should have preference in publishing. + if (publish || publishRed) { + redBins.push_back( *it ); + } + nBinsRed++; + } + continue; + } + + binwiseStatus->SetBinContent(bin,dqm_core::Result::Yellow); + //Similarly exclude clustered yellow bins from publishing and counting: + if( it->test != 10 ) { + if (publish) { + yellowBins.push_back( *it ); + } + nBinsYellow++; + } + continue; + } + } + binwiseStatus->SetBinContent(bin,dqm_core::Result::Undefined); + nBinsUndefined++; + } +//test_change begin +tools::binContainer onebin_my={0,0,0,0,0,0,0}; +tools::binContainer onebin_my_pre={0,0,0,0,0,0,0}; +double maxvalue_pre=-1; +vector<tools::binContainer> topBinEntries; +vector<tools::binContainer> topDeviations; +//int name_flag = 0; +//find_n(histogram->GetName(),name_flag); +//if(histogram->GetEntries() < 20000 ) name_flag = 1; //try to deal with low stat case +double emptyRatio_this = emptyBinCounter/(histogram->GetNbinsX()*histogram->GetNbinsY()); +//std::string tmpname ; +//tmpname = histogram->GetName(); +//if( tmpname.compare("etaphi_ncellinclus")==0 ) +//out<<"*********** emptyRatio_this is "<< emptyRatio_this << std::endl; +if (emptyRatio_this > emptyRatio) name_flag=1; +if(name_flag==1){ + int NTopEntries=0; + if(AllBinInOneStrip.size()>10 ) NTopEntries=10; + else NTopEntries = AllBinInOneStrip.size(); + int AllBinInOneStrip_size = AllBinInOneStrip.size(); + bool *bin_entries_status = new bool [AllBinInOneStrip_size]; + for(int i=0; i< AllBinInOneStrip_size; i++) bin_entries_status[i] = true; + for(int i=0;i<NTopEntries;i++){ + double maxvalue=0; + int counter=0; + int counter2=0; + for(vector<tools::binContainer>::const_iterator it =AllBinInOneStrip.begin();it!=AllBinInOneStrip.end();it++){ + int flag_my = i==0 || ( bin_entries_status[counter] && it->value <= maxvalue_pre); + if(fabs(it->value) >= fabs(maxvalue) && flag_my) { + maxvalue = it->value; + onebin_my = *it; + counter2 = counter; + } + counter++; + } + bin_entries_status[counter2]=0; +if (onebin_my.x!= onebin_my_pre.x||onebin_my.y!=onebin_my_pre.y) topBinEntries.push_back(onebin_my); + maxvalue_pre = maxvalue; + onebin_my_pre = onebin_my; +// topBinEntries.push_back(onebin_my); + } + delete[] bin_entries_status; +} +else { + int NTopdeviation=0; + if(deviations.size()>5) NTopdeviation = 5; + else NTopdeviation = deviations.size(); + int deviations_size = deviations.size(); + bool *bin_dev_status = new bool [ deviations_size]; + for(int i=0; i< deviations_size ; i++) bin_dev_status[i] = true; + for(int i=0;i<NTopdeviation;i++){ + double maxvalue=0; + int counter=0; + int counter2=0; + if(deviations.size()!=0){ + for (vector<tools::binContainer>::const_iterator it = deviations.begin(); it != deviations.end(); ++it){ + int flag_my = i==0 || ( bin_dev_status[counter] && it->value <= maxvalue_pre); + if(fabs(it->value) >= fabs(maxvalue) && flag_my) { + maxvalue = it->value; + onebin_my = *it; + counter2 = counter; + } + counter++; + } + bin_dev_status[counter2]=0; + if (onebin_my.x!= onebin_my_pre.x||onebin_my.y!=onebin_my_pre.y) { + topDeviations.push_back(onebin_my); + maxvalue_pre = maxvalue; + onebin_my_pre = onebin_my; + } +} +// topDeviations.push_back(onebin_my); + + } + delete[] bin_dev_status; + } + if ( publish || publishRed) { + + int objectsPublished = 0; + int clustersPublished = 0; + // Publish red clusters first: + std::sort( redClusters.begin(), redClusters.end(), dqm_algorithms::tools::binCluster::comp ); + vector<tools::binCluster>::const_reverse_iterator rbcrbegin = redClusters.rbegin(); + vector<tools::binCluster>::const_reverse_iterator rbcrend = redClusters.rend(); + for (vector<tools::binCluster>::const_reverse_iterator it = rbcrbegin; + it != rbcrend; ++it) { + + if (objectsPublished < maxPublish) { + char ctag[256]; + sprintf(ctag,"C%.3u-R-%.3uBins@ Eta=(%+.3f_to_%+.3f) Phi=(%+.3f_to_%+.3f) Center=(%+.3f,%+.3f) Radius=%+.3f",clustersPublished,it->n, + xBinCenters[it->ixmin],xBinCenters[it->ixmax],yBinCenters[it->iymin],yBinCenters[it->iymax],it->x,it->y,it->radius); + + string tag = ctag; + int sizeDiff = 30 - tag.size(); + if( sizeDiff > 0 ) { + tag.append(sizeDiff, '_'); + } + + result->tags_[tag] = it->value; + clustersPublished++; + objectsPublished++; + } + } + + + // Publish red bins next: + int binsPublished = 0; + std::sort( redBins.begin(), redBins.end(), dqm_algorithms::tools::binContainer::comp ); + + for ( std::vector<tools::binContainer>::const_reverse_iterator rIter = redBins.rbegin(); + rIter != redBins.rend(); + ++rIter) { + if (objectsPublished < maxPublish) { + char ctag[16]; + sprintf(ctag,"%.3u-R-",binsPublished); + std::string tag = ctag; + tools::MakeBinTag(*rIter,tag); + result->tags_[tag] = rIter->value; + binsPublished++; + objectsPublished++; + } + else { + break; + } + } + + // Now publish yellow bins: + if ( publish ) { + std::sort( yellowBins.begin(), yellowBins.end(), dqm_algorithms::tools::binContainer::comp ); + for ( std::vector<tools::binContainer>::const_reverse_iterator rIter = yellowBins.rbegin(); + rIter != yellowBins.rend(); + ++rIter) { + if (objectsPublished < maxPublish) { + char ctag[16]; + sprintf(ctag,"%.3u-Y-",binsPublished); + std::string tag = ctag; + tools::MakeBinTag(*rIter,tag); + result->tags_[tag] = rIter->value; + binsPublished++; + objectsPublished++; + + } + else { + break; + } + } + } + //Lastly publish yellow clusters: (What are these, anyway?) + if ( publish ) { + std::sort( yellowClusters.begin(), yellowClusters.end(), dqm_algorithms::tools::binCluster::comp ); + for (vector<tools::binCluster>::const_reverse_iterator it = yellowClusters.rbegin(); + it != yellowClusters.rend(); ++it) { + if (objectsPublished < maxPublish) { + char ctag[256]; + sprintf(ctag,"C%.3u-Y-%.3uBins@ Eta=(%+.3f_to_%+.3f) Phi=(%+.3f_to_%+.3f) Center=(%+.3f,%+.3f) Radius=%+.3f",clustersPublished,it->n, + xBinCenters[it->ixmin],xBinCenters[it->ixmax],yBinCenters[it->iymin],yBinCenters[it->iymax],it->x,it->y,it->radius); + string tag = ctag; + int sizeDiff = 30 - tag.size(); + if( sizeDiff > 0 ) { + tag.append(sizeDiff, '_'); + } + result->tags_[tag] = it->value; + clustersPublished++; + objectsPublished++; + } + } + } + + } + result->tags_["NBins_RED"] = nBinsRed; + result->tags_["NBins_YELLOW"] = nBinsYellow; +/* + if( maxDevBin.error != -999.9 ) { + std::string devString = "MaxDeviation-"; + tools::MakeBinTag(maxDevBin,devString); + result->tags_[devString] = maxDeviation; + } +*/ +//test_change begin +if(name_flag!=1){ + for(unsigned int i=0;i<topDeviations.size();i++){ + if(topDeviations[i].error !=-999.9 ) { + char tmp[100]; + sprintf(tmp,"MaxDeviation%i-",i); + std::string myString = tmp; + tools::MakeBinTag(topDeviations[i], myString); + result->tags_[myString] = topDeviations[i].value; + } + } +} +if(name_flag==1) { + if( maxDevBin.error != -999.9 ) { + std::string devString = "MaxDeviation-"; + tools::MakeBinTag(maxDevBin,devString); + result->tags_[devString] = maxDeviation; + } + for(unsigned int i=0;i<topBinEntries.size();i++){ + char tmp[100]; + sprintf(tmp,"LeadingBinContents%i-",i); + std::string myString = tmp; + tools::MakeBinTag(topBinEntries[i], myString); + result->tags_[myString] = topBinEntries[i].value; + } +} +//test_change end + + result->tags_["Algorithm--BinsDiffByStrips"] = 5; //Provide algorithm name and number of results histograms in TObjArray, for convenience of summary maker: + + //Determine if the configuration wants this to be part of an AndGroup, used by BinwiseSummary to require reds from the + // same bin in multiple plots for red to be propogated. + const double andGroup = dqm_algorithms::tools::GetFirstFromMap("AndGroup", config.getParameters(), -99999); + if( andGroup != -99999 ) { + result->tags_["AndGroup"] = andGroup; + } + + + TObjArray * resultList = new TObjArray(5,0); + + //This order is important! Add new histograms at the end of the list only to avoid breaking summarymakers and be sure to increase + // the alocated capacity of the TObjArray set in the constructor above. + resultList->Add(binwiseStatus); + resultList->Add(inputBins); + resultList->Add(binDeviations); + resultList->Add(stripAverages); + resultList->Add(stripVariances); + + resultList->SetOwner(true); + + result->object_ = (std::auto_ptr<TObject>)(TObject*)(resultList); + + + if( doChiSquaredTest ) { + + std::pair<double,double> chiSquareResult = dqm_algorithms::tools::CalcBinsProbChisq(inputValues,inputErrors,stripAveragesVector,stripErrors); + result->tags_["SigmaChiSq"] = chiSquareResult.second; + + if ( testConsistencyWithErrors ) { + //Determine status based on quality of chi squared fit: + if ( chiSquareResult.second <= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( chiSquareResult.second < rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + + return result; + } + } + + // Determine status based on the number of red, yellow, green, and other bins: + int nActiveBins = nBinsGreen + nBinsRed + nBinsYellow + nBinsUndefined; + if( nActiveBins != 0 ) { + if ( (nBinsRed >= nRedBinsToRedStatus) || ((nBinsRed * 1.0 / nActiveBins) > redFracToRedStatus) ) { + result->status_ = dqm_core::Result::Red; + } + else if ( ((nBinsRed + nBinsYellow) >= nYellowBinsToYellowStatus) + || (((nBinsRed + nBinsYellow) / nActiveBins) > yellowFracToYellowStatus) ) { + result->status_ = dqm_core::Result::Yellow; + } + else if ( (nBinsGreen * 1.0 / nActiveBins ) >= greenFracToGreenStatus ) { + result->status_ = dqm_core::Result::Green; + } + else { + result->status_ = dqm_core::Result::Undefined; + } + } + else { + result->status_ = dqm_core::Result::Disabled; + } + return result; +} + + +void +dqm_algorithms::BinsDiffByStrips::printDescription(std::ostream& out) +{ + + out<<"BinsDiffByStrips: Calculates Average bin value and variance for each strip of constant x and finds bins in that strip that our outliers from the mean\n"<<std::endl; + out<<"Mandatory Green/Red Threshold: MaxDeviation: size of deviation from mean, in multiples of variance, for bin to be considered Green/Red. Overall result is result for worst bin"<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to return defined result"<<std::endl; + out<<"Optional Parameter: ignoreval: value to be ignored for calculating average, variance, and identifying bad bins. Ignored bins are flagged as Disabled"<<std::endl; + out<<"Optional Parameter: useStripsOfConstantY: compare bins in strips of constant Y rather than constant X, as is the defualt (set to 1 for true). Default = false"<<std::endl; + + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: ymin: minimum y range"<<std::endl; + out<<"Optional Parameter: ymax: maximum y range"<<std::endl; + out<<"Optional Parameter: GreaterThan: check for bins which are GreaterThan average (set to 1 for true). Default = true"<<std::endl; + out<<"Optional Parameter: LessThan: check for bins which are LessThan average (set to 1 for true). Default = true"<<std::endl; + out<<"Optional Parameter: PublishBins: Save all bin quality decisions in output histogram and save Red and Yellow bins in tag output (set to 1 for true). Default = false"<<std::endl; + out<<"Optional Parameter: PublishRedBins: Save bins identified as Red in tag output(set to 1 for true). Default = false"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save in tag output. Default = 20"<<std::endl; + out<<"Optional Parameter: MinBinsAfterSkimming : Minimum number of bins remaining after skimming for any bins to be flagged as Red/Yellow/Green. If threshold is not met, another attempt will be made at the iteration process with these few bin excluded in the first pass. Failing success, the entire strip will be flagged as Undefined. Default = 5"<<std::endl; + out<<"Optional Parameter: MinAbsDiffFromAvg : Bins whose absolute difference from the mean is less than this amount, in a statistically significant fashion, will always be flagged as green." + <<"Bin will be flagged as either Green or Undefined, depending on significance by which it passes this cut."<<std::endl; + out<<"Optional Parameter: nIterations : Number of iterations to be used in calculating mean and variance while skimming outliers. Default = 10" <<std::endl; + out<<"Optional Parameter: MaxNRetryIteration : Maxiumum number of times the iteration should be restarted should it fail (by leaving fewer than MinBinsAfterSkimming), reseeding with those cells that pass the iteration removed in the first pass. If MaxNRetryIteration = 0, will never retry. Default = 5. " <<std::endl; + out<<"Optional Parameter: IterVariationExponent: exponent k used in calculating the generalized variance, iVar, where iVar = (sum[ (abs[ x - xbar ])^k ])^(1/k). If k = 2, for instance, iVar is equivalent to the standard variance. (If nIterations = 1, this parameter has no effect.) Default = -1.4235"<<std::endl; + out<<"Optional Parameter: IterDeviationThresh : size of deviation from mean, in multiples of the generalized variance, for bin to be excluded during iterative calculation of mean and variance. (If nIterations = 1, this parameter has no effect.) Default = 1.3"<<std::endl; + + out<<"Optional Parameter: SigmaThresh : Minimum significance (distance from threshold in multiples of the error) for quality statement to be made about a bin). Default = 5"<<std::endl; + out<<"Optional Parameter: FindOutliersUsingErrors : Switch to use outlier finding based on the pull of the mean of each bin given its error as compared to the error on the mean, rather than the default error independent aproach."<<std::endl; + out<<"Optional Parameter: UseMeanErrorForScale : Use the average error of the non-outliers, rather than their estimated variance, as the scale against which deviations are measured."<<std::endl; + out<<"Optional Parameter: DoChiSquaredTest : Calculate the Chi_Squared value for the distribution of all the bin values given the scale (estimated variance or, if UseMeanErrorForScale is used, mean error."<<std::endl; + out<<"Optional Parameter: TestConsistencyWithErrors : Switch on FindOutliersUsingErrors, UseMeanErrorForScale, and DoChiSquaredTest and base the DQ decision on the Chi-Squared result"<<std::endl; +} +void +dqm_algorithms::BinsDiffByStrips::find_n(std::string name_tmp,int& name_flag){ + int where = name_tmp.find_last_of("_"); + std::string name; + name = name_tmp.substr(where+1); + if(name.compare("5Sigma")==0 || name_tmp.compare("m_EtavsPhi3")==0 || name_tmp.compare("m_EtavsPhi4")==0 ) name_flag=1; + else name_flag = 0; +} + + diff --git a/DataQuality/dqm_algorithms/src/BinsDiffFromStripMedian.cxx b/DataQuality/dqm_algorithms/src/BinsDiffFromStripMedian.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9a7ed448ae757e3c4cdf2d9f932eeefaf95f7c5c --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinsDiffFromStripMedian.cxx @@ -0,0 +1,434 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* BinsDiffFromStripMedian.cxx is to pick out the problematic bins in 2D histogram assuming that y-axis(the phi direction) be symmetric. + Author: Feng TIAN (columbia university) + Email: Feng.Tian@cern.ch +*/ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinsDiffFromStripMedian.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> + +#include <iostream> +#include <string> + +using namespace std; +bool mySortfunc(bin i,bin j){return (i.m_value > j.m_value);} +bool mySortfunc_ratio(bin i, bin j){return (i.m_outstandingRatio> j.m_outstandingRatio);} +static dqm_algorithms::BinsDiffFromStripMedian myInstance; + +dqm_algorithms::BinsDiffFromStripMedian::BinsDiffFromStripMedian( ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BinsDiffFromStripMedian", this); +} + +dqm_algorithms::BinsDiffFromStripMedian::~BinsDiffFromStripMedian() +{ +} + +dqm_algorithms::BinsDiffFromStripMedian * +dqm_algorithms::BinsDiffFromStripMedian::clone() +{ + + return new BinsDiffFromStripMedian(); +} + + +dqm_core::Result * +dqm_algorithms::BinsDiffFromStripMedian::execute(const std::string & name, + const TObject& object, + const dqm_core::AlgorithmConfig& config ) +{ + TH1* histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const double ignoreval = dqm_algorithms::tools::GetFirstFromMap( "ignoreval", config.getParameters(), -99999); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 1); + const int Nmaxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const bool VisualMode = (bool) dqm_algorithms::tools::GetFirstFromMap( "VisualMode", config.getParameters(), 1); + const int NpublishRed = (int) dqm_algorithms::tools::GetFirstFromMap( "PublishRedBins",config.getParameters(), 0); + const bool ClusterResult = (bool) dqm_algorithms::tools::GetFirstFromMap( "ClusterResult", config.getParameters(), 0); + const double suppressFactor = dqm_algorithms::tools::GetFirstFromMap("SuppressFactor", config.getParameters(), 0.05); + const double suppressRedFactor = dqm_algorithms::tools::GetFirstFromMap("SuppressRedFactor", config.getParameters(), 0.01); + if ( histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double gthreshold; + double rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + vector<double> stripsMedian; + vector<double> stripsAvg; + vector<double> stripsVariance; + double maxInMap=0; + for ( int i = range[0]; i <= range[1]; ++i ) { + vector<double> onestrip; + double stripSum=0; + for ( int j = range[2]; j <= range[3]; ++j ) { + if (histogram->GetBinContent(i,j) == ignoreval) continue; + float binvalue = histogram->GetBinContent(i,j); + onestrip.push_back(binvalue); + stripSum += binvalue; + if(binvalue > maxInMap) { + maxInMap = binvalue; + } + } +// if(onestrip.size()!=0 ) + stripsAvg.push_back(stripSum/onestrip.size()); +// else stripsAvg.push_back(0); + FindStripMedian(onestrip,stripsMedian); + } + for ( int i = range[0]; i <= range[1]; ++i ) { + float sumdiff2=0; + int counter=0; + for ( int j = range[2]; j <= range[3]; ++j ) { + if (histogram->GetBinContent(i,j) == ignoreval) continue; + double binvalue = histogram->GetBinContent(i,j); + double diff=binvalue-stripsAvg[i-range[0]]; + sumdiff2 +=pow(diff,2); + counter++; + } + double variance=-1; + if(counter!=0) variance = sumdiff2 / counter ; + stripsVariance.push_back(variance); + } + dqm_core::Result* result = new dqm_core::Result(); + vector<bin> redbins; + vector<bin> yellowbins; + vector<bin> Allbins; + for ( int k = range[0]; k <= range[1]; ++k ) { + for ( int l = range[2]; l <= range[3]; ++l ) { + double binvalue = histogram->GetBinContent(k,l); + if (binvalue== ignoreval) continue; + double strip_median = stripsMedian[k-range[0]]; + if(stripsMedian[k-range[0]]==0 && stripsVariance[k-range[0]]==0) continue; // skip empty strip + else if(stripsMedian[k-range[0]]==0 && stripsVariance[k-range[0]]!=0 && stripsAvg[k-range[0]]!=0) strip_median = stripsAvg[k-range[0]]; + else if(stripsMedian[k-range[0]]==0 && stripsVariance[k-range[0]]!=0 && stripsAvg[k-range[0]]==0) continue; + double outstandingRatio=0; + if(fabs(strip_median) > 0.00001 ) outstandingRatio= /*binvalue/strip_median*/ (binvalue-strip_median)/sqrt(fabs(strip_median)); + else continue; + double eta = histogram->GetXaxis()->GetBinCenter(k); + double phi = histogram->GetYaxis()->GetBinCenter(l); + bin onebin = {eta,phi,k,l,binvalue,outstandingRatio}; + Allbins.push_back(onebin); +// if( VisualMode && (binvalue / maxInMap < suppressFactor) ) continue; + if(fabs(outstandingRatio) > rthreshold ) { + if( VisualMode && (binvalue / maxInMap < suppressRedFactor) ) + continue; + redbins.push_back(onebin); + } + else if(fabs(outstandingRatio) > gthreshold ){ + if( VisualMode && (binvalue / maxInMap < suppressFactor) ) + continue; + yellowbins.push_back(onebin); + } + } + } + int count_red_c = 0; + int count_yellow_c = 0; + vector<vector<colorbin> > ColorBinMap; +if(ClusterResult){ + // initialize ColorBinMap + for ( int k = range[0]; k <= range[1]; ++k ) { + vector<colorbin> oneColorStrip; + for ( int l = range[2]; l <= range[3]; ++l ) { + colorbin oneColorBin = {static_cast<double>(k), static_cast<double>(l), -1, -1, -1, green, 1}; + oneColorStrip.push_back(oneColorBin); + } + ColorBinMap.push_back(oneColorStrip); + } + +// map redbins and yellowbins to ColorBinMap + for(unsigned int i=0;i<redbins.size();i++){ + int k=redbins[i].m_ix; + int l=redbins[i].m_iy; + + ColorBinMap[k-range[0]][l-range[2]].m_eta = redbins[i].m_eta; + + ColorBinMap[k-range[0]][l-range[2]].m_phi = redbins[i].m_phi; + ColorBinMap[k-range[0]][l-range[2]].m_value = redbins[i].m_value; + ColorBinMap[k-range[0]][l-range[2]].m_color = red; + + } + + + for(unsigned int i=0;i<yellowbins.size();i++){ + int k=yellowbins[i].m_ix; + int l=yellowbins[i].m_iy; + ColorBinMap[k-range[0]][l-range[2]].m_eta = yellowbins[i].m_eta; + ColorBinMap[k-range[0]][l-range[2]].m_phi = yellowbins[i].m_phi; + ColorBinMap[k-range[0]][l-range[2]].m_value = yellowbins[i].m_value; + ColorBinMap[k-range[0]][l-range[2]].m_color = yellow; + } + + +// cluster bad bins + vector<colorcluster > clusterArray; + for(unsigned int i=0;i<redbins.size();i++){ + const int k=redbins[i].m_ix; + const int l=redbins[i].m_iy; + if(ColorBinMap[k-range[0]][l-range[2]].m_color != green){ + colorcluster onecluster = MakeCluster(range[0],range[2],redbins[i],ColorBinMap); + if(onecluster.m_size > 1) clusterArray.push_back(onecluster); + } + } + for(unsigned int i=0;i<yellowbins.size();i++){ + const int k=yellowbins[i].m_ix; + const int l=yellowbins[i].m_iy; + if(ColorBinMap[k-range[0]][l-range[2]].m_color != green){ + colorcluster onecluster = MakeCluster(range[0],range[2],yellowbins[i],ColorBinMap); + if(onecluster.m_size > 1) clusterArray.push_back(onecluster); + } + } + + // publish clusters here: + for(unsigned int i=0;i<clusterArray.size();i++){ + char tmp[500]; + if(clusterArray[i].m_color==red){ + sprintf(tmp,"CR%i-(eta,phi)(r)(size)=(%0.3f,%0.3f)(%0.3f)(%i)",count_red_c,clusterArray[i].m_eta,clusterArray[i].m_phi,clusterArray[i].m_radius,clusterArray[i].m_size); + count_red_c++; + } + else if(clusterArray[i].m_color==yellow){ + sprintf(tmp,"CY%i-(eta,phi)(r)(size)=(%0.3f,%0.3f)(%0.3f)(%i)",count_yellow_c,clusterArray[i].m_eta,clusterArray[i].m_phi,clusterArray[i].m_radius,clusterArray[i].m_size); + count_yellow_c++; + } + std::string tag = tmp; + result->tags_[tag] = clusterArray[i].m_value; + } + result->tags_["NRedClusters"] = count_red_c; + result->tags_["NYellowClusters"] = count_yellow_c; + + } + + + std::sort(redbins.begin(),redbins.end(),mySortfunc); + std::sort(yellowbins.begin(),yellowbins.end(),mySortfunc); + std::sort(Allbins.begin(),Allbins.end(),mySortfunc_ratio); +// publish red bins + int count_red=0; + for(unsigned int i=0;i<redbins.size();i++){ + if(ClusterResult && ColorBinMap[redbins[i].m_ix-range[0]][redbins[i].m_iy-range[2]].m_status==0 ) continue; + if(publish){ + char tmp[500]; + sprintf(tmp,"R%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%0.2e]",count_red,redbins[i].m_eta,redbins[i].m_phi,redbins[i].m_outstandingRatio); + std::string tag = tmp; + result->tags_[tag] = redbins[i].m_value; + } + count_red++; + if(NpublishRed > 0){ + if(count_red > NpublishRed) break; + } + } + +// publish yellow bins + int count_yellow=0; + for(unsigned int i=0;i<yellowbins.size();i++){ + if(ClusterResult &&ColorBinMap[yellowbins[i].m_ix-range[0]][yellowbins[i].m_iy-range[2]].m_status==0) continue; + if(publish && (count_red+count_yellow) < Nmaxpublish ){ + char tmp[500]; + sprintf(tmp,"Y%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%.2e]",count_yellow,yellowbins[i].m_eta,yellowbins[i].m_phi,yellowbins[i].m_outstandingRatio); + std::string tag = tmp; + result->tags_[tag] = yellowbins[i].m_value; + } + count_yellow++; + } + result->tags_["NRedBins"] = count_red; // count_red is the number of red bins printed + result->tags_["NYellowBins"] = count_yellow; // count_yellow is the number of yellow bins printed + + if(count_red+count_yellow==0 && Allbins.size()>=5 ){ + for(int i=0;i<5;i++){ + char tmptmp[500]; + sprintf(tmptmp,"LeadingBin%i-(eta,phi)=(%0.3f,%0.3f)",i,Allbins[i].m_eta,Allbins[i].m_phi); + std::string tagtag = tmptmp; + result->tags_[tagtag] = Allbins[i].m_value; + } + + } + + + if(count_red>0 || count_red_c>0) result->status_ = dqm_core::Result::Red; + else if (count_yellow>0||count_yellow_c>0) result->status_ = dqm_core::Result::Yellow; + else result->status_ = dqm_core::Result::Green; + + return result; + +} +void +dqm_algorithms::BinsDiffFromStripMedian::FindStripMedian(vector<double> onestrip_tmp,vector<double>& stripsMedian){ + double median=0; +// if(onestrip_tmp.size()==0) stripsMedian.push_back(median); +// else{ + std::sort(onestrip_tmp.begin(),onestrip_tmp.end()); + int index1=onestrip_tmp.size()/4; +// int index1=int(floor(onestrip_tmp.size()/4.)); +// int index2=int(floor(onestrip_tmp.size()/2.)); + int index2=onestrip_tmp.size()/2; + int index3=3*onestrip_tmp.size()/4; +// int index3=int(floor(3*onestrip_tmp.size()/4.)); + median = (onestrip_tmp[index1]+onestrip_tmp[index2]+onestrip_tmp[index3])/3.0; +// median = (onestrip_tmp[index2]); + stripsMedian.push_back(median); +// } +} +void AddToList(const int r0,const int r2,int i,int j,vector<vector<colorbin> > & ColorBinMap, vector<colorbin>& LookAtList){ + + if( i-r0<0 || i-r0>=(int)ColorBinMap.size() + || j-r2<0 ||j-r2>=(int)ColorBinMap[0].size() ) return; + + vector<colorbin> tmp; + + if(i-1-r0>=0 && j-1-r2>=0 && ColorBinMap[i-1-r0][j-1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-1-r0][j-1-r2]); + ColorBinMap[i-1-r0][j-1-r2].m_status=0; + } + if(j-1-r2 >=0 && ColorBinMap[i-r0][j-1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-r0][j-1-r2]); + ColorBinMap[i-r0][j-1-r2].m_status=0; + } + if(i+1-r0<(int)ColorBinMap.size() && j-1-r2 >=0 && ColorBinMap[i+1-r0][j-1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i+1-r0][j-1-r2]); + ColorBinMap[i+1-r0][j-1-r2].m_status=0; + } + if(i-1-r0>=0 && ColorBinMap[i-1-r0][j-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-1-r0][j-r2]); + ColorBinMap[i-1-r0][j-r2].m_status=0; + } + + if(i+1-r0<(int)ColorBinMap.size() && ColorBinMap[i+1-r0][j-r2].m_status==1){ + tmp.push_back(ColorBinMap[i+1-r0][j-r2]); + ColorBinMap[i+1-r0][j-r2].m_status=0; + } + if(i-1-r0>=0 && j+1-r2 < (int)ColorBinMap[0].size() + && ColorBinMap[i-1-r0][j+1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-1-r0][j+1-r2]); + ColorBinMap[i-1-r0][j+1-r2].m_status=0; + } +if(j+1-r2<(int)ColorBinMap[0].size()&& ColorBinMap[i-r0][j+1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-r0][j+1-r2]); + ColorBinMap[i-r0][j+1-r2].m_status=0; + } + if(i+1-r0<(int)ColorBinMap.size() && j+1-r2<(int)ColorBinMap[0].size()&&ColorBinMap[i+1-r0][j+1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i+1-r0][j+1-r2]); + ColorBinMap[i+1-r0][j+1-r2].m_status=0; + } + + for(unsigned int k=0;k<tmp.size();k++){ + if(tmp[k].m_color!=green){ + LookAtList.push_back(tmp[k]); + AddToList(r0,r2,tmp[k].m_ix,tmp[k].m_iy,ColorBinMap,LookAtList); + } + } + return; + +} + +double CalEta(vector<colorbin>& LookAtList){ + double sumEta=0; + double sumN=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double eta = LookAtList[i].m_eta; + double n = LookAtList[i].m_value; + sumEta += n*eta; + sumN +=n; + } + if(sumN!=0) return sumEta/sumN; + else return -99; +} +double CalPhi(vector<colorbin>& LookAtList){ + double sumPhi=0; + double sumN=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double phi = LookAtList[i].m_phi; + double n = LookAtList[i].m_value; + sumPhi += n*phi; + sumN +=n; + } + if(sumN!=0) return sumPhi/sumN; + else return -99; +} +double CalVal(vector<colorbin>& LookAtList){ + double sumN=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double n = LookAtList[i].m_value; + sumN += n; + } + return sumN; +} +double CalR(vector<colorbin>& LookAtList,double eta, double phi){ + if(LookAtList.size()<2) return 0; + double maxR=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double distance = sqrt(pow((LookAtList[i].m_eta-eta),2)+pow((LookAtList[i].m_phi-phi),2)); + maxR=distance>maxR?distance:maxR; + } + return maxR; +} + +colorcluster +dqm_algorithms::BinsDiffFromStripMedian::MakeCluster(const int r0,const int r2,bin& onebin, vector<vector<colorbin> > & ColorBinMap){ + colorcluster onecluster={0,0,0,0,green,-1}; + if(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_status==0) + return onecluster; + vector<colorbin> LookAtList; + if(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_color!=green){ + LookAtList.push_back(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2]); + ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_status=0; + AddToList(r0,r2,onebin.m_ix,onebin.m_iy,ColorBinMap, LookAtList); + if(LookAtList.size()>1){ + onecluster.m_size = LookAtList.size(); + onecluster.m_value = CalVal(LookAtList); + if(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_color==red) + onecluster.m_color = red; + else onecluster.m_color = yellow; + onecluster.m_eta = CalEta(LookAtList); + onecluster.m_phi = CalPhi(LookAtList); + onecluster.m_radius = CalR(LookAtList,onecluster.m_eta,onecluster.m_phi); + } + else ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_status=1; + } + return onecluster; +} + +void +dqm_algorithms::BinsDiffFromStripMedian::printDescription(std::ostream& out) +{ + + out<<"BinsDiffFromStripMedian: Calculates smoothed strip median and then find out bins which are aliens "<<std::endl; + + out<<"Mandatory Green/Red Threshold is the value of outstandingRatio=(bin value)/(strip median) based on which to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: ignoreval: valued to be ignored for being processed"<<std::endl; + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (on:1,off:0,default is 1)"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: VisualMode: is to make the evaluation process similar to the shift work, so one will get resonable result efficiently."<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/BinsDiffFromStripMedianOnline.cxx b/DataQuality/dqm_algorithms/src/BinsDiffFromStripMedianOnline.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f51f0587959149a059c5c2062049b2df1fafa4b7 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinsDiffFromStripMedianOnline.cxx @@ -0,0 +1,638 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* BinsDiffFromStripMedianOnline.cxx is to pick out the problematic bins in 2D histogram assuming that y-axis(the phi direction) be symmetric. + Author: Feng TIAN (columbia university) + Email: Feng.Tian@cern.ch +*/ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinsDiffFromStripMedianOnline.h> +#include "dqm_algorithms/BinsDiffFromStripMedian.h" +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> + +#include <iostream> +#include <string> + +using namespace std; + +//bool mySortfunc(binOnline i,binOnline j){return (i.m_value > j.m_value);} +//bool mySortfunc_ratio(binOnline i, binOnline j){return (i.m_outstandingRatio> j.m_outstandingRatio);} + +static dqm_algorithms::BinsDiffFromStripMedianOnline myInstance; + +dqm_algorithms::BinsDiffFromStripMedianOnline::BinsDiffFromStripMedianOnline( ){ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BinsDiffFromStripMedianOnline", this); +} + +dqm_algorithms::BinsDiffFromStripMedianOnline::~BinsDiffFromStripMedianOnline(){ +} + +dqm_algorithms::BinsDiffFromStripMedianOnline * dqm_algorithms::BinsDiffFromStripMedianOnline::clone(){ + return new BinsDiffFromStripMedianOnline(); +} + + +dqm_core::Result * dqm_algorithms::BinsDiffFromStripMedianOnline::execute(const std::string & name, + const TObject& object, + const dqm_core::AlgorithmConfig& config ){ + TH1* histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const double minstatperstrip = dqm_algorithms::tools::GetFirstFromMap( "MinStatPerstrip", config.getParameters(), -1); + const double ignoreval1 = dqm_algorithms::tools::GetFirstFromMap( "ignoreval1", config.getParameters(), -99999); + const double ignoreval2 = dqm_algorithms::tools::GetFirstFromMap( "ignoreval2", config.getParameters(), 0.); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 1); + const int Nmaxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const bool VisualMode = (bool) dqm_algorithms::tools::GetFirstFromMap( "VisualMode", config.getParameters(), 1); + const int NpublishRed = (int) dqm_algorithms::tools::GetFirstFromMap( "PublishRedBins",config.getParameters(), 0); + const bool ClusterResult = (bool) dqm_algorithms::tools::GetFirstFromMap( "ClusterResult", config.getParameters(), 0); + const double suppressFactor = dqm_algorithms::tools::GetFirstFromMap("SuppressFactor", config.getParameters(), 0.05); + const double suppressRedFactor = dqm_algorithms::tools::GetFirstFromMap("SuppressRedFactor", config.getParameters(), 0.01); + const bool OnlineMode = (bool) dqm_algorithms::tools::GetFirstFromMap( "OnlineMode", config.getParameters(), 0); + const double Nred_red = (double) dqm_algorithms::tools::GetFirstFromMap( "Nred_red", config.getParameters(), 5.); + const double Nred_yellow = (double) dqm_algorithms::tools::GetFirstFromMap( "Nred_yellow", config.getParameters(), 3.); + const double Nyellow_yellow = (double) dqm_algorithms::tools::GetFirstFromMap( "Nyellow_yellow", config.getParameters(), 5.); + const double Nredyellow_yellow = (double) dqm_algorithms::tools::GetFirstFromMap( "Nredyellow_yellow", config.getParameters(), 4.); + + if ( histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double gthreshold; + double rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getGreenThresholds() ); + }catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + vector<double> stripsSize; + vector<double> stripsMedian; + vector<double> stripsAvg; + vector<double> stripsVariance; + double maxInMap=0; + + if ( (int)range.size() < 4 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "BinRange vector <4 " ); + } + + for ( int i = range[0]; i <= range[1]; ++i ) { + vector<double> onestrip; + double stripSum=0; + for ( int j = range[2]; j <= range[3]; ++j ) { + float binvalue = histogram->GetBinContent(i,j); + if (fabs(binvalue- ignoreval1)<0.0001 || fabs(binvalue - ignoreval2)<0.0001) continue; + onestrip.push_back(binvalue); + stripSum += binvalue; + if(binvalue > maxInMap) { + maxInMap = binvalue; + } + } + if(onestrip.size()!=0 ) { + stripsAvg.push_back(stripSum/onestrip.size()); + }else { + stripsAvg.push_back(0); + } + FindStripMedianOnline(name,onestrip,stripsMedian); + stripsSize.push_back(onestrip.size()); + + float sumdiff2=0; + int counter=0; + if ((int)stripsAvg.size() <= i-range[0] ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of stripsAvg range " ); + } + float strip_avg = stripsAvg[i-range[0]]; + + for ( int j = range[2]; j <= range[3]; ++j ) { + if (fabs(histogram->GetBinContent(i,j)-ignoreval1)<0.0001 || fabs(histogram->GetBinContent(i,j)-ignoreval2)<0.0001) continue; + double binvalue = histogram->GetBinContent(i,j); + double diff=binvalue-strip_avg; + sumdiff2 +=pow(diff,2); + counter++; + } + double variance=-1; + if(counter!=0) variance = sumdiff2 / counter ; + stripsVariance.push_back(variance); + } + + dqm_core::Result* result = new dqm_core::Result(); + vector<binOnline> redbins; + vector<binOnline> yellowbins; + vector<binOnline> Allbins; + int limit = range[1]-range[0]; + for ( int q=0; q <= limit; ++q ) { + int k=q+range[0]; + if ((int)stripsSize.size() <= q ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of stripsSize range " ); + } + if(stripsSize[q]<minstatperstrip) continue; + if ((int)stripsMedian.size() <= q ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of stripsMedian range " ); + } + if ((int)stripsVariance.size() <= q){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of stripsVariance range " ); + } + if ((int)stripsAvg.size() <= q ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of stripsAvg range " ); + } + double strip_median = stripsMedian[q]; + double strip_variance = stripsVariance[q]; + double strip_avg = stripsAvg[q]; + + if(fabs(strip_median)<0.0001 && fabs(strip_variance)<0.0001){ + continue; // skip empty strip + }else { + if(fabs(strip_median)<0.0001 && fabs(strip_variance)>0.0001 && fabs(strip_avg)>0.0001) { + strip_median = strip_avg; + } else{ + if(fabs(strip_median)<0.0001 && fabs(strip_variance)>0.0001 && fabs(strip_avg)<0.0001) continue; + } + } + + + for ( int l = range[2]; l <= range[3]; ++l ) { + double binvalue = histogram->GetBinContent(k,l); + if (fabs(binvalue-ignoreval1)<0.0001 || fabs(binvalue-ignoreval2)<0.0001) continue; + double outstandingRatio=0; + if(fabs(strip_median) > 0.0001 ){ + outstandingRatio= /*binvalue/strip_median*/ (binvalue-strip_median)/sqrt(fabs(strip_median)); + }else{ + continue; + } + double eta = histogram->GetXaxis()->GetBinCenter(k); + double phi = histogram->GetYaxis()->GetBinCenter(l); + binOnline onebin = {eta,phi,k,l,binvalue,outstandingRatio}; + Allbins.push_back(onebin); + // if( VisualMode && (binvalue / maxInMap < suppressFactor) ) continue; + if(fabs(outstandingRatio) > rthreshold ) { + if( VisualMode && (binvalue / maxInMap < suppressRedFactor) ){ + continue; + } + redbins.push_back(onebin); + }else if(fabs(outstandingRatio) > gthreshold ){ + if( VisualMode && (binvalue / maxInMap < suppressFactor) ){ + continue; + } + yellowbins.push_back(onebin); + } + } + } + int count_red_c = 0; + int count_yellow_c = 0; + vector<vector<colorbinOnline> > ColorBinMap; + if(ClusterResult){ + // initialize ColorBinMap + int limit = range[1]-range[0]; + for ( int q = 0; q <= limit; ++q ) { + int k =q+range[0]; + vector<colorbinOnline> oneColorStrip; + for ( int l = range[2]; l <= range[3]; ++l ) { + // colorbinOnline oneColorBin = {k,l,-1,-1,-1,green,1}; + colorbinOnline oneColorBin = {-1,-1,k,l,-1,green,1}; + oneColorStrip.push_back(oneColorBin); + } + ColorBinMap.push_back(oneColorStrip); + } + + // map redbins and yellowbins to ColorBinMap + for(unsigned int i=0;i<redbins.size();i++){ + // int k=redbins[i].m_ix; + // int l=redbins[i].m_iy; + int q=redbins[i].m_ix - range[0]; + int p = redbins[i].m_iy-range[2]; + + if ((int)ColorBinMap.size() <= q){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if ((int)ColorBinMap[q].size() <= p ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + ColorBinMap[q][p].m_eta = redbins[i].m_eta; + + ColorBinMap[q][p].m_phi = redbins[i].m_phi; + ColorBinMap[q][p].m_value = redbins[i].m_value; + ColorBinMap[q][p].m_color = red; + + } + + + for(unsigned int i=0;i<yellowbins.size();i++){ + // int k=yellowbins[i].m_ix; + // int l=yellowbins[i].m_iy; + int q=yellowbins[i].m_ix - range[0]; + int p = yellowbins[i].m_iy-range[2]; + + if ((int)ColorBinMap.size() <= q ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if ((int)ColorBinMap[q].size() <= p ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + ColorBinMap[q][p].m_eta = yellowbins[i].m_eta; + ColorBinMap[q][p].m_phi = yellowbins[i].m_phi; + ColorBinMap[q][p].m_value = yellowbins[i].m_value; + ColorBinMap[q][p].m_color = yellow; + } + + + // cluster bad bins + vector<colorclusterOnline > clusterArray; + for(unsigned int i=0;i<redbins.size();i++){ + // const int k=redbins[i].m_ix; + // const int l=redbins[i].m_iy; + int q=redbins[i].m_ix - range[0]; + int p = redbins[i].m_iy-range[2]; + + if ((int)ColorBinMap.size() <= q ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if ((int)ColorBinMap[q].size() <= p ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if(ColorBinMap[q][p].m_color != green){ + colorclusterOnline onecluster = MakeClusterOnline(name,range[0],range[2],redbins[i],ColorBinMap); + // colorclusterOnline onecluster = {0,0,0,0,green,-1}; + if((int)onecluster.m_size > 1) clusterArray.push_back(onecluster); + } + } + for(unsigned int i=0;i<yellowbins.size();i++){ + // const int k=yellowbins[i].m_ix; + // const int l=yellowbins[i].m_iy; + int q=yellowbins[i].m_ix - range[0]; + int p = yellowbins[i].m_iy-range[2]; + + if ((int)ColorBinMap.size() <= q ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if ((int)ColorBinMap[q].size() <= p ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if(ColorBinMap[q][p].m_color != green){ + colorclusterOnline onecluster = MakeClusterOnline(name,range[0],range[2],yellowbins[i],ColorBinMap); + // colorclusterOnline onecluster = {0,0,0,0,green,-1}; + if((int)onecluster.m_size > 1) clusterArray.push_back(onecluster); + } + } + + // publish clusters here: + for(unsigned int i=0;i<clusterArray.size();i++){ + char tmp[500]; + if(clusterArray[i].m_color==red){ + snprintf(tmp,500,"CR%i-(eta,phi)(r)(size)=(%0.3f,%0.3f)(%0.3f)(%i)",count_red_c,clusterArray[i].m_eta,clusterArray[i].m_phi,clusterArray[i].m_radius,clusterArray[i].m_size); + count_red_c++; + }else if(clusterArray[i].m_color==yellow){ + snprintf(tmp,500,"CY%i-(eta,phi)(r)(size)=(%0.3f,%0.3f)(%0.3f)(%i)",count_yellow_c,clusterArray[i].m_eta,clusterArray[i].m_phi,clusterArray[i].m_radius,clusterArray[i].m_size); + count_yellow_c++; + } + std::string tag(tmp); + result->tags_[tag] = clusterArray[i].m_value; + } + result->tags_["NRedClusters"] = count_red_c; + result->tags_["NYellowClusters"] = count_yellow_c; + + } + + // std::sort(redbins.begin(),redbins.end(),mySortfunc); + std::sort(redbins.begin(),redbins.end()); + // std::sort(yellowbins.begin(),yellowbins.end(),mySortfunc); + std::sort(yellowbins.begin(),yellowbins.end()); + // std::sort(Allbins.begin(),Allbins.end(),mySortfunc_ratio); + std::sort(Allbins.begin(),Allbins.end()); + // publish red bins + int count_red=0; + for(unsigned int i=0;i<redbins.size();i++){ + + int q = redbins[i].m_ix-range[0]; + int p = redbins[i].m_iy-range[2]; + + if(ClusterResult){ + if(q<(int)ColorBinMap.size()){ + if(p<(int)ColorBinMap[q].size()){ + if( ColorBinMap[q][p].m_status==0 ) continue; + } + } + } + + if(publish){ + char tmp[500]; + snprintf(tmp,500,"R%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%0.2e]",count_red,redbins[i].m_eta,redbins[i].m_phi,redbins[i].m_outstandingRatio); + std::string tag(tmp); + result->tags_[tag] = redbins[i].m_value; + } + count_red++; + if(NpublishRed > 0){ + if(count_red > NpublishRed) break; + } + } + + // publish yellow bins + int count_yellow=0; + for(unsigned int i=0;i<yellowbins.size();i++){ + int q = yellowbins[i].m_ix-range[0]; + int p = yellowbins[i].m_iy-range[2]; + + if(ClusterResult){ + if(q<(int)ColorBinMap.size()){ + if(p<(int)ColorBinMap[q].size()){ + if(ColorBinMap[q][p].m_status==0) continue; + } + } + } + if(publish && (count_red+count_yellow) < Nmaxpublish ){ + char tmp[500]; + snprintf(tmp,500,"Y%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%.2e]",count_yellow,yellowbins[i].m_eta,yellowbins[i].m_phi,yellowbins[i].m_outstandingRatio); + std::string tag(tmp); + result->tags_[tag] = yellowbins[i].m_value; + } + count_yellow++; + } + result->tags_["NRedBins"] = count_red; // count_red is the number of red bins printed + result->tags_["NYellowBins"] = count_yellow; // count_yellow is the number of yellow bins printed + + if(count_red+count_yellow==0 && (int)Allbins.size()>=5 ){ + for(int i=0;i<5;i++){ + char tmptmp[500]; + snprintf(tmptmp,500,"LeadingBin%i-(eta,phi)=(%0.3f,%0.3f)",i,Allbins[i].m_eta,Allbins[i].m_phi); + std::string tagtag(tmptmp); + result->tags_[tagtag] = Allbins[i].m_value; + } + + } + + + if(!OnlineMode){ + if(count_red>0 || count_red_c>0) { + result->status_ = dqm_core::Result::Red; + } else { + if (count_yellow>0||count_yellow_c>0) { + result->status_ = dqm_core::Result::Yellow; + } else { result->status_ = dqm_core::Result::Green; } + } + } else { + if(count_red>=Nred_red){ + result->status_ = dqm_core::Result::Red; + }else if (count_red>=Nred_yellow || count_yellow>=Nyellow_yellow || (count_red+count_yellow)>=Nredyellow_yellow){ + result->status_ = dqm_core::Result::Yellow; + }else{ + result->status_ = dqm_core::Result::Green; + } + } + + return result; + +} + +void dqm_algorithms::BinsDiffFromStripMedianOnline::FindStripMedianOnline(const std::string & name,vector<double> onestrip_tmp,vector<double>& stripsMedian){ + double median=0; + // if(onestrip_tmp.size()==0) stripsMedian.push_back(median); + // else{ + std::sort(onestrip_tmp.begin(),onestrip_tmp.end()); + int index1=(int)(onestrip_tmp.size()/4.); + // int index1=int(floor(onestrip_tmp.size()/4.)); + // int index2=int(floor(onestrip_tmp.size()/2.)); + int index2=(int)(onestrip_tmp.size()/2.); + int index3=(int) (3.*onestrip_tmp.size()/4.); + // int index3=int(floor(3*onestrip_tmp.size()/4.)); + if(onestrip_tmp.size()>0){ + if ((int)onestrip_tmp.size() <= index1 || (int)onestrip_tmp.size() <= index2 || (int)onestrip_tmp.size() <= index3){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of onestrip_tmp range " ); + } + + median = (onestrip_tmp[index1]+onestrip_tmp[index2]+onestrip_tmp[index3])/3.0; + } + // median = (onestrip_tmp[index2]); + stripsMedian.push_back(median); + // } +} + +void dqm_algorithms::BinsDiffFromStripMedianOnline::AddToList(const int r0,const int r2,int i,int j,vector<vector<colorbinOnline> > & ColorBinMap, vector<colorbinOnline>& LookAtList){ + + if( i-r0<0 || i-r0>=(int)ColorBinMap.size()) return; + if( j-r2<0 || j-r2>=(int)ColorBinMap[i-r0].size() ) return; + + vector<colorbinOnline> tmp; + + if(i-1-r0>=0 && i-1-r0<(int)ColorBinMap.size()){ + if(j-1-r2>=0 && j-1-r2<(int)ColorBinMap[i-1-r0].size()){ + if(ColorBinMap[i-1-r0][j-1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-1-r0][j-1-r2]); + ColorBinMap[i-1-r0][j-1-r2].m_status=0; + } + } + } + if(i-r0>=0 && i-r0<(int)ColorBinMap.size()){ + if(j-1-r2>=0 && j-1-r2<(int)ColorBinMap[i-r0].size()){ + if(ColorBinMap[i-r0][j-1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-r0][j-1-r2]); + ColorBinMap[i-r0][j-1-r2].m_status=0; + } + } + } + + if(i+1-r0>=0 && i+1-r0<(int)ColorBinMap.size()){ + if(j-1-r2>=0 && j-1-r2<(int)ColorBinMap[i+1-r0].size()){ + if(ColorBinMap[i+1-r0][j-1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i+1-r0][j-1-r2]); + ColorBinMap[i+1-r0][j-1-r2].m_status=0; + } + } + } + + if(i-1-r0>=0 && i-1-r0<(int)ColorBinMap.size()){ + if(j-r2>=0 && j-r2<(int)ColorBinMap[i-1-r0].size()){ + if(ColorBinMap[i-1-r0][j-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-1-r0][j-r2]); + ColorBinMap[i-1-r0][j-r2].m_status=0; + } + } + } + + + if(i+1-r0>=0 && i+1-r0<(int)ColorBinMap.size()){ + if(j-r2>=0 && j-r2<(int)ColorBinMap[i+1-r0].size()){ + if(ColorBinMap[i+1-r0][j-r2].m_status==1){ + tmp.push_back(ColorBinMap[i+1-r0][j-r2]); + ColorBinMap[i+1-r0][j-r2].m_status=0; + } + } + } + + + if(i-1-r0>=0 && i-1-r0<(int)ColorBinMap.size()){ + if(j+1-r2>=0 && j+1-r2<(int)ColorBinMap[i-1-r0].size()){ + if(ColorBinMap[i-1-r0][j+1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-1-r0][j+1-r2]); + ColorBinMap[i-1-r0][j+1-r2].m_status=0; + } + } + } + + if(i-r0>=0 && i-r0<(int)ColorBinMap.size()){ + if(j+1-r2>=0 && j+1-r2<(int)ColorBinMap[i-r0].size()){ + if(ColorBinMap[i-r0][j+1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i-r0][j+1-r2]); + ColorBinMap[i-r0][j+1-r2].m_status=0; + } + } + } + + if(i+1-r0>=0 && i+1-r0<(int)ColorBinMap.size()){ + if(j+1-r2>=0 && j+1-r2<(int)ColorBinMap[i+1-r0].size()){ + if(ColorBinMap[i+1-r0][j+1-r2].m_status==1){ + tmp.push_back(ColorBinMap[i+1-r0][j+1-r2]); + ColorBinMap[i+1-r0][j+1-r2].m_status=0; + } + } + } + + for(unsigned int k=0;k<tmp.size();k++){ + if(tmp[k].m_color!=green){ + LookAtList.push_back(tmp[k]); + AddToList(r0,r2,tmp[k].m_ix,tmp[k].m_iy,ColorBinMap,LookAtList); + } + } + return; + +} + +double dqm_algorithms::BinsDiffFromStripMedianOnline::CalEta(vector<colorbinOnline>& LookAtList){ + double sumEta=0; + double sumN=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double eta = LookAtList[i].m_eta; + double n = LookAtList[i].m_value; + sumEta += n*eta; + sumN +=n; + } + if(sumN!=0){ + return sumEta/sumN; + }else{ + return -99.; + } +} + +double dqm_algorithms::BinsDiffFromStripMedianOnline::CalPhi(vector<colorbinOnline>& LookAtList){ + double sumPhi=0; + double sumN=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double phi = LookAtList[i].m_phi; + double n = LookAtList[i].m_value; + sumPhi += n*phi; + sumN +=n; + } + if(sumN!=0){ + return sumPhi/sumN; + }else{ + return -99.; + } +} + +double dqm_algorithms::BinsDiffFromStripMedianOnline::CalVal(vector<colorbinOnline>& LookAtList){ + double sumN=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double n = LookAtList[i].m_value; + sumN += n; + } + return sumN; +} +double dqm_algorithms::BinsDiffFromStripMedianOnline::CalR(vector<colorbinOnline>& LookAtList,double eta, double phi){ + if(LookAtList.size()<2) return 0; + double maxR=0; + for(unsigned int i=0;i<LookAtList.size();i++){ + double distance = sqrt(pow((LookAtList[i].m_eta-eta),2)+pow((LookAtList[i].m_phi-phi),2)); + maxR=distance>maxR?distance:maxR; + } + return maxR; +} + +dqm_algorithms::BinsDiffFromStripMedianOnline::colorclusterOnline +dqm_algorithms::BinsDiffFromStripMedianOnline::MakeClusterOnline(const std::string & name,const int r0,const int r2,binOnline& onebin, vector<vector<colorbinOnline> > & ColorBinMap){ + colorclusterOnline onecluster={0,0,0,0,green,-1}; + + if ((int)ColorBinMap.size() <= (onebin.m_ix-r0) ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if ((int)ColorBinMap[onebin.m_ix-r0].size() <= (onebin.m_iy-r2) ){ + throw dqm_core::BadConfig( ERS_HERE, name, "out of ColorBinMap range " ); + } + + if(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_status==0) + return onecluster; + vector<colorbinOnline> LookAtList; + if(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_color!=green){ + LookAtList.push_back(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2]); + ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_status=0; + AddToList(r0,r2,onebin.m_ix,onebin.m_iy,ColorBinMap, LookAtList); + if(LookAtList.size()>1){ + onecluster.m_size = LookAtList.size(); + onecluster.m_value = CalVal(LookAtList); + if(ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_color==red){ + onecluster.m_color = red; + }else{ + onecluster.m_color = yellow; + } + onecluster.m_eta = CalEta(LookAtList); + onecluster.m_phi = CalPhi(LookAtList); + onecluster.m_radius = CalR(LookAtList,onecluster.m_eta,onecluster.m_phi); + } else { + ColorBinMap[onebin.m_ix-r0][onebin.m_iy-r2].m_status=1; + } + } + return onecluster; +} + +void dqm_algorithms::BinsDiffFromStripMedianOnline::printDescription(std::ostream& out){ + + out<<"BinsDiffFromStripMedianOnline: Calculates smoothed strip median and then find out bins which are aliens "<<std::endl; + + out<<"Mandatory Green/Red Threshold is the value of outstandingRatio=(bin value)/(strip median) based on which to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: MinStatPerstrip: Minimum strip statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: ignoreval0: values to be ignored for being processed"<<std::endl; + out<<"Optional Parameter: ignoreval1: values to be ignored for being processed"<<std::endl; + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (on:1,off:0,default is 1)"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: VisualMode: is to make the evaluation process similar to the shift work, so one will get resonable result efficiently."<<std::endl; + + out<<"Optional Parameter: PublishRedBins: Max number of red bins to save."<<std::endl; + out<<"Optional Parameter: ClusterResult: to cluster close bad bins together."<<std::endl; + out<<"Optional Parameter: SuppressFactor: if the ratio of the bin contennt to max one in the histogram is smaller than SuppressFactor, don't set the bin as red or yellow ."<<std::endl; + out<<"Optional Parameter: SuppressRedFactor: if the ratio of the bin contennt to max one in the histogram is smaller than SuppressRedFactor, don't set the bin as red ."<<std::endl; + out<<"Optional Parameter: OnlineMode: switch on when running online."<<std::endl; + out<<"Optional Parameter: Nred_red: minimum number of red bins needed to label the histogram as red."<<std::endl; + out<<"Optional Parameter: Nyellow_yellow: minimum number of yellow bins needed to label the histogram as yellow."<<std::endl; + out<<"Optional Parameter: Nred_yellow: minimum number of red bins needed to label the histogram as yellow."<<std::endl; + out<<"Optional Parameter: Nredyellow_yellow: minimum number of yellow+red bins needed to label the histogram as yellow."<<std::endl; + +} diff --git a/DataQuality/dqm_algorithms/src/BinsFilledOutRange.cxx b/DataQuality/dqm_algorithms/src/BinsFilledOutRange.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3548347f88a8c287881be31bc47f30b25296a8bf --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinsFilledOutRange.cxx @@ -0,0 +1,154 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsFilledOutRange.cxx compares bins of histogram wrt to reference histogram and counts number of bins N Sigma away from ref; returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinsFilledOutRange.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> +#include <ers/ers.h> + +using namespace std; + + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::BinsFilledOutRange myInstance; + + +dqm_algorithms::BinsFilledOutRange::BinsFilledOutRange() +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( "BinsFilledOutRange", this ); +} + +dqm_algorithms::BinsFilledOutRange::~BinsFilledOutRange() +{ +} + +dqm_algorithms::BinsFilledOutRange * +dqm_algorithms::BinsFilledOutRange::clone() +{ + return new BinsFilledOutRange(); +} + + +dqm_core::Result * +dqm_algorithms::BinsFilledOutRange::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + + if(object.IsA()->InheritsFrom( "TH1" )) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 1 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 1 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1"); + } + + + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0); + const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double gthreshold; + double rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + int count = 0; + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + int nbins=histogram->GetNbinsX(); + dqm_core::Result* result = new dqm_core::Result(); + TH1* resulthisto; + if (histogram->InheritsFrom("TH2")) { + resulthisto=(TH1*)(histogram->Clone()); + } else if (histogram->InheritsFrom("TH1")) { + resulthisto=(TH1*)(histogram->Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + resulthisto->Reset(); + + for ( int i = 1; i < range[0]; ++i ) { + double content = histogram -> GetBinContent(i); + if ( content !=0 ) { + ++count; + resulthisto->SetBinContent(i,content); + if (publish && count<maxpublish) { + dqm_algorithms::tools::PublishBin(histogram,i,0,content,result); + } + } + } + for ( int j = range[1]; j <= nbins; ++j ) { + double content= histogram -> GetBinContent(j); + if ( content != 0 ) { + ++count; + resulthisto->SetBinContent(j,content); + if (publish && count<maxpublish) { + dqm_algorithms::tools::PublishBin(histogram,j,0,content,result); + } + } + } + + ERS_DEBUG(1,"Number of bins with content != 0 is " << count ); + ERS_DEBUG(1,"Green threshold: "<< gthreshold << " bin(s); Red threshold : " << rthreshold << " bin(s) "); + + + result->tags_["NBins"] = count; + result->object_ = (std::auto_ptr<TObject>)(TObject*)(resulthisto); + + if (gthreshold > rthreshold) { + if ( count >= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } else { + if ( count <= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count < rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } + + return result; +} +void +dqm_algorithms::BinsFilledOutRange::printDescription(std::ostream& out) +{ + out<<"Bins_Filled_OutsideRange: Checks for number of non-empty bins outside bin range\n"<<std::endl; + + out<<"Mandatory Parameter: xmin: minimum x range"<<std::endl; + out<<"Mandatory Parameter: xmax: maximum x range"<<std::endl; + out<<"Mandatory Green/Red Threshold: NBins: Number of non-empty bins to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (set to 1)"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/src/BinsOutOfRange.cxx b/DataQuality/dqm_algorithms/src/BinsOutOfRange.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2620c030f3380d9de95726a24fe1626f9cff940c --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinsOutOfRange.cxx @@ -0,0 +1,132 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* BinsOutOfRange.cxx is to pick out the problematic bins beyond [RANGE_D,RANGE_U]. + Author: Feng TIAN (columbia university) + Email: Feng.Tian@cern.ch +*/ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinsOutOfRange.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> + +#include <iostream> +#include <string> + +using namespace std; +bool mySortfunc(bin3 i,bin3 j){return ((i.m_value) > (j.m_value));} +static dqm_algorithms::BinsOutOfRange myInstance; + +dqm_algorithms::BinsOutOfRange::BinsOutOfRange( ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BinsOutOfRange", this); +} + +dqm_algorithms::BinsOutOfRange::~BinsOutOfRange() +{ +} + +dqm_algorithms::BinsOutOfRange * +dqm_algorithms::BinsOutOfRange::clone() +{ + + return new BinsOutOfRange(); +} + + +dqm_core::Result * +dqm_algorithms::BinsOutOfRange::execute(const std::string & name, + const TObject& object, + const dqm_core::AlgorithmConfig& config ) +{ + TH1* histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const double ignoreval = dqm_algorithms::tools::GetFirstFromMap( "ignoreval", config.getParameters(), -99999); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 1); + const int Nmaxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const double RANGE_D = dqm_algorithms::tools::GetFirstFromMap( "RANGE_D", config.getParameters(), -50); + const double RANGE_U = dqm_algorithms::tools::GetFirstFromMap( "RANGE_U", config.getParameters(), 50); + if ( histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double gthreshold; + double rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "NbadBins", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NbadBins", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + vector<bin3> badbinstrip; + for ( int k = range[0]; k <= range[1]; ++k ) { + for ( int l = range[2]; l <= range[3]; ++l ) { + double binvalue = histogram->GetBinContent(k,l); + if (binvalue== ignoreval) continue; + double eta = histogram->GetXaxis()->GetBinCenter(k); + double phi = histogram->GetYaxis()->GetBinCenter(l); + if(binvalue > RANGE_D && binvalue < RANGE_U ) continue; + bin3 onebin = {eta,phi,k,l,binvalue}; + badbinstrip.push_back(onebin); + } + } + + std::sort(badbinstrip.begin(),badbinstrip.end(),mySortfunc); + dqm_core::Result* result = new dqm_core::Result(); +// publish problematic bins + int count=0; + for(unsigned int i=0;i<badbinstrip.size();i++){ + if(publish){ + char tmp[500]; + sprintf(tmp,"%i-(eta,phi)=(%0.3f,%0.3f)",count,badbinstrip[i].m_eta,badbinstrip[i].m_phi); + std::string tag = tmp; + result->tags_[tag] = badbinstrip[i].m_value; + } + count++; + if(count>Nmaxpublish) break; + } + + result->tags_["NBadBins"] = count; + + if(count>rthreshold ) result->status_ = dqm_core::Result::Red; + else if (count>gthreshold) result->status_ = dqm_core::Result::Yellow; + else result->status_ = dqm_core::Result::Green; + + return result; + +} + + +void +dqm_algorithms::BinsOutOfRange::printDescription(std::ostream& out) +{ + + out<<"BinsOutOfRange: Print out the badbins which are out of range [range_d,range_u] "<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: ignoreval: valued to be ignored for being processed"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/BinsSymmetric.cxx b/DataQuality/dqm_algorithms/src/BinsSymmetric.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1eae987bb298a30f6b8af19fa5b94f255263038b --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BinsSymmetric.cxx @@ -0,0 +1,218 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BinsSymmetric.cxx check if +ve and -ve bins around the central value are consistent + * \author M Petteni + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BinsSymmetric.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <cstdio> +#include <TClass.h> +#include <ers/ers.h> +#include <iostream> +#include <string> + +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::BinsSymmetric myInstance; + +dqm_algorithms::BinsSymmetric::BinsSymmetric () +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BinsSymmetric",this); +} + +dqm_algorithms::BinsSymmetric::~BinsSymmetric () +{ +} +dqm_algorithms::BinsSymmetric * +dqm_algorithms::BinsSymmetric::clone() +{ + return new BinsSymmetric(); +} + +dqm_core::Result * +dqm_algorithms::BinsSymmetric::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + + TH1 * histogram; + + if (object.IsA()->InheritsFrom("TH1")){ + + histogram = (TH1*)&object; + + if (histogram->GetDimension() > 3 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 3 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + if (histogram->GetEntries() == 0) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is Empty"); + return new dqm_core::Result(dqm_core::Result::Red); + } + + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0); + const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const double mindiffabs = (double) dqm_algorithms::tools::GetFirstFromMap( "MaxDiffAbs", config.getParameters(), 0); + const double bin_threshold = (double) dqm_algorithms::tools::GetFirstFromMap( "NSigmaBin", config.getParameters(), 3); + const bool ignorezero = (bool) dqm_algorithms::tools::GetFirstFromMap("IgnoreZero",config.getParameters(), 0); + + double gthreshold; + double rthreshold; + + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "NSigma", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NSigma", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + int count = 0; + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + + dqm_core::Result* result = new dqm_core::Result(); + + // vectors for global chisq calculation + std::vector<double> binvals,binerrs; + std::vector<double> refvals,referrs; + double small_num = 1.e-05; + + // logic to see if there is a bin at the central value. If so compare central to average of two bins on either side + bool even_nbins = ((range[1] - range[0] + 1) % 2 == 0) ? true : false; + int range_comp = (range[1] - range[0] + 1) / 2; + + int start_bin_low = range[1] - range_comp; + int start_bin_high = range[0] + range_comp; + + // check central bin if there is one + if (!even_nbins){ + + double xbin0 = histogram->GetBinCenter(start_bin_low); + + double bin0 = histogram->GetBinContent(start_bin_low); + double bin1 = histogram->GetBinContent(start_bin_low + 1); + double bin2 = histogram->GetBinContent(start_bin_low - 1); + + double binerr0 = histogram->GetBinError(start_bin_low); + double binerr1 = histogram->GetBinError(start_bin_low + 1); + double binerr2 = histogram->GetBinError(start_bin_low - 1); + + double mean_bins = (bin1+bin2)/2.; + double errmean_bins = sqrt(pow(binerr1,2.)+pow(binerr2,2.)/2.); + + double diff = fabs(bin0 - mean_bins); + double differr = sqrt(pow(binerr0,2.)+pow(errmean_bins,2)); + double sigma = 1.; + + if ((!ignorezero) || (bin0 != 0 && mean_bins != 0)){ + + binvals.push_back(bin0); + binerrs.push_back(binerr0); + // use reference bin for chisq calculation as the combined bin from neighbours + refvals.push_back(mean_bins); + referrs.push_back(errmean_bins); + + if (differr/diff > small_num) sigma = diff/differr; + + // sigma threshold used to highlight potentially problematic bins + if (sigma > bin_threshold && (fabs(diff) > mindiffabs)) { + + ++count; + + if (publish && count <= maxpublish) { + + std::ostringstream os; + os << "Sigma(" << xbin0 << ")(" << bin0 << "," << mean_bins << ")"; + std::string badbins = os.str(); + result->tags_[badbins.c_str()] = sigma; + ERS_DEBUG(1,"x bin" << start_bin_low << " value " << bin0 << " sigma difference " << sigma); + + } + } + } + } + + // now loop over all the other bins + for (int i = 0; i < range_comp; ++i){ + + double binhigh = histogram->GetBinContent(start_bin_high+i); + double binlow = histogram->GetBinContent(start_bin_low-i); + + double xbinhigh = histogram->GetBinCenter(start_bin_high+i); + + double binerrhigh = histogram->GetBinError(start_bin_high+i); + double binerrlow = histogram->GetBinError(start_bin_low-i); + + double diff = fabs(binlow - binhigh); + double differr = sqrt(pow(binerrlow,2.)+pow(binerrhigh,2)); + + if ((!ignorezero) || (binlow != 0 && binhigh != 0)){ + + binvals.push_back(binhigh); + binerrs.push_back(binerrlow); + refvals.push_back(binlow); + referrs.push_back(binerrlow); + + double sigma = 1.; + if (differr > small_num) sigma = diff/differr; + + if (sigma > bin_threshold && (fabs(diff) > mindiffabs)) { + + ++count; + if (publish && count <= maxpublish){ + + std::ostringstream os; + os << "Sigma(" << xbinhigh << ")" << "(" << binlow << "," << binhigh << ")"; + std::string badbins = os.str(); + result->tags_[badbins.c_str()] = sigma; + ERS_DEBUG(1,"x bin " << start_bin_high+i << " value " << binhigh); + ERS_DEBUG(1,"x bin " << start_bin_low-i << " value " << binlow << " sigma difference " << sigma); + } + } + } + } + + std::pair<double,double> chisq_prob = dqm_algorithms::tools::CalcBinsProbChisq(binvals,binerrs,refvals,referrs); + + ERS_DEBUG(1, "Number of bins " << bin_threshold << " Sigma away from reference bin is " << count); + ERS_DEBUG(1, "Green threshold: "<< gthreshold << " bin(s); Red threshold : " << rthreshold << " bin(s) "); + result->tags_["NBins"] = count; + result->tags_["SigmaChisq"] = chisq_prob.second; + + // cut on sigma, this can be eventually modified to cut on prob as well + + double sigma_check = fabs(chisq_prob.second); + if ( sigma_check <= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( sigma_check < rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + return result; + +} + +void dqm_algorithms::BinsSymmetric::printDescription(std::ostream& out){ + + out<<"BinsSymmetric: Checks if histogram is symmetric around mid-point of given range. works only for 1-D histograms \n"<<std::endl; +out<<"Mandatory Green/Red Threshold: NSigma: N sigma for chisq global fit probability to be away from 0 from unit normal distribution. Thresholds are for Green/Red results\n"<<std::endl; + out<<"Optional Parameter: NSigmaBin: Number of sigma bins must be over opposite bin to be flagged and reported (default 3) \n"<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (set to 1)"<<std::endl; + out<<"Optional Parameter: MaxDiffAbs: test fails if NBins more than NSigma away and NBins more than MaxDiffAbs (absolut difference) away"<<std::endl; + out<<"Optional Parameter: MaxDiffRel: test fails if NBins more than NSigma away and NBins more than MaxDiffRel (relative difference) away\n"<<std::endl; + +} diff --git a/DataQuality/dqm_algorithms/src/Bins_Diff_FromAvg.cxx b/DataQuality/dqm_algorithms/src/Bins_Diff_FromAvg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9cfd8f3ee6391214db595a6c9f9fe7eec994acf4 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/Bins_Diff_FromAvg.cxx @@ -0,0 +1,200 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Bins_Diff_FromAvg.cxx calculates average bin value; finds bins more than N Sigma away from average and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/Bins_Diff_FromAvg.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> + +#include <iostream> +#include <string> + +using namespace std; + +static dqm_algorithms::Bins_Diff_FromAvg myInstance; + +dqm_algorithms::Bins_Diff_FromAvg::Bins_Diff_FromAvg( ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("Bins_Diff_FromAvg", this); +} + +dqm_algorithms::Bins_Diff_FromAvg::~Bins_Diff_FromAvg() +{ +} + +dqm_algorithms::Bins_Diff_FromAvg * +dqm_algorithms::Bins_Diff_FromAvg::clone() +{ + + return new Bins_Diff_FromAvg(); +} + + +dqm_core::Result * +dqm_algorithms::Bins_Diff_FromAvg::execute(const std::string & name, + const TObject& object, + const dqm_core::AlgorithmConfig& config ) +{ + TH1* histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const double ignoreval = dqm_algorithms::tools::GetFirstFromMap( "ignoreval", config.getParameters(), -99999); + bool greaterthan = (bool) dqm_algorithms::tools::GetFirstFromMap( "GreaterThan", config.getParameters(), 0); + bool lessthan = (bool) dqm_algorithms::tools::GetFirstFromMap( "LessThan", config.getParameters(), 0); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0); + const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const double maxdiffabs = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffAbs", config.getParameters(), -1); + const double maxdiffrel = dqm_algorithms::tools::GetFirstFromMap( "MaxDiffRel", config.getParameters(), -1); + + if (greaterthan && lessthan) { + ERS_INFO("Both GreaterThan and LessThan parameters set: Will check for for both"); + greaterthan = false; + lessthan = false; + } + + if ( histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double bin_threshold; + double gthreshold; + double rthreshold; + try { + bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "NSigma", config.getParameters() ); + rthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + double sumwe=0; + double sume=0; + TH1* resulthisto; + if (histogram->InheritsFrom("TH2")) { + resulthisto=(TH1*)(histogram->Clone()); + } else if (histogram->InheritsFrom("TH1")) { + resulthisto=(TH1*)(histogram->Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + resulthisto->Reset(); + + int count = 0; + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + + for ( int i = range[0]; i <= range[1]; ++i ) { + for ( int j = range[2]; j <= range[3]; ++j ) { + if (histogram->GetBinContent(i,j) == ignoreval) continue; + if (histogram->GetBinError(i,j) == 0 ) continue; + sumwe += histogram->GetBinContent(i,j)*(1/pow(histogram->GetBinError(i,j),2)); + sume += 1./pow(histogram->GetBinError(i,j),2); + } + } + double avg; + + if (sume !=0 ) { + avg=sumwe/sume; + } else { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["SumErrors"] = sume; + delete resulthisto; + return result; + } + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Average"] = avg; + + for ( int k = range[0]; k <= range[1]; ++k ) { + for ( int l = range[2]; l <= range[3]; ++l ) { + double inputcont = histogram->GetBinContent(k,l); + double inputerr = histogram->GetBinError(k,l); + double diff=inputcont - avg; + double reldiff=1; + if(avg!=0) reldiff=diff/avg; + else if(diff==0) reldiff=0; + if (inputcont == ignoreval) continue; + if (inputerr != 0){ + double sigma=diff/inputerr; + if (greaterthan && diff < 0. ) continue; + if (lessthan && diff > 0. ) continue; + + if ( (fabs(sigma) > bin_threshold) && (fabs(diff) > maxdiffabs) && (fabs(reldiff) > maxdiffrel) ) { + resulthisto->SetBinContent(k,l,inputcont); + count++; + if (publish && count < maxpublish){ + dqm_algorithms::tools::PublishBin(histogram,k,l,inputcont,result); + } + } + } + + } + } + + result->tags_["NBins"] = count; + result->object_ = (std::auto_ptr<TObject>)(TObject*)(resulthisto); + + ERS_DEBUG(1,"Number of bins " << bin_threshold << " Sigma away from average of "<< avg << " is " << count); + ERS_DEBUG(1,"Green threshold: "<< gthreshold << " bin(s); Red threshold : " << rthreshold << " bin(s) "); + + + + if ( count <= gthreshold ) { + result->status_ = dqm_core::Result::Green; + } else if ( count < rthreshold ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + return result; + +} +void +dqm_algorithms::Bins_Diff_FromAvg::printDescription(std::ostream& out) +{ + + out<<"Bins_Diff_FromAvg: Calculates average bin value and checks number of bins N sigma away from calculated average\n"<<std::endl; + + out<<"Mandatory Parameter: NSigma: Number of sigma each bin must be within average bin value\n"<<std::endl; + + + out<<"Mandatory Green/Red Threshold: NBins: number of bins N sigma away from average to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: ymin: minimum y range"<<std::endl; + out<<"Optional Parameter: ymax: maximum y range"<<std::endl; + out<<"Optional Parameter: ignoreval: valued to be ignored for calculating average"<<std::endl; + out<<"Optional Parameter: GreaterThan: check only for bins which are GreaterThan average (set to 1)"<<std::endl; + out<<"Optional Parameter: LessThan: check only for bins which are LessThan average (set to 1)"<<std::endl; + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (set to 1)"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: MaxDiffAbs: test fails if NBins more than NSigma away and NBins more than MaxDiffAbs (absolut difference) away from average"<<std::endl; + out<<"Optional Parameter: MaxDiffRel: test fails if NBins more than NSigma away and NBins more than MaxDiffRel (relative difference) away from average\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/BlackBin.cxx b/DataQuality/dqm_algorithms/src/BlackBin.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0f0babc6d03c4a9fda461d1b3cb4c52f5fa44a2a --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BlackBin.cxx @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BlackBin.cxx checks an individual bin of a 2D histogram wrt to a threshold value and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BlackBin.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + + +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::BlackBin myInstance; + +dqm_algorithms::BlackBin::BlackBin() + +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BlackBin", this); +} + +dqm_algorithms::BlackBin * +dqm_algorithms::BlackBin::clone() +{ + + return new BlackBin(); +} + + +dqm_core::Result * +dqm_algorithms::BlackBin::execute(const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH2 * histogram; + + if( object.IsA()->InheritsFrom( "TH2" ) ) { + histogram = (TH2*)&object; + if (histogram->GetDimension() > 3 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 3 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH2" ); + } + + // Unused, so commented out: (Why does this algorithm not take a threshold?) + // double bin_threshold; + // double gthreshold; + // double rthreshold; + int xbin; + int ybin; + try { + xbin = (int)dqm_algorithms::tools::GetFirstFromMap( "XBin", config.getParameters()); + ybin = (int)dqm_algorithms::tools::GetFirstFromMap( "YBin", config.getParameters()); + } + catch ( dqm_core::Exception & ex ) { + //out << "Some of the parameters are missing!" << std::endl; + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get the bin content of the histogram + double binContents= histogram -> GetBinContent(xbin,ybin); + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["BinContent"] = binContents; + if(binContents>0){ + result->status_ = dqm_core::Result::Disabled; + } + else { + result->status_ = dqm_core::Result::Green; + } + + return result; +} + +void +dqm_algorithms::BlackBin::printDescription(std::ostream& out) +{ + + out<<"Black bin: Returns status -1 (black) if bin has no contents\n" << std::endl; + + out<<"Mandatory parameter: XBin: The label of the X bin that you would like to check\n"<<std::endl; + + out<<"Mandatory parameter: YBin: The label of the Y bin that you would like to check\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/BlackBin1D.cxx b/DataQuality/dqm_algorithms/src/BlackBin1D.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0b20664bbcb2ab06fd7a31cb6c4052a9d15cf8c8 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/BlackBin1D.cxx @@ -0,0 +1,93 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file BlackBin.cxx checks an individual bin of a 2D histogram wrt to a threshold value and returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/BlackBin1D.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + + +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::BlackBin1D myInstance; + +dqm_algorithms::BlackBin1D::BlackBin1D() + +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("BlackBin1D", this); +} + +dqm_algorithms::BlackBin1D * +dqm_algorithms::BlackBin1D::clone() +{ + + return new BlackBin1D(); +} + + +dqm_core::Result * +dqm_algorithms::BlackBin1D::execute(const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Unused so commented out: + //double bin_threshold; + //double gthreshold; + //double rthreshold; + int xbin; + + try { + xbin = (int)dqm_algorithms::tools::GetFirstFromMap( "XBin", config.getParameters()); + + } + catch ( dqm_core::Exception & ex ) { + //out << "Some of the parameters are missing!" << std::endl; + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get the bin content of the histogram + double binContents= histogram -> GetBinContent(xbin); + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["BinContent"] = binContents; + if(binContents>0){ + result->status_ = dqm_core::Result::Disabled; + } + else { + result->status_ = dqm_core::Result::Green; + } + + return result; +} + +void +dqm_algorithms::BlackBin1D::printDescription(std::ostream& out) +{ + + out<<"Black bin 1D: Returns status -1 (black) if bin has no contents\n" << std::endl; + + out<<"Mandatory parameter: XBin: The label of the X bin that you would like to check\n"<<std::endl; + + +} + diff --git a/DataQuality/dqm_algorithms/src/CSCNoisyDead.cxx b/DataQuality/dqm_algorithms/src/CSCNoisyDead.cxx new file mode 100644 index 0000000000000000000000000000000000000000..54185b8b222ac6eb962ebeb23fd76b915461939f --- /dev/null +++ b/DataQuality/dqm_algorithms/src/CSCNoisyDead.cxx @@ -0,0 +1,260 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file CSCNoisyDead.cxx + * \author J. Veatch + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/CSCNoisyDead.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> +#include <ers/ers.h> + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::CSCNoisyDead myInstance; + + +dqm_algorithms::CSCNoisyDead::CSCNoisyDead() +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( "CSCNoisyDead", this ); +} + +dqm_algorithms::CSCNoisyDead::~CSCNoisyDead() +{ +} + +dqm_algorithms::CSCNoisyDead * +dqm_algorithms::CSCNoisyDead::clone() +{ + return new CSCNoisyDead(); +} + + +dqm_core::Result * +dqm_algorithms::CSCNoisyDead::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH2 * histogram; + + if(object.IsA()->InheritsFrom( "TH2" )) { + histogram = (TH2*)&object; + if (histogram->GetDimension() != 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension != 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH2"); + } + + double high = dqm_algorithms::tools::GetFirstFromMap( "HighRange", config.getParameters(), 0.2); + double low = dqm_algorithms::tools::GetFirstFromMap( "LowRange", config.getParameters(), 0.2); + + int gthreshold; + int rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "NStrips", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "NStrips", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + double phi_s_sum, phi_l_sum, eta_s_sum, eta_l_sum; + + double phi_s_avg[48], phi_l_avg[48], eta_s_avg[192], eta_l_avg[192]; + + int NphiDead = 0; + int NphiNoisy = 0; + int NetaDead = 0; + int NetaNoisy = 0; + int NBad=0; + + for (int i = 0; i < 48; i++) { + phi_s_avg[i] = 0; + phi_l_avg[i] = 0; + } + + for (int i = 0; i < 192; i++) { + eta_s_avg[i] = 0; + eta_l_avg[i] = 0; + } + + // Average over Phi strips + for(size_t x = 0; x < 48; x++) { + int xbin = histogram->GetXaxis()->FindBin(x-48); + phi_s_sum = 0; + phi_l_sum = 0; + if (histogram->GetNbinsY() >= 85){ + for(size_t y = 6; y < 86; y++) { + if( y%5 != 0 ) { + + // int lay = y%5; + + double content = histogram->GetBinContent(xbin,y); + + if(y%10 > 5) { + phi_l_sum += content; + }else { + phi_s_sum += content; + } + } + } + } + phi_s_avg[x] = (phi_s_sum/32.0); + phi_l_avg[x] = (phi_l_sum/32.0); + } // End phi strips average + + // Average over Eta strips + for(size_t x = 0; x < 192; x++) { + int xbin = histogram->GetXaxis()->FindBin(x+1); + eta_s_sum = 0; + eta_l_sum = 0; + for(size_t y = 6; y < 86; y++) { + if( y%5 != 0 ) { + + // int lay = y%5; + + double content = histogram->GetBinContent(xbin,y); + + if(y%10 > 5) { + eta_l_sum += content; + }else { + eta_s_sum += content; + } + } + } + eta_s_avg[x] = (eta_s_sum/32.0); + eta_l_avg[x] = (eta_l_sum/32.0); + } // End eta strips average + + // Compare Phi strips to average + for(size_t x = 0; x < 48; x++) { + int xbin = histogram->GetXaxis()->FindBin(int(x)-48); + phi_s_sum = 0; + phi_l_sum = 0; + for(size_t y = 6; y < 86; y++) { + if( y%5 != 0 ) { + + // int lay = y%5; + + double content = histogram->GetBinContent(xbin,y); + + if(y%10 > 5) { + if(content > (1+high)*phi_l_avg[x]){ + NphiNoisy++; + }else if(content < (1-low)*phi_l_avg[x]){ + NphiDead++; + } + }else { + if(content > (1+high)*phi_s_avg[x]){ + NphiNoisy++; + }else if(content < (1-low)*phi_s_avg[x]){ + NphiDead++; + } + } + } + } + } // End phi strips comparison + + // Compare Eta strips to average + for(size_t x = 0; x < 192; x++) { + int xbin = histogram->GetXaxis()->FindBin(x+1); + eta_s_sum = 0; + eta_l_sum = 0; + for(size_t y = 6; y < 86; y++) { + if( y%5 != 0 ) { + + // int lay = y%5; + + double content = histogram->GetBinContent(xbin,y); + + if(y%10 > 5) { + if(content > (1+high)*eta_l_avg[x]){ + NetaNoisy++; + }else if(content < (1-low)*eta_l_avg[x]){ + NetaDead++; + } + }else { + if(content > (1+high)*eta_s_avg[x]){ + NetaNoisy++; + }else if(content < (1-low)*eta_s_avg[x]){ + NetaDead++; + } + } + } + } + } // End phi strips comparison + + dqm_core::Result* result = new dqm_core::Result(); + NBad = NphiNoisy + NphiDead + NetaNoisy + NetaDead; + result->tags_.insert(std::make_pair("NBad",NBad)); + result->tags_.insert(std::make_pair("NphiNoisy",NphiNoisy)); + result->tags_.insert(std::make_pair("NphiDead",NphiDead)); + result->tags_.insert(std::make_pair("NetaNoisy",NetaNoisy)); + result->tags_.insert(std::make_pair("NetaDead",NetaDead)); + + if (NBad >= rthreshold){ + result->status_ = dqm_core::Result::Red; + }else if (NBad < gthreshold){ + result->status_ = dqm_core::Result::Green; + }else{ + result->status_ = dqm_core::Result::Yellow; + } + + return result; + +/* + + dqm_core::Result* result = new dqm_core::Result(); + int max = 1; + if(testrows){ max += histogram->GetNbinsY(); } else { max += histogram->GetNbinsX(); } + std::vector<float> rowtotal; + rowtotal.clear(); + for(int i =0; i<max; ++i){ rowtotal.push_back(0.0); } + + if(checkstrip==0 && redcount >= yellowcount && redcount !=0 ){ + result->tags_["RedBins"] = redcount; + result->status_ = dqm_core::Result::Red; + return result; + } + if(checkstrip==0 && yellowcount !=0 ){ + result->tags_["YellowBins"] = yellowcount; + result->status_ = dqm_core::Result::Yellow; + return result; + } + + if(checkstrip && dorate && redrows >= yellowrows && redrows !=0 ){ + result->tags_["RedRows"] = redrows; + result->status_ = dqm_core::Result::Red; + return result; + } + if(checkstrip && dorate && yellowrows !=0 ){ + result->tags_["YellowRows"] = yellowrows; + result->status_ = dqm_core::Result::Yellow; + return result; + } + + + result->status_ = dqm_core::Result::Green; + return result; +*/ +} + +void +dqm_algorithms::CSCNoisyDead::printDescription(std::ostream& out) +{ + + out<<"CSCNoisyDead: Checks to see how many CSC layers are dead or noisy"<<std::endl; + + out<<"Mandatory Parameter: HighRange : Fraction above average considered noisy"<<std::endl; + out<<"Mandatory Parameter: LowRange : Fraction below average considered dead"<<std::endl; + + out<<"Mandatory Green/Red Threshold : NStrips : "<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/CheckMean.cxx b/DataQuality/dqm_algorithms/src/CheckMean.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ea43f02660169ca37cc8caac3cc2d4e70dbf59c3 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/CheckMean.cxx @@ -0,0 +1,159 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: CheckMean.cxx,v 1.1 2007-04-06 11:02:53 mgwilson Exp $ +// ********************************************************************** + +#include "dqm_algorithms/CheckMean.h" + +#include <cmath> +#include <iostream> + +#include <TH1.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" + + +static dqm_algorithms::CheckMean staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +CheckMean:: +CheckMean() + : name("AlgCheckMean") + , limitName("chi2") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +CheckMean:: +~CheckMean() +{ +} + + +dqm_core::Algorithm* +CheckMean:: +clone() +{ + return new CheckMean(*this); +} + + +dqm_core::Result* +CheckMean:: +execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config ) +{ + dqm_core::Result::Status status(dqm_core::Result::Undefined); + + // Cast to the type of TObject to assess + const TH1* h = dynamic_cast<const TH1*>( &data ); + if( h == 0 ) { + throw dqm_core::BadConfig( ERS_HERE, name, "Cannot cast data to type TH1" ); + } + + const TH1* ref = dynamic_cast<const TH1*>( config.getReference() ); + if( ref == 0 ) { + throw dqm_core::BadConfig( ERS_HERE, name, "Cannot obtain reference of type TH1" ); + } + + // Perform the check + const double mean_data = h->GetMean(); + const double mean_ref = ref->GetMean(); + + const double mean_data_err = h->GetMeanError(); + const double mean_ref_err = ref->GetMeanError(); + + const double chi2_warn = getWarningLimit( config, limitName ); + const double chi2_err = getErrorLimit( config, limitName ); + + const double s = ( mean_data - mean_ref ); + const double s2 = s*s; + const double e2 = mean_data_err*mean_data_err + mean_ref_err*mean_ref_err; + + const double chi2 = s2/e2; + + //out << "mean_data = " << mean_data << "\n"; + //out << "mean_ref = " << mean_ref << "\n"; + //out << "mean_data_err = " << mean_data_err << "\n"; + //out << "mean_ref_err = " << mean_ref_err << "\n"; + //out << "chi2 = " << chi2 << "\n"; + + if( chi2 < chi2_warn ) { + status = dqm_core::Result::Green; + } + else if( chi2 < chi2_err ) { + status = dqm_core::Result::Yellow; + } + else { + status = dqm_core::Result::Red; + } + + // Return the result + return new dqm_core::Result( status ); +} + + +void +CheckMean:: +printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Checks the mean of a TH1 against the mean of a reference TH1\n"; + message += " by assessing a chi2 defined by the two means and their errors\n"; + message += "Parameters: none\n"; + message += "Limits:\n"; + message += " \"" + limitName + "\" : generate warnings on the chi2 value\n"; + message += "\n"; + + out << message; +} + + +// ********************************************************************* +// Protected Methods +// ********************************************************************* + + +double +CheckMean:: +getWarningLimit( const dqm_core::AlgorithmConfig& config, std::string limitName ) +{ + std::map<std::string,double> grmap = config.getGreenThresholds(); + std::map<std::string,double>::const_iterator i = grmap.find( limitName ); + if( i == grmap.end() ) { + throw dqm_core::BadConfig( ERS_HERE, limitName, "Cannot find green threshold" ); + } + + return i->second; +} + + +double +CheckMean:: +getErrorLimit( const dqm_core::AlgorithmConfig& config, std::string limitName ) +{ + std::map<std::string,double> rdmap = config.getRedThresholds(); + std::map<std::string,double>::const_iterator i = rdmap.find( limitName ); + if( i == rdmap.end() ) { + throw dqm_core::BadConfig( ERS_HERE, limitName, "Cannot find red threshold" ); + } + + return i->second; +} + + +} // namespace dqm_algorithms + diff --git a/DataQuality/dqm_algorithms/src/Chi2Test.cxx b/DataQuality/dqm_algorithms/src/Chi2Test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..34727f93a31b6a5a596252d577b7aae6b466851d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/Chi2Test.cxx @@ -0,0 +1,165 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test.cxx does Chi2Test and compares either chi2/ndf or the probability; returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/Chi2Test.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +using namespace std; + + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::Chi2Test chi2_ndf( "Chi2_per_NDF" ); +static dqm_algorithms::Chi2Test chi2_p( "Prob" ); +static dqm_algorithms::Chi2Test chi2_uw("ProbUW" ); +static dqm_algorithms::Chi2Test chi2_ww("ProbWW" ); +static dqm_algorithms::Chi2Test chi2_chi2("Chi2"); + +dqm_algorithms::Chi2Test::Chi2Test( const std::string & name ) + : name_ ( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("Chi2Test_"+ name, this ); +} + +dqm_algorithms::Chi2Test * +dqm_algorithms::Chi2Test::clone() +{ + return new Chi2Test( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::Chi2Test::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + const TH1 * histogram; + + if(object.IsA()->InheritsFrom( "TH1" )) { + histogram = static_cast<const TH1*>( &object ); + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + TH1 * refhist; + double gthresho; + double rthresho; + std::string option; + std::string thresholdname="P"; + if (name_ == "Chi2_per_NDF") { + option="Chi2/ndfUU"; + thresholdname="Chi2_per_NDF"; + }else if (name_ == "Prob" ) { + option="UU"; + }else if (name_ == "ProbUW") { + option="UW"; + }else if (name_ == "ProbWW") { + option="WW"; + } else if (name_ == "Chi2") { + option="CHI2UU"; + thresholdname="Chi2"; + } else { + throw dqm_core::BadConfig( ERS_HERE, "None", name_ ); + } + try { + gthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + + } + + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, "Dimension", name ); + } + + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + + + double value = histogram->Chi2Test( refhist, option.c_str() ); + ERS_DEBUG(1,"Green threshold: "<< gthresho << "; Red threshold: " << rthresho ); + ERS_DEBUG(1,"Chi2 Test with Option " << option << " is " << value ); + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_[thresholdname] = value; + + if (thresholdname == "P") {//Checking against a probability + if ( value >= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value > rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } else {//checking against Chi2 value + if ( value <= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value < rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + + } + ERS_DEBUG(2,"Result: "<<*result); + return result; + +} +void +dqm_algorithms::Chi2Test::printDescription(std::ostream& out) +{ + option="UU"; + std::string thresholdname = "P"; + if (name_ == "Chi2_per_NDF") { + option="Chi2/ndf"; + thresholdname="Chi2_per_NDF"; + }else if (name_ == "Prob") { + option="UU"; + }else if (name_ == "ProbUW") { + option="UW"; + }else if (name_ == "ProbWW") { + option="WW"; + }else if (name_ == "Chi2") { + option="CHI2"; + thresholdname="Chi2"; + } + + out<<"Chi2Test_"+ name_+": Gives back "+thresholdname+" after performing Chi2 test on histogram against referece histogram with option: "<<option<<" (see TH1::GetChi2Test)"<<std::endl; + + + out<<"Mandatory Green/Red Threshold: "+ thresholdname+" : "+thresholdname+" to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/Chi2Test_2D.cxx b/DataQuality/dqm_algorithms/src/Chi2Test_2D.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3ff8c0920fdd7606eb01638f98264e8af38f2311 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/Chi2Test_2D.cxx @@ -0,0 +1,314 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_2D.cxx does Chi2Test on a 2D histogram, and also returns the positions of the highest outlying bins; returns dqm_core::Result + //result is based on the number of outlying bins above NSigma, not on the chisq/ndf value + \Written by Ian Moult + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/Chi2Test_2D.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TH2.h> +#include <TF2.h> +#include <TClass.h> +#include <TGraph.h> +#include <TGraphErrors.h> +#include <ers/ers.h> +#include <vector> +#include <cctype> +#include <map> +using namespace std; + + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::Chi2Test_2D myInstance; + +dqm_algorithms::Chi2Test_2D::Chi2Test_2D() + { + dqm_core::AlgorithmManager::instance().registerAlgorithm("Chi2Test_2D", this ); +} + +dqm_algorithms::Chi2Test_2D * +dqm_algorithms::Chi2Test_2D::clone() +{ + return new Chi2Test_2D(); +} + + +dqm_core::Result * +dqm_algorithms::Chi2Test_2D::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ +const TH2 * inputgraph_original; + + if(object.IsA()->InheritsFrom( "TH1" )) { + inputgraph_original = static_cast<const TH2*>( &object ); + + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + +//now, cast inputgraph_original to a non const object + + TH2* inputgraph = const_cast<TH2*>(inputgraph_original); + + + //Make sure the input histogram has enough statistics + double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), 1 ); + + if (inputgraph->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = inputgraph->GetEntries(); + return result; + } + + + TH2 * refhist; + double gthresho; + double rthresho; + std::string option; + + + //read in the threshold values + std::string thresholdname="NBins"; + + try { + gthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + + } + +//try and get the reference, and make sure that it is good + try { + refhist = static_cast<TH2 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + if (inputgraph->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, "Dimension", name ); + } + + if ((inputgraph->GetNbinsX() != refhist->GetNbinsX()) || (inputgraph->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + + + + +//check if the value "normalize" is 1. If it is, must scale the histogram. Also, make sure that there is an +//error associated with the bin, because you should only be calling normalize on a histogram that has a #of jets in a bin +//that error should be sqrt(n). +// can call sumw2() before scaling to make sure that this is the case, and then can use the rest of the algorithm as normal, +//because the correct errors should all be set +int normalize = dqm_algorithms::tools::GetFirstFromMap( "normalize", config.getParameters(), 1 ); + + +if(normalize==1) +{double ref_entries=refhist->GetEntries(); + double input_entries=inputgraph->GetEntries(); + //call sumw2() to make sure that you have the errors as sqrt(n) + inputgraph->Sumw2(); + refhist->Sumw2(); +//now, rescale the reference histogram to the inputgraph histogram. The errors should scale properly, now that I have called Sumw2() + refhist->Scale(input_entries/ref_entries); +} + + +//read in the values for NSigma, and the number of bins to print out at the end, and the value for MaxSigma +double NSigma = dqm_algorithms::tools::GetFirstFromMap( "NSigma", config.getParameters(), 1 ); +int Num_to_print = dqm_algorithms::tools::GetFirstFromMap( "Num_to_print", config.getParameters(), 1 ); +double MaxSigma = dqm_algorithms::tools::GetFirstFromMap( "MaxSigma", config.getParameters(), 1 ); + +//read in the values for the maximum and minimum x bin +vector<int> range; +try{ +range=dqm_algorithms::tools::GetBinRange(inputgraph,config.getParameters()); +} +catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + int i=0; + int j=0; + double chisq=0; + double errsquared; + double inputerr; + double referr; + double val; + double refval; + double partsum; + int count_ndf=0; + + //define a vector to store the chisq value at the highest ranking bins,which can then be sorted + // so that you can find out what the location of the high chisq values are after you have sorted them + //define a map, with the chisq partsum value as the key, and the global bin number as the element. + vector<double> ChisqValues; + map<double,int> mymap; + + for(i=range[0];i<(range[1]+1);i++) + { + for(j=range[2];j<(range[3]+1);j++) + { + val=inputgraph->GetBinContent(i,j); + refval=refhist->GetBinContent(i,j); + inputerr=inputgraph->GetBinError(i,j); + referr=refhist->GetBinError(i,j); + errsquared=referr*referr+inputerr*inputerr; + if(errsquared > 0.000001) + { + partsum=((val-refval)*(val-refval))/errsquared; + } + else + {partsum=-1; + } + + if (partsum != -1) + { chisq=chisq+partsum; + count_ndf++; + + if(partsum>=NSigma*NSigma) + { ChisqValues.push_back(sqrt(partsum)); + mymap.insert(pair<double,int>(sqrt(partsum),inputgraph->GetBin(i,j))); + } + + } + + + } + + } + + double ndf=count_ndf-1; + double value=chisq/ndf; + dqm_core::Result* result = new dqm_core::Result(); + //write out this chisq/ndf value to the website + result->tags_["Chisq_per_NDF"]=value; + + + +//sort the chisq values for the points that had more than N sigma + std::sort(ChisqValues.begin(),ChisqValues.end()); + +//Output the top Num_to_print values for chisquares at individual points +//define an iterator + vector<double>::iterator p; + p=ChisqValues.end(); + +//since the iterator points to one past the end, must decrement before we use it. + p--; + +//define a second iterator for the map, do not decrement it, as it will be assigned to a point in the map before use + map<double,int>::iterator p2; + + +char ctag[256]; +int k=0; +int global_bin=0; +int xbinnumber; +int ybinnumber; +int zbinnumber; +int& xBin = xbinnumber; +int& yBin = ybinnumber; +int& zBin = zbinnumber; +int globalbinint=0; +double eta; +double phi; + +//declare a variable that will be set to true if the value MaxSigma is exceeded for any bin. This will automatically flag the histogram red +int veto=0; + + +//if mymap has no elements, then output that there were no elements above, and skip the next section +if(mymap.size()==0) +{result->tags_["No flagged bins were found"]=1.0; +} + + +while(mymap.size()>0) +{ + +//find the value of eta/phi that goes along with the previous chisq value +//first find the global bin number from the map + + p2=mymap.find(*p); + if(p2 !=mymap.end()) + { global_bin=p2->second; + globalbinint= (int) global_bin; + inputgraph->GetBinXYZ(globalbinint,xBin,yBin,zBin); + eta=inputgraph->GetXaxis()->GetBinCenter(xBin); + phi=inputgraph->GetYaxis()->GetBinCenter(yBin); + + //write the coordinates and Sigma value to the website + sprintf(ctag," (eta,phi)=(%f,%f) ",eta,phi); + result->tags_[ctag] = *p; + //set the veto variable + if(*p>=MaxSigma) + {veto = 1;} + + } + + else + { + sprintf(ctag,"eta_%i_error",k); + result->tags_[ctag]=0.0; + sprintf(ctag,"phi_%i_error",k); + result->tags_[ctag]=0.0; + } + + + if(p==ChisqValues.begin()||k>Num_to_print) + {break;} + + p--; + k++; + } + +//write out what value of NSigma you were using +//and the maximum number of bins to publish +result->tags_["MaxSigma"]=MaxSigma; +result->tags_["NSigma"]=NSigma; +result->tags_["Max Bins to Publish"]=Num_to_print; + +//write out the number of bins that were above the threshold to the screen + + int BinsOver=ChisqValues.size(); + result->tags_["NBinsOver"]=BinsOver; + +//check the thresholds + + if ( (BinsOver <= gthresho) && veto==0 ) { + result->status_ = dqm_core::Result::Green; + } else if ( (BinsOver < rthresho) && veto==0 ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + + ERS_DEBUG(2,"Result: "<<*result); + + return result; + +} +void +dqm_algorithms::Chi2Test_2D::printDescription(std::ostream& out) +{ + + out<<"Chi2Test_2D: Gives back the position of the highest NBins relative to the reference, and also computes the chisq/ndf "<<std::endl; + + out<<"Mandatory Green/Red Threshold: NBins to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/Chi2Test_Scatterplot.cxx b/DataQuality/dqm_algorithms/src/Chi2Test_Scatterplot.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8b507e5fbd6fdbf2c2a9104a39744b717ff472ce --- /dev/null +++ b/DataQuality/dqm_algorithms/src/Chi2Test_Scatterplot.cxx @@ -0,0 +1,180 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file Chi2Test_Scatterplot.cxx computes the chisq/ndf for a scatterplot; returns dqm_core::Result + * \author Ian Moult + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/Chi2Test_Scatterplot.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TH1F.h> +#include <TH2F.h> +#include <TObjArray.h> +#include <TMath.h> +#include <math.h> +#include <string> + +#include <TClass.h> +#include <TGraph.h> +#include <TGraphErrors.h> +#include <ers/ers.h> + +using namespace std; + + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::Chi2Test_Scatterplot myInstance; + +dqm_algorithms::Chi2Test_Scatterplot::Chi2Test_Scatterplot() + { + dqm_core::AlgorithmManager::instance().registerAlgorithm("Chi2Test_Scatterplot", this ); +} + + +dqm_algorithms::Chi2Test_Scatterplot * +dqm_algorithms::Chi2Test_Scatterplot::clone() +{ + return new Chi2Test_Scatterplot(); +} + + +dqm_core::Result * +dqm_algorithms::Chi2Test_Scatterplot::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + const TH1 * inputgraph2; + + if(object.IsA()->InheritsFrom( "TH1" )) { + inputgraph2 = static_cast<const TH1*>( &object ); + + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //now, cast inputgraph2 to input graph and remove its constness + TH1* inputgraph=const_cast<TH1*>(inputgraph2); + + + + double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), 1 ); + + if (inputgraph->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = inputgraph->GetEntries(); + return result; + } + + + + + TH1 * refhist; + double gthresho; + double rthresho; + std::string option; + + std::string thresholdname="Chi2_per_NDF"; + + try { + gthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + + } + + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + if (inputgraph->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, "Dimension", name ); + } + + + + if ((inputgraph->GetNbinsX() != refhist->GetNbinsX()) || (inputgraph->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + + int n=0; + double chisq=0; + double errsquared; + double inputerr; + double referr; + double val; + double refval; + + + //read in the range of bin values to use + vector<int> range; + try{ + range=dqm_algorithms::tools::GetBinRange(inputgraph,config.getParameters()); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + +//now compute the chisq/ndf + + int count_ndf=0; + + for(n=range[0];n<(range[1]+1);n++) + { inputerr=inputgraph->GetBinError(n); + referr=refhist->GetBinError(n); + errsquared= referr*referr+inputerr*inputerr; + val=inputgraph->GetBinContent(n); + refval=refhist->GetBinContent(n); + if (referr >0.00001 && inputerr >0.00001) + {chisq=chisq+((val-refval)*(val-refval))/errsquared; + count_ndf++; + } + else + {//out<<"One of the errors is too small???? "<<n<<std::endl; + } + + } + + + const double value = (count_ndf > 1) ? (chisq / (count_ndf - 1)) : 0; // avoid to divide by zero (should never happen) + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_[thresholdname] = value; + + +//check the thresholds + + if ( value <= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value < rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + + ERS_DEBUG(2,"Result: "<<*result); + + return result; + +} +void +dqm_algorithms::Chi2Test_Scatterplot::printDescription(std::ostream& out) +{ + + out<<"Chi2Test_Scatterplot performs chisq/ndf test on a scatterplot and returns a dqm_result"<<std::endl; + + + out<<"Mandatory Green/Red Threshold: Chi2_per_NDF to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/ChiComp.cxx b/DataQuality/dqm_algorithms/src/ChiComp.cxx new file mode 100644 index 0000000000000000000000000000000000000000..aecae9e6e9285a1fc3bcfacb9eb7838b72cbe54a --- /dev/null +++ b/DataQuality/dqm_algorithms/src/ChiComp.cxx @@ -0,0 +1,192 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file ChiComp.cxx does a simple Chi Squared like comparison of 2 histograms, returns Chi2/DOF ; returns dqm_core::Result + * \author : Pier-Olivier DeViveiros, inspired by all the other dqm algorithms! + * Call the algorithm using library libdqm_algorithms.so and name AlgChiComp_Basic + */ + +#include "dqm_algorithms/ChiComp.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +#include "TH1.h" +#include "TF1.h" +#include "TProfile.h" +#include "TClass.h" + +using namespace std; + +// Only 1 variation at the moment - might do more later +static dqm_algorithms::ChiComp Basic( "Basic" ); + +dqm_algorithms::ChiComp::ChiComp( const std::string & name ) + : name_ ( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( "AlgChiComp_"+ name, this ); +} + +dqm_algorithms::ChiComp * +dqm_algorithms::ChiComp::clone() +{ + return new ChiComp( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::ChiComp::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + // Histograms read from file + const TH1 * histogram; + TH1 * refhist; + + // Thresholds + double gthresho; + double rthresho; + + // Checks whether this is a Profile plot + bool profile=0; + if(object.IsA()->InheritsFrom( "TProfile" )) + profile=1; + + // Checks which type of histogram this is... + if(object.IsA()->InheritsFrom( "TH1" )) { + histogram = static_cast<const TH1*>( &object ); + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Dimension" ); + } + + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, name, "number of bins" ); + } + + // Get thresholds + + std::string thresh="ChiSqPerNdof"; + try { + gthresho = dqm_algorithms::tools::GetFromMap( thresh, config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( thresh, config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + // Here we clone the Reference so that we can scale it... + TH1 * reference = (TH1*)refhist->Clone(); + + // Cast the histograms into TProfiles id needed + TProfile * prof_hist(0); + TProfile * prof_ref(0); + if(profile){ + prof_hist = (TProfile*)histogram->Clone(); + prof_ref = (TProfile*)refhist->Clone(); + } + + // Force ROOT to use Sum of Squares to handle uncertainties correctly + // Scale Reference - No need to do this for Profile plots... + if(!profile) + { + reference->Sumw2(); + if(histogram->Integral() != reference->Integral()) + reference->Scale(histogram->Integral()/reference->Integral()); + } + + + // Constant to check Validity of Test - Number of points contributing to Chi^2 + int numchi = 0; + + // Chi Square Like Significance + double significance = 0; + + // Calculate Chi Square + for(int i=1; i<histogram->GetNbinsX()+1; i++){ + + // Calculate the contribution + double diff = fabs(histogram->GetBinContent(i) - reference->GetBinContent(i)); + + double uncert1 = histogram->GetBinError(i); + double uncert2 = reference->GetBinError(i); + double uncert = sqrt(uncert1*uncert1 + uncert2*uncert2); + + bool badbin = 0; + + // Check whether this is a 0 uncertainty bin in a profile plot + // If it is the case, we have to ignore it... + if(profile) + badbin = prof_hist->GetBinEntries(i)<2 || prof_ref->GetBinEntries(i)<2; + + // Prevent Negative weights from MCatNLO from messing things up + // Also, zero bins become very problematic when comparng histogrames + // with vaslty different statistics - Remove them... + + if(!profile) + badbin = histogram->GetBinContent(i)<=0 || reference->GetBinContent(i)<=0; + + if(uncert !=0 && badbin ==0){ + numchi++; + significance += (diff/uncert)*(diff/uncert); + } + } + + dqm_core::Result* result = new dqm_core::Result(); + + std::string out ="ChiSqPerBin"; + std::string out1="ChiSqTotal"; + std::string out2="ChiSqUsedBins"; + + if(numchi>0) + { + double value = significance/numchi; + result->tags_[out] = value; + result->tags_[out1] = significance; + result->tags_[out2] = numchi; + if ( value <= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value < rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } else { + result->tags_[out] = 0; + result->tags_[out1]= 0; + result->tags_[out2]= 0; + result->status_ = dqm_core::Result::Undefined; + } + + + // Print all the useful information for comparing plots + result->tags_["Entries"] = histogram->GetEntries(); + result->tags_["Mean"] = histogram->GetMean(); + result->tags_["RMS"] = histogram->GetRMS(); + result->tags_["EntriesReference"] = refhist->GetEntries(); + result->tags_["MeanReference"] = refhist->GetMean(); + result->tags_["RMSReference"] = refhist->GetRMS(); + + return result; +} +void +dqm_algorithms::ChiComp::printDescription(std::ostream& out) +{ + out<<"AlgChiComp_" << name_ << ": Gives back a Chi Squared like quantity per histogram bin in comparison to a reference histogram. Note that this assumes Gaussian statistics, and handles different numbers of events per histogram correctly. It is also fully compatible with TProfile graphs"<<std::endl; + out<<"Mandatory Green/Red Threshold ChiSqPerNdof: Chi Squared per bin for Green/Red results\n"<<std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/CorrelationYX.cxx b/DataQuality/dqm_algorithms/src/CorrelationYX.cxx new file mode 100644 index 0000000000000000000000000000000000000000..16419cf1366ec1753119a16c61b4eac1dc92ed95 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/CorrelationYX.cxx @@ -0,0 +1,170 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_algorithms/CorrelationYX.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "ers/ers.h" + + +static dqm_algorithms::CorrelationYX staticInstance; + + +namespace dqm_algorithms { + + // ********************************************************************* + // Public Methods + // ********************************************************************* + + CorrelationYX:: + CorrelationYX() + : name("AlgCorrelationYX") + { + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); + } + + + CorrelationYX:: + ~CorrelationYX() + { + } + + + dqm_core::Algorithm* + CorrelationYX:: + clone() + { + return new CorrelationYX(*this); + } + + + dqm_core::Result* + CorrelationYX:: + execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) + { + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + int binStart, binEnd; + double gmin; + double rmin; + try { + binStart = (int) dqm_algorithms::tools::GetFirstFromMap("BinStart", config.getParameters() ); + binEnd = (int) dqm_algorithms::tools::GetFirstFromMap("BinEnd" , config.getParameters() ); + rmin = dqm_algorithms::tools::GetFromMap( "CorrMin", config.getRedThresholds()); + gmin = dqm_algorithms::tools::GetFromMap( "CorrMin", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + double count = 0; + double avX = 0; + double avY = 0; + double avX2 = 0; + double avY2 = 0; + double avXY = 0; + double sdX = 0; + double sdY = 0; + double correlation=0; + + int nbiny = histogram -> GetNbinsY(); + if(binStart>binEnd) { + binStart= 1; + binEnd = histogram -> GetNbinsX(); + } + int binSize = binEnd-binStart+1; + + std::vector<double> contents; + contents.resize(binSize); + for(int i=0;i<binSize;i++) { + int binx = binStart+i; + contents[i]=0; + for ( int j = 1; j <= nbiny; ++j ) { + double content= histogram -> GetBinContent(binx,j); + contents[i]+=content; + for(int k=0; k!=content;k++) { + count ++ ; + avX += binx ; + avY += j ; + avX2 += binx*binx ; + avY2 += j*j ; + avXY += binx*j ; + } + } + } + + if(count>0) { + avX = avX / count; + avY = avY / count; + avX2 = avX2 / count; + avY2 = avY2 / count; + avXY = avXY / count; + } + + sdX = sqrt(avX2-avX*avX) ; + sdY = sqrt(avY2-avY*avY) ; + if(sdX>0&&sdY>0)correlation=(avXY-avX*avY)/(sdX*sdY); + + + ERS_DEBUG(1,"Number of entries for bins is "<< count ); + ERS_DEBUG(1,"Correlation biny and binx is "<< correlation ); + ERS_DEBUG(1,"Green: "<< gmin << " entries; Red: " << rmin << " entries "); + + dqm_core::Result* result = new dqm_core::Result(); + + + + if ( correlation >= gmin ) { + result->status_ = dqm_core::Result::Green; + } else if ( correlation > rmin ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + result->tags_["Correlation"] = correlation; + + + return result; + } + + + void + CorrelationYX:: + printDescription(std::ostream& out) + { + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Counts the number of listed bins with entries above CountsTh\n"; + message += "Parameters: BinStart first bin to be checked (1=first bin)\n"; + message += " BinEnd last bin to be checked (nbin=last bin)\n"; + message += " CorrMin minimum correlation Red/Green\n"; + message += "\n"; + + out << message; + } + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/CountsBinsGreaterThan.cxx b/DataQuality/dqm_algorithms/src/CountsBinsGreaterThan.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e367faedcbea81529a9a7ff2e4bbbb829f397d3e --- /dev/null +++ b/DataQuality/dqm_algorithms/src/CountsBinsGreaterThan.cxx @@ -0,0 +1,145 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_algorithms/CountsBinsGreaterThan.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "ers/ers.h" + + +static dqm_algorithms::CountsBinsGreaterThan staticInstance; + + +namespace dqm_algorithms { + + // ********************************************************************* + // Public Methods + // ********************************************************************* + + CountsBinsGreaterThan:: + CountsBinsGreaterThan() + : name("AlgCountsBinsGreaterThan") + { + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); + } + + + CountsBinsGreaterThan:: + ~CountsBinsGreaterThan() + { + } + + + dqm_core::Algorithm* + CountsBinsGreaterThan:: + clone() + { + return new CountsBinsGreaterThan(*this); + } + + + dqm_core::Result* + CountsBinsGreaterThan:: + execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) + { + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + int binStart, binEnd; + int CountsTh; + double gmin; + double rmin; + try { + binStart = (int) dqm_algorithms::tools::GetFirstFromMap("BinStart", config.getParameters() ); + binEnd = (int) dqm_algorithms::tools::GetFirstFromMap("BinEnd" , config.getParameters() ); + CountsTh = (int) dqm_algorithms::tools::GetFirstFromMap("CountsTh", config.getParameters() ); + rmin = dqm_algorithms::tools::GetFromMap( "NEntries", config.getRedThresholds()); + gmin = dqm_algorithms::tools::GetFromMap( "NEntries", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + double count = 0; + + int nbiny = histogram -> GetNbinsY(); + if(binStart>binEnd) { + binStart= 1; + binEnd = histogram -> GetNbinsX(); + } + int binSize = binEnd-binStart+1; + + std::vector<double> contents; + contents.resize(binSize); + for(int i=0;i<binSize;i++) { + int binx = binStart+i; + contents[i]=0; + for ( int j = 1; j <= nbiny; ++j ) { + double content= histogram -> GetBinContent(binx,j); + contents[i]+=content; + if(content>CountsTh)count++; + } + } + + + ERS_DEBUG(1,"Number of entries for bins is "<< count ); + ERS_DEBUG(1,"Green: "<< gmin << " entries; Red: " << rmin << " entries "); + + dqm_core::Result* result = new dqm_core::Result(); + + + + if ( count >= gmin ) { + result->status_ = dqm_core::Result::Green; + } else if ( count > rmin ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + result->tags_["BinsAboveTh"] = count; + + + return result; + } + + + void + CountsBinsGreaterThan:: + printDescription(std::ostream& out) + { + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Counts the number of listed bins with entries above CountsTh\n"; + message += "Parameters: BinStart first bin to be checked (1=first bin)\n"; + message += " BinEnd last bin to be checked (nbin=last bin)\n"; + message += " CountsTh thresholds on bin counts \n"; + message += " Nentries Red/Green"; + message += "\n"; + + out << message; + } + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/DivideBin.cxx b/DataQuality/dqm_algorithms/src/DivideBin.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bb1937e542582f21bf1390708759ebd99e4c795a --- /dev/null +++ b/DataQuality/dqm_algorithms/src/DivideBin.cxx @@ -0,0 +1,130 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideBin.cxx calculates the ratio of two bins + * \author Mansoora Shamim + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/DivideBin.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> +#include <TH1.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +static dqm_algorithms::DivideBin myInstance; + +dqm_algorithms::DivideBin::DivideBin() + +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("DivideBin", this); +} + +dqm_algorithms::DivideBin * +dqm_algorithms::DivideBin::clone() +{ + + return new DivideBin(); +} + + +dqm_core::Result * +dqm_algorithms::DivideBin::execute(const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + + double gthresho; + double rthresho; + int xbin_num; + int xbin_denom; + try { + xbin_num = (int)dqm_algorithms::tools::GetFirstFromMap( "TestBin", config.getParameters()); + xbin_denom = (int)dqm_algorithms::tools::GetFirstFromMap( "RefBin", config.getParameters()); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + try { + gthresho = dqm_algorithms::tools::GetFromMap( "Threshold", config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( "Threshold", config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig(ERS_HERE,name,"Parameter: 'Threshold' is mandatory, cannot continue"); + + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + const double minrefentries = dqm_algorithms::tools::GetFirstFromMap( "MinRefEntries", config.getParameters(), 1 ); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + // Get the denominator + double hdenom = histogram->GetBinContent(xbin_denom); + + if ( minrefentries > 0 && hdenom < minrefentries) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientRefEntries"] = hdenom; + return result; + } + + // Get the numerator + double hnum = histogram -> GetBinContent(xbin_num); + + double value = hnum/hdenom; + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["BinRatio"] = value; + +if (rthresho < gthresho){ + if ( value >= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value < rthresho ) { + result->status_ = dqm_core::Result::Red; + } else { + result->status_ = dqm_core::Result::Yellow; + } +} else { + if ( value <= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value > rthresho ) { + result->status_ = dqm_core::Result::Red; + } else { + result->status_ = dqm_core::Result::Yellow; + } +} + + return result; +} + + +void dqm_algorithms::DivideBin::printDescription(std::ostream& out) { + out<<"DivideBin : Performs the division of a particular bin by the total entries in that histogram "<< std::endl; + out<<"Optional Parameter : MinStat : Minimum histogram statistics needed to perform Algorithm"<< std::endl; + out<<"Optional Parameter : MinRefEntries : Minimum number of entries in reference bin needed to perform Algorithm"<< std::endl; + out<<"Mandatory parameter: TestBin: Index of the bin in x that should be tested\n"<< std::endl; + out<<"Mandatory parameter: RefBin: Index of the bin in x that should be used as a reference\n"<< std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/DivideReference.cxx b/DataQuality/dqm_algorithms/src/DivideReference.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9c4f0b638d4be3922ebf339bcff640af6d090fee --- /dev/null +++ b/DataQuality/dqm_algorithms/src/DivideReference.cxx @@ -0,0 +1,139 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideReference.cxx checks an histogram with a specified algorithm, after summing to input histograms the reference histogram + * \author andrea.dotti@cern.ch + */ + +#include <dqm_algorithms/DivideReference.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_algorithms/tools/SimpleAlgorithmConfig.h> +#include <TH1.h> +#include <TClass.h> +#include <TObjArray.h> +#include <dqm_core/AlgorithmManager.h> + +#include <iostream> +using namespace std; + +namespace { + static dqm_algorithms::DivideReference d1("All_Bins_Filled"); + static dqm_algorithms::DivideReference d2("Bins_Diff_FromAvg"); + static dqm_algorithms::DivideReference d3("Bins_GreaterThan_Threshold"); + static dqm_algorithms::DivideReference d4("Bins_GreaterThanEqual_Threshold"); + static dqm_algorithms::DivideReference d5("Bins_LessThan_Threshold"); + static dqm_algorithms::DivideReference d6("Bins_LessThanEqual_Threshold"); + static dqm_algorithms::DivideReference d7("Bins_Equal_Threshold"); + static dqm_algorithms::DivideReference d8("Bins_NotEqual_Threshold"); + static dqm_algorithms::DivideReference d9("BinContentComp"); +} + +dqm_algorithms::DivideReference::DivideReference(const std::string& name ) : name_(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("DivideReference_"+name,this); +} + +dqm_algorithms::DivideReference* +dqm_algorithms::DivideReference::clone() +{ + return new DivideReference(name_); +} + +dqm_core::Result* +dqm_algorithms::DivideReference::execute(const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)(object.Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEffectiveEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + delete histogram; + return result; + } + + + TObject* ro = config.getReference(); + TObject* firstReference=0; + TObject* secondReference=0; + try { + dqm_algorithms::tools::handleReference( *ro , firstReference , secondReference ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + //Check the reference + TH1* refhist = dynamic_cast<TH1*>(firstReference); + if ( refhist==0 ) + { + throw dqm_core::BadRefHist( ERS_HERE, "Dimension", name ); + } + if ((histogram->GetDimension() != refhist->GetDimension()) || + (histogram->GetNbinsX() != refhist->GetNbinsX()) || + (histogram->GetNbinsY() != refhist->GetNbinsY()) || + refhist->GetNbinsZ() != histogram->GetNbinsZ() ) + { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + //Configuration done, prepare input histogram + histogram->Divide(refhist); + //Now prepare to run the real algorithm... + ERS_DEBUG(2,"Running algorithm: "<<name_); + dqm_core::Algorithm* subalgorithm; + try { + subalgorithm = dqm_core::AlgorithmManager::instance().getAlgorithm( name_ ); + } + catch ( dqm_core::AlgorithmNotFound& ex ) + { + ERS_DEBUG(2,"Cannot find algorithm:"+name_); + throw dqm_core::BadConfig(ERS_HERE,name,"Cannot Find sub-algorithm:"+name_); + } + //Copy configuration and update reference + dqm_algorithms::tools::SimpleAlgorithmConfig newConf( config ); + newConf.setReference( secondReference ); + dqm_core::Result* result = subalgorithm->execute( name , *histogram , newConf); + ERS_DEBUG(2,"Sub algorithm returns:"<<*result); + //Add modified histogram to result + TObject* robject = result->getObject(); + if ( !robject ) //No object defined, add the modified histogram + { + ERS_DEBUG(2,"Adding modified histogram in result"); + result->object_.reset(histogram); + } + else //Transform the object_ in TObjArray (if needed) and add this result + { + ERS_DEBUG(2,"Result already have an associated TObject, appending modified histogram"); + if ( robject->IsA()->InheritsFrom("TCollection") ) //It is already an array add it... + { + static_cast<TCollection*>(robject)->Add( histogram ); + //Check in again + result->object_.reset( robject ); + } + else + { + TObjArray* array = new TObjArray( 2 ); + array->AddAt( robject , 0 ); + array->AddAt( histogram , 1 ); + //Check in again + result->object_.reset( array ); + } + ERS_DEBUG(2,"Result now have a TObjArray of size:"<<static_cast<TObjArray*>(result->getObject())->GetEntries()); + } + return result; +} + + +void dqm_algorithms::DivideReference::printDescription(std::ostream& out) { + out<<"DivideReference_"+name_+" : Performst the "+name_+" algorithm after dividing the input histogram by the reference. I.e. performing: histogram /= Reference (see TH1::Divide). Adds to the output TObject list the modified input histogram."<<std::endl; + out<<"Optional Parameter : MinStat : Minimum histogram statistics needed to perform Algorithm"<<std::endl; + + +} diff --git a/DataQuality/dqm_algorithms/src/GatherData.cxx b/DataQuality/dqm_algorithms/src/GatherData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4284dc5518a1aa3e8b31a00a2aeb7de07d92e450 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/GatherData.cxx @@ -0,0 +1,112 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: GatherData.cxx 585724 2014-02-28 18:07:18Z ponyisi $ +// ********************************************************************** + +#include "dqm_algorithms/GatherData.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TH1.h> +#include <TGraph.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" + + +static dqm_algorithms::GatherData staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +GatherData:: +GatherData() + : name("GatherData") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +GatherData:: +~GatherData() +{ +} + + +dqm_core::Algorithm* +GatherData:: +clone() +{ + return new GatherData(*this); +} + + +dqm_core::Result* +GatherData:: +execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& ) +{ + dqm_core::Result::Status status(dqm_core::Result::Undefined); + + // Cast to the type of TObject to assess + const TH1* h = dynamic_cast<const TH1*>( &data ); + const TGraph* g = dynamic_cast<const TGraph*>( &data ); + if( h == 0 && g == 0 ) { + throw dqm_core::BadConfig( ERS_HERE, name, "Cannot cast data to type TH1" ); + } + + std::map<std::string,double> tags; + if( h != 0 ) { + tags["Mean"] = h->GetMean(); + tags["MeanError"] = h->GetMeanError(); + tags["RMS"] = h->GetRMS(); + tags["RMSError"] = h->GetRMSError(); + } + + if( g != 0 ) { + tags["XMean"] = g->GetMean(1); + tags["YMean"] = g->GetMean(2); + tags["XRMS"] = g->GetRMS(1); + tags["YRMS"] = g->GetRMS(2); + } + + dqm_core::Result* result = new dqm_core::Result( status ); + result->tags_ = tags; + + return result; +} + + +void +GatherData:: +printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Extracts data (ex., mean, RMS) from an object without performing\n"; + message += " any assessment; the status is always \"Undefined\"\n"; + message += "Parameters: none\n"; + message += "Limits: none\n"; + message += "\n"; + + out << message; +} + + +// ********************************************************************* +// Protected Methods +// ********************************************************************* + + +} // namespace dqm_algorithms + diff --git a/DataQuality/dqm_algorithms/src/GraphPrint.cxx b/DataQuality/dqm_algorithms/src/GraphPrint.cxx new file mode 100644 index 0000000000000000000000000000000000000000..acbed0a211d2950c57dca487a11a0c5e7f8ee6a1 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/GraphPrint.cxx @@ -0,0 +1,69 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! author Jahred Adelman +*/ +#include <dqm_algorithms/GraphPrint.h> +#include <TGraphErrors.h> +#include <TMath.h> +#include <TClass.h> +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/Result.h> +#include <ers/ers.h> +#include <string> +#include <sstream> +#include <iostream> +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::GraphPrint myInstance; + +dqm_algorithms::GraphPrint::GraphPrint() { + dqm_core::AlgorithmManager::instance().registerAlgorithm("GraphPrint",this); +} + +dqm_algorithms::GraphPrint::~GraphPrint() {} + +dqm_algorithms::GraphPrint* dqm_algorithms::GraphPrint::clone(){ + return new GraphPrint(); +} + +dqm_core::Result* dqm_algorithms::GraphPrint::execute(const std::string & name, + const TObject & obj, + const dqm_core::AlgorithmConfig & /* config */ ) +{ + TGraph* graph; + if ( obj.IsA()->InheritsFrom("TGraph") ) + { + ERS_DEBUG(2,"Got TGraph called: "<<obj.GetName()<<" of type:"<<obj.IsA()->GetName()); + graph = (TGraph*)&obj; + } + else + { + throw dqm_core::BadConfig(ERS_HERE,name,"Object is not a TGraph "); + } + Int_t npoints = graph->GetN(); + + // Everything is now configured correctly, we can start + dqm_core::Result* result = new dqm_core::Result; + for ( Int_t bin = 0 ; bin < npoints ; ++bin) //Loop on all points + { + Double_t x = 0, y = 0; + graph->GetPoint(bin,x,y); + // Check point error bars + ERS_DEBUG(3,"Looking at point "<<bin<< " and I see x = " << x << " and y = " << y); + std::string binname = Form("Candidate %d in LB %.0f, Event", bin, x); + //std::string binname = Form("Candidate %d LB %d Event:", bin, int(x)); + result->tags_[binname.c_str()] = y; + } + + result->status_=dqm_core::Result::Green; + return result; +} + +void +dqm_algorithms::GraphPrint::printDescription(std::ostream& out) +{ + out << " Just dump all the bin contents of a TGraph!" << std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/GraphTest.cxx b/DataQuality/dqm_algorithms/src/GraphTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4206c48e2b2db2ffb7aef1e38044ac218ff18a34 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/GraphTest.cxx @@ -0,0 +1,281 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file RootFit.h file declares the dqm_algorithms::RootFit class. + * \author Haleh Hadavand +*/ +#include <dqm_algorithms/GraphTest.h> +#include <TGraphErrors.h> +#include <TMath.h> +#include <TClass.h> +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/Result.h> +#include <ers/ers.h> +#include <string> +#include <sstream> +#include <iostream> +#include <dqm_core/AlgorithmManager.h> + +#define NPARS 6 + +static dqm_algorithms::GraphTest myInstance; + +dqm_algorithms::GraphTest::GraphTest() { + dqm_core::AlgorithmManager::instance().registerAlgorithm("GraphTest",this); +} + +dqm_algorithms::GraphTest::~GraphTest() {} + +dqm_algorithms::GraphTest* dqm_algorithms::GraphTest::clone(){ + return new GraphTest(); +} + +dqm_core::Result* dqm_algorithms::GraphTest::execute(const std::string & name, + const TObject & obj, + const dqm_core::AlgorithmConfig & config ) +{ + TGraph* graph; + TGraph* refhist = 0; + bool ownObject=false; + if ( obj.IsA()->InheritsFrom("TGraph") ) + { + ERS_DEBUG(2,"Got TGraph called: "<<obj.GetName()<<" of type:"<<obj.IsA()->GetName()); + graph = (TGraph*)&obj; + } + else if ( obj.IsA()->InheritsFrom("TH1") ) + { + ERS_DEBUG(2,"Got TH1: converting to TGraphErrors"); + graph = new TGraphErrors((TH1*)&obj); + graph->SetNameTitle("TempG","TempG"); + ownObject = true; // In case we are here we have to delete the graph + } + else + { + throw dqm_core::BadConfig(ERS_HERE,name,"Object is not a TGraph or a TH1"); + } + //Now get reference object and check compatibility + ERS_DEBUG(2,"Retreiving reference graph"); + + try { + refhist = static_cast<TGraph *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + ERS_DEBUG(2,"No reference specified, will skip point-by-point comparison"); + } + Int_t npoints = graph->GetN(); + ERS_DEBUG(2,"Number of points to be checked: "<<npoints); + if ( refhist ) { + if ( ! refhist->IsA()->InheritsFrom("TGraph") ) + { + if ( ownObject ) delete graph; + throw dqm_core::BadRefHist(ERS_HERE,name,"Reference is not a TGraph"); + } + if ( refhist->GetN() != npoints ) + { + if ( ownObject ) delete graph; + throw dqm_core::BadConfig(ERS_HERE,name,"Reference and object with different number of points"); + } + } + else { + ERS_DEBUG(2,"No reference specified, will skip point-by-point comparison"); + } + // Configure the DQ algorithm + const std::string param[NPARS] = {"XErrHigh","XErrLow","YErrHigh","YErrLow","DistFactor","NBins"}; + Double_t bigNumber = 1.7E+308; //some big number... + Double_t grValue[NPARS] = { bigNumber , bigNumber , bigNumber , bigNumber , 1, 0 }; + Double_t reValue[NPARS] = { bigNumber , bigNumber , bigNumber , bigNumber , 1, 0 }; + for ( unsigned int i = 0; i<NPARS;++i) { + // get configuration for Green Threshold + try + { + grValue[i] = dqm_algorithms::tools::GetFromMap(param[i] , config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) + { + ERS_DEBUG(1,"Parameter: i"<<param[i]<<"' for Green not found in configuration, using default: "<<reValue[i]); + } + // get configuration for Red Threshold + try + { + reValue[i] = dqm_algorithms::tools::GetFromMap(param[i] , config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) + { + ERS_DEBUG(1,"Parameter: i"<<param[i]<<"' for Red not found in configuration, using default: "<<reValue[i]); + } + if ( reValue[i] < grValue[i] ) // Non sense values + { + std::stringstream msg; + msg<<"Configuration Error (Red<Green):"<<param[i]<<" G="<<grValue[i]<<" R="<<reValue[i]; + if ( ownObject ) delete graph; + throw dqm_core::BadConfig(ERS_HERE,name,msg.str()); + } + } // End of configuration retreival +#if DEBUG_LEVEL > 1 + if ( grValue[4]==0 ) { ERS_DEBUG(2,"Exact Match request for Green"); } + if ( reValue[4]==0 ) { ERS_DEBUG(2,"Exact Match request for Red"); } + std::stringstream configuration; + for ( int i = 0;i<NPARS;++i) + { + configuration<<" - "<<param[i]<<" Green:"<<grValue[i]<<" Red:"<<reValue[i]; + } + ERS_DEBUG(2,"Configuration: "<<configuration.str()); +#endif + // Just a translation in something more readable... + Double_t grXEH =grValue[0]; // Error (High) on X + Double_t grXEL =grValue[1]; // Error (Low) on X + Double_t grYEH =grValue[2]; // Error (High) on Y + Double_t grYEL =grValue[3]; // Error (Low) on Y + Double_t grExpF=grValue[4]; // Moltiplicative Factor for DX,DY + Double_t Ngreen=grValue[5]; // Number of points to fail + Double_t reXEH =reValue[0]; // Error (High) on X + Double_t reXEL =reValue[1]; // Error (Low) on X + Double_t reYEH =reValue[2]; // Error (High) on Y + Double_t reYEL =reValue[3]; // Error (Low) on Y + Double_t reExpF=reValue[4]; // Multiplicative Factor for DX,DY + Double_t Nred = reValue[5]; // Number of points to fail + // Everything is now configured correctly, we can start + Int_t yellowCounterErrorBars=0 , yellowCounterPoints=0; + Int_t redCounterErrorBars=0 , redCounterPoints=0; + std::stringstream errorsList; + dqm_core::Result* result = new dqm_core::Result; + for ( Int_t bin = 0 ; bin < npoints ; ++bin) //Loop on all points + { + // Check point error bars + ERS_DEBUG(3,"====> Starting check on point "<<bin); + ERS_DEBUG(3,"Checking error bars"); + Double_t xEH=graph->GetErrorXhigh(bin),xEL=graph->GetErrorXlow(bin); + Double_t yEH=graph->GetErrorYhigh(bin),yEL=graph->GetErrorYlow(bin); + if ( xEH>grXEH || xEL>grXEL || yEH>grYEH || yEL>grYEL ) + { + ERS_DEBUG(2,"[YELLOW] (point "<<bin<<") error bars:xH="<<xEH<<",xL="<<xEL<<",yH="<<yEH<<",yL="<<yEL); + ERS_DEBUG(3,"Limits are: xH="<<grValue[0]<<" xL="<<grValue[1]<<" yH="<<grValue[2]<<" yL="<<grValue[3]<<" nGreen="<<grValue[5]); + errorsList<<"; point "<<bin<<" Err. bars:xH="<<xEH<<",xL="<<xEL<<",yH="<<yEH<<",yL="<<yEL; + ++yellowCounterErrorBars; + } + if ( xEH>reXEH || xEL>reXEL || yEH>reYEH || yEL>reYEL ) + { + ERS_DEBUG(2,"[RED] (point "<<bin<<") error bars:xH="<<xEH<<",xL="<<xEL<<",yH="<<yEH<<",yL="<<yEL); + ERS_DEBUG(3,"Limits are: xH="<<reValue[0]<<" xL="<<reValue[1]<<" yH="<<reValue[2]<<" yL="<<reValue[3]<<" nRed="<<reValue[5]); + ERS_DEBUG(1,"[RED] Result");// game over, RED level reached + ++redCounterErrorBars; + result->tags_.insert(std::make_pair("RedErrorBarsForPoint",bin)); + } + // Now Check if point is compatible with reference point (x_r,y_r) + // reference point (asymmetric) errors bars + // (xEH,xEL,yEH,yEL) define the max. allowed distance for + // The ProximityFactor can be used to set two different thresholds for + // yellow and red. + // If ref. point errors bars are zeros do not check that coordinate + // Ex. Point is Green if: x_r - f*xEL =< x =< x_r + f*xEH AND + // y_r - f*yEL =< y =< y_r + f*yEH + ERS_DEBUG(3,"Checking compatibility with reference point"); + Double_t x,y; + graph->GetPoint(bin,x,y); + Double_t x_r = x ,y_r = y; + if (refhist) refhist->GetPoint(bin,x_r,y_r); + Double_t DX = x-x_r , DY=y-y_r; + Double_t xEH_r = 0 , xEL_r = 0 , yEH_r = 0 , yEL_r = 0; + if ( refhist ) { + xEH_r = refhist->GetErrorXhigh(bin); + xEL_r = refhist->GetErrorXlow(bin); + yEH_r = refhist->GetErrorYhigh(bin); + yEL_r = refhist->GetErrorYlow(bin); + } + if ( xEH_r==0 && xEL_r==0 ) + { + ERS_DEBUG(3,"Turn off check on x (point "<<bin<<")"); + DX=0; // Do not check X + } + if ( yEH_r==0 && yEL_r==0 ) + { + ERS_DEBUG(3,"Turn off check on y (point "<<bin<<")"); + DY=0; // Do not check Y + } + if ( DX > grExpF*xEH_r || DX < -grExpF*xEL_r || + DY > grExpF*yEH_r || DY < -grExpF*yEL_r ) + { + ERS_DEBUG(2,"[YELLOW] Point "<<bin<<" does not match with reference value (DX,DY)=("<<DX<<","<<DY<<")"); + ERS_DEBUG(3,"Limits are: "<<-grExpF*xEL_r<<"<DX<"<<grExpF*xEH_r<<" ; "<<-grExpF*yEL_r<<"<DY<"<<grExpF*yEH_r); + errorsList<<"; point "<<bin<<" Does not match with reference (DX,DY)=("<<DX<<","<<DY<<")"; + ++yellowCounterPoints; + std::stringstream out; + out << yellowCounterPoints; + std::string yellowtag = out.str(); + if(yellowCounterPoints<10) yellowtag= "0"+yellowtag; + yellowtag ="YellowPointNumber"+yellowtag; + result->tags_.insert(std::make_pair(yellowtag,bin)); + } + if ( DX > reExpF*xEH_r || DX < -reExpF*xEL_r || + DY > reExpF*yEH_r || DY < -reExpF*yEL_r ) + { + ERS_DEBUG(2,"[RED] Point "<<bin<<" does not match with reference value (DX,DY)=("<<DX<<","<<DY<<")"); + ERS_DEBUG(3,"Limits are: "<<-grExpF*xEL_r<<"<DX<"<<grExpF*xEH_r<<" ; "<<-grExpF*yEL_r<<"<DY<"<<grExpF*yEH_r); + ERS_DEBUG(1,"[RED] Result"); + ++redCounterPoints; + std::stringstream out; + out << redCounterPoints; + std::string redtag = out.str(); + if(redCounterPoints<10) redtag= "0"+redtag; + redtag ="RedPointNumber"+redtag; + result->tags_.insert(std::make_pair(redtag,bin)); + //result->tags_.insert(std::make_pair("RedPointNumber"+redCounterPoints,bin)); + } + ERS_DEBUG(3,"End of checks for Point "<<bin); + } // End loop on points + if ( redCounterErrorBars > Nred || redCounterPoints > Nred ) + { + ERS_DEBUG(1,"[Error] Result with "<<redCounterErrorBars+redCounterPoints<<" errors"); + ERS_DEBUG(2,"List of errors"<<errorsList.str()); + if ( ownObject ) delete graph; + result->status_=dqm_core::Result::Red; + if ( redCounterErrorBars > 0 ) + result->tags_.insert(std::make_pair("NumRedErrorBars",redCounterErrorBars)); + if ( redCounterPoints > 0 ) + result->tags_.insert(std::make_pair("NumRedComparison",redCounterPoints)); + return result; + } + if ( yellowCounterErrorBars > Ngreen || yellowCounterPoints > Ngreen ) + { + ERS_DEBUG(1,"[YELLOW] Result with "<<yellowCounterErrorBars+yellowCounterPoints<<" errors"); + ERS_DEBUG(2,"List of errors"<<errorsList.str()); + if ( ownObject ) delete graph; + if ( yellowCounterErrorBars > 0 ) + result->tags_.insert(std::make_pair("NumYellowsErrorBars",yellowCounterErrorBars)); + if ( yellowCounterPoints > 0 ) + result->tags_.insert(std::make_pair("NumYellowsComparison",yellowCounterPoints)); + result->status_=dqm_core::Result::Yellow; + return result; + } + ERS_DEBUG(1,"[GREEN] Result"); + if ( ownObject ) delete graph; + delete result; + return new dqm_core::Result(dqm_core::Result::Green); +} + +void +dqm_algorithms::GraphTest::printDescription(std::ostream& out) +{ + out<<"GraphTest DQ algorithm: check validity of a TGraph (or TH1)"<<std::endl + <<"This test can be used to perform a test on a TGraph with (or without) error bars, in case asymmmetric."<<std::endl + <<"It performs two tests:"<<std::endl + <<"1- It checks that each point in the TGraph has \"small\" error bars"<<std::endl + <<"2- It checks that each point is \"close\" to a reference value"<<std::endl + <<"For test 2 a reference TGraph has to be provided (in this way each point may have a different reference value). "<<std::endl + <<"The (x,y) coordinates of the point are compared with the reference point coordinates (x_r,y_r) and REFERENCE "<<std::endl + <<" point error bars defining the maximum allowed distance. i.e."<<std::endl + <<"the point is good if: x_r - f*x_err < x < x_r + f*x_err AND y_r - f*y_err < y < y_r + f*y_err"<<std::endl + <<"\"f\" is a factor that can be used to specify different limits for Green and Red thresholds."<<std::endl + <<"If, for a specific reference point, the error bars along one coordinate are set to zero the test 2 is NOT performed for that point (this can be used to exclude, for example, a dead channel through the reference graph). "<<std::endl + <<"The algorithms can work also with TGraphAsymmErrors object, so high and low errors can always be specified separately."<<std::endl + <<"The optional parameters that can be set, separetely, for Green and Red thresholds are:"<<std::endl + <<"XErrHigh : Maximum (higher) error bar length x coord (default is 1.844E19)."<<std::endl + <<"XErrLow : Maximum (lower) error bar length x coord (default is 1.844E19)."<<std::endl + <<"YErrHigh : Maximum (higher) error bar length y coord (default is 1.844E19)."<<std::endl + <<"YErrLow : Maximum (lower) error bar length y coord (default is 1.844E19)."<<std::endl + <<"DistFactor : The factor \"f\" used in second part of the test (default is 1)."<<std::endl + <<"NBins : This is the number of points allowed to fail to change result(default is 0)."<<std::endl; + +} diff --git a/DataQuality/dqm_algorithms/src/GrubbsOutlierTest.cxx b/DataQuality/dqm_algorithms/src/GrubbsOutlierTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..992a3c3fecbd1fc8428cc39bcce92d75a7c9c0ae --- /dev/null +++ b/DataQuality/dqm_algorithms/src/GrubbsOutlierTest.cxx @@ -0,0 +1,325 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file GrubbsOutlierTest.cxx + * \description Determine outliers at a given significance level by defining the Grubbs test + * statistic, and finding out the probability of each bin being an outlier. The + * critical value is computed for each bin and the probability is estimated + * using the two tailed students T distribution. If the probability for a given bin + * falls below the significance level the bin is an outlier. The flag can be computed + * using fraction of outlier bins. + * + * \author Venkatesh Kaushik <venkat.kaushik@cern.ch> + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/GrubbsOutlierTest.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <ers/ers.h> + +// STL +#include <sstream> + +// ROOT +#include <TH1.h> +#include <TF1.h> +#include <TMath.h> +#include <TClass.h> + +#ifndef GTESTPARS +#define GTESTPARS 5 +#endif + +dqm_algorithms::GrubbsOutlierTest GrubbsTest( "Grubbs" ); + +dqm_algorithms::GrubbsOutlierTest::GrubbsOutlierTest( const std::string & name ) + : name_ ( name ) { + dqm_core::AlgorithmManager::instance().registerAlgorithm("OutlierTest_"+ name, this ); +} + +dqm_algorithms::GrubbsOutlierTest * +dqm_algorithms::GrubbsOutlierTest::clone() +{ + return new GrubbsOutlierTest( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::GrubbsOutlierTest::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + const TH1 * histogram; + + // check if it inherits from 2d histogram + if ( object.IsA()->InheritsFrom("TH2") ) { + throw dqm_core::BadConfig( ERS_HERE , name , " dimension > 1 "); + } + + // check if its a 1d histogram or not + if ( object.IsA()->InheritsFrom("TH1") ) { + histogram = (TH1*)&object; + } else { + throw dqm_core::BadConfig( ERS_HERE ,name , " does not inherit from TH1"); + } + + // Configure the DQ algorithm + double grThr, reThr; // Green and Red thresholds + + // param 1: skip bin mod(N) + const int skipmod = (int)dqm_algorithms::tools::GetFirstFromMap("SkipBinModulo", config.getParameters(), histogram->GetNbinsX() + 10); + if (skipmod < 1) { + std::ostringstream msg; + msg << " Parameter \"SkipBinModulo\" is out of bounds. Value given = " << skipmod; + msg << "\n Range of values acceptable: integer >= 1"; + msg << "\n Default Value: skip none. Do not set \"SkipBinModulo\" in your config to use default"; + throw dqm_core::BadConfig(ERS_HERE,name,msg.str()); + } + + // param 2: significance level + const double signL = dqm_algorithms::tools::GetFirstFromMap("Significance", config.getParameters(), 0.04); + if (signL < 0.01 || signL > 0.95) { + std::ostringstream msg; + msg << " Parameter \"Significance\" is out of bounds. Value given = " << signL; + msg << "\n Range of values acceptable: floating point number [0.01, 0.95]"; + msg << "\n Default Value: 0.04. Do not set \"Significance\" in your config to use default"; + throw dqm_core::BadConfig(ERS_HERE,name,msg.str()); + } + + // param 3: min stat per bin + const double minStat = dqm_algorithms::tools::GetFirstFromMap("MinStatPerBin", config.getParameters(), 10); + if (minStat < 0) { + std::ostringstream msg; + msg << " Parameter \"MinStatPerBin\" is out of bounds. Value given = " << signL; + msg << "\n Range of values acceptable: integer >= 0"; + msg << "\n Default Value: 10. Do not set \"MinStatPerBin\" in your config to use default"; + throw dqm_core::BadConfig(ERS_HERE,name,msg.str()); + } + + // param 4,5: min and max bins + // the following is a duplicate of dqm_algorithms::tools::GetBinRange, but with different parameter names + const double notFound = -99999; + const double xmin = dqm_algorithms::tools::GetFirstFromMap("Min", config.getParameters(), notFound); + const double xmax = dqm_algorithms::tools::GetFirstFromMap("Max", config.getParameters(), notFound); + const int minbin = (xmin == notFound) ? 1 : histogram->GetXaxis()->FindBin(xmin); + const int maxbin = (xmax == notFound) ? histogram->GetNbinsX() : histogram->GetXaxis()->FindBin(xmax); + ERS_DEBUG(1, "xmin = " << xmin << ", xmax = " << xmax << " , minbin = " << minbin << ", maxbin = " << maxbin); + + // param 6: include bins with entries < minStat as outliers? + const bool useMinStat = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("IsMinStatOutlier", config.getParameters(), 1)); + ERS_DEBUG(1, "useMinStat = " << useMinStat); + + // Get Green and Red Thresholds + try { + + grThr = dqm_algorithms::tools::GetFromMap("Threshold",config.getGreenThresholds() ); + reThr = dqm_algorithms::tools::GetFromMap("Threshold",config.getRedThresholds() ); + + } catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig(ERS_HERE,name,"Paramter: 'Threshold' is mandatory, cannot continue"); + } + + if ( grThr > 1.0 || reThr > 1.0) { + throw dqm_core::BadConfig(ERS_HERE,name_,"Configuration Error: Threshold>100%"); + } + + //loop over bins and store values + int binc = 0; + std::vector<float> binCountVec; + std::vector<size_t> binIndices; + + // find mean, sigma max and min binvals + for(int k = minbin; k < maxbin; k++) { + // skip every N'th bin + if (k % skipmod == 0) {} + else { + float binval = histogram->GetBinContent(k); + binCountVec.push_back(binval); + if((binval <= minStat) && useMinStat) { + binIndices.push_back(binc); + } + binc++; + } // else + } // for k + + // find number of (and fraction of) outliers + int minOutliers = binIndices.size(); + int maxOutliers, nOutliers = minOutliers; + int nbinsDenominator = binCountVec.size(); + + dqm_core::Result * result = new dqm_core::Result; + + std::ostringstream msg; + try { + // invoke Grubbs' test + maxOutliers = GrubbsTest(binCountVec,binIndices,signL); + + // debug + msg<< "maxOutliers = " << maxOutliers << "\t bincountVecsize = " << nbinsDenominator << "\t"; + if(binIndices.size() <= binCountVec.size()) + for(size_t g= 0; g < binIndices.size(); g++) + msg << binIndices[g] << ":" << binCountVec[binIndices[g]] <<"\n"; + ERS_DEBUG(1, msg.str()); + + } catch ( dqm_core::Exception & ex ) { + msg << " Exception caught in GrubbsTest \n"; + throw dqm_core::BadConfig(ERS_HERE,name,msg.str()); + } + + // no. of outliers + if(maxOutliers >= 0) { + nOutliers += (useMinStat ? maxOutliers : 0); + } + result->tags_.insert(std::make_pair("NumOfOutliers",nOutliers)); + + // fraction of outliers + float totalBins = nbinsDenominator > 0 ? nbinsDenominator : histogram->GetNbinsX(); + float outlierFraction = 0.; +#ifndef __APPLE__ + bool IsInf = isinf(float(nOutliers) / totalBins); + bool IsNaN = isnan(float(nOutliers) / totalBins); +#else + bool IsInf = std::isinf(float(nOutliers) / totalBins); + bool IsNaN = std::isnan(float(nOutliers) / totalBins); +#endif + if(!IsInf || !IsNaN) + outlierFraction = float(nOutliers) / totalBins; + + result->tags_.insert(std::make_pair("OutlierFraction",outlierFraction)); + msg.str(""); + msg << "Outlier fraction = "<< nOutliers << "/" << totalBins << " = " << outlierFraction; + ERS_DEBUG(1, msg.str()); + + + // compare red/yellow/green thresholds with outlierfraction + // and return results + if (reThr> grThr) { + if ( outlierFraction>reThr ) + { + ERS_DEBUG(1,"[RED] Result : "<<outlierFraction); + result->status_=dqm_core::Result::Red; + return result; + } + else if ( outlierFraction > grThr ) + { + ERS_DEBUG(1,"[YELLOW] Result : "<<outlierFraction); + result->status_=dqm_core::Result::Yellow; + return result; + } + }else { + if ( outlierFraction < reThr ) + { + ERS_DEBUG(1,"[RED] Result : "<<outlierFraction); + result->status_=dqm_core::Result::Red; + return result; + } + else if ( outlierFraction < grThr ) + { + ERS_DEBUG(1,"[YELLOW] Result : "<<outlierFraction); + result->status_=dqm_core::Result::Yellow; + return result; + } + } + + // return (default) result + ERS_DEBUG(1,"[GREEN] Result"); + result->status_=dqm_core::Result::Green; + return result; + +} + +// Algorithm implementation +int dqm_algorithms::GrubbsOutlierTest::GrubbsTest(std::vector<float>& vec, std::vector<size_t>&binIndices, float signLevel) { + // return codes: + // >= 0 : number of outliers found + // -1 : input vector empty + // -2 : less then two bins have occupancy (need >= 2 bins filled for this test) + // -3 : significance level > 100% (nonsensical) + // -4 : significance level < 0.1% (is never achievable in most cases) + + // negative return codes + if(vec.empty()) return -1; + + size_t nItems = vec.size(); + if(vec.size() < 2) return -2; + + float epsilon = 1.e-5; + if(signLevel > 1.0) return -3; + + if((signLevel-0.001) < epsilon) return -4; + + bool notEmpty = !binIndices.empty(); + + // find mean + float mean = 0.; + for(size_t j = 0; j < nItems; j++) mean += vec[j]; + mean /= nItems; + + // find standard deviation (sd) + float sigma = 0.; + for(size_t j = 0; j < nItems; j++) { + float diff = (vec[j]-mean); + sigma += diff*diff; + } + sigma /= (nItems-1); + sigma = sqrt(sigma); + + float zval = 0., tval = 0., prob = 0.; + int retval = 0; + // loop over bins and... + for(size_t j = 0; j < nItems; j++) { + + // define test statistic z = |mean - val|/sigma + zval = fabs(mean - vec[j])/sigma; + + // find out the critical value (tval) for the test statistic + tval = sqrt(nItems*(nItems-2)*(zval*zval)/((nItems-1)*(nItems-1)-nItems*(zval*zval))); + + // determine the probability (two sided student's t pdf with N-2 d.o.f) of tval being + // far away (determined by significance level) from others so as to be considered an outlier + prob = 2*(1. - TMath::StudentI(tval,nItems-2)); + + // if p-value falls below significance level, this bin is an outlier + if(prob < signLevel) { + if(notEmpty) { + bool storeMe = true; + for(size_t k = 0; k < binIndices.size(); k++) { + if(binIndices[k] == j) { storeMe = false; break; } + } // for + if(storeMe) { + binIndices.push_back(j); + retval++; + } + } else { + binIndices.push_back(j); + retval ++; + } + } // if prob + } // for j + + // return #of outliers found + return retval; + +} + + void +dqm_algorithms::GrubbsOutlierTest::printDescription(std::ostream& out) { + out << "-------------- Grubbs' Test for Outliers ----------------------------------------------------" << std::endl; + out << "Identify outlier bins in a 1d histogram. Given N = {n1, n2, n3...} where n1 = frequency in 1st bin etc..\n"; + out << "Define test statistic: Z_i = |n_i - mean| / sigma, where mean = sum(n_i)/sizeof(N) and sigma = standard deviation of N\n"; + out << "For each Z_i calculate the critical value (tval) of the test-statistic and find out its corresponding p-value. if p-value\n"; + out << "p-value is calculated using \"two-sided t-distribution\" pdf with sizeof(N)-2 degrees of freedom.\n"; + out << "If p-value <= significance, reject null hypothesis (H_0 = no outliers).\n"; + out << "----------------------------------------------------------------------------------------------" << std::endl; + out << "Parameters : IsMinStatOutlier, Min, Max, MinStatPerBin, Significance, SkipBinModulo\n"; + out << "----------------------------------------------------------------------------------------------" << std::endl; + out << "IsMinStatOutlier: If bin contents are less than MinStatPerBin, is it an outlier? [type = bool] [values = 0, 1] [ default: 1]\n"; + out << "Min, Max : Process bin numbers corresponding to Min, Max (on x-axis). [type = float] [default: all bins]\n"; + out << "MinStatPerBin : Min number of entries per bin in order to be considered for testing. [type = integer] [values >= 0] [default = 9]\n"; + out << "Significance : Null hypothesis (no outliers) is rejected if critical value > significance [type = float] [range = [0.04, 0.99], default = 0.04]\n"; + out << "SkipBinModulo : Skip every N'th bin. [type = integer] [values = [0, #of bins in 1d hist], default: skip none]\n"; + out << "----------------------------------------------------------------------------------------------" << std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/HLTMETComponents.cxx b/DataQuality/dqm_algorithms/src/HLTMETComponents.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0b14e8b9999a89e99085371df249abcc7dc379e0 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/HLTMETComponents.cxx @@ -0,0 +1,156 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* Algorithm: AlgHLTMETComponents does the following + * Check if any sub-detector component is empty. Empty means the following: + * overflow or underflow bins are filled or integral of histogram is zero. + * Author : Venkatesh Kaushik <venkat.kaushik@cern.ch> + * Date : March 2010 + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/HLTMETComponents.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + + +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::HLTMETComponents myInstance; + +dqm_algorithms::HLTMETComponents::HLTMETComponents() + +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("AlgHLTMETComponents", this); +} + +dqm_algorithms::HLTMETComponents * +dqm_algorithms::HLTMETComponents::clone() +{ + + return new HLTMETComponents(); +} + + +dqm_core::Result * +dqm_algorithms::HLTMETComponents::execute(const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH2 *histogram; + + if( object.IsA()->InheritsFrom( "TH2" ) ) { + histogram = (TH2*)&object; + int dimension = histogram->GetDimension(); + if (dimension != 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension != 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH2" ); + } +/////////////////////////////////////////////////////////////////////////////////////////// + + int nXBins = histogram -> GetNbinsX(); // components + if(nXBins > 25) { + nXBins = 25; + } + const int nYBins = histogram -> GetNbinsY(); // SumEt per sampling + + + // read thresholds + int colflags[4]; + colflags[0] = static_cast<int>(dqm_algorithms::tools::GetFirstFromMap("METYellowMin", config.getParameters(), 1)); + colflags[1] = static_cast<int>(dqm_algorithms::tools::GetFirstFromMap("METYellowMax", config.getParameters(), nXBins)); + colflags[2] = static_cast<int>(dqm_algorithms::tools::GetFirstFromMap("METRedMin", config.getParameters(), 1)); + colflags[3] = static_cast<int>(dqm_algorithms::tools::GetFirstFromMap("METRedMax", config.getParameters(), nXBins)); + // read options + bool doflags[2]; + doflags[0] = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("DoYellowFlag", config.getParameters(), 1)); + doflags[1] = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("DoRedFlag", config.getParameters(), 1)); + + dqm_core::Result* result = new dqm_core::Result(); + colflags[0] = ((colflags[0] > 0) && (colflags[0] <= nXBins)) ? colflags[0] : 1; + colflags[1] = ((colflags[1] >= colflags[0]) && (colflags[1] <= nXBins)) ? colflags[1] : nXBins; + colflags[2] = ((colflags[2] > 0) && (colflags[2] <= nXBins)) ? colflags[2] : 1; + colflags[3] = ((colflags[3] >= colflags[2]) && (colflags[3] <= nXBins)) ? colflags[3] : nXBins; + bool yellowFlagComp = false, redFlagComp = false; + int ytot = 0, ycnt = 0, rtot = 0, rcnt = 0; + + // yellow flag + float epsilon = 1.e-3; + if(doflags[0]) { + for( int j = colflags[0]; j <= colflags[1]; j++ ) { + TString binLabel = histogram->GetXaxis()->GetBinLabel(j); + TH1D *hprojy = histogram->ProjectionY(Form("hpy1yf%02d_%s",j,binLabel.Data()),j,j+1,"egoff"); + if(hprojy) { + float uflow = fabs(hprojy->GetBinContent(0)); + float oflow = fabs(hprojy->GetBinContent(nYBins+1)); + float btotal = hprojy->Integral(); + + // total bins requested for yellow flags + ytot++; + // flag true if overflow/underflow has entries or if histo is empty + // denoting missing component + if(((uflow > epsilon) || (oflow > epsilon)) && (btotal < epsilon)) { + yellowFlagComp = true; + // count bins flagged as yellow + ycnt++; + } // if uflow + delete hprojy; hprojy = 0; + } // if hprojy + } // for + } // if doflags[0] + + // red flag + if(doflags[1]) { + for( int j = colflags[2]; j <= colflags[3]; j++ ) { + TString binLabel = histogram->GetXaxis()->GetBinLabel(j); + TH1D *hprojy = histogram->ProjectionY(Form("hpy1rf%02d_%s",j,binLabel.Data()),j,j+1,"egoff"); + if(hprojy) { + float uflow = fabs(hprojy->GetBinContent(0)); + float oflow = fabs(hprojy->GetBinContent(nYBins+1)); + float btotal = hprojy->Integral(); + rtot++; + // flag true if overflow/underflow has entries or if histo is empty + // denoting missing component + if(((uflow > epsilon) || (oflow > epsilon)) && (btotal < epsilon)) { + redFlagComp = true; + rcnt++; + } // if uflow + delete hprojy; hprojy = 0; + } // if hprojy + } // for + } // if doflags[1] + + // set results (default green, + result->status_ = dqm_core::Result::Green; + if(doflags[0] && yellowFlagComp) { + result->status_ = dqm_core::Result::Yellow; + } + if(doflags[1] && redFlagComp) { + result->status_ = dqm_core::Result::Red; + } + result->tags_["YellowMETComponents"] = ycnt; + result->tags_["RedMETComponents"] = rcnt; + +/////////////////////////////////////////////////////////////////////////////////////////// + + return result; +} + +void +dqm_algorithms::HLTMETComponents::printDescription(std::ostream& out) +{ + + out << "HLT MET Components: Of the 25 components (24 calo samplings and 1 muon component of MET) "; + out << "Check if any sub-detector component is empty. Empty means any of the following:"; + out << " overflow/underflow bins are filled, or integral of histogram is zero. " << std::endl; + out<< "Each component (25 of them) are bins on abscissa and the 1d histograms represent the quantity (SumEt)" << std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/HLTMETStatus.cxx b/DataQuality/dqm_algorithms/src/HLTMETStatus.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4baf6b6b6f2da04c28b616224ccd2332d6f07a0d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/HLTMETStatus.cxx @@ -0,0 +1,181 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* Algorithm: AlgHLTMETStatus does the following + * Checks the [EF/L2]_MET_status histograms (produced for 10 min block / entire run) + * There are 32 status bits and each bin of the above histograms represent a status. + * If the status bits 17 -> 29 (in general binLo -> binHi) are filled, flag = YELLOW + * If the status bits 32 -> 32 (in general binLo -> binHi) are filled, flag = RED + * Expects the following from configuration [<value> corresponds to a bin number] + * METYellowMin = <value> specify the bins you want to compute flags for [1-32] + * METYellowMax = <value> ditto + * METRedMin = <value> ditto + * METRedMax = <value> ditto + * DoYellowFlag = <1 or 0> 0 means don't compute yellow flags + * DoRedFlag = <1 or 0> 0 means don't compute red flags + * + * Author : Venkatesh Kaushik <venkat.kaushik@cern.ch> + * Date : March 2010 + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/HLTMETStatus.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> +#include <cmath> +#include <math.h> + +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::HLTMETStatus myInstance; + +dqm_algorithms::HLTMETStatus::HLTMETStatus() + +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("AlgHLTMETStatus", this); +} + +dqm_algorithms::HLTMETStatus * +dqm_algorithms::HLTMETStatus::clone() +{ + + return new HLTMETStatus(); +} + + +dqm_core::Result * +dqm_algorithms::HLTMETStatus::execute(const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + /////////////////////////////////////////////////////////////////////////////////////////// + // Get Green and Red Thresholds + double grThr = 0.05, reThr = 0.1; // Green and Red thresholds + try { + grThr = dqm_algorithms::tools::GetFromMap("Threshold",config.getGreenThresholds() ); + reThr = dqm_algorithms::tools::GetFromMap("Threshold",config.getRedThresholds() ); + } catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig(ERS_HERE,name,"Paramter: 'Threshold' is mandatory, cannot continue"); + } + + //non sense case: compare fraction and threshold >100% + if ((grThr>1.0 || reThr>1.0) ) { + throw dqm_core::BadConfig(ERS_HERE,name_,"Configuration Error: Threshold should be between [0.0, 1.0] 10% => 0.1"); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Get Parameters + size_t ntotBins = (size_t) histogram -> GetNbinsX(); + + // read thresholds + size_t colflags[4]; + colflags[0] = static_cast<size_t>(dqm_algorithms::tools::GetFirstFromMap("METYellowMin", config.getParameters(), 1)); + colflags[1] = static_cast<size_t>(dqm_algorithms::tools::GetFirstFromMap("METYellowMax", config.getParameters(), ntotBins)); + colflags[2] = static_cast<size_t>(dqm_algorithms::tools::GetFirstFromMap("METRedMin", config.getParameters(), 1)); + colflags[3] = static_cast<size_t>(dqm_algorithms::tools::GetFirstFromMap("METRedMax", config.getParameters(), ntotBins)); + // read options + bool doflags[2]; + doflags[0] = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("DoYellowFlag", config.getParameters(), 1)); + doflags[1] = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("DoRedFlag", config.getParameters(), 1)); + + dqm_core::Result* result = new dqm_core::Result(); + colflags[0] = ((colflags[0] > 0) && (colflags[0] <= ntotBins)) ? colflags[0] : 1; + colflags[1] = ((colflags[1] >= colflags[0]) && (colflags[1] <= ntotBins)) ? colflags[1] : ntotBins; + colflags[2] = ((colflags[2] > 0) && (colflags[2] <= ntotBins)) ? colflags[2] : 1; + colflags[3] = ((colflags[3] >= colflags[2]) && (colflags[3] <= ntotBins)) ? colflags[3] : ntotBins; + bool yellowLo2HiEmpty = true, redLo2HiEmpty = true; + int ytot = 0, ycnt = 0, rtot = 0, rcnt = 0; + + // we fill 1(error) or 0(no-error) for each bin for every event + // therefore we have to divide #of entries by #of bins + // to get the #of events + double nentries = histogram -> GetEntries(); + double nevtstot = 1.; // no. of events + if(!std::isnan(nentries/ntotBins) || !std::isinf(nentries / ntotBins)) nevtstot = nentries/ntotBins; + + // yellow flag + double theYFracMax = -9., theRFracMax = -9.; + if(doflags[0]) { + for( size_t j = colflags[0]; j <= colflags[1]; j++ ) { + // if at least one of the bins > 0 : flag = YELLOW + ytot ++; + double thebinc = histogram -> GetBinContent(j); + // fraction of events having this error-bit set + double thefrac = thebinc / nevtstot; + + // "Worst-case flag not to exceed YELLOW" flag: + // if threshold exceeds green threshold, set yellow + // if threshold exceeds red threshold, still set yellow + // reThr > grThr + if(thefrac > grThr) { + if(theYFracMax < thefrac) theYFracMax = thefrac; + yellowLo2HiEmpty = false; + ycnt ++; + } + } + } + + // red flag + if(doflags[1]) { + for( size_t j = colflags[2]; j <= colflags[3]; j++ ) { + // if at least one of the bins > 0 : flag = RED + rtot ++; + double thebinc = histogram -> GetBinContent(j); + // fraction of events having this error-bit set + double thefrac = thebinc / nevtstot; + if(thefrac > reThr) { + if(theRFracMax < thefrac) theRFracMax = thefrac; + redLo2HiEmpty = false; + rcnt++; + } + } + } + + // set results + result->status_ = dqm_core::Result::Green; + + if(doflags[0] && !yellowLo2HiEmpty) { + result->status_ = dqm_core::Result::Yellow; + } + + if(doflags[1] && !redLo2HiEmpty) { + result->status_ = dqm_core::Result::Red; + } + + result->tags_["NumOfStatusBitsYellow"] = ycnt; + result->tags_["EventFractionYellow"] = theYFracMax; + result->tags_["NumOfStatusBitsRed"] = rcnt; + result->tags_["EventFractionRed"] = theRFracMax; + +/////////////////////////////////////////////////////////////////////////////////////////// + + return result; +} + +void +dqm_algorithms::HLTMETStatus::printDescription(std::ostream& out) +{ + + out<<"HLT MET Status: Of the 32 status bits, check if any subset of bits are set. If so, flag YELLOW" << std::endl; + out<<"Bit #32 is global error bit, if set flag RED." << std::endl; + + out<<"Mandatory parameter: XBin: The label of the X bin that you would like to check\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/IterativeGaussianFit.cxx b/DataQuality/dqm_algorithms/src/IterativeGaussianFit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..43b6c03c8acc6732ba6d5166b391de7308d48f81 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/IterativeGaussianFit.cxx @@ -0,0 +1,162 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_algorithms/IterativeGaussianFit.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +#include "TClass.h" +#include "TObject.h" +#include "TH1.h" +#include "TF1.h" + +#include <memory> +#include <iostream> +#include <cmath> + +namespace { // anonymous +dqm_algorithms::IterativeGaussianFit instance("IterativeGaussianFit"); // global instance to have this algorithm registered with the manager +} + +dqm_algorithms::IterativeGaussianFit::IterativeGaussianFit(const std::string &name): m_name(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(m_name, this); +} + +dqm_algorithms::IterativeGaussianFit::~IterativeGaussianFit() +{ + /* noop */ +} + +dqm_algorithms::IterativeGaussianFit *dqm_algorithms::IterativeGaussianFit::clone() +{ + return new IterativeGaussianFit(m_name); // somebody else must delete this +} + +dqm_core::Result *dqm_algorithms::IterativeGaussianFit::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + if (!object.IsA()->InheritsFrom("TH1")) { // this could also be TH2 or TH3 + throw dqm_core::BadConfig(ERS_HERE, name, "histogram does not inherit from TH1"); + } + const TH1 &histogram = dynamic_cast<const TH1 &>(object); // should be possible after the previous check (otherwise we'd get a std::bad_cast) + if (histogram.GetDimension() > 1) { // sorry, we only do one-dimensional fits here + throw dqm_core::BadConfig(ERS_HERE, name, "histogram has more than one dimension"); + } + const int minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 1000); + if (histogram.GetEffectiveEntries() < minstat) { // you'd better have at least some entries, or the fit may yield strange results + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram.GetEffectiveEntries(); + return result; + } + const double sigmaRange = dqm_algorithms::tools::GetFirstFromMap("SigmaRange", config.getParameters()); // mandatory parameter + if (sigmaRange <= 0) { + throw dqm_core::BadConfig(ERS_HERE, name, "SigmaRange must be greater than zero."); + } + if (sigmaRange < 1) { + ERS_DEBUG(1, "Careful, your SigmaRange = " << sigmaRange << " is rather small"); // or should we just throw an exception? + } + const double meanNominal = dqm_algorithms::tools::GetFirstFromMap("MeanNominal", config.getParameters(), 0); // optional parameter + const double sigmaMax = dqm_algorithms::tools::GetFirstFromMap("SigmaMax", config.getParameters(), 0); // optional parameter + if (sigmaMax < 0) { + throw dqm_core::BadConfig(ERS_HERE, name, "SigmaMax must be greater than zero."); // zero means unlimited + } + + std::auto_ptr<TH1> h(static_cast<TH1 *>(histogram.Clone())); // we need a non-const copy of the object passed to this function + // under normal conditions we would have used the copy constructor here, but the one provided by ROOT gives nothing but a segmentation fault + std::auto_ptr<TF1> f(new TF1("f", "gaus")); // we use auto_ptrs to avoid cleaning up manually, because this function has some emergency exits + if (sigmaMax) { + f->SetParLimits(2, 0, sigmaMax); // limit the possible range of sigma to avoid meaningless fit results + f->SetParameter(2, sigmaMax / 2); // set some arbitrary initial value that falls into the allowed range, otherwise Minuit will complain + f->SetRange(meanNominal - sigmaMax, meanNominal + sigmaMax); // very first guess, let's hope that this is not completely off + } + + const unsigned int maxIterations = 10; // don't do more than this number of iterations, otherwise terminate abnormally + const double sufficientPrecision = 0.01; // terminate the iteration as soon as the relative change of sigma is less than this + + unsigned int i = 0; // iteration counter + while (true) { // don't worry, there's a break down there + const double sigmaOld = (i == 0) ? 0 : f->GetParameter(2); // compare old and new sigma to terminate the iteration + std::string fitOptions("INQ"); // integrate over each bin, do not draw the function, do not print messages + if (i > 0 || sigmaMax) fitOptions.append("R"); // do the initial fit without a range restriction, but only if sigma is not limited + if (sigmaMax) fitOptions.append("B"); // if a limit for sigma was set, then use it (but always setting this would not work) + + const int fitStatus = h->Fit(f.get(), fitOptions.c_str()); // you hardly notice you've got an auto_ptr, except in cases like this + if (fitStatus) { // see the documentation of TH1::Fit about the meaning of this status flag ... it should be zero if the fit went well + ERS_DEBUG(1, "Fit failed in iteration " << i << ", status = " << fitStatus); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Red); + if (fitStatus < 0) result->status_ = dqm_core::Result::Undefined; // this usually happens because of an empty histogram (normally already caught by MinStat) + result->tags_["Iteration"] = i; + result->tags_["FitStatus"] = fitStatus; + return result; + } + + const double mean = f->GetParameter(1); + const double sigma = f->GetParameter(2); + ERS_DEBUG(2, "Iteration " << i << ": mean = " << mean << ", sigma = " << sigma); + f->SetRange(mean - sigmaRange * sigma, mean + sigmaRange * sigma); // this is the important feature! + + if (sigma == 0) { // maybe this is not really fatal, but at least it shows that something strange is going on + ERS_DEBUG(1, "Fit yielded sigma = 0 in iteration " << i); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Red); + result->tags_["Iteration"] = i; + result->tags_["Mean"] = mean; + result->tags_["Sigma"] = sigma; + return result; + } // at least we're now sure that we can safely divide by sigma + + if (sigma == sigmaMax) { // we've hit the parameter limit, so the fit cannot yield sensible results + ERS_DEBUG(1, "Fit result for sigma is at the limit " << sigmaMax); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Red); + result->tags_["Iteration"] = i; + result->tags_["Sigma"] = sigma; + result->tags_["SigmaMax"] = sigmaMax; + return result; + } + + if ((std::fabs(sigma - sigmaOld) / sigma) < sufficientPrecision) break; // this is good enough for us + + if (i >= maxIterations) { // stop here, but we should have reached the break (above) much earlier + ERS_DEBUG(1, "Sorry, this is not taking us anywhere: the iteration does not seem to converge"); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); // may sometimes happen by chance, especially if the distribution is rather narrow + result->tags_["Iteration"] = i; + result->tags_["SigmaOld"] = sigmaOld; + result->tags_["SigmaNew"] = sigma; + return result; + } + ++i; // next iteration + } // while + + const int ndf = f->GetNDF(); + const double chi2 = f->GetChisquare(); + const double chi2NDF = (ndf > 0) ? (chi2 / ndf) : 0; // prevent fits with no degrees of freedom from returning NaN or INF. + + std::map<std::string, double> resultValues; // all elements in this map will be published, and they can also be used as thresholds + resultValues["Constant"] = f->GetParameter(0); // hm, does the constant tell us anything? + resultValues["ConstantError"] = f->GetParError(0); // and does anybody care about the errors of the fit parameters? + resultValues["Mean"] = f->GetParameter(1); + resultValues["MeanError"] = f->GetParError(1); + resultValues["Sigma"] = f->GetParameter(2); + resultValues["SigmaError"] = f->GetParError(2); + resultValues["Chi2NDF"] = chi2NDF; // for the sake of completeness + resultValues["Probability"] = f->GetProb(); // maybe somebody wants to set a threshold on this? + resultValues["MeanDeviation"] = std::fabs(f->GetParameter(1) - meanNominal); // useful to detect shifts from the expected value + return dqm_algorithms::tools::MakeComparisons(resultValues, config.getGreenThresholds(), config.getRedThresholds()); // this function does all the magic +} + +void dqm_algorithms::IterativeGaussianFit::printDescription(std::ostream& out) +{ + out << m_name << ": Applies a Gaussian fit over a limited fit range.\n" + " The fit range is iteratively determined in terms of Gaussian sigmas on each side of the mean.\n" + " The algorithm stops if sigma doesn't change anymore, or after a maximum number of iterations.\n" + "Mandatory parameter: SigmaRange - over plus/minus how many sigmas the fit should be applied.\n" + "Optional parameter: MeanNominal - the expected mean value, used for calculating MeanDeviation (default 0)\n" + "Optional parameter: SigmaMax - limit the maximum possible fit result for sigma (default unlimited)\n" + "Optional parameter: MinStat - minimum number of entries required in the histogram (default 1000).\n" + "Returned values: Constant, Mean, and Sigma of the fitted Gaussian including their errors, Chi2NDF and Probability.\n" + " MeanDeviation - the absolute difference of Mean and MeanNominal, useful for detecting shifts.\n" + "Thresholds can be set on any of the returned values, or a combination thereof." << std::endl; + // xmin/xmax parameters wouldn't make sense, because it's a feature of this algorithm to determine these values itself +} diff --git a/DataQuality/dqm_algorithms/src/JarqueBeraTest.cxx b/DataQuality/dqm_algorithms/src/JarqueBeraTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..46780c8ea7fb457234f779491ac71a60f2149310 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/JarqueBeraTest.cxx @@ -0,0 +1,124 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file JarqueBeraTest.cxx calculates JB and compares either the value or the probability; returns dqm_core::Result + * \author andrea.dotti@cern.ch + */ + +#include <dqm_core/AlgorithmManager.h> +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/JarqueBeraTest.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TClass.h> +#include <TMath.h> + +static dqm_algorithms::JarqueBeraTest jb("JB"); +static dqm_algorithms::JarqueBeraTest jb_prob("Prob"); + +dqm_algorithms::JarqueBeraTest::JarqueBeraTest( const std::string & name ) : name_(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("JarqueBeraTest_"+ name, this ); +} + + +dqm_algorithms::JarqueBeraTest* +dqm_algorithms::JarqueBeraTest::clone() +{ + return new JarqueBeraTest(name_); +} + +dqm_core::Result * +dqm_algorithms::JarqueBeraTest::execute( const std::string & name , + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + const TH1 * histogram; + if(object.IsA()->InheritsFrom( "TH1" )) { + histogram = static_cast<const TH1*>( &object ); + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + ERS_DEBUG(2,"Minimum statistics required:"<<minstat); + if (histogram->GetEffectiveEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + return result; + } + double gthresho,rthresho; + std::string thresholdname="JB"; + if ( name_ == "Prob") thresholdname = "P"; + try { + gthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( thresholdname, config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + ERS_DEBUG(2,"Green Threshold: "<<gthresho<<" Red: "<<rthresho); + + // N.B. Root's return the excess kurtosis, i.e. gamma_2-3 + // The excess kurtosis is defined scuh as K(N(0,1))=0 + double k = histogram->GetKurtosis(); + double s = histogram->GetSkewness(); + double n = histogram->GetEffectiveEntries(); + double jb = n/6*( s*s + (k*k)/4 ); //Calculate Jarque Bera + //The statistic JB has an asymptotic chi-square distribution with two degrees of freedom + // and can be used to test the null hypothesis that the data are from a normal distribution. + double prob = TMath::Prob( jb , 2 ); + ERS_DEBUG(2," K="<<k<<" S="<<s<<" n="<<n<<" jb="<<jb<<" prob="<<prob); + + //Check against thresholds + double testValue; + if ( name_ == "Prob" ) testValue = prob; //Use probability + else testValue = jb; // Use the JB value for comparison + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["JB"] = jb; + result->tags_["Prob"]=prob; + if ( TMath::IsNaN( testValue ) ) //This may happen if RMS==0 Kurtosis and Skewness are inf + { + result->status_=dqm_core::Result::Undefined; + return result; + } + if ( name_=="Prob" ) + { + if ( testValue >= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( testValue > rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } + else + { + if ( testValue <= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( testValue < rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } + return result; +} + +void +dqm_algorithms::JarqueBeraTest::printDescription(std::ostream& out) +{ + out<<"JarqueBeraTest"+name_+" gives back the "; + if ( name_ == "Prob") out<<" probability that the input histogram follows the normal distribution\n"<<std::endl; + else out<<" Jarque-Bera value of the input histogram\n"<<std::endl; + out<<"Mandatory Green/Red Threshold: "; + if ( name_ == "Prob") out<<" P : Probability"; + else out<<" JB : Jarque-Bera value"; + out<<" to give Green/Red result.\n"<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/KillBinsByStrip.cxx b/DataQuality/dqm_algorithms/src/KillBinsByStrip.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0ae9043c71acf1ddee9b32d6a2ea124dad5a5db6 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/KillBinsByStrip.cxx @@ -0,0 +1,231 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* KillBinsByStrip.cxx + Selects out outlier bins from a 2D histogram, by strip, by gradually re-calculating the strip average without those bins. + Assumes that y-axis (phi coordinates) is symmetric from detector design. + Author: Olivier Simard (CEA-Saclay) + Email: Olivier.Simard@cern.ch +*/ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/KillBinsByStrip.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <TH1.h> +#include <TH2.h> +#include <TH1D.h> +#include <TClass.h> + +using namespace std; + +bool mySortfunc(bin2 i,bin2 j){return (i.m_value > j.m_value);} +bool mySortfunc_ratio(bin2 i, bin2 j){return (i.m_deviation> j.m_deviation);} +static dqm_algorithms::KillBinsByStrip myInstance; + +//_________________________________________________________________________________________ +dqm_algorithms::KillBinsByStrip::KillBinsByStrip(){ dqm_core::AlgorithmManager::instance().registerAlgorithm("KillBinsByStrip", this); } +dqm_algorithms::KillBinsByStrip::~KillBinsByStrip(){ } +dqm_algorithms::KillBinsByStrip* dqm_algorithms::KillBinsByStrip::clone(){ return new KillBinsByStrip(); } + +//_________________________________________________________________________________________ +dqm_core::Result* dqm_algorithms::KillBinsByStrip::execute(const std::string& name,const TObject& object,const dqm_core::AlgorithmConfig& config) +{ + // Runs KillBinsByStrip algorithm on the 2D-histogram provided in 'object'. + + TH2* histogram = NULL; + if( object.IsA()->InheritsFrom("TH2") ){ + histogram = (TH2*)&object; + if(histogram->GetDimension() != 2 ){ throw dqm_core::BadConfig( ERS_HERE, name, "Not a 2D-histogram" ); } + } else { throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1/TH2" ); } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + //const double ignoreval = dqm_algorithms::tools::GetFirstFromMap( "ignoreval", config.getParameters(), -99999); + const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 1); + const int Nmaxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + const bool VisualMode = (bool) dqm_algorithms::tools::GetFirstFromMap( "VisualMode", config.getParameters(), 0); + const int NpublishRed = (int) dqm_algorithms::tools::GetFirstFromMap( "PublishRedBins",config.getParameters(), 0); + + if (histogram->GetEntries() < minstat) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double gthreshold = 0., rthreshold = 0.; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "MaxDeviation", config.getGreenThresholds() ); + } catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + // get bin limits + std::vector<int> range = dqm_algorithms::tools::GetBinRange(histogram,config.getParameters()); + dqm_core::Result* result = new dqm_core::Result(); + vector<bin2> redbins; + vector<bin2> yellowbins; + vector<bin2> Allbins; + + // objects needed before loop + TH1D* projected_strip = NULL; + char hname[56]; + int ix,iy; + int binphi,biny,binz; + int nmax = 0, nbins = 0; + double binval = 0., maxval = 0.; + //double average = 0. + double stripavg = 0.,striperr = 0.,striperr2 = 0.,testval = 0.; + + // Some parameters set by hand: move to jobOption + int m_PoissonLimit = 5; + + + // loop over all strips (eta or x-axis) + for(ix = range[0]; ix <= range[1]; ++ix){ + + double eta = histogram->GetXaxis()->GetBinCenter(ix); + + // make up some name for the 1D-projection so that ROOT::TName does not complain + sprintf(hname,"%s_py_bin%d",histogram->GetName(),ix); + projected_strip = histogram->ProjectionY(hname,ix,ix); // single strip projection + nmax = 0; + nbins = 0; + + + // then within each strip remove bins until the deviation stabilizes. + // note that because the maximum can be anywhere in the strip, one cannot + // loop systematically over all bins. we rather search for the maximum and test it directly. + // Here "TH1::GetMaximumBin()" is used but one can replace it by anything that + // would be more efficient or faster. + while(true){ + + striperr = 0.; + striperr2 = 0.; + + // number of bins with data in the strip (does not include previous maxima, if nmax>0) + if(nmax==0) for(iy=1;iy<=projected_strip->GetXaxis()->GetNbins();iy++) if(projected_strip->GetBinContent(iy)>0) nbins += 1; + + // identify current maximum in the strip + projected_strip->GetMaximumBin(binphi,biny,binz); // projected x-axis means the bin in phi (y-axis) + maxval = projected_strip->GetBinContent(binphi); + binval = maxval; + + // get out of this loop if the strip is empty or when we have emptied the strip + if(nbins<=0) break; + + // arithmetic mean for this strip + stripavg = projected_strip->Integral()/(double)nbins; + + // error on the mean: we might have to consider switching to Poisson if the number of remaining bins is low + if(nbins<=m_PoissonLimit){ + + // Poisson error calculated from mean + striperr = sqrt(stripavg); + + } else { + + // calculate sigma^2 + for(iy=1;iy<=projected_strip->GetXaxis()->GetNbins();iy++) if(projected_strip->GetBinContent(iy)>0) striperr2 += pow((projected_strip->GetBinContent(iy)-stripavg),2); + // calculate error on the mean + striperr = sqrt(striperr2)/sqrt((double)nbins); + + } + + // calculate deviation from stripavg + if(striperr>0.) testval = fabs(maxval-stripavg)/striperr; + else testval = 0.; + + // decision + bool die = false; + double phi = projected_strip->GetXaxis()->GetBinCenter(binphi); + bin2 onebin = {eta,phi,ix,binphi,binval,testval}; + if(testval > rthreshold) redbins.push_back(onebin); + else if(testval > gthreshold) yellowbins.push_back(onebin); + else { // no problem, write that bin but then exits + Allbins.push_back(onebin); + die = true; + } + + // if the while-loop is not broken, keep looking for secondary maxima after + // removing the maximum that was just found. + // if there are any other reason to stop testing one should implement it here + if(die) break; + + // apply KillBin method - remove the content of latest offending-bin + projected_strip->SetBinContent(binphi,0); // kill bin + nmax += 1; // register one more maximum in the strip + nbins -= 1; // remove one count from strip + + } // while + + delete projected_strip; + + } // for(ix) + + + // The following is more or less the same. + std::sort(redbins.begin(),redbins.end(),mySortfunc); + std::sort(yellowbins.begin(),yellowbins.end(),mySortfunc); + std::sort(Allbins.begin(),Allbins.end(),mySortfunc_ratio); + char tmpstr[500]; + int count_red=0,count_yellow=0; + + // publish red bins + for(unsigned int i=0;i<redbins.size();i++){ + if(VisualMode) continue; + if(publish){ + sprintf(tmpstr,"R%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%0.2e]",count_red,redbins[i].m_eta,redbins[i].m_phi,redbins[i].m_deviation); + std::string tag = tmpstr; + result->tags_[tag] = redbins[i].m_value; + } + count_red++; + if(NpublishRed > 0){ + if(count_red > NpublishRed) break; + } + } + + // publish yellow bins + for(unsigned int i=0;i<yellowbins.size();i++){ + if(VisualMode) continue; + if(publish && (count_red+count_yellow) < Nmaxpublish ){ + sprintf(tmpstr,"Y%i-(eta,phi)[OSRatio]=(%0.3f,%0.3f)[%.2e]",count_yellow,yellowbins[i].m_eta,yellowbins[i].m_phi,yellowbins[i].m_deviation); + std::string tag = tmpstr; + result->tags_[tag] = yellowbins[i].m_value; + } + count_yellow++; + } + result->tags_["NRedBins"] = count_red; // count_red is the number of red bins printed + result->tags_["NYellowBins"] = count_yellow; // count_yellow is the number of yellow bins printed + + if(count_red+count_yellow==0 && Allbins.size()>0){ + for(unsigned int i=0;i<Allbins.size();i++){ + sprintf(tmpstr,"LeadingBin%i-(eta,phi)=(%0.3f,%0.3f)",i,Allbins[i].m_eta,Allbins[i].m_phi); + std::string tagtag = tmpstr; + result->tags_[tagtag] = Allbins[i].m_value; + } + } + + if(count_red>0) result->status_ = dqm_core::Result::Red; + else if(count_yellow>0) result->status_ = dqm_core::Result::Yellow; + else result->status_ = dqm_core::Result::Green; + + return result; +} + +//_________________________________________________________________________________________ +void dqm_algorithms::KillBinsByStrip::printDescription(std::ostream& out) +{ + out<<"KillBinsByStrip: Selects out outlier bins from a 2D histogram, by strip, by gradually re-calculating the strip average without those bins."<<std::endl; + out<<" Assumes that y-axis (phi coordinates) is symmetric from detector design."<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: ignoreval: valued to be ignored for being processed"<<std::endl; + out<<"Optional Parameter: PublishBins: Save bins which are different from average in Result (on:1,off:0,default is 1)"<<std::endl; + out<<"Optional Parameter: MaxPublish: Max number of bins to save (default 20)"<<std::endl; + out<<"Optional Parameter: VisualMode: is to make the evaluation process similar to the shift work, so one will get resonable result efficiently."<<std::endl; + return; +} + diff --git a/DataQuality/dqm_algorithms/src/KolmogorovTest.cxx b/DataQuality/dqm_algorithms/src/KolmogorovTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6477ff9612cb502eae557f92da43e7c1d5e3f726 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/KolmogorovTest.cxx @@ -0,0 +1,174 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KolmogorovTest.cxx does KolmogorovTest with different options like Norm and/or MaxDist ; returns dqm_core::Result + * \author Haleh Hadavand + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/KolmogorovTest.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +using namespace std; + + +#include <dqm_core/AlgorithmManager.h> + +static dqm_algorithms::KolmogorovTest kolmo_Prob( "Prob" ); +static dqm_algorithms::KolmogorovTest kolmo_MaxDist( "MaxDist" ); +static dqm_algorithms::KolmogorovTest kolmo_Norm( "Norm" ); +static dqm_algorithms::KolmogorovTest kolmo_NormMaxDist( "MaxDistPlusNorm" ); + + +dqm_algorithms::KolmogorovTest::KolmogorovTest( const std::string & name ) + : name_ ( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( "KolmogorovTest_"+ name, this ); +} + +dqm_algorithms::KolmogorovTest * +dqm_algorithms::KolmogorovTest::clone() +{ + return new KolmogorovTest( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::KolmogorovTest::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + const TH1 * histogram; + const TH1 * refhist; + double gthresho; + double rthresho; + + if(object.IsA()->InheritsFrom( "TH1" )) { + histogram = static_cast<const TH1*>( &object ); + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + try { + refhist = dynamic_cast<const TH1*>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + if (!refhist) { + throw dqm_core::BadRefHist(ERS_HERE, name, "Reference is not a histogram"); + } + + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Dimension" ); + } + + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, name, "number of bins" ); + } + + if (histogram->GetDimension()==2 && (name_=="MaxDist" || name_=="MaxDistPlustNorm")){ + throw dqm_core::BadConfig( ERS_HERE, name, "MaxDist option cannot be used on 2D histograms" ); + } + + + std::string option; + std::string thresh; + if (name_ == "Prob") { + option=""; + thresh="P"; + }else if (name_ == "MaxDist") { + option="M"; + thresh="MaxDist"; + }else if (name_ == "Norm") { + option="N"; + thresh="P"; + }else if (name_ == "MaxDistPlusNorm") { + option="NM"; + thresh="MaxDist"; + }else { + throw dqm_core::BadConfig( ERS_HERE, "None", name_ ); + } + + try { + gthresho = dqm_algorithms::tools::GetFromMap( thresh, config.getGreenThresholds() ); + rthresho = dqm_algorithms::tools::GetFromMap( thresh, config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + double value = histogram->KolmogorovTest( refhist, option.c_str()); + + ERS_DEBUG(1, "Kolmogorov Test with Option " << name_ << " is " << value ); + ERS_DEBUG(1, "Green threshold: "<< gthresho << "; Red threshold: " << rthresho ); + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_[name_] = value; + if (thresh =="P"){ + if ( value >= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value > rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + }else { + if ( value <= gthresho ) { + result->status_ = dqm_core::Result::Green; + } else if ( value < rthresho ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + } + + return result; +} +void +dqm_algorithms::KolmogorovTest::printDescription(std::ostream& out) +{ + std::string thresh; + if (name_ == "Prob") { + option=""; + thresh="P"; + }else if (name_ == "MaxDist") { + option="M"; + thresh="MaxDist"; + }else if (name_ == "Norm") { + option="N"; + thresh="P"; + }else if (name_ == "MaxDistPlusNorm") { + option="NM"; + thresh="MaxDist"; + } + + if (name_ == "Norm" || name_ == "Prob") { + out<<"KolmogorovTest_"+ name_+": Give back probability after performing KolmogorovTest on histogram against referece histogram with "+option+" option\n"<<std::endl; + } else { + out<<"KolmogorovTest_"+ name_+": Give back MaxDist(for 1D histograms only) after performing KolmogorovTest on histogram against referece histogram with "+option+" option\n"<<std::endl; + } + out<<"Mandatory Green/Red Threshold: "+thresh+" : Probability to give Green/Red result\n"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/KurtosisTest.cxx b/DataQuality/dqm_algorithms/src/KurtosisTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7bab109305798c5a3cea685734b1ba21d4c0ac5d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/KurtosisTest.cxx @@ -0,0 +1,119 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file KurtosisTest.cxx checks excess kurtosis wrt to a threshold value and returns dqm_core::Result + * \author andrea.dotti@cern.ch + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/KurtosisTest.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> +#include <TMath.h> + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::KurtosisTest kurtosis_GreaterThan( "GreaterThan" ); + dqm_algorithms::KurtosisTest kurtosis_LessThan( "LessThan" ); + dqm_algorithms::KurtosisTest kurtosis_GreaterThanAbs( "GreaterThanAbs" );// Ok, for Kurtosis this is not so much sense (K<0 and K>0 indicate really different things), but just for completeness + dqm_algorithms::KurtosisTest kurtosis_LessThanAbs( "LessThanAbs" ); // Kurtosis( normal(0,1) ) =0 +} + +//NB. Following ROOT definition This is the excess kurtosis, i.e. fourth standarized momentum -3. K(N(0,1))=0 +dqm_algorithms::KurtosisTest::KurtosisTest( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("KurtosisTest_"+name,this); +} + +dqm_algorithms::KurtosisTest * +dqm_algorithms::KurtosisTest::clone() +{ + return new KurtosisTest( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::KurtosisTest::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEffectiveEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + return result; + } + + double gthreshold; + double rthreshold; + + int axis = (int) dqm_algorithms::tools::GetFirstFromMap( "Axis", config.getParameters(), 1); + + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "K", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "K", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + ERS_DEBUG(1,"Axis for kurtosis calculation:"<<axis); + + Double_t kurtosis = histogram->GetKurtosis( axis ); + Double_t kurtosis_e = histogram->GetKurtosis( axis + 10 ); + + dqm_core::Result* result = new dqm_core::Result(); + ERS_DEBUG(1,"Kurtosis = "<<kurtosis<<" +- "<<kurtosis_e) + result->tags_["Kurtosis"] = kurtosis; + result->tags_["ApproxStandardError"]=kurtosis_e; + + if ( CompareKurtosisTest( name_ , kurtosis ,gthreshold) ) { + result->status_ = dqm_core::Result::Green; + } else if ( CompareKurtosisTest( name_, kurtosis, rthreshold) ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + + return result; + +} + +bool +dqm_algorithms::KurtosisTest::CompareKurtosisTest(const std::string & type, double value, double threshold) { + + if (type == "GreaterThan") return (value > threshold); + if (type == "LessThan") return (value < threshold); + if (type == "GreaterThanAbs") return ( TMath::Abs(value) > threshold ); + if (type == "LessThanAbs") return ( TMath::Abs(value) < threshold); + return 0; +} + + +void +dqm_algorithms::KurtosisTest::printDescription(std::ostream& out) +{ + out<<"KurtosisTest_"+name_+" : Checks if the Excess Kurtosis of the distribution is "+name_+" threshold value\n"<<std::endl; + + out<<"Mandatory Green/Red Threshold: K: Value of Kurtosis"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: Axis: Axis along which compute Kurtosis: 1=X, 2=Y, 3=Z"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/L1Calo_OutlierAndFlatnessTest.cxx b/DataQuality/dqm_algorithms/src/L1Calo_OutlierAndFlatnessTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c4985fa473e1d747fa1a904dad188103a79094ff --- /dev/null +++ b/DataQuality/dqm_algorithms/src/L1Calo_OutlierAndFlatnessTest.cxx @@ -0,0 +1,235 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file L1Calo_OutlierAndFlatnessTest.cxx checks and removes outliers from TH1-Histos and tests the remaining distribution for flatness. Returns dqm_core::Result + * \author Steffen Schaepe, simplified for L1Calo purposes by Sarah Heim + */ + +#include <dqm_algorithms/L1Calo_OutlierAndFlatnessTest.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> + +#include <dqm_core/AlgorithmManager.h> +#include "dqm_core/exceptions.h" +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_core/Result.h> + +#include <TMath.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> + +namespace +{ + dqm_algorithms::L1Calo_OutlierAndFlatnessTest L1Calo_OutlierAndFlatnessTest( "L1Calo_OutlierAndFlatnessTest" ); +} + + +dqm_algorithms::L1Calo_OutlierAndFlatnessTest::L1Calo_OutlierAndFlatnessTest( const std::string & name ) : name_( name ) { + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); + counterSkip = 0; +} + +dqm_algorithms::L1Calo_OutlierAndFlatnessTest * dqm_algorithms::L1Calo_OutlierAndFlatnessTest::clone(){ + return new L1Calo_OutlierAndFlatnessTest( name_ ); +} + +dqm_core::Result *dqm_algorithms::L1Calo_OutlierAndFlatnessTest::execute( const std::string& name, const TObject& object, + const dqm_core::AlgorithmConfig& config) { + +// if(counterSkip < counterSkipMax){ +// dqm_core::Result* result = new dqm_core::Result(); +// result->status_ = dqm_core::Result::Green; +// counterSkip++; +// return result; +// } + +// counterSkip = 0; + + TH1 const * histogram; + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = static_cast<TH1 const *>(&object); + + if (histogram->GetDimension() > 2 ) { + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = tools::GetFirstFromMap( "MinStat", config.getParameters(), 1); + + //Check for minimum statistics + if (histogram->GetEntries() < minstat ) { + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Green; + result->tags_["Not enough Signal Statistics"] = minstat; + //delete histogram; + return result; + } + + //check if histogram contains only zeros + int checkZeroContent = (int) tools::GetFirstFromMap( "CheckZeroContent", config.getParameters(), 1 ); + + if ((checkZeroContent > 0) && (histogram->Integral() == 0) && (histogram->GetEntries() > 0)) { + ERS_DEBUG(1, "Histogram " <<histogram->GetName()<<" is filled with zeroes!"); + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Red; + result->tags_["Integral"] = histogram->Integral(); + //delete histogram; + return result; + } + + + int checkSigmaDev = 1; + int dontCountSigmaOutliers = 0; + int ignore0 = 1; + double sigmaDev = 0; + double absDev = 0; + + //Get configuration parameters and set defaults + try { + ignore0 = (int) tools::GetFirstFromMap( "Ignore0", config.getParameters(), 1 ); + + checkSigmaDev = (int) tools::GetFirstFromMap( "CheckSigmaDev", config.getParameters(), 1 ); + + absDev = tools::GetFirstFromMap( "AbsDev", config.getParameters(), 15.0 ); + + if (checkSigmaDev) { + sigmaDev = tools::GetFirstFromMap( "SigmaDev", config.getParameters()); + dontCountSigmaOutliers = (int) tools::GetFirstFromMap( "DontCountSigmaOutliers", config.getParameters(), 0); + } + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + const std::vector<int> range = dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + const int xminBin = range[0]; + const int xmaxBin = range[1]; + + //compute the number of empty bins (or bins=0) + int zeroBins = 0; + for (int i = xminBin; i <= xmaxBin; i++) { + if (histogram->GetBinContent(i) == 0) zeroBins++; + } + + //Compute outlier bins by using a simplified Grubb's test without cutting on a t-distribution but by giving an external threshold defining how many standard deviations a value has to differ from the mean to be classified as an outlier or by giving an absolute threshold for classifying values as outliers + int totalBadBins = 0; + int totalUncountedBadBins = 0; + double mean=0; + double stdev=0; + + //compute the arithmetic mean + double sum=0,sum2=0; + int counter = 0; + + for(int i=xminBin;i <= xmaxBin;i++){ + if( histogram->GetBinContent(i) != 0 || ignore0 == false) { + sum += histogram->GetBinContent(i); + sum2 += histogram->GetBinContent(i)*histogram->GetBinContent(i); + counter++; + } + } + + mean = counter > 0 ? sum/(double)counter : 0; + stdev = counter > 0 ? sqrt( (1/(double)counter)*sum2 - mean*mean) : 0; + + + //check how many bins are out of N sigma range (SigmaDev) or out of the absolute dev (AbsDev) or over absolute limit (AbsLimit), count them as (uncounted) outliers + double dev; + double absdev_test = 0; + if (checkSigmaDev) { + for (int i = xminBin; i <= xmaxBin; i++) { + if ((histogram->GetBinContent(i) != 0) || (ignore0 == 0)) { + dev=fabs(histogram->GetBinContent(i) - mean)/stdev; + absdev_test=fabs(histogram->GetBinContent(i) - mean); + if ((dev > sigmaDev) && (absdev_test > absDev)) { + if (dontCountSigmaOutliers){ + totalUncountedBadBins++; + } else { + totalBadBins++; + } + } + } + } + } + + int totalBadBins_all = 0; + int totalUncountedBadBins_all = 0; + double mean_all=0; + double stdev_all=0; + + //compute the arithmetic mean + double sum_all=0,sum2_all=0; + int counter_all = 0; + + for(int i=0;i <= histogram->GetNbinsX() ;i++){ + if( histogram->GetBinContent(i) != 0 || ignore0 == false) { + sum_all += histogram->GetBinContent(i); + sum2_all += histogram->GetBinContent(i)*histogram->GetBinContent(i); + counter_all++; + } + } + + mean_all = counter_all > 0 ? sum_all/(double)counter_all : 0; + stdev_all = counter_all > 0 ? sqrt( (1/(double)counter_all)*sum2_all - mean_all*mean_all) : 0; + + + //check how many bins are out of N sigma range (SigmaDev) or out of the absolute dev (AbsDev) or over absolute limit (AbsLimit), count them as (uncounted) outliers + double dev_all; + double absdev_test_all = 0; + if (checkSigmaDev) { + for (int i=0;i <= histogram->GetNbinsX() ;i++) { + if ((histogram->GetBinContent(i) != 0) || (ignore0 == 0)) { + dev_all=fabs(histogram->GetBinContent(i) - mean_all)/stdev_all; + absdev_test_all=fabs(histogram->GetBinContent(i) - mean_all); + if ((dev_all > sigmaDev) && (absdev_test_all > absDev)) { + if (dontCountSigmaOutliers){ + totalUncountedBadBins_all++; + } else { + totalBadBins_all++; + } + } + } + } + } + + + //Prepare map for results and commit outlier specific parts + std::map<std::string,double> algparams; + algparams["Number_of_outlier_bins"] = totalBadBins; + algparams["Number_of_outlier_bins_all"] = totalBadBins_all; + algparams["Mean"] = mean; + algparams["Standard_deviation"] = stdev; + algparams["Number_of_bins_equal_zero"] = zeroBins; + + + //Compare with given thresholds and compute DQ-Flag + dqm_core::Result *result = tools::MakeComparisons(algparams, config.getGreenThresholds(), config.getRedThresholds()); + + + return result; +} + +void dqm_algorithms::L1Calo_OutlierAndFlatnessTest::printDescription(std::ostream& out) { + out << name_ << ": derivation of OutlierAndFlatnessTest, slimmed and optimized for L1Calo needs" + "Checks TH1-inherited histograms for bins which lie either Nsigma or AbsDev away from the mean (by default excludes bins with zero entries). Can also check mean itself\n" + "Config Parameters:\n" + "\tCheckSigmaDev:\tCheck for deviation in units of standard deviations from mean (default 1).\n" + "\tMinStat:\tMinimum Statistics for the histogram to be checked (default 1).\n" + "\txmin and/or xmax:\tRestrict all counting to this x-axis interval (default: full axis range).\n" + "\txmin and/or xmax:\tThere is a second output parameter (Number_of_outlier_bins_all), which always uses the full range.\n" + "\tIgnore0:\tBins with 0 content are ignored for outlier/mean computation (default 1).\n" + "\tSigmaDev:\tNumber of Standard Deviations a single bin has to differ from the mean of the distribution to be classified as outlier. Has to be given if \"CheckSigmaDev\" is set to 1. (default 5)\n" + "\tAbsDev:\tAbsolute value a single bin has to differ from the mean of the distribution to be classified as outlier. Has to be given if \"CheckAbsDev\" is set to 1.\n" + "\tDontCountSigmaDev:\tBins deviating by a given number of standard deviations are not counted as outliers (default 0)." + "\tDontCountSigmaDev:\t(Not recommended to be switched on in current config)\n" + "Threshold Parameters:\n" + "\tStandard_deviation: \tStandard Deviation of distribution.\n" + "\tNumber_of_outlier_bins:\tNumber of bins classified as outliers using the given thresholds (in chosen histogram range).\n" + "\tNumber_of_outlier_bins_all:\tNumber of bins classified as outliers using the given thresholds (in full histogram range).\n" + "\tMean:\tMean of distribution.\n" + "\tNumber_of_bins_equal_zero:\tNumber of Bins with zero content." << std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/LastBinThreshold.cxx b/DataQuality/dqm_algorithms/src/LastBinThreshold.cxx new file mode 100644 index 0000000000000000000000000000000000000000..de737c406d9ffeaa617fb9512451692e2520358d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/LastBinThreshold.cxx @@ -0,0 +1,168 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file LastBinThreshold.cxx checks whether the last bin(s) in a histogram exceed the given thresholds, returns dqm_core::Result + * \author Adrian Vogel + */ + +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_algorithms/LastBinThreshold.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +#include "TClass.h" +#include "TObject.h" +#include "TH1.h" + +#include <iostream> +#include <cmath> + +namespace { // anonymous +dqm_algorithms::LastBinThreshold instance("LastBinThreshold"); // global instance to have this algorithm registered with the manager +} + +dqm_algorithms::LastBinThreshold::LastBinThreshold(const std::string &name): m_name(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(m_name, this); +} + +dqm_algorithms::LastBinThreshold::~LastBinThreshold() +{ + /* noop */ +} + +dqm_algorithms::LastBinThreshold *dqm_algorithms::LastBinThreshold::clone() +{ + return new LastBinThreshold(m_name); // somebody else must delete this +} + +dqm_core::Result *dqm_algorithms::LastBinThreshold::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + if (!object.IsA()->InheritsFrom("TH1")) { // this could also be TH2 or TH3 + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + const TH1 &histogram = dynamic_cast<const TH1 &>(object); // should be possible after the previous check (otherwise we'd get a std::bad_cast) + if (histogram.GetDimension() > 1) { // only one-dimensional histograms have a last bin, but feel free to generalise this for D > 1 if you like + throw dqm_core::BadConfig(ERS_HERE, name, "has more than one dimension"); + } + + getParameters(name, config); + getThresholds(name, config); + + dqm_core::Result *result = new dqm_core::Result(); // somebody else must delete this + int grnExceeded = 0; // how many of the checked bins exceeded the green threshold + int redExceeded = 0; // how many of the checked bins exceeded the red threshold + + int currentBin = histogram.GetNbinsX(); // this is the last proper bin (we don't want the overflow bin) + if (m_getEntries == 0) { // skip trailing bins with zero content + while ((histogram.GetBinContent(currentBin) == 0) && (currentBin > 0)) --currentBin; + } else if (m_getEntries == 1) { // assume that this value corresponds to the bin number of the last bin + currentBin = histogram.GetEntries(); + } else if (m_getEntries == 2) { /* noop */ } // just start checking from the rightmost bin + + result->tags_["LastBinNumber"] = currentBin; // report where we began the checks (mostly for debugging) + result->tags_["LastBinCenter"] = histogram.GetBinCenter(currentBin); // report where that is on the x-axis + // if the histogram is completely empty then currentBin is now zero, and we shouldn't check anything, + // therefore the break statement is at the front (!) of the following loop + + for (int i = 0; i < m_nBinsToWatch; ++i) { // step through the final NBinsToWatch bins + if (currentBin == 0) break; // we hit the left end (and we don't want the underflow bin) + double content = histogram.GetBinContent(currentBin); + if (m_valueThresholds) { + if (m_greaterThan) content = histogram.GetXaxis()->GetBinUpEdge(currentBin); + else content = histogram.GetXaxis()->GetBinLowEdge(currentBin); + } + if (exceeds(content, m_grn)) ++grnExceeded; // can be less-than or greater-than relation + if (exceeds(content, m_red)) ++redExceeded; // can be less-than or greater-than relation + --currentBin; + } + + result->tags_["GreenExceeded"] = grnExceeded; + result->tags_["RedExceeded"] = redExceeded; + if (grnExceeded < redExceeded) // sanity check, this should never happen because getThresholds() makes sure the thresholds have the right order + throw dqm_core::BadConfig(ERS_HERE, name, "more bins exceeded the red threshold than the green threshold, this shouldn't happen"); + + if (grnExceeded < m_nBinsToExceed) result->status_ = dqm_core::Result::Green; + else if (redExceeded < m_nBinsToExceed) result->status_ = dqm_core::Result::Yellow; + else result->status_ = dqm_core::Result::Red; + return result; +} + +void dqm_algorithms::LastBinThreshold::printDescription(std::ostream& out) +{ + out << m_name << ": Checks whether the last bin(s) of a histogram exceed the given thresholds.\n" + "Mandatory green/red thresholds: Threshold - the thresholds against which the bin contents are compared.\n" + "Optional parameter: NBinsToWatch - number of final bins that will be checked. (NBinsToWatch >= 1, default = 1)\n" + " The result of the algorithm is the worst-case result of all checked bins.\n" + "Optional parameter: NBinsToExceed - minimal number of checked bins that have to exceed the given thresholds\n" + " before the corresponding result is returned. (1 <= NBinsToExceed <= NBinsToWatch, default = 1)\n" + "Optional parameter: GreaterThan - how the values will be compared. (GreaterThan = {0, 1}, default = 1)\n" + " GreaterThan == 0: the given thresholds are lower thresholds. (requires green >= red)\n" + " GreaterThan == 1: the given thresholds are upper thresholds. (requires green <= red)\n" + "Optional parameter: ValueThresholds - which values will be compared. (ValueThresholds = {0, 1}, default = 0)\n" + " ValueThresholds == 0: the thresholds correspond to the bin content.\n" + " ValueThresholds == 1: the thresholds correspond to the bin x-axis value.\n" + "Optional parameter: GetEntries - how to determine which bin is the last. (GetEntries = {0, 1, 2}, default = 0)\n" + " GetEntries == 0: find the rightmost non-zero bin, ignore trailing zero bins.\n" + " GetEntries == 1: take the return value of TH1::GetEntries() as the number of the last bin.\n" + " GetEntries == 2: take the rightmost bin as the last bin, regardless of the bin content.\n" + "Returned value: LastBinNumber - the bin number of the last checked (i. e. non-zero) bin.\n" + "Returned value: LastBinCenter - the centre of that bin on the horizontal axis.\n" + "Returned value: GreenExceeded - how many bins exceeded the green threshold.\n" + "Returned value: RedExceeded - how many bins exceeded the red threshold." << std::endl; +} + +void dqm_algorithms::LastBinThreshold::getParameters(const std::string &name, const dqm_core::AlgorithmConfig &config) +{ + // The following intermediate variables do not yet have the correct type, + // since dqm_core::AlgorithmConfig::getParameters can only return values of type double. + // We cannot cast them immediately because we still need to perform some manual range checks. + // + const double par0 = dqm_algorithms::tools::GetFirstFromMap("NBinsToWatch", config.getParameters(), 1); // default = 1 + const double par1 = dqm_algorithms::tools::GetFirstFromMap("NBinsToExceed", config.getParameters(), 1); // default = 1 + const double par2 = dqm_algorithms::tools::GetFirstFromMap("GreaterThan", config.getParameters(), 1); // default = true + const double par3 = dqm_algorithms::tools::GetFirstFromMap("ValueThresholds", config.getParameters(), 0); // default = false + const double par4 = dqm_algorithms::tools::GetFirstFromMap("GetEntries", config.getParameters(), 0); // default = 0 + + if (par0 < 1) + throw dqm_core::BadConfig(ERS_HERE, name, "NBinsToWatch must be 1 or greater"); + if (par1 < 1) + throw dqm_core::BadConfig(ERS_HERE, name, "NBinsToExceed must be 1 or greater"); + if (par1 > par0) + throw dqm_core::BadConfig(ERS_HERE, name, "NBinsToExceed must not be greater than NBinsToWatch"); + if ((par2 != 0) && (par2 != 1)) + throw dqm_core::BadConfig(ERS_HERE, name, "GreaterThan must be 0 or 1"); + if ((par3 != 0) && (par3 != 1)) + throw dqm_core::BadConfig(ERS_HERE, name, "ValueThresholds must be 0 or 1"); + if ((par4 != 0) && (par4 != 1) && (par4 != 2)) + throw dqm_core::BadConfig(ERS_HERE, name, "GetEntries must be 0, 1 or 2"); + + m_nBinsToWatch = static_cast<int>(par0); + m_nBinsToExceed = static_cast<int>(par1); + m_greaterThan = static_cast<bool>(par2); + m_valueThresholds = static_cast<bool>(par3); + m_getEntries = static_cast<int>(par4); +} + +void dqm_algorithms::LastBinThreshold::getThresholds(const std::string &name, const dqm_core::AlgorithmConfig &config) +{ + m_grn = dqm_algorithms::tools::GetFromMap("Threshold", config.getGreenThresholds()); + m_red = dqm_algorithms::tools::GetFromMap("Threshold", config.getRedThresholds()); + + if (m_greaterThan && (m_red < m_grn)) + throw dqm_core::BadConfig(ERS_HERE, name, "using greater-than comparison, but red threshold is less than green threshold"); + else if (!m_greaterThan && (m_red > m_grn)) + throw dqm_core::BadConfig(ERS_HERE, name, "using less-than comparison, but red threshold is greater than green threshold"); +} + +inline bool dqm_algorithms::LastBinThreshold::exceeds(double value, double threshold) const +{ + if (m_greaterThan) + return value > threshold; + else + return value < threshold; + // We could derive that behaviour from testing whether (m_grn < m_red) or (m_grn > m_red), but then we + // weren't able to find a reasonable behaviour if (m_grn == m_red), i. e. for people who never want yellow. +} diff --git a/DataQuality/dqm_algorithms/src/MDTADCSpectrum.cxx b/DataQuality/dqm_algorithms/src/MDTADCSpectrum.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f80658a431d16bc929f985a5f1c6a78ec20f79fc --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTADCSpectrum.cxx @@ -0,0 +1,223 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTADCSpectrum.cxx,v 1.0 2008/10/08 Valerio Consorti +// ********************************************************************** + + +#include "dqm_algorithms/MDTADCSpectrum.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TF1.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + + +static dqm_algorithms::MDTADCSpectrum staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTADCSpectrum::MDTADCSpectrum() + : name("MDTADCspectrum") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTADCSpectrum::~MDTADCSpectrum() +{ +} + + +dqm_core::Algorithm* +MDTADCSpectrum::clone() +{ + return new MDTADCSpectrum(*this); +} + + +dqm_core::Result* +MDTADCSpectrum::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * hist; + TH1 * ref; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double thresh; + double greenTh; + double redTh; + try { + thresh = dqm_algorithms::tools::GetFirstFromMap( "thresh", config.getParameters(), 50); + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 0); + redTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + + try { + ref = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + //Algo + + Double_t n_min_50=0; + Double_t n_min_50_ref=0; + + Double_t N = hist->GetEntries(); + Double_t N_ref = ref ->GetEntries(); + + int i=0; + + do{ + i++; + n_min_50 += hist->GetBinContent(i); + if(i>hist->GetNbinsX()){ + ERS_INFO("bin limit!"<<i); + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Undefined; + return result; + }; + }while(hist->GetBinCenter(i)<thresh); + + i=0; + + do{ + i++; + n_min_50_ref += ref->GetBinContent(i); + if(i>ref->GetNbinsX()){ + ERS_INFO("bin limit!"<<i); + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Undefined; + return result; + }; + }while(ref->GetBinCenter(i)<thresh); + + Double_t f = -1; + Double_t f_r= 1; + Double_t sigma_hist = -1; + Double_t sigma_ref = -1; + Double_t sigma = -1; + Double_t F = -1; + + + if(N == 0 && N_ref == 0) { + ERS_INFO("null N entries found"); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["ERROR_null_entries_found"] = -999.; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + if(N !=0 && N_ref !=0){ + f = n_min_50/N; + f_r = n_min_50_ref/N_ref; + + if(f*f_r == 0 || (1-f)<0 || (1-f_r)<0 ){ + ERS_DEBUG(1,"*) f = "<<f<<" f_r = "<<f_r); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["ERROR_problem_in_fraction_computation"] = -999.; + result->tags_["n_min_50/N"] = f; + result->tags_["n_min_50_ref/N_ref"] = f_r; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + //Bernulli distribution + + sigma_hist= sqrt(f*(1-f)/N); + sigma_ref= sqrt(f_r*(1-f_r)/N_ref); + + F=f/f_r; + + sigma = F*sqrt((sigma_hist/f)*(sigma_hist/f)+(sigma_ref/f_r)*(sigma_ref/f_r)); + + + }; + + + //Result + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["00-Pedestal_fraction"] = f; + result->tags_["1-Pedestal_over_Ped_ref"] = (1-F); + result->tags_["sigma_1-Ped_over_Ped_ref"] = sigma; + + if(f<= greenTh || (f>greenTh && f_r>greenTh)) { + result->status_ = dqm_core::Result::Green; + } + else if( f>redTh && f_r<greenTh ) { + result->tags_["Difference_against_Ref-Pedestal_fraction_Ref"] = f_r; + result->status_ = dqm_core::Result::Red; + } + else { + result->status_ = dqm_core::Result::Yellow; + } + + // Return the result + return result; +} + + +void +MDTADCSpectrum::printDescription(std::ostream& out){ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Checks if the ratio of hits under treshold is below the limits\n"; + message += " Comparison with reference is performed \n"; + message += "Mandatory Parameters: Green/Red Threshold: Limits: warning: ratio limits \n"; + message += " error\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " thresh = ADC cut on pedestal N counts (def 50)\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTChi2.cxx b/DataQuality/dqm_algorithms/src/MDTChi2.cxx new file mode 100644 index 0000000000000000000000000000000000000000..365a20b0ad71be2c04b93ac2ec43b2500bd0cf95 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTChi2.cxx @@ -0,0 +1,185 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTChi2.cxx,v 1.0 2008/10/08 Valerio Consorti +// ********************************************************************** + +#include "dqm_algorithms/MDTChi2.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> +#include <TF1.h> +#include <TProfile.h> +#include "TMath.h" + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +static dqm_algorithms::MDTChi2 staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTChi2::MDTChi2() + : name("MDTchi2") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTChi2::~MDTChi2() +{ +} + + +dqm_core::Algorithm* +MDTChi2::clone() +{ + return new MDTChi2(*this); +} + + +dqm_core::Result* +MDTChi2::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * hist; + TH1 * ref; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double greenTh; + double redTh; + try { + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 50); + redTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + + try { + ref = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + if (hist->GetNbinsX() != ref->GetNbinsX() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different bin numbre in X axis!" ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + + //Algo + + int i = 0; + int count = 1; + Double_t n = 0; + Double_t n_ref = 0; + Double_t chi2 = 0; + int max_bin = hist -> GetNbinsX(); + Double_t N = hist -> GetEntries(); + Double_t N_ref = ref -> GetEntries(); + + if(N == 0){ + ERS_INFO("Histogram has no entries" <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + }; + + if(N_ref == 0){ + ERS_INFO("Reference histogram has no entries" <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientRefEntries"] = ref->GetEntries(); + return result; + }; + + double norm=1; + double norm_ref=1; + + if(N != 0) norm=1/N; + if(N_ref != 0) norm_ref=1/N_ref; + + for(i=1;i<=max_bin;i++){ + n = hist->GetBinContent(i); + n_ref = ref->GetBinContent(i); + if( n != 0 || n_ref != 0) chi2+=(n*norm-n_ref*norm_ref)*(n*norm-n_ref*norm_ref)/(n*norm*norm+n_ref*norm_ref*norm_ref); + if( n == 0 && n_ref == 0) count++; + }; + + Double_t prob=0; + prob=TMath::Prob(chi2,(max_bin-count)); + + + //Result + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["chi2_prob"] = prob; + + if (prob>greenTh) { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } else if ( prob<=greenTh && prob>redTh ) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (prob<=redTh) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } + return result; +} + + +void +MDTChi2::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Perform a chi square check between input istogram and reference\n"; + message += "Mandatory Green/Red Threshold: Limits: chi square probability limits\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTCluster.cxx b/DataQuality/dqm_algorithms/src/MDTCluster.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f2cc423e9597cc2287f59a15bc53795e2e429a58 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTCluster.cxx @@ -0,0 +1,303 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTCluster.cxx,v 1.0 2008/10/08 Valerio Consorti +// ********************************************************************** + +#include "dqm_algorithms/MDTCluster.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> +#include <utility> +#include <string> +#include <vector> + + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +static dqm_algorithms::MDTCluster staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTCluster::MDTCluster() + : name("MDTcluster") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTCluster::~MDTCluster() +{ +} + + +dqm_core::Algorithm* +MDTCluster::clone() +{ + return new MDTCluster(*this); +} + + +dqm_core::Result* +MDTCluster::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * hist; + TH1 * ref; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double n_sigma; + double greenTh; + double redTh; + try { + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 500); + n_sigma = dqm_algorithms::tools::GetFirstFromMap("N_sigma", config.getParameters()); + redTh = dqm_algorithms::tools::GetFromMap( "ClusterSize", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "ClusterSize", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + double cluster_size=greenTh; + + //Get Reference Histo + + try { + ref = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + if (hist->GetNbinsX() != ref->GetNbinsX() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different bin numbre in X axis!" ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + +//Algo + double N; + double N_ref; + + N= hist->GetEntries(); + N_ref= ref->GetEntries(); + + if(N == 0){ + ERS_INFO("Histogram has no entries" <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + }; + + if(N_ref == 0){ + ERS_INFO("Reference histogram has no entries" <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientRefEntries"] = ref->GetEntries(); + return result; + }; + + //Scaling reference to histo + + double norm= (double) N/N_ref; + ref->Scale(norm); + + + //Storing bin-bin differences between histo and reference + unsigned int i=1; + int j=1; + std::vector<double> diff; + + for(j=1;j<=hist->GetNbinsX();j++){ + diff.push_back(hist->GetBinContent(j)-ref->GetBinContent(j)); + }; + + + + //looking for clusters: + //the custer begins when the difference between hist and ref is larger than + //n_sigma*sqrt(hist_N_bin_entries+ref_N_bin_entries*norm*norm) + //and finishes when the difference is smaller. + + i=0; + bool cluster_open=0; + std::pair<int,int> bin_start_end; + std::pair<int , std::pair<int,int> > cluster_size_binStart_binEnd; + std::vector< std::pair< int , std::pair< int, int> > > clusters; + int size=0; + + for(i=0;i<diff.size();i++){ + + if(fabs(diff[i])>n_sigma*sqrt(hist->GetBinContent(i+1)+ref->GetBinContent(i+1)*norm)){ + if(cluster_open){ + if(i!=0){ + + if(diff[i-1]*diff[i]>0){ + size++; + }; + + if(diff[i-1]*diff[i]<=0 ){ + if(size>=cluster_size){ + bin_start_end.second=i; + cluster_size_binStart_binEnd.first=size; + cluster_size_binStart_binEnd.second=bin_start_end; + clusters.push_back(cluster_size_binStart_binEnd); + }; + cluster_open=0; + }; + + if(i==0){ + ERS_INFO("Cluster searching fail"); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["i"] = i; + return result; + }; + }; + }; + + if(!cluster_open){ + cluster_open=1; + size=0; + bin_start_end.first=i+1; + size++; + }; + + }; + + if(fabs(diff[i])<=n_sigma*sqrt(hist->GetBinContent(i+1)+ref->GetBinContent(i+1)*norm)){ + if(cluster_open){ + if(size>=cluster_size){ + bin_start_end.second=i; + cluster_size_binStart_binEnd.first=size; + cluster_size_binStart_binEnd.second=bin_start_end; + clusters.push_back(cluster_size_binStart_binEnd); + }; + cluster_open=0; + }; + }; + if(i==diff.size()-1){ + if(cluster_open){ + if(size>=cluster_size){ + bin_start_end.second=i+1; + cluster_size_binStart_binEnd.first=size; + cluster_size_binStart_binEnd.second=bin_start_end; + clusters.push_back(cluster_size_binStart_binEnd); + }; + cluster_open=0; + }; + }; + }; + + +//Result + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["00-N_clusters"] = clusters.size(); + + std::string Cluster="Cluster_"; + char num[2]; + std::string Size="_info_1_size"; + std::string start_at_bin="_info_2_start_at_bin"; + std::string finish_at_bin="_info_3_finish_at_bin"; + std::string message1; + std::string message2; + std::string message3; + + for(i=0;i<clusters.size();i++){ + if((i+1)<10){ + sprintf(num,"0%d",(i+1)); + }; + + if((i+1)>=10){ + sprintf(num,"%d",(i+1)); + }; + + message1 = Cluster + (std::string) num + Size; + message2 = Cluster + (std::string) num + start_at_bin; + message3 = Cluster + (std::string) num + finish_at_bin; + + result->tags_[message1] = clusters[i].first; + result->tags_[message2] = clusters[i].second.first; + result->tags_[message3] = clusters[i].second.second; + }; + + + i=0; + int flag=0; + for(i=0;i<clusters.size();i++){ + if(clusters[i].first<redTh) flag++; + if(clusters[i].first>=redTh) flag+=2; + }; + + + if (flag<1) { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } else if ( flag>=1 && flag<2 ) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (flag>=2) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } + + return result; +} + + +void +MDTCluster::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: look for clusters of adiacent bins where each bin differ from reference more then n sigma\n"; + message += "Mandatory Green/Red Threshold: ClusterSize: the green threshold is the minimum cluster size, each cluster\n"; + message += " smaller than this size will not recorded as cluster by this algorithm\n"; + message += " red threshold is the limit size of a cluster, if there is just one cluster\n"; + message += " bigger then this limit the flag will be red;\n"; + message += " otherwise the flag will be red if it find more at last 2 clusters\n"; + message += " N_sigma : maximum distance in standard deviation of a bin of the histo from the reference one\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTMLOverview.cxx b/DataQuality/dqm_algorithms/src/MDTMLOverview.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7c8f4424e115546d1cb733dadbee91e4bb5c0fa5 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTMLOverview.cxx @@ -0,0 +1,233 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTMLOverview.cxx,v 1.0 2008/10/08 Valerio Consorti +// ********************************************************************** + +#include "dqm_algorithms/MDTMLOverview.h" + +#include <cmath> +#include <iostream> +#include <map> +#include <list> +#include <string> +#include <vector> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> +#include <TF1.h> +#include <TProfile.h> +#include "TMath.h" + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +static dqm_algorithms::MDTMLOverview staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTMLOverview::MDTMLOverview() + : name("MDTMLoverview") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTMLOverview::~MDTMLOverview() +{ +} + + +dqm_core::Algorithm* +MDTMLOverview::clone() +{ + return new MDTMLOverview(*this); +} + + +dqm_core::Result* +MDTMLOverview::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * hist; + TH1 * ref; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + bool ref_y_n=0; + double thresh; + double minstat; + double greenTh; + double redTh; + try { + ref_y_n = dqm_algorithms::tools::GetFirstFromMap("ref", config.getParameters(), 0); + thresh = dqm_algorithms::tools::GetFirstFromMap("thresh", config.getParameters()); + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 50); + redTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + + try { + ref = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + if (hist->GetNbinsX() != ref->GetNbinsX() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different bin number in X axis!" ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + + //Algo + + int binX = hist->GetNbinsX(); + //double x_center=0; + + std::list<int> hist_buffer; + std::list<int> ref_buffer; + std::vector< double > new_empty_bins; + int count=0; + + for(int x_index=1; x_index<=binX; x_index++){ + if( hist->GetBinContent(x_index) != 0 ) hist_buffer.push_back((int)hist->GetBinContent(x_index)); + if(ref_y_n==1) { + if( ref->GetBinContent(x_index) != 0 ) ref_buffer.push_back((int)ref->GetBinContent(x_index)); + } + }; + + hist_buffer.sort(); + std::list<int>::iterator it_hist; + int size_hist = hist_buffer.size(); + it_hist=hist_buffer.begin(); + for(int i=1; i<(size_hist/2); i++) it_hist++; + int mediana_hist = *it_hist; + + if(ref_y_n==1) { + + ref_buffer.sort(); + std::list<int>::iterator it_ref; + int size_ref = ref_buffer.size(); + it_ref=ref_buffer.begin(); + for(int j=1; j<(size_ref/2); j++) it_ref++; + int mediana_ref = *it_ref; + + for(int xi=1; xi<=binX; xi++){ + if( hist->GetBinContent(xi) < mediana_hist*thresh/100 && ref->GetBinContent(xi) >= mediana_ref*thresh/100){ + count++; + new_empty_bins.push_back(hist->GetBinCenter(xi)); + }; + }; + } else if(ref_y_n==0){ + for(int xi=1; xi<=binX; xi++){ + if( hist->GetBinContent(xi) < mediana_hist*thresh/100){ + count++; + new_empty_bins.push_back(hist->GetBinCenter(xi)); + }; + }; + }; + + + //double tot=binX; + //if(ref_y_n==0) tot=binX; + + //Tag generator + + dqm_core::Result* result = new dqm_core::Result(); + + std::string message; + std::string eta="ETA_"; + std::string ml="__ML"; + char eta_num[2]; + std::string ml_num; + double num_ml_off=1; + int counter=0; + + int empty_bin_number=new_empty_bins.size(); + + for(int i=0; i<empty_bin_number; i++){ + counter=-1; + do{ + counter++; + if(counter>=20) break; + }while(fabs(counter-new_empty_bins[i])>0.3); + + sprintf(eta_num,"%d",counter); + if( (counter-new_empty_bins[i])>=0)ml_num="1"; + if( (counter-new_empty_bins[i])<0) ml_num="2"; + message=eta+(std::string)eta_num+ml+ml_num; + result->tags_[message]=num_ml_off; + }; + + //Result + + result->tags_["00-number_of_off_ML"] = count; + + if (count<greenTh) { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } else if ( count>=greenTh && count<redTh ) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (count>=redTh) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } + return result; +} + + +void +MDTMLOverview::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: compare the histo with reference and check if there are any ML switched off\n"; + message += "Mandatory Green/Red Threshold: Limits: number of new ML switched off while are on in reference\n"; + message += " thresh = % of the mean entries per ML under which the algo will set ML off\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " ref = Bool value: 1 if you want perform the check comparing with ref\n"; + message += " 0 if you want perform the check without the comparison with ref\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTMultiplicity.cxx b/DataQuality/dqm_algorithms/src/MDTMultiplicity.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c988324429f2d6817ad46f6922f668f82f1dfec0 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTMultiplicity.cxx @@ -0,0 +1,356 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTMultiplicity.cxx,v 2.0 2008/10/08 Valerio Consorti +// ********************************************************************** + +#include "dqm_algorithms/MDTMultiplicity.h" + +#include <cmath> +#include <iostream> +#include <map> +#include <vector> +#include <string> + +#include <TClass.h> +#include <TH1.h> +#include <TF1.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + + +static dqm_algorithms::MDTMultiplicity staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTMultiplicity::MDTMultiplicity() + : name("MDTmultiplicity") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTMultiplicity::~MDTMultiplicity() +{ +} + + +dqm_core::Algorithm* +MDTMultiplicity::clone() +{ + return new MDTMultiplicity(*this); +} + + +dqm_core::Result* +MDTMultiplicity::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + using namespace std; + + TH1 * hist; + TH1 * ref; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Reference Histo + + try { + ref = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + + //Get Parameters and Thresholds + double minstat; + double thresh_on_difference=75; + double thresh_on_peak_content=15; + //double peak_number=2; + double pos1=3; + double pos2=6; + double pos3=-1; + double greenTh=1; + double redTh=2; + double ref_y_n=1; + + try { + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 100); + thresh_on_difference = dqm_algorithms::tools::GetFirstFromMap("IsolationThresh", config.getParameters(), 75); + thresh_on_peak_content = dqm_algorithms::tools::GetFirstFromMap("StatisticThresh", config.getParameters(), 15); + //peak_number = dqm_algorithms::tools::GetFirstFromMap("NumberOfPeaks", config.getParameters()); + pos1 = dqm_algorithms::tools::GetFirstFromMap("FirstPeakPosition", config.getParameters(), 4); + pos2 = dqm_algorithms::tools::GetFirstFromMap("SecondPeakPosition", config.getParameters(), 8); + pos3 = dqm_algorithms::tools::GetFirstFromMap("ThirdPeakPosition", config.getParameters(), -1); + ref_y_n = dqm_algorithms::tools::GetFirstFromMap("UseRef", config.getParameters(), 0); + redTh = dqm_algorithms::tools::GetFromMap( "PeakShift", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "PeakShift", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + //Algo + unsigned int i=0; + unsigned int k=0; + vector<double> derivate; + vector<double> peak_candidate; + vector<double> peak; + vector<double> valley; + + vector<double> derivate_ref; + vector<double> peak_candidate_ref; + vector<double> peak_ref; + vector<double> valley_ref; + + //Filling vector of derivate + for(i=1;i<=(unsigned int)hist->GetNbinsX();i++){ + if((i+1)<=(unsigned int)hist->GetNbinsX()) derivate.push_back(hist->GetBinContent(i+1)-hist->GetBinContent(i)); + if((i+1)<=(unsigned int)ref->GetNbinsX() && ref_y_n==1) derivate_ref.push_back(ref->GetBinContent(i+1)-ref->GetBinContent(i)); + }; + + i=0; + + //Look for peaks and valley + Double_t highest_peak=0; + Double_t peak_content; + Double_t first_valley_content; + Double_t second_valley_content; + Double_t highest_peak_ref=0; + Double_t peak_content_ref; + Double_t first_valley_content_ref; + Double_t second_valley_content_ref; + + if(derivate[0]>=0) valley.push_back(0); + if(derivate[0]<0){ + peak_candidate.push_back(0); + highest_peak=hist->GetBinContent(1); + } + if(ref_y_n==1){ + if(derivate_ref[0]>=0) valley_ref.push_back(0); + if(derivate_ref[0]<0){ + peak_candidate_ref.push_back(0); + highest_peak_ref=ref->GetBinContent(1); + } + }; + + for(i=0;i<(derivate.size()-1);i++){ + if(derivate[i]>0 && derivate[i+1]<0){ + peak_candidate.push_back(i+1); + peak_content=hist->GetBinContent(i+2); + if(peak_content>highest_peak) highest_peak=peak_content; + }else if(derivate[i]<0 && derivate[i+1]>0){ + valley.push_back(i+1); + }; + + if(ref_y_n==1){ + if(derivate_ref[i]>0 && derivate_ref[i+1]<0){ + peak_candidate_ref.push_back(i+1); + peak_content_ref=ref->GetBinContent(i+2); + if(peak_content_ref>highest_peak_ref) highest_peak_ref=peak_content_ref; + }else if(derivate_ref[i]<0 && derivate_ref[i+1]>0){ + valley_ref.push_back(i+1); + }; + }; + }; + + valley.push_back(hist->GetNbinsX()); + valley_ref.push_back(hist->GetNbinsX()); + + //Peak Definition (isolation and high statistic) + i=0; + + for(i=0;i<peak_candidate.size();i++){ + peak_content=hist->GetBinContent((Int_t)peak_candidate[i]+1); + first_valley_content=hist->GetBinContent((Int_t)valley[i]+1); + second_valley_content=hist->GetBinContent((Int_t)valley[i+1]+1); + if(first_valley_content==0) first_valley_content=1; + if(second_valley_content==0) second_valley_content=1; + + if((first_valley_content<=second_valley_content) && (peak_content>(thresh_on_peak_content*highest_peak/100)) && (first_valley_content<(thresh_on_difference*peak_content/100))){ + peak.push_back(peak_candidate[i]); + }else if((first_valley_content>second_valley_content) && (peak_content>(thresh_on_peak_content*highest_peak/100)) && (second_valley_content<(thresh_on_difference*peak_content/100))){ + peak.push_back(peak_candidate[i]); + }; + }; + + i=0; + if(ref_y_n==1){ + for(i=0;i<peak_candidate_ref.size();i++){ + peak_content_ref=ref->GetBinContent((Int_t)peak_candidate_ref[i]+1); + first_valley_content_ref=ref->GetBinContent((Int_t)valley_ref[i]+1); + second_valley_content_ref=ref->GetBinContent((Int_t)valley_ref[i+1]+1); + if(first_valley_content_ref==0) first_valley_content_ref=1; + if(second_valley_content_ref==0) second_valley_content_ref=1; + + if((first_valley_content_ref<=second_valley_content_ref) && (peak_content_ref>(thresh_on_peak_content*highest_peak_ref/100)) && (first_valley_content_ref<(thresh_on_difference*peak_content_ref/100))){ + peak_ref.push_back(peak_candidate_ref[i]); + }else if((first_valley_content_ref>second_valley_content_ref) && (peak_content_ref>(thresh_on_peak_content*highest_peak_ref/100)) && (second_valley_content_ref<(thresh_on_difference*peak_content_ref/100))){ + peak_ref.push_back(peak_candidate_ref[i]); + }; + }; + }; + + //Result + + dqm_core::Result* result = new dqm_core::Result(); + + double count=0; + //double first_peak=-1; + //double second_peak=-1; + //double third_peak=-1; + double diff1=9999; + double diff2=9999; + double diff3=9999; + + if(ref_y_n==0){ + i=0; + for(i=0;i<peak.size();i++){ + if(fabs(peak[i]-pos1)<=diff1){ + //first_peak=i; + diff1=fabs(peak[i]-pos1); + }; + if(fabs(peak[i]-pos2)<=diff2){ + //second_peak=i; + diff2=fabs(peak[i]-pos2); + }; + if(fabs(peak[i]-pos3)<=diff3 && pos3>0){ + //third_peak=i; + diff3=fabs(peak[i]-pos3); + }; + }; + //if(peak.size() != peak_number) count = 10; + if(diff1>greenTh) count++; + if(diff2>greenTh) count++; + if(diff3>greenTh && pos3>0) count++; + if(diff1>redTh) count+=2; + if(diff2>redTh) count+=2; + if(diff3>redTh && pos3>0) count+=2; + + i=0; + string tag_n_r; + string peak_tag = "-Peak"; + char numb_n_r[3]; + + result->tags_["00-Number_of_found_peaks"] = peak.size(); + for(i=0;i<peak.size();i++){ + if(i<10) sprintf(numb_n_r,"0%d",(i+1)); + if(i>=10) sprintf(numb_n_r,"%d",(i+1)); + tag_n_r=(std::string)numb_n_r+peak_tag; + result->tags_[tag_n_r] = peak[i]; + }; + }; + + if(ref_y_n==1){ + i=0; + k=0; + vector<double> diff; + vector<double> peak_corrispondence; + for(i=0;i<peak.size();i++){ + diff1=9999; + peak_corrispondence.push_back(99999); + diff.push_back(99999); + for(k=0;k<peak_ref.size();k++){ + if(fabs(peak[i]-peak_ref[k])<=diff1){ + peak_corrispondence[i]=k; + diff[i]=fabs(peak[i]-peak_ref[k]); + diff1=fabs(peak[i]-peak_ref[k]); + }; + }; + }; + i=0; + for(i=0;i<peak.size();i++){ + if(diff[i]>greenTh) count++; + if(diff[i]>redTh) count+=2; + }; + + //if(peak.size()!=peak_ref.size()) count+=10; + + string tag; + string run_tag ="a-"; + string ref_tag ="b-"; + string multi = "Peak"; + char numb[3]; + + result->tags_["a-00-Number_of_found_peaks"] = peak.size(); + result->tags_["b-00-Number_of_found_peaks_ref"] = peak_ref.size(); + + for(i=0;i<peak.size();i++){ + if(i<10) sprintf(numb,"0%d",(i+1)); + if(i>=10) sprintf(numb,"%d",(i+1)); + tag=run_tag+(std::string)numb+multi; + result->tags_[tag] = peak[i]; + }; + i=0; + for(i=0;i<peak_ref.size();i++){ + if(i<10) sprintf(numb,"0%d",(i+1)); + if(i>=10) sprintf(numb,"%d",(i+1)); + tag=ref_tag+(std::string)numb+multi; + result->tags_[tag] = peak_ref[i]; + }; + }; + + if(count==0){ + result->status_ = dqm_core::Result::Green; + }; + if(count>=1 && count<3){ + result->status_ = dqm_core::Result::Yellow; + }; + if(count>=3){ + result->status_ = dqm_core::Result::Red; + }; + + // Return the result + return result; +} + + +void +MDTMultiplicity::printDescription(std::ostream& out){ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: it look for peaks in the histogram and it compare their position with user defined position or with reference histogram peak position. The algorithm define a peak first looking for the higher statistic bin then it look for other bins with at last a user defined percent of the entrance of the maximum bin \n"; + message += "Green/Red Thresh: PeakShift: the number of bins tollerated for the shift of a peak\n"; + message += "Mandatory Params: MinStat: minimum statistical requirement\n"; + message += " IsolationThresh: The alghorithm need it to define a peak. It define the minumum difference,in percent, between the peak entrance and the closer 'valley' entrance(valley is defined as the bin where the derivate change sign from negative to positive).\n"; + message += " StatisticThresh: The minimum bin entrance required expressed in percent compared with the maximum bin. If the bin has less then this percent of entrance it can't be defined as a peak.\n"; + message += " FirstPeakPosition: Mandatory in no reference mode. It is the position expected for the first peak\n"; + message += " SecondPeakPosition: Mandatory in no reference mode. It is the position expected for the second peak\n"; + message += " ThirdPeakPosition: Mandatory in no reference mode. It is the position expected for the third peak\n"; + message += " UseRef: 1 to use a reference histogram, 0 to use user definition for the peaks position without a reference comparison\n"; + message += "Optional Params: NumberOfPeaks: In the no reference mode it define how many peaks the algorithm has to looking for. if it find more then this number of peack it set the flag red\n"; + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTOverview.cxx b/DataQuality/dqm_algorithms/src/MDTOverview.cxx new file mode 100644 index 0000000000000000000000000000000000000000..65115d87470fbe1bcafbb4c6f568e6062d3512d4 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTOverview.cxx @@ -0,0 +1,326 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_algorithms/MDTOverview.h" + +#include <iostream> +#include <utility> +#include <vector> +#include <list> +#include <string> + +#include "TH2.h" +#include "TAxis.h" +#include "TClass.h" + + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +static dqm_algorithms::MDTOverview MDTOverview_Global( "MDTOverview_Global" ); +static dqm_algorithms::MDTOverview MDTOverview_Station( "MDTOverview_Station" ); + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTOverview::MDTOverview(const std::string & name) + : name_ ( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTOverview::~MDTOverview() +{ +} + + +dqm_core::Algorithm* +MDTOverview::clone() +{ + return new MDTOverview(name_); +} + + +dqm_core::Result* +MDTOverview::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH2 * hist; + TH2 * ref; + + if( object.IsA()->InheritsFrom( "TH2" ) ) { + hist = (TH2*)&object; + if (hist->GetDimension() != 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension != 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH2" ); + } + + //Get Parameters and Thresholds + + double greenTh; + double redTh; + double minstat; + double thresh; + double using_ref_for_flag; + std::string thresholdname; + if (name_ == "MDTOverview_Global") { + thresholdname="Percentage"; + } else if (name_ == "MDTOverview_Station") { + thresholdname="Limits"; + } else { + throw dqm_core::BadConfig( ERS_HERE, "None", name_ ); + } + + try { + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 5000); + thresh = dqm_algorithms::tools::GetFirstFromMap("thresh", config.getParameters(), 10); + using_ref_for_flag = dqm_algorithms::tools::GetFirstFromMap("using_ref_for_flag", config.getParameters(), 0); + redTh = dqm_algorithms::tools::GetFromMap( thresholdname, config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( thresholdname, config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + try { + ref = static_cast<TH2 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + + //Algo + int binX = hist->GetNbinsX(); + int binY = hist->GetNbinsY(); + double nML=0; + + std::list<int> hist_buffer; + std::list<int> ref_buffer; + + for(int x_index=1;x_index<=binX;x_index++){ + for(int y_index=1;y_index<=binY;y_index++){ + if( hist->GetBinContent(x_index,y_index) != 0 ) hist_buffer.push_back((int)hist->GetBinContent(x_index,y_index)); + if( ref->GetBinContent(x_index,y_index) != 0 ) ref_buffer.push_back((int)ref->GetBinContent(x_index,y_index)); + }; + }; + + const char *htitle = hist->GetTitle(); + ERS_DEBUG(1,"Histogram title: "<< htitle); + + if (name_ == "MDTOverview_Global") { + //GLOBAL htitle="Global HitsPerML Endcap" + //if (strstr(htitle, "Global")) { + if (strstr(htitle, "BA")) { + nML = 594; //4 BOG0 included + } else if (strstr(htitle, "BC")) { + nML = 590; + } else if (strstr(htitle, "EA")) { + nML = 502; // 16 BIS7 + 8 BIS8 +16 BEE + 10 EEL included + } else if (strstr(htitle, "EC")) { + nML = 502; // BIS7/8 + BEE + EEL included + } + + } else if (name_ == "MDTOverview_Station") { + // Barrel htitle="HitsPerML_BX_Station" + if (strstr(htitle, "B")) { + if (strstr(htitle,"Inner")) { + ERS_DEBUG(1,"Station Inner "); + nML = 212; + } else if (strstr(htitle,"Middle")) { + ERS_DEBUG(1,"Station Middle "); + nML = 178; + } else if (strstr(htitle,"Outer")) { + ERS_DEBUG(1,"Station Outer "); + if (strstr(htitle, "BA")) { + nML = 204; // BOG0 included + } else if (strstr(htitle, "BC")) { + nML = 200; + } + } + // Endcap htitle="HitsPerML_EX_Station" + } else if (strstr(htitle, "E")) { + + if (strstr(htitle,"Inner")) { + ERS_DEBUG(1,"Station Inner "); + nML = 124;// 16 BIS7 + 8 BIS8 included + } else if (strstr(htitle,"Middle")) { + ERS_DEBUG(1,"Station Middle "); + nML = 160; + } else if (strstr(htitle,"Outer")) { + ERS_DEBUG(1,"Station Outer "); + nML = 192; + } else if (strstr(htitle,"extra")) { + ERS_DEBUG(1,"Extra chambers (BEE, EEL, BIS7, BIS8)"); + nML = 26;// 16 BEE + 10 EEL included + } + } + } + + hist_buffer.sort(); + ref_buffer.sort(); + + std::list<int>::iterator it_hist; + std::list<int>::iterator it_ref; + + int size_hist = hist_buffer.size(); + int size_ref = ref_buffer.size(); + + it_hist=hist_buffer.begin(); + it_ref=ref_buffer.begin(); + + for(int i=1;i<(size_hist/2);i++) it_hist++; + for(int i=1;i<(size_ref/2);i++) it_ref++; + + int mediana_hist = *it_hist; + int mediana_ref = *it_ref; + + int count=0; + int count_non_0=0; + int sec_count=0; + int ML_count=0; + int sector=1; + std::pair<int,int> empty_bin; + std::vector< std::pair<int,int> > new_empty_bins; + + for(int y_index=1;y_index<=binY;y_index++){ + if(ML_count==2){ + ML_count=0; + sec_count=0; + sector++; + }; + ML_count++; + + for(int x_index=1;x_index<=binX;x_index++){ + if(using_ref_for_flag) { + if( hist->GetBinContent(x_index,y_index)< mediana_hist*thresh/100 && ref->GetBinContent(x_index,y_index) >= mediana_ref*thresh/100){ + sec_count++; + count++; + if( hist->GetBinContent(x_index,y_index)>0) count_non_0++; + } + } else { + if( hist->GetBinContent(x_index,y_index)< mediana_hist*thresh/100){ + sec_count++; + count++; + }; + } + }; + + if(ML_count==2 && sec_count>0){ + empty_bin.first=sector; + empty_bin.second=sec_count; + new_empty_bins.push_back(empty_bin); + } + }; + + if(nML<=0){ + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Configuration_ERROR_Setted_N_tot_ML"] = nML; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + //Result + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["00-%_ML_ON"] = 100*((double)(size_hist-count_non_0)/nML); + + if(thresholdname == "Limits" ) { + + if(count>0) { + std::string tag; + std::string tag1="Sector"; + char sect[2]; + std::string tag2="_number_of_ML_off"; + result->tags_["01-NEW_ML_OFF"] = count; + for(int j=0; j<(int)new_empty_bins.size(); j++){ + if(new_empty_bins[j].first<10) { + sprintf(sect,"0%d",new_empty_bins[j].first); + } else { + sprintf(sect,"1%d",(new_empty_bins[j].first-10)); + } + tag="01-"+tag1+(std::string)sect+tag2; + result->tags_[tag] = new_empty_bins[j].second; + }; + } + if (nML-count-size_hist > 0) result->tags_["02-KNOWN_ML_OFF"] = nML-count-size_hist; + + // Flag assignment + if (count > redTh) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } else if ( count <= redTh && count > greenTh ) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (count <= greenTh) { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } else { + result->status_ = dqm_core::Result::Undefined; + ERS_DEBUG(1,"Undefined"); + } + + } else if (thresholdname == "Percentage") { + // Flag assignment + if (100*((double)size_hist/nML)<redTh) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } else if ( 100*((double)size_hist/nML)>=redTh && 100*((double)size_hist/nML)<greenTh ) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (100*((double)size_hist/nML)>=greenTh) { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } else { + result->status_ = dqm_core::Result::Undefined; + ERS_DEBUG(1,"Undefined"); + } + } + return result; +} + + +void +MDTOverview::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name_ + "\"\n"; + message += "Description: check if there are any bins with less then a thresh% of the entries of the median bin\n"; + message += " and perform a comparison with reference.\n"; + message += "MDTOverview_Global: Mandatory Green/Red Threshold: Percentage: of ML OFF\n"; + message += "MDTOverview_Station: Mandatory Green/Red Threshold: Limits: number of ML OFF\n"; + message += "Optional Parameters: thresh = min % of hits from the median chamber accepted\n"; + message += " MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " using_ref_for_flag = if enabled (1) it compares the OFF MLs with reference, if not enabled (0)\n"; + message += " the flag is setted checking the absolute % of ML on in the detector\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTPercentUnderThresh.cxx b/DataQuality/dqm_algorithms/src/MDTPercentUnderThresh.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1cd49e85be74574680bc8f9287ce5debb49fbfcb --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTPercentUnderThresh.cxx @@ -0,0 +1,156 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTPercentUnderThresh.cxx,v 1.0 2009/06/10 Valerio Consorti +// ********************************************************************** + + +#include "dqm_algorithms/MDTPercentUnderThresh.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TF1.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + + +static dqm_algorithms::MDTPercentUnderThresh staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTPercentUnderThresh::MDTPercentUnderThresh() + : name("MDTpercent_under_thresh") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTPercentUnderThresh::~MDTPercentUnderThresh() +{ +} + + +dqm_core::Algorithm* +MDTPercentUnderThresh::clone() +{ + return new MDTPercentUnderThresh(*this); +} + + +dqm_core::Result* +MDTPercentUnderThresh::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * hist; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double thresh; + double greenTh; + double redTh; + try { + thresh = dqm_algorithms::tools::GetFirstFromMap( "Thresh", config.getParameters()); + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), 0); + redTh = dqm_algorithms::tools::GetFromMap( "Percent", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "Percent", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + //Algo + + Double_t hit_under_th=0; + + Double_t N = hist->GetEntries(); + + if(N == 0) { + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Empty_Histogram_found_N_Entries"] = N; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + int i=0; + + do{ + i++; + if(i>hist->GetNbinsX()){ + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Config_error_maximum_bin_exceed_looking_for_bin_number"] = i; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + hit_under_th += hist->GetBinContent(i); + }while(hist->GetBinCenter(i)<thresh); + + double percent = 100 - 100*((double) hit_under_th)/((double) N); + + //Result + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Entries_above_thresh(%)"] = percent; + + if( percent >= greenTh ) { + result->status_ = dqm_core::Result::Green; + } + else if( percent <greenTh && percent>redTh ) { + result->status_ = dqm_core::Result::Yellow; + } + else { + result->status_ = dqm_core::Result::Red; + } + + // Return the result + return result; +} + + +void +MDTPercentUnderThresh::printDescription(std::ostream& out){ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Compute the percent of entries above a threshold and and compare it with user defined green and red Threshold\n"; + message += "Mandatory Parameters: Green/Red Threshold: Percent: Percent of the entries above threshold requested"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " thresh = threshold\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTTDCOfflineSpectrum.cxx b/DataQuality/dqm_algorithms/src/MDTTDCOfflineSpectrum.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4123ace15a841a72a0f4c97e041da696482a0109 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTTDCOfflineSpectrum.cxx @@ -0,0 +1,150 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/MDTTDCOfflineSpectrum.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> + +#include <iostream> + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::MDTTDCOfflineSpectrum MDTTDCOfflineSpectrum( "AlgMDTTDCOfflineSpectrum" ); +} + + +dqm_algorithms::MDTTDCOfflineSpectrum::MDTTDCOfflineSpectrum( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +dqm_algorithms::MDTTDCOfflineSpectrum * +dqm_algorithms::MDTTDCOfflineSpectrum::clone() +{ + + return new MDTTDCOfflineSpectrum( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::MDTTDCOfflineSpectrum::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + // const bool publish = (bool) dqm_algorithms::tools::GetFirstFromMap( "PublishBins", config.getParameters(), 0); + // const int maxpublish = (int) dqm_algorithms::tools::GetFirstFromMap( "MaxPublish", config.getParameters(), 20); + + if (histogram->GetEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + double t0_warning; + double t0_error; + double tmax_warning; + double tmax_error; + try { + t0_warning = dqm_algorithms::tools::GetFirstFromMap( "t0Warning", config.getParameters() ); + t0_error = dqm_algorithms::tools::GetFirstFromMap( "t0Error", config.getParameters() ); + tmax_warning = dqm_algorithms::tools::GetFirstFromMap( "tMaxWarning", config.getParameters() ); + tmax_error = dqm_algorithms::tools::GetFirstFromMap( "tMaxError", config.getParameters() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + std::vector<int> range=dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + dqm_core::Result* result = new dqm_core::Result(); + + TF1* t0Fit = histogram->GetFunction("func1"); + TF1* tmaxFit = histogram->GetFunction("func2"); + if(!t0Fit || !tmaxFit) throw dqm_core::BadConfig( ERS_HERE, name, "TH1 has no TF1" ); + double t0 = t0Fit->GetParameter(1); + double tmax = tmaxFit->GetParameter(1); + double tdrift = tmax - t0; + double t0Err = t0Fit->GetParameter(2); + double tmaxErr = tmaxFit->GetParameter(2); + + ERS_DEBUG(1, name_ << " TDrift " << " is " << tdrift ); + ERS_DEBUG(1,"Green threshold: t0 > "<< t0_warning << " tmax < " << tmax_warning << " ; Red threshold : t0 < " << t0_error << " tmax > " << tmax_error ); + + std::map<std::string,double> tags; + + if ( t0 > t0_warning && tmax < tmax_warning && std::abs(tdrift) < 1000 && t0 < 750 && tmax > 850) { + result->status_ = dqm_core::Result::Green; + } + else if ( t0 > t0_error && tmax < tmax_error && std::abs(tdrift) < 1200 && t0 < 800 && tmax > 800) { + if(t0 < t0_warning || t0 > 800) tags["t0_Warning"] = t0; + else tags["t0"] = t0; + if(tmax > tmax_warning || tmax < 800) tags["tMax_Warning"] = tmax; + else tags["tMax"] = tmax; + if( std::abs(tdrift) > 1200 ) tags["tDrift_Warning"] = tdrift; + else tags["tdrift"] = tdrift; + result->status_ = dqm_core::Result::Yellow; + } + else { + result->status_ = dqm_core::Result::Red; + if(t0 < t0_error || t0 > 1000) tags["t0_Error"] = t0; + else tags["t0"] = t0; + if(tmax > tmax_error || tmax < 700) tags["tMax_Error"] = tmax; + else tags["tMax"] = tmax; + if( std::abs(tdrift) > 1400 ) tags["tDrift_Error"] = tdrift; + else tags["tdrift"] = tdrift; + } + + if(tags.size()==0) { + tags["t0"] = t0; + tags["tmax"] = tmax; + tags["tdrift"] = tdrift; + } + if(t0Err > 2.*t0){ + tags["t0_FitError"] = t0Err; + result->status_ = dqm_core::Result::Red; + } + if(tmaxErr > 2.*tmax) { + tags["tmax_FitError"] = tmaxErr; + result->status_ = dqm_core::Result::Red; + } + + result->tags_ = tags; + + return result; + +} + +void +dqm_algorithms::MDTTDCOfflineSpectrum::printDescription(std::ostream& out) +{ + + out << "Analyze pre-fitted MDTTDC spectra histograms" << std::endl; + out << "Required Parameters: name " << name_ << ", t0Warning threshold" << ", tMaxWarning threshold" << std::endl; + out << "Required parameters: t0Error" << ", tMaxError " << std::endl; + out << "Returns yellow if t0 < t0Warning or t0 > 800 or if tMax > tMaxWarning or tMax < 800" << std::endl; + out << "Returns red if t0 < t0Error or t0 > 1000 or if tMax > tMaxError or tMax < 700" << std::endl; + out << "Returns red if t0Err > 2.*t0 or tMaxErr > 2.*tMax" << std::endl; + out << "Requires that a histogram has a function named \"func1\" for the t0 fit and \"func2\" for the tMax fit" << std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/MDTTDCSpectrum.cxx b/DataQuality/dqm_algorithms/src/MDTTDCSpectrum.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f56e7e2e78a5e990d8e82dfab2cc27e32ede8d01 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTTDCSpectrum.cxx @@ -0,0 +1,270 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTTDCSpectrum.cxx,v 1.0 2008/10/08 Valerio Consorti +// ********************************************************************** + +#include "dqm_algorithms/MDTTDCSpectrum.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> +#include <TF1.h> +//#include <TProfile.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + + +static dqm_algorithms::MDTTDCSpectrum staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTTDCSpectrum::MDTTDCSpectrum() + : name("MDTTDCspectrum") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTTDCSpectrum::~MDTTDCSpectrum() +{ +} + + +dqm_core::Algorithm* +MDTTDCSpectrum::clone() +{ + return new MDTTDCSpectrum(*this); +} + + +dqm_core::Result* +MDTTDCSpectrum::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * hist; + TH1 * ref; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + hist = (TH1*)&object; + if (hist->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double chi2; + double greenTh; + double redTh; + double max_shift; + try { + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), -1); + chi2 = dqm_algorithms::tools::GetFirstFromMap("chi2", config.getParameters(), -1); + max_shift = dqm_algorithms::tools::GetFirstFromMap("max_shift", config.getParameters(), 999999); + redTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "Limits", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + + try { + ref = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (hist->GetDimension() != ref->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + + //Check of statistics + if (hist->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<hist->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = hist->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< hist->GetEntries()<< " entries "); + + + //Algo + Double_t chi2_per_NDF=999999999; + + TF1* fit_ref = (TF1*) ref->GetFunction("TimeSpectrum"); + TF1* fit_hist= (TF1*) hist->GetFunction("TimeSpectrum"); + + if(fit_ref == 0){ + ERS_INFO("Missing reference fit for "<<hist->GetName()); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Fit_parameter_NOT_found"] = -999.; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + if(fit_hist == 0){ + ERS_INFO("Missing fit for "<<hist->GetName()); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Fit_parameter_NOT_found"] = -999.; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + if(fit_hist->GetNDF() !=0) chi2_per_NDF = (fit_hist->GetChisquare())/(fit_hist->GetNDF()); + + //Check of chi2 + if (chi2_per_NDF > chi2 && chi2>0) { + ERS_INFO("Histogram does not satisfy chi_square/NDF requirement: " <<hist->GetName()); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Chi2_over_threshold"] = chi2_per_NDF; + result->status_ = dqm_core::Result::Undefined; + return result; + } + + if(fit_hist->GetNDF() == 0){ + ERS_INFO("NDF not available for histogram " <<hist->GetName()); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Fit_parameter_NDF"] = 0; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + Double_t t0_ref=0; + Double_t t0_err_ref=0; + Double_t tmax_ref=0; + Double_t tmax_err_ref=0; + + if(fit_ref !=0) t0_ref = ((fit_ref->GetParameter(4))*0.78125); + if(fit_ref !=0) t0_err_ref = ((fit_ref->GetParError(4))*0.78125); + if(fit_ref !=0) tmax_ref = ((fit_ref->GetParameter(5))*0.78125); + if(fit_ref !=0) tmax_err_ref = ((fit_ref->GetParError(5))*0.78125); + //Lower limit for t0_err_ref and tmax_err_ref + if (t0_err_ref<1.) { + t0_err_ref =1.; + } + if (tmax_err_ref<2.) { + tmax_err_ref =2.; + } + + Double_t t0=-99999.; + Double_t t0_err=0; + Double_t tmax=0; + Double_t tmax_err=0; + + if(fit_hist !=0) t0 = ((fit_hist->GetParameter(4))*0.78125); + if(fit_hist !=0) t0_err = ((fit_hist->GetParError(4))*0.78125); + if(fit_hist !=0) tmax = ((fit_hist->GetParameter(5))*0.78125); + if(fit_hist !=0) tmax_err = ((fit_hist->GetParError(5))*0.78125); + //Lower limit for t0_err and tmax_err + if (t0_err<1.) { + t0_err =1.; + } + if (tmax_err<2.) { + tmax_err =2.; + } + + Double_t Dt0=fabs(t0-t0_ref); + Double_t Dtd=fabs(tmax-t0-tmax_ref+t0_ref); + + Double_t sigma_Dt0=sqrt(t0_err*t0_err+t0_err_ref*t0_err_ref); + Double_t sigma_Dtmax=sqrt(tmax_err*tmax_err+tmax_err_ref*tmax_err_ref); + Double_t sigma_Dtd= sqrt(tmax_err*tmax_err+t0_err*t0_err+tmax_err_ref*tmax_err_ref+t0_err_ref*t0_err_ref); + + if( sigma_Dt0 ==0 || sigma_Dtmax==0 ){ + ERS_DEBUG(1,"ERROR: fit parameter errors not found!"); + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["Fit_parameter_NOT_found"] = -999.; + result->status_ = dqm_core::Result::Undefined; + return result; + }; + + + //Result + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["01-t0(ns)"] = t0; + + result->tags_["02-sigma_t0(ns)"] = t0_err; + result->tags_["03-t_drift(ns)"] = (tmax-t0); + result->tags_["04-sigma_t_drift(ns)"] = sqrt(tmax_err*tmax_err+t0_err*t0_err); + + int flag_count=0; + + if( Dtd*0.78125>max_shift ){ + flag_count+=1000; + result->tags_["05-ERROR_(td-td_Ref)"] = Dtd; + }; + + if(Dt0>redTh*sigma_Dt0){ + flag_count+=3; + result->tags_["07-ERROR_(t0-t0_Ref)"] = Dt0; + result->tags_["08-ERROR_sigma(t0-t0_Ref)"] = sigma_Dt0; + }else if(Dt0>greenTh*sigma_Dt0){ + flag_count+=1; + result->tags_["07-ERROR_(t0-t0_Ref)"] = Dt0; + result->tags_["08-ERROR_sigma(t0-t0_Ref)"] = sigma_Dt0; + }; + + + if(Dtd>redTh*sigma_Dtd){ + flag_count+=3; + result->tags_["05-ERROR_(td-td_Ref)"] = Dtd; + result->tags_["06-ERROR_sigma(td-td_Ref)"] = sigma_Dtd; + } else if(Dtd>greenTh*sigma_Dtd){ + flag_count+=1; + result->tags_["05-ERROR_(td-td_Ref)"] = Dtd; + result->tags_["06-ERROR_sigma(td-td_Ref)"] = sigma_Dtd; + }; + + + if (flag_count>2) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } else if (flag_count>=1 && flag_count<=2) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (flag_count<1) { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } + return result; +} + + +void +MDTTDCSpectrum::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Check if the histogram t0 tmax and t_drift are compatible with the reference\n"; + message += "Mandatory Parameters: Green/Red Threshold: Limits: warning: number of standard deviation from mean\n"; + message += " error\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " chi2 = chi square limit for histogram fit\n"; + message += " max_shift = maximum difference between t_drif of the histograns and reference\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTTubeCheck.cxx b/DataQuality/dqm_algorithms/src/MDTTubeCheck.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dc9e9120b19a9669584833be1f9dd9e09f26737d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTTubeCheck.cxx @@ -0,0 +1,207 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTTubeCheck.cxx,v 1.0 2008/31/07 Elena Solfaroli Camillocci +// ********************************************************************** + +#include "dqm_algorithms/MDTTubeCheck.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> +//#include <TF1.h> +//#include <TProfile.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + + +static dqm_algorithms::MDTTubeCheck staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTTubeCheck::MDTTubeCheck() + : name("MDTTubeCheck") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTTubeCheck::~MDTTubeCheck() +{ +} + + +dqm_core::Algorithm* +MDTTubeCheck::clone() +{ + return new MDTTubeCheck(*this); +} + + +dqm_core::Result* +MDTTubeCheck::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * histogram(0); + TH1 * refhist(0); + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double bin_threshold; + double refcheck; + double greenTh; + double redTh; + double LowStatLevel; + try { + bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "BinThreshold", config.getParameters()); + refcheck = dqm_algorithms::tools::GetFirstFromMap( "ReferenceCheck", config.getParameters()); + LowStatLevel = dqm_algorithms::tools::GetFirstFromMap( "LowStatLevel", config.getParameters(), 10); + minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + redTh = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + if (refcheck>0) { + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + if (histogram->GetNbinsX() != refhist->GetNbinsX() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different number of bins!" ); + } + } + + //Check of statistics + if (histogram->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<histogram->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< histogram->GetEntries()<< " entries "); + + int NewDead_count = 0; + int StillDead_count = 0; + int Revived_count = 0; + int LowStat_count = 0; + std::vector<int> range; + if (histogram->GetDimension() == 1){ + range = dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + } else { + ERS_INFO("Histogram has not dimension 1 : " <<histogram->GetName()); + throw dqm_core::Exception( ERS_HERE, histogram->GetName() ); + } + + std::vector<int> Tubes; + for ( int i = range[0]; i <= range[1]; ++i ) { + double content = histogram->GetBinContent(i); + if (content == LowStatLevel) { + ++LowStat_count; + } else if (content != 0.) { + if (refcheck>0) { + double RefCont = refhist->GetBinContent(i); + if ((content < bin_threshold) && ((RefCont >= bin_threshold) || (RefCont == LowStatLevel))) { + ++NewDead_count; + Tubes.push_back(i); + } else if ((content < bin_threshold) && ((RefCont < bin_threshold) || (RefCont == LowStatLevel))) { + ++StillDead_count; + } else if ((content >= bin_threshold) && (RefCont < bin_threshold)) { + ++Revived_count; + } + } else { + if (((content < bin_threshold) ) ) { + ++NewDead_count; + Tubes.push_back(i); + } + } + } + } + ERS_DEBUG(1,"Number of bins " << name << " different from a treshold of " << bin_threshold << " is " << NewDead_count ); + + dqm_core::Result* result = new dqm_core::Result(); + if (LowStat_count > 0) result->tags_["NTubes_withLowStat"] = LowStat_count; + if (Revived_count > 0) result->tags_["NTubes_Revived"] = Revived_count; + result->tags_["NewDead_Tubes"] = NewDead_count; + if (Tubes.size()>0) { + for (int k=0; k<(int)Tubes.size(); k++) { + std::string ToDB="ChangedStatusTube_"; + char* nn; + asprintf(&nn, "%i", k+1); + ToDB += nn; + result->tags_[ToDB] = Tubes[k]; + ERS_DEBUG(1,"MDT Tube which changed status: "<<ToDB<<" = "<<Tubes[k] ); + } + } + if (NewDead_count >= redTh) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } else if ( (NewDead_count > greenTh) || (Revived_count > 0)) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else if (LowStat_count > 0) { + result->status_ = dqm_core::Result::Undefined; + ERS_DEBUG(1,"Undefined"); + } else if (StillDead_count == range[1]) { + //All tubes are still dead + result->status_ = dqm_core::Result::Undefined; + } else { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } + return result; +} + + +void +MDTTubeCheck::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Check if the number of entries in bins is less than BinThreshold and compare with Reference Histo \n"; + message += "Mandatory Parameter: BinThreshold = Look for bins less than BinTreshold; Count number of bins satifying requirement \n"; + message += "Mandatory Parameter: ReferenceCheck = 0 if no check on reference is requested \n"; + message += "Mandatory Green/Red Threshold: NBins = number of bins satifying requirement\n"; + message += "Optional Parameters: LowStatLevel = Level (in y) that means too few statistics for analysis\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " xmin: minimum x range\n"; + message += " xmax: maximum x range\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MDTTubeCheckError.cxx b/DataQuality/dqm_algorithms/src/MDTTubeCheckError.cxx new file mode 100644 index 0000000000000000000000000000000000000000..af81576dd3ba463bef5515151c4399d01a4048c4 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MDTTubeCheckError.cxx @@ -0,0 +1,214 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: MDTTubeCheckError.cxx,v 1.0 2008/31/07 Elena Solfaroli Camillocci +// ********************************************************************** + +#include "dqm_algorithms/MDTTubeCheckError.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TClass.h> +#include <TH1.h> +#include <TAxis.h> +//#include <TF1.h> +//#include <TProfile.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + + +static dqm_algorithms::MDTTubeCheckError staticInstance; + + +namespace dqm_algorithms { + +// ********************************************************************* +// Public Methods +// ********************************************************************* + +MDTTubeCheckError::MDTTubeCheckError() + : name("MDTTubeCheckError") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); +} + + +MDTTubeCheckError::~MDTTubeCheckError() +{ +} + + +dqm_core::Algorithm* +MDTTubeCheckError::clone() +{ + return new MDTTubeCheckError(*this); +} + + +dqm_core::Result* +MDTTubeCheckError::execute( const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1* histogram; + TH1* refhist=0; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + if (histogram->GetDimension() >= 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension >= 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //Get Parameters and Thresholds + double minstat; + double bin_threshold; + double nErr; + double LowStatErr; + double LowStatThre; + double refcheck; + double greenTh; + double redTh; + try { + bin_threshold = dqm_algorithms::tools::GetFirstFromMap( "BinThreshold", config.getParameters()); + nErr = dqm_algorithms::tools::GetFirstFromMap( "nErrBin", config.getParameters()); + LowStatErr = dqm_algorithms::tools::GetFirstFromMap( "LowStatErr", config.getParameters(), 99999.); + LowStatThre = dqm_algorithms::tools::GetFirstFromMap( "LowStatThre", config.getParameters(), 0.); + refcheck = dqm_algorithms::tools::GetFirstFromMap( "ReferenceCheck", config.getParameters()); + minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), -1); + redTh = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds()); + greenTh = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + //Get Reference Histo + if (refcheck>0) { + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different dimension!" ); + } + if (histogram->GetNbinsX() != refhist->GetNbinsX() ) { + throw dqm_core::BadRefHist( ERS_HERE, name, "Reference VS histo: Different number of bins!" ); + } + } + + //Check of statistics + if (histogram->GetEntries() < minstat ) { + ERS_INFO("Histogram does not satisfy MinStat requirement " <<histogram->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + ERS_DEBUG(1,"Statistics: "<< histogram->GetEntries()<< " entries "); + + int count = 0; + std::vector<int> range; + if (histogram->GetDimension() == 1){ + range = dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + } else { + ERS_INFO("Histogram has not dimension 1 : " <<histogram->GetName()); + throw dqm_core::Exception( ERS_HERE, histogram->GetName() ); + } + if (range[1] == 0) { + ERS_INFO("Empty histogram: " <<histogram->GetName()); + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Undefined; + ERS_DEBUG(1,"Undefined"); + return result; + } + + std::vector<int> Tubes; + int EmptyTubes =0; + int LowStatTubes =0; + for ( int i = range[0]; i <= range[1]; ++i ) { + double Content = histogram->GetBinContent(i); + double ErrCont = histogram->GetBinError(i); + if (ErrCont > LowStatErr) LowStatTubes++; + if (Content+fabs(ErrCont) != 0.) { + if ((Content + nErr*ErrCont) < bin_threshold ) { + if (refcheck>0) { + double RefCont = refhist->GetBinContent(i); + double RefErrCont = refhist->GetBinError(i); + double Diff = fabs(Content - RefCont); + double ErrDiff = sqrt(ErrCont*ErrCont + RefErrCont*RefErrCont); + if (Diff > nErr*ErrDiff) { + ++count; + Tubes.push_back(i); + } + } else { + ++count; + Tubes.push_back(i); + } + } + } else { ++EmptyTubes; } + } + ERS_DEBUG(1,"Number of bins " << name << " different from a treshold of " << bin_threshold << " is " << count ); + + dqm_core::Result* result = new dqm_core::Result(); + result->tags_["NChangedStatusTubes"] = count; + if (Tubes.size()>0) { + for (int k=0; k<(int)Tubes.size(); k++) { + std::string ToDB="ChangedStatusTube_"; + char* nn; + asprintf(&nn, "%i", k+1); + ToDB += nn; + result->tags_[ToDB] = Tubes[k]; + ERS_DEBUG(1,"MDT Tube which changed status: "<<ToDB<<" = "<<Tubes[k] ); + } + } + + if ((EmptyTubes == range[1]) || ((LowStatTubes/range[1]) > LowStatThre)) { + result->status_ = dqm_core::Result::Undefined; + ERS_DEBUG(1,"Undefined"); + } else if (count >= redTh) { + result->status_ = dqm_core::Result::Red; + ERS_DEBUG(1,"Red"); + } else if ( count > greenTh) { + result->status_ = dqm_core::Result::Yellow; + ERS_DEBUG(1,"Yellow"); + } else { + result->status_ = dqm_core::Result::Green; + ERS_DEBUG(1,"Green"); + } + return result; +} + + +void +MDTTubeCheckError::printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: Check if the number of entries in bins is less than BinThreshold and compare with Reference Histo \n"; + message += "Mandatory Parameter: BinThreshold: Look for bins less than BinTreshold; Count number of bins satifying requirement \n"; + message += "Mandatory Parameter: nErrBin: n-sigma of acceptance for check with the BinTreshold \n"; + message += "Mandatory Parameter: ReferenceCheck: 0 if no check on reference is requested \n"; + message += "Mandatory Green/Red Threshold: NBins: number of bins satifying requirement\n"; + message += "Optional Parameters: MinStat = Minimum histogram statistics needed to perform Algorithm\n"; + message += " LowStatErr = error threshold for bin with too low statistics \n"; + message += " LowStatThre = threshold for fraction of bins with too low statistics \n"; + message += " xmin: minimum x range\n"; + message += " xmax: maximum x range\n"; + message += "\n"; + + out << message; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/MaskedBinRow.cxx b/DataQuality/dqm_algorithms/src/MaskedBinRow.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8234deec3834473d334a21ee55e4002f1648c5bc --- /dev/null +++ b/DataQuality/dqm_algorithms/src/MaskedBinRow.cxx @@ -0,0 +1,221 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file MaskedBinRow.cxx + * \author R. Calkins + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/MaskedBinRow.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH2.h> +#include <TF1.h> +#include <TClass.h> +#include <math.h> +#include <ers/ers.h> + + +#include <dqm_core/AlgorithmManager.h> +static dqm_algorithms::MaskedBinRow myInstance; + + +dqm_algorithms::MaskedBinRow::MaskedBinRow() +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm( "MaskedBinRow", this ); +} + +dqm_algorithms::MaskedBinRow::~MaskedBinRow() +{ +} + +dqm_algorithms::MaskedBinRow * +dqm_algorithms::MaskedBinRow::clone() +{ + return new MaskedBinRow(); +} + + +dqm_core::Result * +dqm_algorithms::MaskedBinRow::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH2 * histogram; + + if(object.IsA()->InheritsFrom( "TH2" )) { + histogram = (TH2*)&object; + if (histogram->GetDimension() != 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension != 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH2"); + } + + + int maskedbin = dqm_algorithms::tools::GetFirstFromMap( "MaskedBin", config.getParameters()); + int testrows = dqm_algorithms::tools::GetFirstFromMap( "TestRows", config.getParameters(), 0); + int okbin = dqm_algorithms::tools::GetFirstFromMap( "OkBin", config.getParameters(), -1); + int dorate = dqm_algorithms::tools::GetFirstFromMap( "DoRate", config.getParameters(), 0); + int checkstrip = dqm_algorithms::tools::GetFirstFromMap( "CheckStrip", config.getParameters(), 0); + int useReference = dqm_algorithms::tools::GetFirstFromMap( "UseReference", config.getParameters(), 0); + + TH2* refhist=0; + if (useReference) { + refhist = static_cast<TH2 *>( config.getReference() ); + } + + if(refhist !=0){ + if(refhist->InheritsFrom( "TH2" )) { + if (refhist->GetDimension() != 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "reference histogram dimension != 2 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "reference does not inherit from TH2"); + } + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + } + // if( refhist !=0 and okbin != -1 ){ + // throw dqm_core::BadConfig( ERS_HERE, name, " MaskedBin is outside range" ); + // } + + if ( !testrows && okbin > histogram->GetNbinsX() ) { + throw dqm_core::BadConfig( ERS_HERE, name, " MaskedBin is outside range" ); + } + if ( testrows && okbin > histogram->GetNbinsY() ) { + throw dqm_core::BadConfig( ERS_HERE, name, " MaskedBin is outside range" ); + } + + double gthreshold; + double rthreshold; + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "BinThreshold", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "BinThreshold", config.getGreenThresholds() ); + } + catch( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + + + int redcount = 0; + int yellowcount = 0; + int redrows= 0; + int yellowrows = 0; + + dqm_core::Result* result = new dqm_core::Result(); + int max = 1; + if(testrows){ max += histogram->GetNbinsY(); } else { max += histogram->GetNbinsX(); } + std::vector<float> rowtotal; + rowtotal.clear(); + for(int i =0; i<max; ++i){ rowtotal.push_back(0.0); } + + + for(int i =1; i< histogram->GetNbinsX()+1; ++i){ + for(int j =1; j< histogram->GetNbinsY()+1; ++j){ + if(testrows==0 && j == maskedbin ) continue; + if(testrows==1 && i == maskedbin ) continue; + if( testrows ) { + rowtotal[j-1] += histogram->GetBinContent(i,j); + } else { + rowtotal[i-1] += histogram->GetBinContent(i,j); + } + } + } + // for(int i =0; i< rowtotal.size();++i){ out << rowtotal[i] << " " ; } std::cout<<std::endl; + + // ERS_DEBUG(1,"rowtotal =" << rowtotal) ; + + for(int i =1; i< histogram->GetNbinsX()+1; ++i){ + for(int j =1; j< histogram->GetNbinsY()+1; ++j){ + float bincontent= histogram->GetBinContent(i,j); + //float total =0; // currently unused + if (dorate && testrows) { + bincontent /= rowtotal[j - 1]; + //total = rowtotal[j - 1]; + } + if (dorate && !testrows) { + bincontent /= rowtotal[i - 1]; + //total = rowtotal[i - 1]; + } + + if(bincontent>gthreshold){ + if( testrows==1 && histogram->GetBinContent(maskedbin,j) != 0) continue; + if( testrows==0 && histogram->GetBinContent(i,maskedbin) != 0) continue; + if(refhist != 0){ + if( refhist->GetBinContent(i,j) != 0){ + // out<< histogram->GetName() <<" ("<< i <<"," <<j << ") Bincontent =" <<bincontent << " total=" << total << " real bin content="<< histogram->GetBinContent(i,j)<<std::endl; + if(bincontent < 1.0-gthreshold && bincontent > 1.0-rthreshold ) yellowrows++; + if(bincontent < 1.0-rthreshold ) redrows++; + continue; + } + } + if( testrows==0 && j == okbin){ + if(bincontent < 1.0-gthreshold && bincontent > 1.0-rthreshold ) yellowrows++; + if(bincontent < 1.0-rthreshold ) redrows++; + continue; } + if( testrows==1 && i == okbin){ + if(bincontent < 1.0-gthreshold && bincontent > 1.0-rthreshold ) yellowrows++; + if(bincontent < 1.0-rthreshold ) redrows++; + continue; } + + ERS_DEBUG(1,"Found bin : ("<< i<< ","<<j<<" ) = " << bincontent ) ; + + dqm_algorithms::tools::PublishBin(histogram,i,j,bincontent,result); + if(bincontent>rthreshold){ + ++redcount; + }else{ + ++yellowcount; + } + } + + } + } + + + + + if(checkstrip==0 && redcount >= yellowcount && redcount !=0 ){ + result->tags_["RedBins"] = redcount; + result->status_ = dqm_core::Result::Red; + return result; + } + if(checkstrip==0 && yellowcount !=0 ){ + result->tags_["YellowBins"] = yellowcount; + result->status_ = dqm_core::Result::Yellow; + return result; + } + + if(checkstrip && dorate && redrows >= yellowrows && redrows !=0 ){ + result->tags_["RedRows"] = redrows; + result->status_ = dqm_core::Result::Red; + return result; + } + if(checkstrip && dorate && yellowrows !=0 ){ + result->tags_["YellowRows"] = yellowrows; + result->status_ = dqm_core::Result::Yellow; + return result; + } + + + result->status_ = dqm_core::Result::Green; + return result; + +} + +void +dqm_algorithms::MaskedBinRow::printDescription(std::ostream& out) +{ + + out<<"MaskedBinRow: Does a bins over threshold test in columns/rows but ignores columns/rows if a 'masked' bin has entries\n"<<std::endl; + + out<<"Mandatory Parameter: MaskedBin : This is the row or column that has the 'masked' bins. \n"<<std::endl; + + out<<"Optional Parameter: TestRows : If masked bin has entries, ignore entries in row rather than columns when parameter is set to 1. default = 0 "<<std::endl; + out<<"Optional Parameter: OkBin : This is the row or column that has the 'ok' bin and will be ignored when preforming the algorithm "<<std::endl; + out<<"Optional Parameter: DoRate : This tells the algorithm to check the rate of digital errors rather than an absolute number"<<std::endl; + out<<"Optional Parameter: CheckStrip : To be used with DoRate. Rather than check individual bins, it checks that the fraction of events outside the ok bin is below the threshold."<<std::endl; + out<<"Optional Parameter: UseReference : Reference histogram with entries in the 'ok' bins will be used to indicate that these bins should be ignored when parameter is set to 1. default = 0 "<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/src/OccupancyHoleFinder.cxx b/DataQuality/dqm_algorithms/src/OccupancyHoleFinder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..26086deada86c2361f74073ed1ef7b064e43a19a --- /dev/null +++ b/DataQuality/dqm_algorithms/src/OccupancyHoleFinder.cxx @@ -0,0 +1,420 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file + * \author Justin Griffiths + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/OccupancyHoleFinder.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TH2.h> +#include <TClass.h> +#include <ers/ers.h> + +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <algorithm> +#include <utility> +#include <map> +#include <sstream> +#include <cstdlib> + +#include <dqm_core/AlgorithmManager.h> + + +namespace { + dqm_algorithms::OccupancyHoleFinder MDT( "MDT" ); + dqm_algorithms::OccupancyHoleFinder Default(""); +} + +dqm_algorithms::OccupancyHoleFinder::OccupancyHoleFinder(const std::string &n) + : m_name(n) +{ + + if(m_name.size()) dqm_core::AlgorithmManager::instance().registerAlgorithm( m_name+"_OccupancyHoleFinder", this ); + else dqm_core::AlgorithmManager::instance().registerAlgorithm( "OccupancyHoleFinder", this ); +} + +dqm_algorithms::OccupancyHoleFinder::~OccupancyHoleFinder() +{ +} + +dqm_algorithms::OccupancyHoleFinder * +dqm_algorithms::OccupancyHoleFinder::clone() +{ + return new OccupancyHoleFinder(m_name); +} + + +dqm_core::Result * +dqm_algorithms::OccupancyHoleFinder::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + + const TH2* histo = dynamic_cast<const TH2*> (&object); + if (!histo) { + throw dqm_core::BadConfig(ERS_HERE, name, "Input object is not a TH2"); + } + TH1* histo_medians = getMedian(histo); + int active_lbns = 0; + //map of chamber bin number by number of lbns that it is dead + //more precisely the key is a y-axis bin number, while + //the value is a list of lbns in which the chamber was dead + std::map<int, std::vector<int> > dead_chambers_map; + //map of lbn by number of dead chambers + std::map<int, int> lbn_occupancy; + + double median_threshold; + double min_median; + //double gthreshold; // currently unused + double rthreshold; + try { + median_threshold = dqm_algorithms::tools::GetFirstFromMap( "MedianThreshold", config.getParameters() ); + min_median = dqm_algorithms::tools::GetFirstFromMap( "MinMedian", config.getParameters() ); + rthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getRedThresholds() ); + //gthreshold = dqm_algorithms::tools::GetFromMap( "NBins", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + //if percentage_alive > suppress_thresh, don't print to display + double suppress_thresh=0; + //this should be a bool, if true, then don't print info on web-display + double suppress_chamber=0; + try{ + suppress_thresh = dqm_algorithms::tools::GetFirstFromMap( "SuppressThresh", config.getParameters() ); + suppress_chamber = dqm_algorithms::tools::GetFirstFromMap( "SuppressChamber", config.getParameters() ); + } + catch ( dqm_core::Exception & ex ) { + suppress_thresh=0; + suppress_chamber=0; + } + + for(int ibinx = 1; ibinx != histo->GetNbinsX()+1; ++ibinx){ + float median = histo_medians->GetBinContent(ibinx); + //ignore strips where there are very few statistics + //can configure 'min_median' + if(median < min_median) { + lbn_occupancy[ibinx] = histo->GetNbinsY(); + active_lbns++; + continue; + } + active_lbns++; + int ndead_chambers = 0; + for(int ibiny = 1; ibiny != histo->GetNbinsY()+1; ++ibiny){ + float content = histo->GetBinContent(ibinx, ibiny); + //median_threshold is the percentage of the median strip + //content that an individual bin should satisfy + if(content < median*median_threshold) { + ndead_chambers++; + std::map<int, std::vector<int> >::iterator itr = dead_chambers_map.find(ibiny); + if(itr == dead_chambers_map.end()) { + std::vector<int> lbns; + lbns.push_back(ibinx); + dead_chambers_map.insert( std::make_pair(ibiny, lbns) ); + } + else (*itr).second.push_back( ibinx ); + } + lbn_occupancy[ibinx] = ndead_chambers; + }//ybins + }//xbins + + //Analyze chambers that died during run + dqm_core::Result* result = new dqm_core::Result(); + std::map<std::string,double> tags; + //ensure that we do not write too much info to the webpage + int writes = 0; + if(suppress_chamber==false){ + for(std::map<int, std::vector<int> >::const_iterator itr = dead_chambers_map.begin(); itr != dead_chambers_map.end(); ++itr){ + const std::vector<int> &lbns = (*itr).second; + std::string chamber_name = getChamberName(histo, (*itr).first); + if(writes>100) break; + if( (int) lbns.size() == active_lbns ){ + // out << "Completely dead chamber " << chamber_name << std::endl;; + tags[TString::Format("Dead %s", chamber_name.c_str()).Data()] = -1; + writes++; + } + else { + writes++; + tags[TString::Format("N_lbns %s Dead", chamber_name.c_str()).Data()] = (*itr).second.size()*histo->GetXaxis()->GetBinWidth(1); + std::stringstream ss; + int start = -1; + int last_binx = start; + for(unsigned int ii = 0; ii != lbns.size(); ++ii){ + int ibinx = lbns[ii]; + if(start == -1) { + start = lbns[ii]; + last_binx = start; + ss << histo->GetXaxis()->GetBinLowEdge(ibinx) << " - "; + continue; + } + if(ibinx > last_binx+1){ + ss << histo->GetXaxis()->GetBinLowEdge(last_binx)+histo->GetXaxis()->GetBinWidth(last_binx) << ", "; + ss << histo->GetXaxis()->GetBinLowEdge(ibinx) << " - "; + start = ibinx; + last_binx = start; + continue; + } + if(ii+1 == lbns.size()){ + //last element + ss << histo->GetXaxis()->GetBinLowEdge(ibinx)+histo->GetXaxis()->GetBinWidth(ibinx) << ", "; + } + last_binx = ibinx; + } + //out << "Chamber " << chamber_name << " : " << ss.str() << std::endl; + }//else + } + }//suppress_chamber + + int dead_lbns = 0;//number of strips where occupancy < 90% (configurable) + int start_bin_id = -1; + //int last_bin_id = start_bin_id; // currently unused (because last_lbn is currently unused) + int last_ndead = 0; + int counter = 0;//current entry in lbn_occupancy + for(std::map<int, int>::const_iterator itr = lbn_occupancy.begin(); itr != lbn_occupancy.end(); ++itr, ++counter){ + int bin_id = (*itr).first; + int current_lbn = histo->GetXaxis()->GetBinLowEdge(bin_id); + int start_lbn = 0; + if(start_bin_id > -1) start_lbn = histo->GetXaxis()->GetBinLowEdge(start_bin_id); + else start_lbn = 1; + //int last_lbn = 0; // currently unused + //if(last_bin_id > -1) last_lbn = histo->GetXaxis()->GetBinLowEdge(last_bin_id); + //else last_bin_id = 1; + int lbn_width = histo->GetXaxis()->GetBinWidth(bin_id); + + float percentage_alive = 100*(1-(*itr).second*1./histo->GetNbinsY()); + float last_percentage_alive = 100*(1-last_ndead*1./histo->GetNbinsY()); + //bool good_lbn(true); // currently unused + //A value of dead_lbns>0 causes a red flag. + if(percentage_alive < rthreshold){ + if((*itr).second != histo->GetNbinsY()) dead_lbns++; //do not flag red when entire strip is empty--likely this is not a problem + //good_lbn = false; + //tags[TString::Format("%i-%i", current_lbn, current_lbn+bin_width).Data()] = percentage_alive; + } + + //Attempt to write out in format: + //lbn_i-lbn_j XX% live + if(start_bin_id == -1) { + start_bin_id = bin_id; + //last_bin_id = start_bin_id; + last_ndead = (*itr).second; + continue; + } + + if(last_ndead != (*itr).second || counter+1 == (int) lbn_occupancy.size()){ + if(writes<100){ + if(counter+1 == (int) lbn_occupancy.size() && percentage_alive < suppress_thresh) { + //This should happen on the last strip + tags[TString::Format("%i-%i", start_lbn, current_lbn+lbn_width).Data()] = percentage_alive; + } + else if(last_percentage_alive < suppress_thresh) { + //This happens when the current number of dead bins differs from the last number of dead bins + //Thus we write out the previous percentage at this point + tags[TString::Format("%i-%i", start_lbn, current_lbn-1).Data()] = last_percentage_alive; + } + start_bin_id = bin_id; + //last_bin_id = bin_id; + last_ndead = (*itr).second; + writes++; + } + } + //last_bin_id = bin_id; + } + if(dead_lbns) { + result->status_ = dqm_core::Result::Red; + } + else result->status_ = dqm_core::Result::Green; + + result->tags_ = tags; + return result; + +} + +void +dqm_algorithms::OccupancyHoleFinder::printDescription(std::ostream& /*out*/) +{ + +// out<<"OccupancyHoleFinder: Checks number of bins N sigma away from reference histogram bin value or given Value\n"<<std::endl; +// out<<"Simply Dump the Bin Number/Name of Bin with bin contents as result" << std::endl; +} + +//return histogram with median in each vertical strip +TH1* +dqm_algorithms::OccupancyHoleFinder::getMedian(const TH2* histo) +{ + TH1F* h = new TH1F( TString::Format("%s_median", histo->GetName()),"", histo->GetNbinsX(), histo->GetXaxis()->GetXmin(), histo->GetXaxis()->GetXmax() ); + + for(int ibinx = 1; ibinx != histo->GetNbinsX()+1; ++ibinx){ + std::vector<float> y_bin_vals; + for(int ibiny = 1; ibiny != histo->GetNbinsY()+1; ++ibiny){ + y_bin_vals.push_back(histo->GetBinContent(ibinx, ibiny)); + //out << "THIS CHAMBER :" << ibiny << ": " << getChamberName(histo, ibiny) << std::endl; + } + std::sort( y_bin_vals.begin(), y_bin_vals.end()); + int size = y_bin_vals.size(); + if(size == 0) { + h->SetBinContent(ibinx, 0); + continue; + } + float median = (size%2 == 0 ? (y_bin_vals[size/2-1]+y_bin_vals[size/2])/2 : y_bin_vals[size/2]); + h->SetBinContent(ibinx, median); + } + return h; +} + +std::string +dqm_algorithms::OccupancyHoleFinder::getChamberName(const TH2* histo, int biny){ + + if(m_name == "MDT") return getMDTChamberName(histo, biny); + if(std::string(histo->GetYaxis()->GetBinLabel(biny)).size()) return histo->GetYaxis()->GetBinLabel(biny); + std::stringstream ss; + ss << biny; + return ss.str(); +} + +std::string +dqm_algorithms::OccupancyHoleFinder::getMDTChamberName(const TH2* histo, int biny){ + + std::string name = histo->GetYaxis()->GetBinLabel(biny); + + int count = 0; + while(name.size() == 0 && biny-count >= 1){ + name = histo->GetYaxis()->GetBinLabel(biny-count); + if(name.size() == 0) count++; + } + + std::string hname = histo->GetName(); + char side = hname[15]; + if(name == "BO0" && count == 2){ + //hack around aesthetic choice + name = "BO1"; + count = 0; + } + else if(name == "BO1" && side == 'A'){ + //hack around aesthetic choice + count++; + } + + int phiStat = count+1; + char stat_type = '0'; + int etaStat = atoi(&name[2]); + if(name[0] == 'B'){ + if(name[1] == 'E') { + stat_type = 'E'; + phiStat*=2; + } + else if(name[1] == 'I') { + if( etaStat <= 5){ + if(phiStat%2 == 0 && phiStat <= 10) stat_type = 'S'; + else if(phiStat%2 == 1 && phiStat <= 10) stat_type = 'L'; + else if(phiStat == 11 || phiStat == 16) stat_type = 'R'; + else if(phiStat == 12 || phiStat == 17) stat_type = 'M'; + else if(phiStat == 13 || phiStat == 15 || phiStat == 18) stat_type = 'S'; + else if(phiStat == 14) stat_type = 'L'; + //fix phiStat + if (phiStat > 16) phiStat-=2; + else if (phiStat <=16 && phiStat > 11) phiStat--; + } + else if(etaStat == 6){ + if(phiStat%2 == 0) stat_type = 'S'; + else if(phiStat%2 == 1) stat_type = 'L'; + if( phiStat == 11 || phiStat == 15) stat_type = 'R'; + } + else { + stat_type = 'S'; + phiStat*=2; + } + } + else if(name[1] == 'M') { + if(etaStat <= 3){ + if(phiStat%2==0) stat_type = 'S'; + else stat_type = 'L'; + if(phiStat == 12 || phiStat == 14) stat_type = 'F'; + } + else if(etaStat <= 5){ + if(phiStat%2 == 0) stat_type = 'S'; + else if(phiStat%2 == 1) stat_type = 'L'; + //fix phiStat + if(phiStat>=13) phiStat+=2; + if(phiStat==12) { stat_type = 'L'; phiStat++; } + } + else { + if(phiStat%2 == 0) stat_type = 'S'; + else if(phiStat%2 == 1) stat_type = 'L'; + if(phiStat == 12) {stat_type = 'L'; phiStat=15;} + if(phiStat == 13) {stat_type = 'S'; phiStat=16;} + } + } + else {//'O' + if( etaStat == 0 ) { + stat_type = 'G'; + phiStat = (phiStat == 1? 12 : 14); + side = 'B'; + } + else if(etaStat <=6){ + if(phiStat%2==0) stat_type='S'; + else stat_type = 'L'; + + if(etaStat%2==0 && (phiStat==12||phiStat==14) ) stat_type = 'G'; + else if(etaStat%2==1 && (phiStat==12||phiStat==14)) stat_type = 'F'; + } + else { + etaStat = (phiStat > 2? 8 : 7); + stat_type = (etaStat== 7 ? 'F' : 'G'); + phiStat = (phiStat%2 == 1? 12 : 14); + } + } + + } + else{//Endcap + if(name[1] == 'E'){ + stat_type = 'L'; + etaStat = (phiStat > 3? 2: 1); + if(side == 'A'){ + if(phiStat == 1) phiStat = 5; + else if(phiStat%2 == 0) phiStat = 11; + else phiStat = 13; + } + else{ + if(phiStat == 1) phiStat = 5; + else if(phiStat%2==0) phiStat = 13; + else phiStat = 15; + } + } + else if(name[1] == 'I'){ + if(etaStat<=2){ + if(phiStat%2==0) stat_type = 'S'; + else if(phiStat%2==1) stat_type = 'L'; + } + else if(etaStat<=4){ + stat_type='L'; + phiStat*=2; + phiStat--; + } + else{ + stat_type='L'; + phiStat = (phiStat == 1? 1 : 9); + } + } + else {// 'M' or 'O' + if(phiStat%2==0) stat_type = 'S'; + else stat_type = 'L'; + } + } + + std::string phiStat_str = TString::Format("%i", phiStat).Data(); + if(phiStat_str.size() == 1) phiStat_str = std::string("0")+phiStat_str; + std::string etaStat_c = TString::Format("%i", etaStat).Data(); + name = name.substr(0,2); + name+=stat_type; + name+=etaStat_c; + name+=side; + name+=phiStat_str; + return name; +} diff --git a/DataQuality/dqm_algorithms/src/OutlierAndFlatnessTest.cxx b/DataQuality/dqm_algorithms/src/OutlierAndFlatnessTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2db79db53bd8326628c90c87746e7b387a4cb84e --- /dev/null +++ b/DataQuality/dqm_algorithms/src/OutlierAndFlatnessTest.cxx @@ -0,0 +1,351 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// Checks and removes outliers from TH1-Histos and tests the remaining distribution for flatness. Originally by Steffen Schaepe. + +#include "dqm_algorithms/OutlierAndFlatnessTest.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" + +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/Result.h" + +#include "TMath.h" +#include "TH1.h" +#include "TF1.h" +#include "TH1C.h" +#include "TH2C.h" +#include "TClass.h" + +#include <memory> + +namespace +{ +dqm_algorithms::OutlierAndFlatnessTest OutlierAndFlatnessTest("OutlierAndFlatnessTest"); +} + +dqm_algorithms::OutlierAndFlatnessTest::OutlierAndFlatnessTest(const std::string &name) : name_(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +dqm_algorithms::OutlierAndFlatnessTest *dqm_algorithms::OutlierAndFlatnessTest::clone() +{ + return new OutlierAndFlatnessTest(name_); +} + +dqm_core::Result *dqm_algorithms::OutlierAndFlatnessTest::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + if (!object.IsA()->InheritsFrom("TH1")) { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + std::auto_ptr<TH1> histogram(static_cast<TH1 *>(object.Clone())); // we just checked that this is really a TH1, so we can safely type-cast the pointer + if (histogram->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2"); + } + const bool isOneDimensional = (histogram->GetDimension() == 1); // can only be 1 or 2 after the previous check + + // check for minimum statistics + + const double minstat = tools::GetFirstFromMap("MinStat", config.getParameters(), 1); + if (histogram->GetEntries() < minstat) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + // check if histogram conatins only zeros + + const bool checkZeroContent = static_cast<bool>(tools::GetFirstFromMap("CheckZeroContent", config.getParameters(), 1)); + if (checkZeroContent && (histogram->Integral() == 0) && (histogram->GetEntries() > 0)) { + ERS_DEBUG(1, "Histogram " << histogram->GetName() << " is filled with zeros!"); + dqm_core::Result* result = new dqm_core::Result(dqm_core::Result::Red); + result->tags_["Integral"] = histogram->Integral(); + return result; + } + + // get configuration parameters and set defaults + + const bool checkFlatness = static_cast<bool>(tools::GetFirstFromMap("CheckFlatness", config.getParameters(), 1)); // default: true + const bool fitCircular = static_cast<bool>(tools::GetFirstFromMap("FitCircular", config.getParameters(), 0)); // default: false + const bool ignore0 = static_cast<bool>(tools::GetFirstFromMap("Ignore0", config.getParameters(), 1)); // default: true + + const bool checkSigmaDev = static_cast<bool>(tools::GetFirstFromMap("CheckSigmaDev", config.getParameters(), 1)); // default: true + const double sigmaDev = checkSigmaDev ? tools::GetFirstFromMap("SigmaDev", config.getParameters()) : 0; // only applicable if checkSigmaDev, then mandatory + const bool dontCountSigmaOutliers = checkSigmaDev ? static_cast<bool>(tools::GetFirstFromMap("DontCountSigmaOutliers", config.getParameters(), 0)) : false; // only applicable if checkSigmaDev, default: false + + const bool checkAbsDev = static_cast<bool>(tools::GetFirstFromMap("CheckAbsDev", config.getParameters(), 0)); // default: false + const double absDev = checkAbsDev ? tools::GetFirstFromMap("AbsDev", config.getParameters()) : 0; // only applicable if checkAbsDev, then mandatory + + const bool checkRelDev = static_cast<bool>(tools::GetFirstFromMap("CheckRelDev", config.getParameters(), 0)); // default: false + const double relDev = checkRelDev ? tools::GetFirstFromMap("RelDev", config.getParameters()) : 0; // only applicable if checkRelDev, then mandatory + + const bool checkAbsLimit = static_cast<bool>(tools::GetFirstFromMap("CheckAbsLimit", config.getParameters(), 0)); // default: false + const double absLimit = checkAbsLimit ? tools::GetFirstFromMap("AbsLimit", config.getParameters()) : 0; // only applicable if checkAbsLimit, then mandatory + + const bool normRef = static_cast<bool>(tools::GetFirstFromMap("DivideByReference", config.getParameters(), 0)); // default: false + const bool diffRef = static_cast<bool>(tools::GetFirstFromMap("SubtractReference", config.getParameters(), 0)); // default: false + + // if the checks are to be done against a reference take care of this now + + TH1 *refhist = 0; + if (diffRef || normRef) { + if (diffRef && normRef) { + throw dqm_core::BadConfig(ERS_HERE, name, "Can either divide or subtract reference, not both"); + } + try { + refhist = static_cast<TH1 *>(config.getReference()); + } catch(dqm_core::Exception &ex) { + throw dqm_core::BadRefHist(ERS_HERE, name, "Could not retrieve reference"); + } + if (histogram->GetDimension() != refhist->GetDimension()) { + throw dqm_core::BadRefHist(ERS_HERE, name, "Wrong dimension of reference"); + } + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY())) { + throw dqm_core::BadRefHist(ERS_HERE, name, "Non-matching number of bins of reference"); + } + + // scale reference to the same integral as the test hist + refhist->Sumw2(); + refhist->Scale(histogram->Integral() / refhist->Integral()); + + if (diffRef) histogram->Add(refhist, -1.0); + if (normRef) histogram->Divide(refhist); + } + + const std::vector<int> range = dqm_algorithms::tools::GetBinRange(histogram.get(), config.getParameters()); + const int xminBin = range[0]; + const int xmaxBin = range[1]; + const int yminBin = range[2]; + const int ymaxBin = range[3]; + + int zeroBins = 0; + for (int i = xminBin; i <= xmaxBin; ++i) { + for (int j = yminBin; j <= ymaxBin; ++j) { + if (histogram->GetBinContent(i, j) == 0) ++zeroBins; // count empty or zero bins + } + } + + // compute outlier bins by using a simplified Grubb's test without cutting on a t-distribution but by giving an external threshold defining how many standard deviations a value has to differ from the mean to be classified as an outlier or by giving an absolute threshold for classifying values as outliers + + int totalBadBins = 0; + int totalUncountedBadBins = 0; + double mean = 0; + double stddev = 0; + int currentIteration = 0; + const int maxIterations = 1000; + + const int nBinsX = histogram->GetNbinsX(); + const int nBinsY = histogram->GetNbinsY(); + std::auto_ptr<TH1> knownOutliers(isOneDimensional ? // keep a record of known outliers (histogram is only used to set boolean flags) + static_cast<TH1 *>(new TH1C("knownOutliers", "knownOutliers", nBinsX, 0, nBinsX)) : // save the space for the additional frame of underflow/overflow bins + static_cast<TH1 *>(new TH2C("knownOutliers", "knownOutliers", nBinsX, 0, nBinsX, nBinsY, 0, nBinsY))); // ... but not sure if the savings make up for ugly code + + while (++currentIteration < maxIterations) { // we break earlier if no new outliers are found + int newBadBins = 0; + int newUncountedBadBins = 0; + + // compute the arithmetic mean and standard deviation + int nBins = 0; + double sum = 0; + double sumsqr = 0; + for (int i = xminBin; i <= xmaxBin; ++i) { + for (int j = yminBin; j <= ymaxBin; ++j) { + const bool isOutlier = knownOutliers->GetBinContent(i, j); + if (isOutlier) continue; // skip known outliers + const double binContent = histogram->GetBinContent(i, j); + if ((binContent == 0) && ignore0) continue; // skip zero bins if requested + + ++nBins; + sum += binContent; + sumsqr += binContent * binContent; + } + } + mean = nBins ? (sum / nBins) : 0; // avoid division by zero + stddev = nBins ? std::sqrt(sumsqr / nBins - mean * mean) : 0; // one-pass: sigma^2 = < X^2 > - < X >^2 + + // check how many bins are out of N sigma range (SigmaDev) or out of the absolute dev (AbsDev) or over absolute limit (AbsLimit), count them as (uncounted) outliers and remove them from the histogram + + if (checkRelDev || checkAbsDev || checkAbsLimit || checkSigmaDev) { + for (int i = xminBin; i <= xmaxBin; ++i) { + for (int j = yminBin; j <= ymaxBin; ++j) { + const bool isOutlier = knownOutliers->GetBinContent(i, j); + if (isOutlier) continue; // skip known outliers + const double binContent = histogram->GetBinContent(i, j); + if ((binContent == 0) && ignore0) continue; // skip zero bins if requested + + bool foundOutlier = false; + if (checkAbsLimit && !foundOutlier) { + if (binContent > absLimit) { + ++newBadBins; + foundOutlier = true; + } + } + if (checkAbsDev && !foundOutlier) { + if (std::fabs(binContent - mean) > absDev) { + ++newBadBins; + foundOutlier = true; + } + } + if (checkRelDev && !foundOutlier) { + if (std::fabs(binContent - mean) > (relDev * mean)) { + ++newBadBins; + foundOutlier = true; + } + } + if (checkSigmaDev && !foundOutlier) { + if (std::fabs(binContent - mean) > (sigmaDev * stddev)) { + if (dontCountSigmaOutliers) ++newUncountedBadBins; + else ++newBadBins; + foundOutlier = true; + } + } + if (foundOutlier) { + histogram->SetBinContent(i, j, 0); // ignore this bin in the subsequent fit (below) + histogram->SetBinError(i, j, 0); // ignore this bin in the subsequent fit (below) + knownOutliers->SetBinContent(i, j, true); // ingnore this bin in the next iteration of this loop + } + } // for (int j) + } // for (int i) + } // if (check...) + if ((newBadBins == 0) && (newUncountedBadBins == 0)) break; // we're done + totalUncountedBadBins += newUncountedBadBins; + totalBadBins += newBadBins; + } // while (protection against endless looping) + if (currentIteration == maxIterations) { + throw dqm_core::BadConfig(ERS_HERE, name, "maximum number of iterations reached while searching for outliers"); // should never happen + } + if (totalUncountedBadBins > 0) { + ERS_DEBUG(1, "Histogram " << histogram->GetName() << " has " << totalUncountedBadBins << " bins exceeding sigma limit which are NOT counted as outliers, but which are omitted for calculating mean and stddev"); + } + + // prepare map for results and commit outlier specific parts + std::map<std::string, double> results; // you can set flagging thresholds on any of these result tags + results["Number_of_outlier_bins"] = totalBadBins; + results["Corrected_mean"] = mean; + results["Corrected_standard_deviation"] = stddev; + results["Number_of_bins_equal_zero"] = zeroBins; + + if (checkFlatness) { + if (!isOneDimensional) { + throw dqm_core::BadConfig(ERS_HERE, name, "cannot check 2D histograms for flatness, please set CheckFlatness = 0"); + } + TF1 *occupancyFit = 0; + + const double xminAxis = histogram->GetXaxis()->GetBinLowEdge(xminBin); + const double xmaxAxis = histogram->GetXaxis()->GetBinUpEdge(xmaxBin); + const double width = (xmaxAxis - xminAxis); + const double center = (xmaxAxis + xminAxis) / 2; + + if (fitCircular) { + occupancyFit = new TF1("occupancyFit", "[0]+[1]*sin([3]*(x-[4]-[5]))+[2]*cos(2*[3]*(x-[4]-[5]))"); // poor man's Fourier analysis: first-order sin() plus second-order cos() + occupancyFit->SetParName(0, "constant"); + occupancyFit->SetParName(1, "asym"); + occupancyFit->SetParName(2, "sym"); + occupancyFit->SetParName(3, "scale"); + occupancyFit->SetParName(4, "offset"); + occupancyFit->SetParName(5, "phaseoffset"); + occupancyFit->SetParLimits(5, -0.5 * width, +0.5 * width); + occupancyFit->FixParameter(3, 2 * TMath::Pi() / width); + occupancyFit->FixParameter(4, center - width / 2); + } else { + occupancyFit = new TF1("occupancyFit", "[0]+[1]*(x-[3])+[2]*(x-[3])*(x-[3])"); // parabola: second-order polynomial + occupancyFit->SetParName(0, "constant"); + occupancyFit->SetParName(1, "asym"); + occupancyFit->SetParName(2, "sym"); + occupancyFit->SetParName(3, "offset"); + // shift zero for fit to the center of the distribution + occupancyFit->FixParameter(3, center); + } + + occupancyFit->SetRange(xminAxis, xmaxAxis); + histogram->Fit(occupancyFit, "QNR"); + + double maxBin = 0; + double phaseOffset = 0; + if (fitCircular) { + // compute maximum deviation from sine and cosine distribution at the point of maximum deviation + phaseOffset = occupancyFit->GetParameter("phaseoffset"); + maxBin = center + width / 4 + phaseOffset; + } else { + // compute maximum deviation from quadratic and linear contibutrions in the fit at the edges of the distribution + maxBin = center + width / 2; + } + + const double constant = occupancyFit->GetParameter("constant"); + + double asym = 0; + double sym = 0; + + if (diffRef) { + asym = occupancyFit->GetParameter("asym"); + } else { + const double parBuff = occupancyFit->GetParameter("sym"); + occupancyFit->SetParameter("sym", 0); + asym = std::fabs(occupancyFit->Eval(maxBin) - constant); + occupancyFit->SetParameter("sym", parBuff); + asym = constant ? std::fabs(asym / constant) : 0; + } + + if (diffRef) { + sym = occupancyFit->GetParameter("sym"); + } else { + const double parBuff = occupancyFit->GetParameter("asym"); + occupancyFit->SetParameter("asym", 0); + sym = std::fabs(occupancyFit->Eval(maxBin) - constant); + occupancyFit->SetParameter("asym", parBuff); + sym = constant ? std::fabs(sym / constant) : 0; + if (!fitCircular) { + sym /= 2; + } + } + + const int ndf = occupancyFit->GetNDF(); + const double chisquare = occupancyFit->GetChisquare(); + const double chisquareNDF = (ndf > 0) ? (chisquare / ndf) : 0; // prevent fits with no degrees of freedom from returning NaN or INF. + + // commit flatness specific results to result map + results["Max_rel_sym_deviation"] = sym; + results["Max_rel_asym_deviation"] = asym; + results["Chisquare_ndf"] = chisquareNDF; + results["Phase_offset"] = phaseOffset; + + delete occupancyFit; + } // if (checkFlatness) + + // compare with given thresholds and compute DQ status + return tools::MakeComparisons(results, config.getGreenThresholds(), config.getRedThresholds()); // this utility function handles all threshold comparisons +} + +void dqm_algorithms::OutlierAndFlatnessTest::printDescription(std::ostream& out) +{ + out << name_ << ": Checks TH1-inherited histograms for bins which lie either Nsigma or AbsDev away from the mean (by default excludes bins with zero entries) or which exceed a given limit and removes them from the distribution.\n" + "Remaining (corrected for outliers) distribution is fitted with either a quadratic or a sinusoidal function (option FitCircular) and symmetric and asymmetric deviations from a flat distribution are computed by evaluating the quadratic and linear fit contributions respectively.\n" + "Parameters:\n" + "\tFitCircular:\tFit sinoidal function instead of quadratic. This is usefull for distributions expected to show circular behaviour (e.g. phi distributions) (default 0).\n" + "\tCheckFlatness:\tThis switch can be used to disable the flatness test and just check for outliers (default 1).\n" + "\tCheckAbsDev:\tCheck for absolute deviation from mean (default 0).\n" + "\tCheckRelDev:\tCheck for relative deviation from mean (default 0).\n" + "\tCheckAbsLimit:\tCheck for values exceeding given absolute limit (default 0).\n" + "\tCheckSigmaDev:\tCheck for deviation in units of standard deviations from mean (default 1).\n" + "\tDontCountSigmaDev:\tBins deviating by a given number of standard deviations are removed from the distribution for mean and flatness computation, but not counted as outliers (default 0).\n" + "\tCheckZeroContent:\tIf set to 1 the algorithm will check whether the histogram is filled with only zeros and return red in this case. WARNING this uses the TH1::Integral function which seems to be problematic in Lightweigth Histograms. (default 1).\n" + "\tMinStat:\tMinimum Statistics for the histogram to be checked (default 1).\n" + "\txmin and/or xmax:\tRestrict all counting and fitting to this x-axis interval (default: full axis range).\n" + "\tIgnore0:\tBins with 0 content are ignored for outlier computation (ignored for flatness-test anyway) (default 1).\n" + "\tSigmaDev:\tNumber of Standard Deviations a single bin has to differ from the mean of the distribution to be classified as outlier. Has to be given if \"CheckSigmaDev\" is set to 1. (default 5)\n" + "\tAbsDev:\tAbsolute value a single bin has to differ from the mean of the distribution to be classified as outlier. Has to be given if \"CheckAbsDev\" is set to 1.\n" + "\tRelDev:\tFraction of the mean value a single bin has to differ from the mean of the distribution to be classified as outlier (i.e. a bin is classified as outlier if it deviates more than |AbsDev*mean| from the mean of the distribution). Has to be given if \"CheckRelDev\" is set to 1.\n" + "\tAbsLimit:\tAbsolute limit a single bin has to exceed to be classified as outlier. Has to be given if \"CheckAbsLimit\" is set to 1.\n" + "\tDivideByReference:\tDivide test histogram by reference histogram and perform checks on the resulting ratio. (default 0)\n" + "\tSubtractReference:\tSubtract reference histogram from test histogram and perform checks on the resulting difference. Carefull! This yields pretty unstable results for the flatness tests! (default 0)\n" + "Thresholds:\n" + "\tNumber_of_outlier_bins:\tNumber of bins classified as outliers using the given thresholds.\n" + "\tCorrected_mean:\tMean of distribution ignoring outliers.\n" + "\tCorrected_standard_deviation:\tStandard Deviation of distribution ignoring outliers.\n" + "\tMax_rel_sym_deviation:\tMaximum relative symmetric deviation from a flat distribution.\n" + "\tMax_rel_asym_deviation:\tMaximum relative asymmetric deviation from a flat distribution.\n" + "\tNumber_of_bins_equal_zero:\tNumber of Bins with zero content." << std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/PassInput.cxx b/DataQuality/dqm_algorithms/src/PassInput.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a270dfcf3c342a6ee6019f9d49624adad6d95dc3 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/PassInput.cxx @@ -0,0 +1,118 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file PassInput.cxx takes the input and returns it in dqm_core::Result. This is intended to act as a way of getting histograms + * and configuration information to a summary maker, in order to perform multi-input analysis. + * \author Evan Wulf + */ + +#ifndef DQM_ALGORITHMS_PASSINPUT_CXX +#define DQM_ALGORITHMS_PASSINPUT_CXX + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/PassInput.h> + +#include <TClass.h> +#include <map> + +#include <dqm_core/AlgorithmManager.h> + +#ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST +static dqm_algorithms::PassInput myInstance; +#endif // + +dqm_algorithms::PassInput::PassInput( ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("PassInput", this); +} + +dqm_algorithms::PassInput::~PassInput() +{ +} + +dqm_algorithms::PassInput * +dqm_algorithms::PassInput::clone() +{ + + return new PassInput(); +} + + +dqm_core::Result * +dqm_algorithms::PassInput::execute(const std::string & name, + const TObject& object, + const dqm_core::AlgorithmConfig& config ) +{ + dqm_core::Result* result = new dqm_core::Result(); + std::string tagName; + + if( (!object.IsA()->InheritsFrom( "TH1" )) && (!object.IsA()->InheritsFrom( "TObjArray" )) ) { + throw dqm_core::BadConfig( ERS_HERE, name, "input object does not inherit from either TH1 or TObjArray"); + } + + //Pass this input object pointer + TObject* resultObject = object.Clone(); + result->object_ = (std::auto_ptr<TObject>)resultObject; + + //Pass the config as a series of tags (with labels embedded in the strings): + //First the options: + std::map<std::string,double> configParametersMap = config.getParameters(); //Copy needed to avoid runtime errors. AlgConfig needs to return map by reference, which it does not do. + if (!configParametersMap.empty()){ + for ( std::map<std::string,double>::const_iterator paramIter = configParametersMap.begin(); + paramIter != configParametersMap.end(); ++paramIter ) { + // if( paramIter->second.empty() ) { + // //Could just drop this, or throw an error, but will keep and label as empty for now + // tagName="EmptyParameter--" + paramIter->first; + // result->tags_[tagName] = -1.; + // continue; + // } + // if ( paramIter->second.size() == 1 ) { + tagName="ConfParameter--" + paramIter->first; + result->tags_[tagName] = paramIter->second; + // } + // else { + // int i=0; + // for( std::vector<double>::const_iterator valueIter = paramIter->second.begin(); + // valueIter != paramIter->second.end(); valueIter++ ) { + // char numStr[32]; + // sprintf(numStr,"%d",i); + // tagName="ConfParameter["+(numStr+("]--"+ paramIter->first)); + // result->tags_[tagName] = *valueIter; + // } + // } + } + } + //Now the Green Thresholds: + std::map<std::string,double> greenThreshMap = config.getGreenThresholds(); //Copy needed to avoid runtime errors. + if (!greenThreshMap.empty()) { + for ( std::map<std::string,double>::const_iterator itr = greenThreshMap.begin(); + itr != greenThreshMap.end(); ++itr ){ + tagName = "GThreshold--"+itr->first; + result->tags_[tagName] = itr->second; + } + } + //Finally, the Red Thresholds: + std::map<std::string,double> redThreshMap = config.getRedThresholds(); //Copy needed to avoid runtime errors. + if (!redThreshMap.empty()) { + for ( std::map<std::string,double>::const_iterator itr = redThreshMap.begin(); + itr != redThreshMap.end(); ++itr ){ + tagName = "RThreshold--"+itr->first; + result->tags_[tagName] = itr->second; + } + } + + //No checks are done, so the result should be undefined: + result->status_ = dqm_core::Result::Undefined; + + return result; +} + +void +dqm_algorithms::PassInput::printDescription(std::ostream& out) +{ + out<<"PassInput: Minimal algorithm to pass its input histogram through to its result." << std::endl; + +} + +#endif // #ifndef DQM_ALGORITHMS_PASSINPUT_CXX diff --git a/DataQuality/dqm_algorithms/src/ReferenceMasking.cxx b/DataQuality/dqm_algorithms/src/ReferenceMasking.cxx new file mode 100644 index 0000000000000000000000000000000000000000..064b1d0851ce1e33ce08e12342f1ef2ab6c41124 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/ReferenceMasking.cxx @@ -0,0 +1,134 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file ReferenceMasking.cxx checks an histogram with a specified algorithm, after summing to input histograms the reference histogram + * \author andrea.dotti@cern.ch + */ + +#include <dqm_algorithms/ReferenceMasking.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TClass.h> +#include <TObjArray.h> +#include <dqm_core/AlgorithmManager.h> + +namespace { + static dqm_algorithms::ReferenceMasking Bins_GreaterThan_Threshold("Bins_GreaterThan_Threshold"); + static dqm_algorithms::ReferenceMasking BinsDiffFromAvg("Bins_Diff_FromAvg"); +} + +dqm_algorithms::ReferenceMasking::ReferenceMasking(const std::string& name ) : name_(name) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("ReferenceMasking_"+name,this); +} + +dqm_algorithms::ReferenceMasking* +dqm_algorithms::ReferenceMasking::clone() +{ + return new ReferenceMasking(name_); +} + +dqm_core::Result* +dqm_algorithms::ReferenceMasking::execute(const std::string& name, const TObject& object, const dqm_core::AlgorithmConfig& config) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)(object.Clone()); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEffectiveEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + delete histogram; + return result; + } + + double coeff = dqm_algorithms::tools::GetFirstFromMap("C",config.getParameters(), 0); + + TH1* refhist; + try { + refhist = static_cast<TH1 *>( config.getReference() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadRefHist(ERS_HERE,name," Could not retreive reference"); + } + if (histogram->GetDimension() != refhist->GetDimension() ) { + throw dqm_core::BadRefHist( ERS_HERE, "Dimension", name ); + } + if ((histogram->GetNbinsX() != refhist->GetNbinsX()) || (histogram->GetNbinsY() != refhist->GetNbinsY()) || refhist->GetNbinsZ() != histogram->GetNbinsZ() ) { + throw dqm_core::BadRefHist( ERS_HERE, "number of bins", name ); + } + ERS_DEBUG(2,"Masking bins according to reference. Will set content to"<<coeff); + + for ( Int_t binx=histogram->GetXaxis()->GetFirst() ; binx<=histogram->GetXaxis()->GetLast();++binx) + { + for ( Int_t biny=histogram->GetYaxis()->GetFirst() ; biny<=histogram->GetYaxis()->GetLast();++biny) + { + for ( Int_t binz=histogram->GetZaxis()->GetFirst() ; binz<=histogram->GetZaxis()->GetLast();++binz) + { + if ( refhist->GetBinContent(binx,biny,binz) != 0 ) + { + ERS_DEBUG(3,"Found a bin in reference with entries !=0, set content of bin ("<<binx<<","<<biny<<","<<binz<<") with "<<coeff); + histogram->SetBinContent( binx , biny, binz , coeff ); + } + } + } + } + + + + //Now prepare to run the real algorithm... + ERS_DEBUG(2,"Running algorithm: "<<name_); + dqm_core::Algorithm* subalgorithm; + try { + subalgorithm = dqm_core::AlgorithmManager::instance().getAlgorithm( name_ ); + } + catch ( dqm_core::AlgorithmNotFound& ex ) + { + ERS_DEBUG(2,"Cannot find algorithm:"+name_); + throw dqm_core::BadConfig(ERS_HERE,name,"Cannot Find sub-algorithm:"+name_); + } + dqm_core::Result* result = subalgorithm->execute( name , *histogram , config); + ERS_DEBUG(2,"Sub algorithm returns:"<<*result); + //Add modified histogram to result + TObject* robject = result->getObject(); + if ( !robject ) //No object defined, add this + { + ERS_DEBUG(2,"Adding modified histogram in result"); + result->object_.reset(histogram); + } + else //Transform the object_ in TObjArray (if needed) and add this result + { + ERS_DEBUG(2,"Result already have an associated TObject, appending modified histogram"); + if ( robject->IsA()->InheritsFrom("TObjArray") ) //It is already an array add it... + { + static_cast<TObjArray*>(robject)->Add( histogram ); + //Check in again + result->object_.reset( robject ); + } + else + { + TObjArray* array = new TObjArray( 2 ); + array->AddAt( robject , 0 ); + array->AddAt( histogram , 1 ); + //Check in again + result->object_.reset( array ); + } + ERS_DEBUG(2,"Result now have a TObjArray of size:"<<static_cast<TObjArray*>(result->getObject())->GetEntries()); + } + return result; +} + + +void dqm_algorithms::ReferenceMasking::printDescription(std::ostream& out) { + out<<"ReferenceMasking_"+name_+" : Performst the "+name_+" algorithm after using the reference histogram to mask bins. I.e. Perform TH1::SetBinContent(bin,c) for all bins of reference with entries!=0. c (default 0) can be set via configuration. Adds to the output TObject list the modified input histogram."<<std::endl; + out<<"Optional Parameter : MinStat : Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter : C : The value of the content of the masked bin. Default c=0"<<std::endl; + +} diff --git a/DataQuality/dqm_algorithms/src/RepeatAlgorithm.cxx b/DataQuality/dqm_algorithms/src/RepeatAlgorithm.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9faf464c70ca80915c35d28bcdedb9621b8c473e --- /dev/null +++ b/DataQuality/dqm_algorithms/src/RepeatAlgorithm.cxx @@ -0,0 +1,165 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ********************************************************************** +// $Id: RepeatAlgorithm.cxx,v 1.5 2009-05-07 14:45:54 ponyisi Exp $ +// ********************************************************************** + +#include "dqm_algorithms/RepeatAlgorithm.h" +#include "dqm_core/LibraryManager.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "dqm_core/test/DummyAlgorithmConfig.h" + +#include <iostream> +#include <boost/scoped_ptr.hpp> + +#include <TCollection.h> +#include <TDirectory.h> +#include <TFile.h> +#include <TGraph.h> +#include <TKey.h> + +namespace { + dqm_algorithms::RepeatAlgorithm instance; +} + +namespace dqm_algorithms{ + +RepeatAlgorithm:: +RepeatAlgorithm( const RepeatAlgorithm& ) : + subalg_() { +} + +RepeatAlgorithm:: +RepeatAlgorithm() +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("RepeatAlgorithm", this); +} + +RepeatAlgorithm:: +~RepeatAlgorithm() +{ +} + +dqm_core::Algorithm* +RepeatAlgorithm:: +clone() +{ + return new RepeatAlgorithm(*this); +} + +void +RepeatAlgorithm:: +printDescription(std::ostream& out) +{ + std::string message; + message += "\n"; + message += "Algorithm: RepeatAlgorithm\n"; + message += "Description: Repeats the specified algorithm for each input reference.\n"; + message += "Parameters: AuxAlgName--xxx: run algorithm xxx\n"; + message += " RepeatAlgorithm--ResultsNEntries: return # of entries of reference histogram as a result\n"; + + out << message; +} + + +dqm_core::Result* +RepeatAlgorithm:: +execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& config ) +{ + dqm_core::Result::Status status(dqm_core::Result::Undefined); + std::map<std::string,double> tags; + std::unique_ptr<TObjArray> returnObjs(new TObjArray); + + if (!subalg_.get()) { + // rely on requested subalg not changing over time + std::string subalgname(dqm_algorithms::tools::ExtractAlgorithmName(config)); + try { + subalg_.reset(dqm_core::AlgorithmManager::instance().getAlgorithm(subalgname)); + } + catch (dqm_core::Exception& ex) { + throw dqm_core::BadConfig( ERS_HERE, "RepeatAlgorithm", ex.what(), ex ); + } + } + TObject* ref(0); + try { + ref = config.getReference(); + } catch (dqm_core::BadConfig &) { + throw dqm_core::BadConfig( ERS_HERE, "RepeatAlgorithm", "No references defined for RepeatAlgorithm - this makes no sense" ); + } + const TCollection* listptr(dynamic_cast<const TCollection*>(ref)); + if (!listptr) { + throw dqm_core::BadConfig( ERS_HERE, "RepeatAlgorithm", "Reference needs to be a TCollection" ); + } + TIter itr(listptr); + while ( TObject* ireference = itr.Next() ) { + boost::scoped_ptr<dqm_core::AlgorithmConfig> subConfig(ConfigureSubAlg(config, ireference)); + dqm_core::Result* subResult = subalg_->execute( name, data, *subConfig ); + if( subResult->status_ != dqm_core::Result::Undefined ) { + status = ( status == dqm_core::Result::Undefined ) ? dqm_core::Result::Green : status; + status = ( subResult->status_ < status ) ? subResult->status_ : status; + } + + std::map<std::string,double>::const_iterator tagsEnd = subResult->tags_.end(); + std::map<std::string,double>::const_iterator tagsIter = subResult->tags_.begin(); + for( ; tagsIter != tagsEnd; ++tagsIter ) { + tags[ireference->GetName() + std::string("|") + tagsIter->first] = tagsIter->second; + } + tags[ireference->GetName() + std::string("|Status")] = subResult->status_; + if ( dqm_algorithms::tools::GetFirstFromMap("RepeatAlgorithm--ResultsNEntries", config.getParameters(), 0) > 0 ) { + TH1* hireference = dynamic_cast<TH1*>(ireference); + if (hireference) { + tags[ireference->GetName() + std::string("|NEntries")] = hireference->GetEntries(); + } else { + throw dqm_core::BadConfig( ERS_HERE, "RepeatAlgorithm", std::string("Reference ") + ireference->GetName() + " is not TH1, yet we want to get # entries" ); + } + } + + if (subResult->getObject()) { + // do nothing here; ROOT handling is terrible + // returnObjs->Add(subResult->getObject()->Clone()); + } + //delete subConfig; + delete subResult; + } + + dqm_core::Result* result = new dqm_core::Result( status ); + result->tags_ = tags; + if (!returnObjs->IsEmpty()) { + result->object_.reset(returnObjs.release()); + } + + return result; +} + +dqm_core::AlgorithmConfig* +RepeatAlgorithm:: +ConfigureSubAlg(const dqm_core::AlgorithmConfig& config, TObject* reference) +{ +// caller owns the returned object + +// what we do: copy reference, params, limits to newly created config +// copy all params except AuxAlgName--blah and RepeatAlgorithm--blah + + auto rv(new dqm_core::test::DummyAlgorithmConfig(reference)); + + for (const auto parVal : config.getParameters()) { + if (parVal.first.find("AuxAlgName--") == std::string::npos + && parVal.first.find("RepeatAlgorithm--") == std::string::npos) { + rv->addParameter(parVal.first, parVal.second); + } + } + for (const auto grthr : config.getGreenThresholds()) { + rv->addGreenThreshold(grthr.first, grthr.second); + } + for (const auto rdthr : config.getRedThresholds()) { + rv->addRedThreshold(rdthr.first, rdthr.second); + } + return rv; +} + + + +}//namespace dqi diff --git a/DataQuality/dqm_algorithms/src/RootFit.cxx b/DataQuality/dqm_algorithms/src/RootFit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..91b03fc386fed340add21c905412a4e45d19b464 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/RootFit.cxx @@ -0,0 +1,338 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file RootFit.cxx does one of the basic fits implemented by ROOT and returns dqm_core::Result + * \author Haleh Hadavand + * \author Cristobal Cuenca Almenar, Novermber 29th 2009 + * \author of Fermi function Matt King and Akimasa Ishikawa, 8th Mar 2010 + */ + +#include <dqm_algorithms/RootFit.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TClass.h> +#include <ers/ers.h> +#include <TROOT.h> +#include <memory> +#include <TMath.h> +#include <dqm_core/AlgorithmManager.h> + + +namespace +{ + dqm_algorithms::RootFit gaussian_fit( "gaus" ); + dqm_algorithms::RootFit linear_fit( "pol1" ); + dqm_algorithms::RootFit landau_fit( "landau" ); + dqm_algorithms::RootFit sinusoid_fit( "sinusoid" ); + dqm_algorithms::RootFit gauspol1_fit( "gauspluspol1" ); + dqm_algorithms::RootFit doublegaussian_fit( "doublegaus" ); + dqm_algorithms::RootFit gausplusexpo_fit( "gausplusexpo" ); + dqm_algorithms::RootFit fermi_fit( "fermi" ); + dqm_algorithms::RootFit flat_fit( "flat" ); +} + +dqm_algorithms::RootFit::RootFit( const std::string & name ) + : name_( name ) +{ + + if (name_ == "gaus"){ + func.reset( new TF1("gaus1","gaus") ); + } + if (name_ == "pol1"){ + func.reset( new TF1("pol11","pol1") ); + } + if (name_ == "landau"){ + func.reset( new TF1("landau1","landau") ); + } + if (name_ == "sinusoid"){ + func.reset( new TF1("sinusoid","[0]*sin(x) + [1]*cos(x)") ); + } + if (name_ == "gauspluspol1"){ + func.reset( new TF1("gauspluspol1","gaus(0)+pol1(3)") ); + } + if (name_ == "doublegaus"){ + func.reset( new TF1("doublegaus","gaus(0)+gaus(3)",0,1) ); + } + if (name_ == "gausplusexpo"){ + func.reset( new TF1("gausplusexpo","gaus(0)+expo(3)",0,1) ); + } + if (name_ == "fermi"){ + func.reset( new TF1("fermi","[0]/(1+exp(([1]-x)/[2]))") ); + } + if (name_ == "flat"){ + func.reset( new TF1("flat","[0]") ); + } + dqm_core::AlgorithmManager::instance().registerAlgorithm( "Simple_"+name +"_Fit", this ); +} + +dqm_algorithms::RootFit::~RootFit() +{ + // totally defeats the purpose of auto_ptr, but fixes a segfault in 5.34 ... + func.release(); +} + +dqm_algorithms::RootFit * +dqm_algorithms::RootFit::clone() +{ + return new RootFit( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::RootFit::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + //std::cout<<"ROOTFIT = calling rootfit with name "<<name<<std::endl; + TH1 * histogram; + if(object.IsA()->InheritsFrom( "TH1" )) + { + histogram = (TH1*)&object; + if (histogram->GetDimension() > 1 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 1 for Fit" ); + } + //if (histogram->GetEffectiveEntries()==0 ){ + //throw dqm_core::BadConfig( ERS_HERE, name, "Histogram is empty: No Fit performed" ); + //} + + } + else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + //std::cout<<"ROOTFIT = Trying to get parameters"<<std::endl; + double xmin = dqm_algorithms::tools::GetFirstFromMap( "xmin", config.getParameters(), histogram->GetXaxis()->GetXmin()); + double xmax = dqm_algorithms::tools::GetFirstFromMap( "xmax", config.getParameters(), histogram->GetXaxis()->GetXmax()); + const bool ignoreFirstLastBin = dqm_algorithms::tools::GetFirstFromMap( "ignoreFirstLastBin", config.getParameters(), 0 ); + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + const bool verbose = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "Verbose", config.getParameters(), 0)); + + const double minSig = dqm_algorithms::tools::GetFirstFromMap( "MinSignificance", config.getParameters(), 0); + + // const bool draw = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "DrawFitCurve", config.getParameters(), 0)); + const double lf = dqm_algorithms::tools::GetFirstFromMap( "LikelihoodFit", config.getParameters(), 0); + + //std::cout << "verbose " << verbose + //<< " draw " << draw + //<< " lf " << lf << std::endl; + + if (histogram->GetEffectiveEntries() < minstat || histogram->GetEffectiveEntries()==0) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + return result; + } + + TAxis *x = histogram->GetXaxis(); + int nbins = x->GetNbins(); + double high = x->GetBinUpEdge(nbins); + double low = x->GetBinUpEdge(0); + + if ( xmin>high || xmin<low || xmax>high || xmax<low) { + throw dqm_core::BadConfig( ERS_HERE, name, "xmin and/or xmax value not in histogram bin range" ); + } + + std::string option; + //Always set option end to avoid making graphics object and drawing it. + //draw fit curve if DrawFitCurve == 1.0 + if (verbose){ + //if( draw ) option = ""; + //else option="N"; + option="N"; + } else { + //if( draw ) option = "Q"; + //else option = "QN"; + option = "QN"; + } + + // Likelihood fit + if( lf == 1.0 ) option += "L"; + else if ( lf == 2.0 ) option += "LL"; + + //Use Minos technique as recommended for better error calculation, if errors are important: + if ( minSig != 0 ) { + option += "E"; + } + //show histo name and fit option for verbose mode + if( verbose ){ + std::cout <<" histo name " << histogram->GetName() << std::endl; + std::cout <<" fit option " << option << std::endl; + } + //std::cout<<"ROOTFIT Trying to do fit"<<std::endl; + if (name_ == "gauspluspol1"){ + func->SetParameters(histogram->GetBinContent(histogram->GetMaximumBin()),histogram->GetMean(),histogram->GetRMS()); + func->SetParNames ("Constant","Mean","Sigma","pol1[0]","pol1[1]"); + } + else if (name_ == "pol1"){ + func->SetParNames ("pol1[0]","pol1[1]"); + } + else if (name_ == "sinusoid") { + func->SetParameters(4.0,-1.0); + func->SetParNames("s1","s2"); + } + else if (name_ == "doublegaus"){ + TF1 f1("f1","gaus",xmin,xmax); + histogram->Fit(&f1,"q"); + double par[6] ; + + f1.GetParameters(par); + func->SetParameters(par); + func->SetParameter(3,histogram->GetBinContent(histogram->GetMaximumBin())); + func->SetParameter(4,histogram->GetMean()); + func->SetParameter(5,par[2]); + func->SetParNames("Constant","Mean","Sigma","Constant1","Mean1","Sigma1"); + /* + const int numsig1 = func->GetParNumber("Sigma1"); + const double sigmaup = dqm_algorithms::tools::GetFirstFromMap( "Sigma_upperLimit", config.getParameters(), 1000000); + func->SetParLimits(numsig1, 0., sigmaup); + */ + } + else if (name_ == "gausplusexpo") { + func->SetParameters(histogram->GetBinContent(histogram->GetMaximumBin()),histogram->GetMean(),histogram->GetRMS()); + func->SetParNames("Constant","Mean","Sigma","ConstantExpo","Slope"); + } + else if (name_ == "fermi") { + func->SetParameter(0,0.99); + func->SetParameter(1,5); + func->SetParameter(2,1); + func->SetParNames("Plateau","Threshold","Resolution"); + } + else if(name_ == "flat") { + if(verbose)std::cout << "set "<<name<< " parameters" << std::endl; + func->SetParNames("Height"); + } +/* + const int numsig = func->GetParNumber("Sigma"); + + if (numsig != -1 ){ + double sigmaup = dqm_algorithms::tools::GetFirstFromMap( "Sigma_upperLimit", config.getParameters(), 1000000); + func->SetParLimits(numsig, 0., sigmaup); + } + */ + + + if(ignoreFirstLastBin) { + int firstNonEmptyBin=0; + int lastNonEmptyBin=0; + for(int i=1 ; i<=nbins ; i++) { + if(histogram->GetBinContent(i)!=0.0) { + firstNonEmptyBin=i; + break; + } + } + for(int i=nbins ; i>=0 ; i--) { + if(histogram->GetBinContent(i)!=0.0) { + lastNonEmptyBin=i; + break; + } + } + + if( lastNonEmptyBin-firstNonEmptyBin>2) { //ensures at least two good non-empty bins + if ( x->GetBinLowEdge(firstNonEmptyBin+1) > xmin ) { + xmin=x->GetBinLowEdge(firstNonEmptyBin+1); + } + if ( x->GetBinUpEdge(lastNonEmptyBin-1) < xmax ) { + xmax=x->GetBinUpEdge(lastNonEmptyBin-1); + } + } + + } + histogram->Fit( func.get(), option.c_str(),"",xmin,xmax ); + if (name_ == "doublegaus") { + double par[6]; + func->GetParameters(par); + if (TMath::Abs(par[2]) > TMath::Abs(par[5])) { + func->SetParNames("Constant1","Mean1","Sigma1","Constant","Mean","Sigma"); + double sigma=func->GetParameter(2); + func->SetParameter(2,fabs(sigma)); + } + else { + func->SetParNames("Constant","Mean","Sigma","Constant1","Mean1","Sigma1"); + double sigma=func->GetParameter(5); + func->SetParameter(5,fabs(sigma)); + } + } + + const int numsig = func->GetParNumber("Sigma"); + if (numsig != -1 ){ + double sigma=func->GetParameter(numsig); + func->SetParameter(numsig,fabs(sigma)); + } + + try { + dqm_core::Result *result= dqm_algorithms::tools::GetFitResult (func.get() , config, minSig ); + return result; + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } +} + +void +dqm_algorithms::RootFit::printDescription(std::ostream& out) +{ + out<<"Simple_"+name_+"_Fit: Does simple "+name_+" fit to histogram and checks fit parameters against thresholds\n"<<std::endl; + if ( name_ == "gaus"){ + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Treshold: Mean : Mean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: AbsMean : AbsMean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Simga : Sigma fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Constant : Constant fit value to give Green/Red Result\n"<<std::endl; + } else if ( name_ == "sinusoid"){ + out<<"The sinusoid fit has the following functional form: s1*sin(x) + s2*cos(x)."<<std::endl + <<"Checks can be configured on both parameters, s1 and s2, with green and red thresholds:"<<std::endl; + } else if ( name_ == "doublegaus"){ + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"smaller width will be assigned to Sigma"<<std::endl; + out<<"Green/Red Treshold: Mean : Mean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: AbsMean : AbsMean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Sigma : Sigma fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Constant : Constant fit value to give Green/Red Result\n"<<std::endl; + out<<"Green/Red Treshold: Mean1 : Mean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: AbsMean1 : AbsMean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Simga1 : Sigma fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Constant1 : Constant fit value to give Green/Red Result\n"<<std::endl; + } else if (name_ == "pol1") { + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Treshold: pol1[0] : Constant linear fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: pol1[1] : Slope linear fit value to give Green/Red Result\n"<<std::endl; + } else if (name_ == "gauspluspol1"){ + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Treshold: Mean : Mean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: AbsMean : AbsMean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Sigma : Sigma fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Constant : Constant fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: pol1[0] : Constant linear fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: pol1[1] : Slope linear fit value to give Green/Red Result\n"<<std::endl; + } else if (name_ == "gausplusexpo"){ + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Treshold: Mean : Mean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: AbsMean : AbsMean fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Sigma : Sigma fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Constant : Constant fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: ConstantExpo : ConstantExpo fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Slope : Slope fit value to give Green/Red Result\n"<<std::endl; + } else if (name_ == "landau") { + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Treshold: MPV : MPV fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Sigma : Sigma fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Treshold: Constant : Constant fit value to give Green/Red Result\n"<<std::endl; + } else if (name_ == "fermi" ) { + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Threshold: Plateau : Plateau fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Threshold: Threshold : Fermi energy fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Threshold: Resolution : Templature fit value to give Green/Red Result\n"<<std::endl; + } + out<<"Optional Parameter: Verbose: Write out fit results to log file (set to 1)"<<std::endl; + out<<"Optional Parameter: LikelihoodFit: Fit with L or LL option if 1 or 2"<<std::endl; + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: MinSignificance : Minimum multiple of the error in fit paramenter by which the parameter must exceed the thresholds"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: SubtractFromMean: value subtracted from XMean before test is applied: allows using AbsXMean for non-zero expected mean"<<std::endl; + out<<"Optional Parameter: ignoreFirstLastBin: ignores the first and last non-empty bin"<<std::endl; +// out<<"Optional Parameter: Sigma_upperLimit: Upper limit on Sigma- lower limit set to 0. and default upper value is 1e^6\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/RootFitGraph.cxx b/DataQuality/dqm_algorithms/src/RootFitGraph.cxx new file mode 100644 index 0000000000000000000000000000000000000000..74fa1fdd47e157793c5286ee88c7962f55c4c69d --- /dev/null +++ b/DataQuality/dqm_algorithms/src/RootFitGraph.cxx @@ -0,0 +1,215 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file RootFitGraph.cxx fits TGraph and returns dqm_core::Result + * \author Akimasa Ishikawa (akimasa.ishikawa), 15th Apr 2010 + * based on Fermi fit in RootFit.cxx by Matt King + */ + +#include <dqm_algorithms/RootFitGraph.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TGraph.h> +#include <TGraphAsymmErrors.h> +#include <TClass.h> +#include <ers/ers.h> +#include <TROOT.h> +#include <memory> +#include <TMath.h> +#include <dqm_core/AlgorithmManager.h> + + +namespace +{ + dqm_algorithms::RootFitGraph fermi_fit( "fermi" ); + dqm_algorithms::RootFitGraph erf_fit( "erf" ); + dqm_algorithms::RootFitGraph flat_fit( "flat" ); +} + +dqm_algorithms::RootFitGraph::RootFitGraph( const std::string & name ) + : name_( name ) +{ + + if (name_ == "fermi"){ + func = std::auto_ptr<TF1> ( new TF1("fermi","[0]/(1+exp(([1]-x)/[2]))") ); + } + if (name_ == "erf"){ + func = std::auto_ptr<TF1> ( new TF1("erf","[0]*TMath::Erf((x-[1])/(sqrt(2.)*[2]))") ); + } + if (name_ == "flat"){ + func = std::auto_ptr<TF1> ( new TF1("flat","[0]") ); + } + dqm_core::AlgorithmManager::instance().registerAlgorithm( "Simple_"+name +"_Fit_Graph", this ); +} + +dqm_algorithms::RootFitGraph::~RootFitGraph() +{ + // totally defeats the purpose of auto_ptr, but fixes a segfault in 5.34 ... + func.release(); +} + +dqm_algorithms::RootFitGraph * +dqm_algorithms::RootFitGraph::clone() +{ + return new RootFitGraph( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::RootFitGraph::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + + //std::cout<<"ROOTFITGRAPH = calling rootfit with name "<<name<<std::endl; + TGraph * graph; + if(object.IsA()->InheritsFrom( "TGraph" )) + { + graph = (TGraph*)&object; + } + else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TGraph" ); + } + + //std::cout<<"ROOTFITGRAPH = trying to get parameters"<<std::endl; + Axis_t xmin = dqm_algorithms::tools::GetFirstFromMap( "xmin", config.getParameters(), graph->GetXaxis()->GetXmin()); + Axis_t xmax = dqm_algorithms::tools::GetFirstFromMap( "xmax", config.getParameters(), graph->GetXaxis()->GetXmax()); + + Axis_t ymin = dqm_algorithms::tools::GetFirstFromMap( "ymin", config.getParameters(), graph->GetYaxis()->GetXmin()); + Axis_t ymax = dqm_algorithms::tools::GetFirstFromMap( "ymax", config.getParameters(), graph->GetYaxis()->GetXmax()); + + double xaxismean = (xmax + xmin)/2.; + double xdiff = xmax - xmin; + double ydiff = ymax - ymin; + + + const double minpoint = dqm_algorithms::tools::GetFirstFromMap( "MinPoint", config.getParameters(), -1); + const bool verbose = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "Verbose", config.getParameters(), 0)); + const double minSig = dqm_algorithms::tools::GetFirstFromMap( "MinSignificance", config.getParameters(), 0); + const bool improve = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "ImproveFit", config.getParameters(), 0)); + + //std::cout << "verbose " << verbose + //<< " draw " << draw + //<< " lf " << lf << std::endl; + //std::cout<<"ROOTFITGRAPH = trying to get num points"<<std::endl; + if (graph->GetN() < minpoint || graph->GetN()==0) { + if(verbose)std::cout << name << " number of points are too small " << graph->GetN() << std::endl; + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientN"] = graph->GetN(); + return result; + } + if(verbose)std::cout << name << " enough number of points " << graph->GetN() << std::endl; + //std::cout<<"ROOTFITGRAPH = trying to get axes"<<std::endl; + TAxis *x = graph->GetXaxis(); + int nbins = x->GetNbins(); + double high = x->GetBinUpEdge(nbins); + double low = x->GetBinUpEdge(0); + + + if ( xmin>high || xmin<low || xmax>high || xmax<low) { + throw dqm_core::BadConfig( ERS_HERE, name, "xmin and/or xmax value not in graph bin range" ); + } + + std::string option; + //Always set option end to avoid making graphics object and drawing it. + //draw fit curve if DrawFitCurve == 1.0 + if (verbose){ + //if( draw == 1.0 ) option = ""; + //else option="N"; + option="N"; + } else { + //if( draw == 1.0 ) option = "Q"; + //else option = "QN"; + option = "QN"; + } + + //Use Minos technique as recommended for better error calculation, if errors are important: + // if both minos and improve are specified ("EM"), minos is used by ROOT automatically + if ( minSig != 0 ) option += "E"; + if ( improve ) option += "M"; + //show histo name and fit option for verbose mode + if( verbose ){ + std::cout <<" graph name " << graph->GetName() << std::endl; + std::cout <<" fit option " << option << std::endl; + } + //std::cout<<"ROOTFITGRAPH = trying to do fits"<<std::endl; + if (name_ == "fermi") { + if(verbose)std::cout << "set "<<name<< " parameters" << std::endl; + func->SetParameter(0,ymax*0.9); + func->SetParameter(1,xaxismean); + func->SetParameter(2,xdiff/50.); + func->SetParNames("Plateau","Threshold","Resolution"); + + func->SetParLimits(0, ymin - 0.1 * ydiff, ymax + 0.1 * ydiff ); + func->SetParLimits(1, xmin, xmax ); + func->SetParLimits(2, 0., xdiff/4. ); + } + else if(name_ == "erf") { + if(verbose)std::cout << "set "<<name<< " parameters" << std::endl; + func->SetParameter(0,ymax*0.9); + func->SetParameter(1,xaxismean); + func->SetParameter(2,xdiff/50.); + func->SetParNames("Plateau","Threshold","Resolution"); + + func->SetParLimits(0, ymin - 0.1 * ydiff, ymax + 0.1 * ydiff ); + func->SetParLimits(1, xmin, xmax ); + func->SetParLimits(2, 0., xdiff/4. ); + } + else if(name_ == "flat") { + if(verbose)std::cout << "set "<<name<< " parameters" << std::endl; + func->SetParNames("Height"); + } +/* + const int numsig = func->GetParNumber("Sigma"); + + if (numsig != -1 ){ + double sigmaup = dqm_algorithms::tools::GetFirstFromMap( "Sigma_upperLimit", config.getParameters(), 1000000); + func->SetParLimits(numsig, 0., sigmaup); + } + */ + + if(verbose)std::cout << "fit "<<name<< " with interval cut " << xmin << " - " << xmax << std::endl; + graph->Fit( func.get(), option.c_str(),"",xmin,xmax ); + + const int numsig = func->GetParNumber("Sigma"); + if (numsig != -1 ){ + double sigma=func->GetParameter(numsig); + func->SetParameter(numsig,fabs(sigma)); + } + + try { + dqm_core::Result *result= dqm_algorithms::tools::GetFitResult (func.get() , config, minSig ); + return result; + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } +} + +void +dqm_algorithms::RootFitGraph::printDescription(std::ostream& out) +{ + out<<"Simple_"+name_+"_Fit_Graph: Does simple "+name_+" fit to graph and checks fit parameters against thresholds\n"<<std::endl; + if (name_ == "fermi" ) { + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Threshold: Plateau : Plateau fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Threshold: Threshold : Fermi energy fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Threshold: Resolution : Templature fit value to give Green/Red Result\n"<<std::endl; + }else if (name_ == "erf" ) { + out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl; + out<<"Green/Red Threshold: Plateau : Plateau fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Threshold: Threshold : mean of gaussian fit value to give Green/Red Result"<<std::endl; + out<<"Green/Red Threshold: Resolution : sigma of gaussian fit value to give Green/Red Result\n"<<std::endl; + } + out<<"Optional Parameter: Verbose: Write out fit results to log file (set to 1)"<<std::endl; + out<<"Optional Parameter: MinPoint: Minimum graph point needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: MinSignificance : Minimum multiple of the error in fit paramenter by which the parameter must exceed the thresholds"<<std::endl; + out<<"Optional Parameter: ImproveFit : IMPROVE is used to avoid local minima"<<std::endl; + out<<"Optional Parameter: xmin: minimum x range"<<std::endl; + out<<"Optional Parameter: xmax: maximum x range"<<std::endl; + out<<"Optional Parameter: SubtractFromMean: value subtracted from XMean before test is applied: allows using AbsXMean for non-zero expected mean"<<std::endl; +// out<<"Optional Parameter: Sigma_upperLimit: Upper limit on Sigma- lower limit set to 0. and default upper value is 1e^6\n"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/SCTTrackTiming.cxx b/DataQuality/dqm_algorithms/src/SCTTrackTiming.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b3fe9a7b66792e0418028fafc1eb00eca7267c0a --- /dev/null +++ b/DataQuality/dqm_algorithms/src/SCTTrackTiming.cxx @@ -0,0 +1,175 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "dqm_algorithms/SCTTrackTiming.h" + +#include <cmath> +#include <iostream> +#include <map> + +#include <TH1.h> +#include <TClass.h> + +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/Result.h" + +static dqm_algorithms::SCTTrackTiming staticInstance; + +namespace dqm_algorithms { + + // ********************************************************************* + // Public Methods + // ********************************************************************* + + void + SCTTrackTiming:: + printDescription(std::ostream& out) + { + std::string message; + message += "\n"; + message += "Algorithm: \"" + name + "\"\n"; + message += "Description: For use with SCT Track Time Bins ONLY!\n"; + message += " Prints the ratio of 010 : 01X hits.\n"; + message += " Prints the mean hit time, with 100 as -1 BunchCrossing (early) and 001 as +1 BunchCrossing (late)\n"; + message += " where 011 would contribute half a hit to 0 BC (timed in) and half a hit to +1 BC (late)\n"; + message += " and the hit patterns 000, 111, and 101 will be ignored.\n"; + message += "\n"; + + out << message; + } + + SCTTrackTiming:: + SCTTrackTiming() + : name("SCTTrackTiming") + , NbinsX(8) + { + dqm_core::AlgorithmManager::instance().registerAlgorithm( name, this ); + } + + + SCTTrackTiming:: + ~SCTTrackTiming() + { + } + + + dqm_core::Algorithm* + SCTTrackTiming:: + clone() + { + return new SCTTrackTiming(*this); + } + + + dqm_core::Result* + SCTTrackTiming:: + execute( const std::string& name, const TObject& data, const dqm_core::AlgorithmConfig& /* config */) + { + //No status flags are set + dqm_core::Result* result = new dqm_core::Result(); + result->status_ = dqm_core::Result::Undefined; + + TH1* h; + if(data.IsA()->InheritsFrom( "TH1" )) { + h = (TH1*)&data; + if (h->GetDimension() > 1 ) { + throw dqm_core::BadConfig( ERS_HERE, name, "Not SCT Time Bins: Hist. Dimension > 1 " ); + } + if (h->GetNbinsX() != 8) { + throw dqm_core::BadConfig( ERS_HERE, name, "Not SCT Time Bins: Hist. NBins != 8 " ); + } + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1"); + } + + //Histogram is assumed to be SCT Time Bins. + NbinsX = 8; + + //Get the ratio & average for hit times + double Hits010 = 0.; + double Hits011 = 0.; + double EarlyHits = 0.; + double InTimeHits = 0.; + double LateHits = 0.; + double AllEntries = 0.; + + double TBin = 0.; + + TBin = h->GetBinContent(0+1); //000 + AllEntries += TBin; + + TBin = h->GetBinContent(1+1); //001 + LateHits += TBin; + AllEntries += TBin; + + TBin = h->GetBinContent(2+1); //010 + Hits010 += TBin; + InTimeHits += TBin; + AllEntries += TBin; + + TBin = h->GetBinContent(3+1); //011 + Hits011 += TBin; + InTimeHits += TBin/2; + LateHits += TBin/2; + AllEntries += TBin; + + TBin = h->GetBinContent(4+1); //100 + EarlyHits += TBin; + AllEntries += TBin; + + TBin = h->GetBinContent(5+1); //101 + AllEntries += TBin; + + TBin = h->GetBinContent(6+1); //110 + EarlyHits += TBin/2; + InTimeHits += TBin/2; + AllEntries += TBin; + + TBin = h->GetBinContent(7+1); //111 + AllEntries += TBin; + + //NOTE: If some quantity cannot be calculated it should not be printed at all. + //Printing a default value will simply skew the scale of history plots. + + if (Hits010 + Hits011 > 0.) { //sufficient entries + double HitBin_ratio = Hits010 / (Hits010 + Hits011); + std::string HitBin_ratio_name = Form("%s_Ratio_010_over_01X", name.c_str()); + result->tags_[HitBin_ratio_name.c_str()] = HitBin_ratio; + } + + if (AllEntries > 0.) { //sufficient entries + double Edge0_ratio = Hits010 / AllEntries; + std::string Edge0_name = Form("%s_Ratio_010_over_XXX", name.c_str()); + result->tags_[Edge0_name.c_str()] = Edge0_ratio; + } + + if (AllEntries > 0.) { //sufficient entries + double Edge1_ratio = Hits011 / AllEntries; + std::string Edge1_name = Form("%s_Ratio_011_over_XXX", name.c_str()); + result->tags_[Edge1_name.c_str()] = Edge1_ratio; + } + + if (AllEntries > 0.) { //sufficient entries + double EdgeX_ratio = (Hits010 + Hits011) / AllEntries; + std::string EdgeX_name = Form("%s_Ratio_01X_over_XXX", name.c_str()); + result->tags_[EdgeX_name.c_str()] = EdgeX_ratio; + } + + if (LateHits + InTimeHits + EarlyHits > 0.) { //sufficient entries + double HitMean_time = (LateHits - EarlyHits) / (LateHits + InTimeHits + EarlyHits); + std::string HitMean_name = Form("%s_MeanHitTimeBC", name.c_str()); + result->tags_[HitMean_name.c_str()] = HitMean_time; + + double HitWidth_time = (LateHits + EarlyHits) / (LateHits + InTimeHits + EarlyHits); + HitWidth_time = std::sqrt(HitWidth_time - HitMean_time*HitMean_time); + std::string HitWidth_name = Form("%s_VarianceHitTimeBC", name.c_str()); + result->tags_[HitWidth_name.c_str()] = HitWidth_time; + } + + return result; + } + +} diff --git a/DataQuality/dqm_algorithms/src/SideBand.cxx b/DataQuality/dqm_algorithms/src/SideBand.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c8413c78c9d97593ade2cb95e5f17a34f5ed6d41 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/SideBand.cxx @@ -0,0 +1,148 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SideBand.h file implements the dqm_algorithms::SideBand base class. + * \author Andrea Dotti +*/ + +#include <dqm_algorithms/SideBand.h> +#include <TH1.h> +#include <TClass.h> +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/Result.h> +#include <ers/ers.h> +#include <string> +#include <sstream> +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::SideBand Absolute( "SideBand_Absolute" ); + dqm_algorithms::SideBand Relative( "SideBand_Relative" ); +} + +dqm_algorithms::SideBand::SideBand(const std::string & name) : name_(name) { + dqm_core::AlgorithmManager::instance().registerAlgorithm(name,this); +} + +dqm_algorithms::SideBand* dqm_algorithms::SideBand::clone() { + return new SideBand( name_ ); +} + +dqm_core::Result* dqm_algorithms::SideBand::execute(const std::string & name , + const TObject & obj, + const dqm_core::AlgorithmConfig & config ) +{ + TH1* histo; + if ( obj.IsA()->InheritsFrom("TH2") || obj.IsA()->InheritsFrom("TH3") ) + { + throw dqm_core::BadConfig( ERS_HERE , name , " dimension > 1 "); + } + if ( obj.IsA()->InheritsFrom("TH1") ) + { + ERS_DEBUG(2,"Got TH1 called: "<<obj.GetName()<<" of type:"<<obj.IsA()->GetName()); + histo=(TH1*)&obj; + } + else + { + throw dqm_core::BadConfig( ERS_HERE ,name , " does not inherit from TH1"); + } + // Configure the DQ algorithm + const bool UseUnderFlow = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("UseUnderFlow", config.getParameters(), 0)); + const bool UseOverFlow = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap("UseOverFlow", config.getParameters(), 0)); + // the following is a duplicate of dqm_algorithms::tools::GetBinRange, but with different parameter names + const double notFound = -99999; + const double xmin = dqm_algorithms::tools::GetFirstFromMap("Min", config.getParameters(), notFound); + const double xmax = dqm_algorithms::tools::GetFirstFromMap("Max", config.getParameters(), notFound); + const int minbin = (xmin == notFound) ? 1 : histo->GetXaxis()->FindBin(xmin); + const int maxbin = (xmax == notFound) ? histo->GetNbinsX() : histo->GetXaxis()->FindBin(xmax); + + double grThr, reThr; // Green and Red thresholds + try + { + grThr = dqm_algorithms::tools::GetFromMap("Threshold",config.getGreenThresholds() ); + reThr = dqm_algorithms::tools::GetFromMap("Threshold",config.getRedThresholds() ); + } + catch ( dqm_core::Exception & ex ) + { + throw dqm_core::BadConfig(ERS_HERE,name,"Paramter: 'Threshold' is mandatory, cannot continue"); + } + + if ( name_== "SideBand_Relative" && (grThr>1.0 || reThr>1.0) ) + //non sense case: compare fraction and threshold >100% + { + throw dqm_core::BadConfig(ERS_HERE,name_,"Configuration Error: Threshold>100%"); + } +#if DEBUG_LEVEL > 1 + std::stringstream configuration; + configuration + << " - UseUnderFlow = " << UseUnderFlow << " - UseOverFlow = " << UseOverFlow + << " - Min = " << xmin << " - Max = " << xmax + << " - Green Threshold = " << grThr << " - Red Threshold = " << reThr; + ERS_DEBUG(2,"Configuration:"<<configuration.str()); +#endif + // Just a translation in something more readable... + const bool AbsoluteValue = ( name_ == "SideBand_Absolute" ); + Double_t tot = histo->Integral( 1, histo->GetNbinsX() ); + Double_t inside = histo->Integral( minbin , maxbin ); + if ( UseUnderFlow ) tot+=histo->GetBinContent(0); + if ( UseOverFlow ) tot+=histo->GetBinContent(histo->GetNbinsX()+1); + Double_t sideband = tot-inside; + if ( !AbsoluteValue ) { // Compare fraction of events in sideband + // if (tot != 0) { + if (tot > 0. || tot < 0.) {// should be safer than != + sideband /= tot; + } + } + ERS_DEBUG(2,"Total:"<<tot<<" SideBand:"<<sideband); + dqm_core::Result * result = new dqm_core::Result; + result->tags_.insert(std::make_pair("TotalIntegral",tot)); + result->tags_.insert(std::make_pair("SideBands",sideband)); + + + if (reThr> grThr) { + if ( sideband>reThr ){ + ERS_DEBUG(1,"[RED] Result : "<<sideband); + result->status_=dqm_core::Result::Red; + return result; + } else if ( sideband > grThr ){ + ERS_DEBUG(1,"[YELLOW] Result : "<<sideband); + result->status_=dqm_core::Result::Yellow; + return result; + } + }else { + if ( sideband < reThr ){ + ERS_DEBUG(1,"[RED] Result : "<<sideband); + result->status_=dqm_core::Result::Red; + return result; + } else if ( sideband < grThr ){ + ERS_DEBUG(1,"[YELLOW] Result : "<<sideband); + result->status_=dqm_core::Result::Yellow; + return result; + } + } + + ERS_DEBUG(1,"[GREEN] Result"); + result->status_=dqm_core::Result::Green; + return result; +} + +void dqm_algorithms::SideBand::printDescription(std::ostream& out){ + std::stringstream msg; + msg<<name_<<": Checks the integral of a histogram outside a specified range "; + if ( name_=="SideBand_Absolute" ) + msg<<" using an absolute threshold."; + else + msg<<" using a relative threshold."; + msg<<"\n\n"; + out << msg.str() << + "Parameter: UseUnderFlow: if != 0 include also underflow bin\n" + "Parameter: UseOverFlow: if != 0 include also overflow bin\n" + "Parameter: Min: Specify Lower limit (unset means full range)\n" + "Parameter: Max: Specify Upper limit (unset means full range)\n" + "Threshold: Threshold: How large or small the sidebands should be.\n" + " The comparison type (greater-than or less-than) depends on\n" + " the relative order of the green and red threshold value." << std::endl; +} diff --git a/DataQuality/dqm_algorithms/src/SkewnessTest.cxx b/DataQuality/dqm_algorithms/src/SkewnessTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..503911caa5b4ddee3b59a537ba5ffa39352bd943 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/SkewnessTest.cxx @@ -0,0 +1,120 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SkewnessTest.cxx checks skewness wrt to a threshold value and returns dqm_core::Result + * \author andrea.dotti@cern.ch + */ + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/SkewnessTest.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <TH1.h> +#include <TF1.h> +#include <TClass.h> +#include <ers/ers.h> +#include <TMath.h> + + +#include <dqm_core/AlgorithmManager.h> + +namespace +{ + dqm_algorithms::SkewnessTest skweness_GreaterThan( "GreaterThan" ); + dqm_algorithms::SkewnessTest skewness_LessThan( "LessThan" ); + dqm_algorithms::SkewnessTest skewness_GreaterThanAbs( "GreaterThanAbs" ); + dqm_algorithms::SkewnessTest skewness_LessThanAbs( "LessThanAbs" ); +} + + +dqm_algorithms::SkewnessTest::SkewnessTest( const std::string & name ) + : name_( name ) +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm("SkewnessTest_"+name,this); +} + +dqm_algorithms::SkewnessTest * +dqm_algorithms::SkewnessTest::clone() +{ + return new SkewnessTest( name_ ); +} + + +dqm_core::Result * +dqm_algorithms::SkewnessTest::execute( const std::string & name, + const TObject & object, + const dqm_core::AlgorithmConfig & config ) +{ + TH1 * histogram; + + if( object.IsA()->InheritsFrom( "TH1" ) ) { + histogram = (TH1*)&object; + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" ); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap( "MinStat", config.getParameters(), -1); + + if (histogram->GetEffectiveEntries() < minstat ) { + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEffectiveEntries"] = histogram->GetEffectiveEntries(); + return result; + } + + double gthreshold; + double rthreshold; + + const int axis = (int) dqm_algorithms::tools::GetFirstFromMap( "Axis", config.getParameters(), 1); + + try { + rthreshold = dqm_algorithms::tools::GetFromMap( "S", config.getRedThresholds() ); + gthreshold = dqm_algorithms::tools::GetFromMap( "S", config.getGreenThresholds() ); + } + catch ( dqm_core::Exception & ex ) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex ); + } + ERS_DEBUG(1,"Axis for skewness calculation:"<<axis); + + Double_t skewness = histogram->GetSkewness( axis ); + Double_t skewness_e = histogram->GetSkewness( axis + 10 ); + + dqm_core::Result* result = new dqm_core::Result(); + ERS_DEBUG(1,"Skewness = "<<skewness<<" +- "<<skewness_e); + result->tags_["Skewness"] = skewness; + result->tags_["ApproxStandardError"]=skewness_e; + + if ( CompareSkewnessTest( name_ , skewness ,gthreshold) ) { + result->status_ = dqm_core::Result::Green; + } else if ( CompareSkewnessTest( name_, skewness, rthreshold) ) { + result->status_ = dqm_core::Result::Yellow; + } else { + result->status_ = dqm_core::Result::Red; + } + + return result; + +} + +bool +dqm_algorithms::SkewnessTest::CompareSkewnessTest(const std::string & type, double value, double threshold) { + + if (type == "GreaterThan") return (value > threshold); + if (type == "LessThan") return (value < threshold); + if (type == "GreaterThanAbs") return ( TMath::Abs(value) > threshold ); + if (type == "LessThanAbs") return ( TMath::Abs(value) < threshold); + return 0; +} + + +void +dqm_algorithms::SkewnessTest::printDescription(std::ostream& out) +{ + out<<"SkewnessTest_"+name_+" : Checks if the Skewness of the distribution is "+name_+" threshold value\n"<<std::endl; + + out<<"Mandatory Green/Red Threshold: S: Value of Skewness"<<std::endl; + + out<<"Optional Parameter: MinStat: Minimum histogram statistics needed to perform Algorithm"<<std::endl; + out<<"Optional Parameter: Axis: Axis along which compute Skewness: 1=X, 2=Y, 3=Z"<<std::endl; + +} + diff --git a/DataQuality/dqm_algorithms/src/TRTAvgEventSizeCheck.cxx b/DataQuality/dqm_algorithms/src/TRTAvgEventSizeCheck.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8335630fac0c50311e0c5cbafedb98f97cafd34b --- /dev/null +++ b/DataQuality/dqm_algorithms/src/TRTAvgEventSizeCheck.cxx @@ -0,0 +1,184 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifdef ONLINE // can only be built in an online environment + +#include "dqm_algorithms/TRTAvgEventSizeCheck.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" + +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmRegistrator.h" +#include "dqm_core/AlgorithmConfig.h" +#include "ers/ers.h" + +#include "ipc/partition.h" +#include "is/inforeceiver.h" +#include "is/callbackinfo.h" +#include "is/infoT.h" + +#include <limits> +#include <cmath> + +namespace /* anonymous */ { + +class TRTBeamConditions : public ISInfoReceiver +{ +public: + static TRTBeamConditions &instance(); + float get(); + virtual ~TRTBeamConditions() {} + +private: + TRTBeamConditions(); + void callback(ISCallbackInfo *info); + +private: + static const char *m_name; + boost::mutex m_mutex; // not really required here because m_value is of primitive type float + float m_value; +}; + +const char *TRTBeamConditions::m_name("beamconditions.hitfractionTRT_longToT"); + +TRTBeamConditions &TRTBeamConditions::instance() +{ + static TRTBeamConditions s_instance; + return s_instance; +} + +float TRTBeamConditions::get() +{ + boost::mutex::scoped_lock lock(m_mutex); + return m_value; +} + +TRTBeamConditions::TRTBeamConditions() : ISInfoReceiver(IPCPartition("initial")), m_mutex(), m_value(0) +{ + try { + subscribe(m_name, &TRTBeamConditions::callback, this); + } catch (daq::is::Exception &ex) { + ERS_LOG("Subscribing to " << m_name << " IS Info failed: " << ex); + } +} + +void TRTBeamConditions::callback(ISCallbackInfo *info) +{ + try { + ISInfoFloat hitfraction; + info->value(hitfraction); + + const long long timestamp = info->time().total_mksec_utc(); + const long long now = OWLTime().total_mksec_utc(); + const long long maxAge = 5 * 60 * 1000000; // five minutes + + boost::mutex::scoped_lock lock(m_mutex); + if (now - timestamp < maxAge) { + m_value = hitfraction.getValue(); + } else { + m_value = 0; // reject old values + } + } catch (daq::is::Exception &ex) { + ERS_LOG("Receiving " << m_name << " IS Info failed: " << ex); + } +} + +dqm_core::AlgorithmRegistrator<dqm_algorithms::TRTAvgEventSizeCheck> __ii__("TRTAvgEventSizeCheck"); + +} // namespace + + + +dqm_algorithms::TRTAvgEventSizeCheck::TRTAvgEventSizeCheck() : lastCollisionsSeen_(boost::posix_time::min_date_time) // never +{ + (void)TRTBeamConditions::instance(); // already initiate the subscription +} + +dqm_algorithms::TRTAvgEventSizeCheck *dqm_algorithms::TRTAvgEventSizeCheck::clone() +{ + return new TRTAvgEventSizeCheck(); +} + +dqm_core::Result *dqm_algorithms::TRTAvgEventSizeCheck::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + if (!object.IsA()->InheritsFrom("TH1")) { + throw dqm_core::BadConfig(ERS_HERE, name, "histogram does not inherit from TH1"); + } + const TH1 &histogram = dynamic_cast<const TH1 &>(object); // should be safe after the previous check + if (histogram.GetDimension() > 1) { + throw dqm_core::BadConfig(ERS_HERE, name, "histogram has more than one dimension"); + } + + const double noiseLimit = dqm_algorithms::tools::GetFirstFromMap("NoiseLimit", config.getParameters()); + const double delaySeconds = dqm_algorithms::tools::GetFirstFromMap("DelayTime", config.getParameters(), 60); + const boost::posix_time::time_duration delayTime = boost::posix_time::seconds(delaySeconds); // same value + + const double hitFraction = TRTBeamConditions::instance().get(); + const bool collisions = (hitFraction > noiseLimit); + const bool unknown = (hitFraction == 0); // the beam monitoring is just starting or the published value is too old + + const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + if (collisions) lastCollisionsSeen_ = now; + const bool acceptLargeEvents = (now <= (lastCollisionsSeen_ + delayTime) || unknown); // also accept large events if the beam monitoring is not working + + const char *avgThresholdName = acceptLargeEvents ? "Avg_Collisions" : "Avg_Noise"; // select which set of thresholds to use + const double avgG = dqm_algorithms::tools::GetFromMap(avgThresholdName, config.getGreenThresholds()); + const double avgR = dqm_algorithms::tools::GetFromMap(avgThresholdName, config.getRedThresholds()); + + double sum = 0; + double sum2 = 0; + int spyReadoutEnabled = 0; + int spyReadoutDisabled = 0; + + for (int i = 1; i <= histogram.GetNbinsX(); ++i) { + const double binContent = histogram.GetBinContent(i); + if (binContent) { // skip zero bins + sum += binContent; + sum2 += binContent * binContent; + ++spyReadoutEnabled; + } else { + ++spyReadoutDisabled; + } + } + + const int &N = spyReadoutEnabled; // just a shorter name for this + const double avg = N ? sum / N : 0; // protect against division by zero + const double rms = N ? std::sqrt(sum2 / N - avg * avg) : 0; // protect against division by zero + + dqm_core::Result *result = new dqm_core::Result; + + if (avg <= 0) result->status_ = dqm_core::Result::Undefined; // negative values should never appear + else if (avg <= avgG) result->status_ = dqm_core::Result::Green; + else if (avg < avgR) result->status_ = dqm_core::Result::Yellow; + else result->status_ = dqm_core::Result::Red; + + result->tags_["Avg"] = avg; + result->tags_["RMS"] = rms; + result->tags_["SpyReadoutDisabled"] = spyReadoutDisabled; + result->tags_["_HitFraction_"] = hitFraction; + result->tags_["_Collisions_"] = collisions; + result->tags_["_AcceptLargeEvents_"] = acceptLargeEvents; + return result; +} + +void dqm_algorithms::TRTAvgEventSizeCheck::printDescription(std::ostream& out) +{ + out << "TRTAvgEventSizeCheck: checks the average event size from the TRT RODs.\n" + "The algorithm applies two different sets of thresholds, depending on whether we have collisions or not.\n" + "Mandatory parameters:\n" + " NoiseLimit: if \"hitfractionTRT_longToT\" is above this value, the algorithm assumes we are having collisions.\n" + "Optional parameters:\n" + " DelayTime: how long after collisions the algorithm still accepts large events (in seconds, default = 60).\n" + "Mandatory thresholds:\n" + " Avg_Collisions: the allowed average event size when we are having collisions.\n" + " Avg_Noise: the allowed average event size when we are not having collisions.\n" + "Results:\n" + " Avg: the average event size, averaged over all RODs in the histogram, excluding the ones with disabled spy readout.\n" + " RMS: the RMS of the average event size distribution, excluding the ones with disabled spy readout.\n" + " SpyReadoutDisabled: the number of RODs with disabled spy readout.\n" + " _HitFraction_: the value of \"hitfractionTRT_longToT\", mirrored as a DQMF result.\n" + " _Collisions_: is \"hitfractionTRT_longToT\" currently above the NoiseLimit?\n" + " _AcceptLargeEvents_: are we still in the DelayTime after collisions?" << std::endl; +} + +#endif // ONLINE diff --git a/DataQuality/dqm_algorithms/src/TRTCheckPeakSimple.cxx b/DataQuality/dqm_algorithms/src/TRTCheckPeakSimple.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d78c5b2c3a328688ed551178ecd1119f0f3239e5 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/TRTCheckPeakSimple.cxx @@ -0,0 +1,138 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file TRTCheckPeakSimple.cxx checks on the most probable value (peak) in the histogram and returns dqm_core::Result + * \author Peter Cwetanski + */ + +#include "dqm_algorithms/TRTCheckPeakSimple.h" +#include "dqm_core/exceptions.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/Result.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "ers/ers.h" + +#include "TClass.h" +#include "TH1.h" +#include "TF1.h" + +#include <cmath> +#include <iostream> +#include <map> + +static dqm_algorithms::TRTCheckPeakSimple staticInstance; + +namespace dqm_algorithms +{ + +TRTCheckPeakSimple::TRTCheckPeakSimple(): name("TRTCheckPeakSimple") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +TRTCheckPeakSimple::~TRTCheckPeakSimple() +{ +} + +dqm_core::Algorithm *TRTCheckPeakSimple::clone() +{ + return new TRTCheckPeakSimple(*this); +} + + +dqm_core::Result *TRTCheckPeakSimple::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + TH1 *histogram; + + if (object.IsA()->InheritsFrom("TH1")) { + histogram = (TH1*) &object; + if (histogram->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 2 "); + } + } else { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + const double minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), -1); + + if (histogram->GetEntries() < minstat) { + // ERS_INFO("Histogram does not satisfy MinStat requirement " << histogram->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + dqm_core::Result *result = new dqm_core::Result(); + + if (histogram->Integral() == 0 && histogram->GetEntries() > 0) { + ERS_DEBUG(1, "Histogram " << histogram->GetName() << " is filled with zeroes!"); + result->status_ = dqm_core::Result::Red; + result->tags_["Integral"] = histogram->Integral(); + return result; + } + + + const int nbinsx = histogram->GetNbinsX(); + const double gthreshold = dqm_algorithms::tools::GetFromMap("PeakPosition", config.getGreenThresholds()); + const double rthreshold = dqm_algorithms::tools::GetFromMap("PeakPosition", config.getRedThresholds()); + const std::vector<int> range = dqm_algorithms::tools::GetBinRange(histogram, config.getParameters()); + const int xmin = range[0]; + const int xmax = range[1]; + + //compute the number of empty bins (or bins=0) + int zerobins = 0; + for (int i = 1; i <= nbinsx; i++) { + if (histogram->GetBinContent(i) == 0) { + zerobins++; + } + } + + //compute the weighted mean + float wmean = 0; + float sum = 0; + float integral = 0; + int counter = 0; + for (int i = xmin; i <= xmax; i++) { + integral += histogram->GetBinContent(i); + sum += i * (histogram->GetBinContent(i)); + counter++; + } + wmean = sum / integral; // make sure that integer division does not truncate decimal of mean + + //find the most probable value (peak) + float maxbinsum = 0; + float binsum = 0; + float peakbin = 0; + float peakpos = 0; + + for (int i = xmin + 1; i <= xmax - 1; i++) { + binsum = histogram->GetBinContent(i - 1) + histogram->GetBinContent(i) + histogram->GetBinContent(i + 1); + if (binsum > maxbinsum) { + maxbinsum = binsum; + if (maxbinsum != 0) { + peakbin = ((i - 1) * histogram->GetBinContent(i - 1) + i * histogram->GetBinContent(i) + (i + 1) * histogram->GetBinContent(i + 1)) / maxbinsum; + peakpos = (histogram->GetBinCenter(i - 1) * histogram->GetBinContent(i - 1) + histogram->GetBinCenter(i) * histogram->GetBinContent(i) + histogram->GetBinCenter(i + 1) * histogram->GetBinContent(i + 1)) / maxbinsum; + } else { + peakbin = 0; + peakpos = 0; + } + } + } + + result->tags_["Weighted_mean"] = wmean; + result->tags_["PeakBin"] = peakbin; + result->tags_["PeakPosition"] = peakpos; + + if (peakpos >= gthreshold) result->status_ = dqm_core::Result::Green; + else if (peakpos > rthreshold) result->status_ = dqm_core::Result::Yellow; + else result->status_ = dqm_core::Result::Red; + return result; +} + +void TRTCheckPeakSimple::printDescription(std::ostream& out) +{ + out << name << ": Checks on the most probable value (peak) in the histogram." << std::endl; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/TRTHistogramHasNonZeroEntries.cxx b/DataQuality/dqm_algorithms/src/TRTHistogramHasNonZeroEntries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5c594a4984eedf4c65370d04093a4643bce2d731 --- /dev/null +++ b/DataQuality/dqm_algorithms/src/TRTHistogramHasNonZeroEntries.cxx @@ -0,0 +1,85 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file TRTHistogramHasNonZeroEntries.cxx checks if histogram has entries that are not zero and returns dqm_core::Result + * \author Peter Cwetanski + */ + +#include "dqm_algorithms/TRTHistogramHasNonZeroEntries.h" +#include "dqm_core/AlgorithmManager.h" +#include "dqm_core/AlgorithmConfig.h" +#include "dqm_core/exceptions.h" +#include "dqm_algorithms/tools/AlgorithmHelper.h" +#include "dqm_core/Result.h" +#include "ers/ers.h" + +#include "TH1.h" +#include "TF1.h" +#include "TClass.h" + +#include <cmath> +#include <iostream> +#include <map> + +static dqm_algorithms::TRTHistogramHasNonZeroEntries staticInstance; + +namespace dqm_algorithms +{ + +TRTHistogramHasNonZeroEntries::TRTHistogramHasNonZeroEntries(): name("TRTHistogram_Has_NonZero_Entries") +{ + dqm_core::AlgorithmManager::instance().registerAlgorithm(name, this); +} + +TRTHistogramHasNonZeroEntries::~TRTHistogramHasNonZeroEntries() +{ +} + +dqm_core::Algorithm *TRTHistogramHasNonZeroEntries::clone() +{ + return new TRTHistogramHasNonZeroEntries(*this); +} + +dqm_core::Result *TRTHistogramHasNonZeroEntries::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config) +{ + TH1 *histogram; + + if (object.IsA()->InheritsFrom("TH1")) { + histogram = (TH1*) &object; + if (histogram->GetDimension() > 3) { + throw dqm_core::BadConfig(ERS_HERE, name, "dimension > 3 "); + } + } else { + throw dqm_core::BadConfig(ERS_HERE, name, "does not inherit from TH1"); + } + + const double minstat = dqm_algorithms::tools::GetFirstFromMap("MinStat", config.getParameters(), -1); + + if (histogram->GetEntries() < minstat) { + // ERS_INFO("Histogram does not satisfy MinStat requirement " << histogram->GetName()); + dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["InsufficientEntries"] = histogram->GetEntries(); + return result; + } + + dqm_core::Result *result = new dqm_core::Result(); + + if (histogram->GetEntries() == 0 || histogram->Integral() == 0) { + ERS_DEBUG(1, "Histogram " << histogram->GetName() << " is Empty"); + result->status_ = dqm_core::Result::Red; + result->tags_["Integral"] = histogram->Integral(); + } else { + ERS_DEBUG(1, "Histogram " << histogram->GetName() << " is Not Empty"); + result->status_ = dqm_core::Result::Green; + result->tags_["Integral"] = histogram->Integral(); + } + return result; +} + +void TRTHistogramHasNonZeroEntries::printDescription(std::ostream& out) +{ + out << name << ": Checks if histogram has entries that are not zero." << std::endl; +} + +} // namespace dqm_algorithms diff --git a/DataQuality/dqm_algorithms/src/TripleGaussCollFit.cxx b/DataQuality/dqm_algorithms/src/TripleGaussCollFit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..775a299e3b6525eafcdae962be177dc0815f8c5b --- /dev/null +++ b/DataQuality/dqm_algorithms/src/TripleGaussCollFit.cxx @@ -0,0 +1,454 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*** Collisions monitoring algorithm by Tudor Costin & Peter Onyisi + +Revision history: + +v1.1a (TC): + +-multLB_writeTags() will now query the bins to get lower and upper good LBs +instead of assuming a 1-1 correspondence between bins and LBs +-added a couple of #ifdef statements: + TC_WORKBENCH - when set, alg. uses a different heade in local mode + This is used for testing purposes ONLY and should never + be used in the live environment. + + PARAM_IS_AREA - when set, the three-Gaussian formula is defined so that the + parameters multiplying the Gaussian exponents represent the + integrated area under the Gaussian; otherwise, they + represent the height of the peaks. + +v1.1 (TC): + +-improved code to pick starting height of Gaussians. Will now query the 1D +histogram for given ranges of ns (was: bin ranges) +-starting zeros are added to the output LB_(#S)_(#F) to improve formatting +-Mean_zero_gaus parameter will now translate the entire function, not just middle peak +-Changed names of some configurable parameters to reflect this. +-All parameters except the heights/areas of gaussians are now fixed by default +-Reasonable(?) limits imposed in case the user overrides the above fixing. + (cannot be overriden at present) + +v1.0a,b(TC) + +-various bug fixes. + +v1.0 (TC): +-first release with multiple LB functionality +-This should actually be labelled v2.0, but too late now + + +*/ + +#ifndef TC_WORKBENCH +#include "dqm_algorithms/TripleGaussCollFit.h" +#include <dqm_core/AlgorithmManager.h> +#include <dqm_core/exceptions.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include "ers/ers.h" + +namespace { + dqm_algorithms::TripleGaussCollFit three_gauss_fit( "default" ); +} + +#else +#include "TripleGaussCollFit_standalone.h" +#endif + +#include "TH2.h" +#include "TClass.h" //shocking that this doesn't fall in by now +#include <iostream> +#include "TMath.h" + + + +//for some reason, FindBin() is not a const method, so I have to discard the const part. Sigh. +Double_t getStartValue(TH1* thehist, Double_t minx, Double_t maxx) { + + Double_t result = 0.0; + int minidx = thehist->FindBin(minx), maxidx = thehist->FindBin(maxx); + for (int idx = minidx; idx <= maxidx; idx++) { + Double_t val = thehist->GetBinContent(idx); + if (val > result) + result = val; + } + + return result; +} + + +const char* fmt = "%0*d"; + +void multLB_writeTags(std::vector<int>* goodLB, dqm_core::Result* result, TH1* thehist) { + + /* This method assumes that the entries in goodLB are in ascending order!! */ + + char buf[10]; + std::string lb_str = "LB_"; + int firstLB = (*goodLB)[0], offset = 1; + unsigned int c = 1, sz = goodLB->size(), psz = (unsigned int) TMath::Log10(sz)+1; + Double_t lo, hi; + + while (c < sz) { + if ((*goodLB)[c] == firstLB + offset) + offset++; + + else { + std::string tagname = lb_str; + //find the low LB + + lo = thehist->GetXaxis()->GetBinLowEdge(firstLB); + //out << "bin " << firstLB << " lower edge is " << lo << std::endl; + + if (lo == TMath::Floor(lo)) + sprintf(buf, fmt, psz, (Int_t)lo); + else + sprintf(buf, fmt, psz, (Int_t)(TMath::Floor(lo))+1); + + tagname += buf; + tagname += "_"; + + hi = thehist->GetXaxis()->GetBinUpEdge(firstLB+offset-1); + //out << "bin " << firstLB+offset-1 << " high edge is " << hi << std::endl; + + if (hi == TMath::Floor(hi)) + sprintf(buf, fmt, psz, (Int_t)(TMath::Floor(hi))-1); + else + sprintf(buf, fmt, psz, (Int_t)TMath::Floor(hi)); + + //sprintf(buf, fmt, psz, firstLB+offset-1); + tagname += buf; + result->tags_ [tagname] = 1.0; + firstLB = (*goodLB)[c]; + offset = 1; + } + + c++; //I've always wanted to write this + } + + lo = thehist->GetXaxis()->GetBinLowEdge(firstLB); + //out << "bin " << firstLB << " lower edge is " << lo << std::endl; + + if (lo == TMath::Floor(lo)) + sprintf(buf, fmt, psz, (Int_t)lo); + else + sprintf(buf, fmt, psz, (Int_t)(TMath::Floor(lo))+1); + //sprintf(buf, fmt, psz, firstLB); + + lb_str += buf; + lb_str += "_"; + hi = thehist->GetXaxis()->GetBinUpEdge(firstLB+offset-1); + if (hi == TMath::Floor(hi)) + sprintf(buf, fmt, psz, (Int_t)(TMath::Floor(hi))-1); + else + sprintf(buf, fmt, psz, (Int_t)TMath::Floor(hi)); + //sprintf(buf, fmt, psz, (*goodLB)[c-1]); + lb_str += buf; + result->tags_ [lb_str] = 1.0; + +} + +/**** + +The following parameters are held fixed by default (whether user specified or using built-in values): + -Mean_zero_gaus (default is 0.0) + -Mean_offzero_gaus (default is 23.2, obtained by empirical fits. Should be overriden for certain detectors!) + -Width_all (default is 4.3, also obtained empirically) + +If they are allowed to float, the following limits are imposed. This is currently not configurable. + -Mean_zero_gaus: specified or default value, plus or minus 5 + -Mean_offzero_gaus: specified or default value, plus or minus 10 + -Width_all: between 1.0 and 10.0 +**/ + +typedef std::map<std::string, double> param_map; +typedef std::map<std::string, double> err_map; + +#define PARAM_IS_AREA //if this is not in, the constants multiplying the Gaussians are defined as max_ht, not integr. area + +namespace dqm_algorithms { + + TripleGaussCollFit::TripleGaussCollFit(const std::string& _name) : name(_name) { + + //Register our instance with the Alg. Manager + gaus3_fn = 0; + dqm_core::AlgorithmManager::instance().registerAlgorithm( "Gaus3_" + name +"_Fit", this ); + + } + + TripleGaussCollFit::~TripleGaussCollFit() { + + if (gaus3_fn != 0) { + delete gaus3_fn; + gaus3_fn = 0; + } + + } + + TripleGaussCollFit* TripleGaussCollFit::clone() { + return new TripleGaussCollFit(name); + } + +// This method probably need not be implemented, but I should have it anyway... + void TripleGaussCollFit::printDescription(std::ostream& out) { + + out << "Gaus3_"+ name +"_Fit: specialized fit for the Tile timining difference plot." << std::endl; + out << "Current parameter values: " << std::endl; + + if (gaus3_fn != 0) + for (int i=0; i < gaus3_fn->GetNpar(); i++) + out << " Param. " << i << ": " << gaus3_fn->GetParName(i) << " , current value: " + << gaus3_fn->GetParameter(i) << std::endl; + + else + out << " execute() has not been called" << std::endl; + + out << "Parameter list: " << std::endl + << " allowFitMean: 1 allows fitting for a shift in the entire function around zero by up to 5ns" << std::endl + << " allowFitMeanNonzeroPeaks: 1 allows fitting of the distance between center and off-center Gaussians" << std::endl + << " allowFitResolution: 1 allows fitting the (shared) width of the Gaussians" << std::endl + << " reportSignificance: 1 reports the central peak significance for each LB as a tag" << std::endl + << " meanZeroPeak: starting or fixed mean of the Gaussian centered at zero" << std::endl + << " meanNonZeroPeaks: starting or fixed mean of the other Gaussians" << std::endl + << " resolutionAll: starting or fixed value of the width of the Gaussians" << std::endl + << " minSignificance: number of events required for checks to be valid, undefined if not set." << std::endl + << " centralPeakMinSignificance: significance of central peak required for a LB to pass threshold; default is 3.0" << std::endl + << " minEvents: number of events required to attempt a fit; default is 5." << std::endl ; + + out << "Currently, no thresholds are defined." << std::endl; + + } + + dqm_core::Result* TripleGaussCollFit::execute (const std::string& /* s */, const TObject& object, const dqm_core::AlgorithmConfig& cfg) { + + TH1* histogram; + if(object.IsA()->InheritsFrom("TH1")) //or this can be done via dynamic casting + { + histogram = (TH1*) &(object); + if (histogram->GetDimension() > 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name, "called with histogram of dimension > 2" ); + } + } + else + throw dqm_core::BadConfig( ERS_HERE, name, "called with object that does not inherit from TH1" ); + + //Setup our TF1: find the binwidth + Double_t binwidth = 0; + if (histogram->GetDimension() == 1) //running in 1D mode + if (histogram->GetNbinsX() >= 1) { + binwidth = histogram->GetBinWidth(1); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "called with histogram with no bins"); + } + + else { //running in 2D mode { + TH1* proj = ((TH2*) histogram)->ProjectionY("", 0, 0); + if (proj->GetNbinsX() >= 1) { + binwidth = proj ->GetBinWidth(1); + } else { + throw dqm_core::BadConfig( ERS_HERE, name, "called with histogram with no bins"); + } + } + #ifdef PARAM_IS_AREA + gaus3_fn = new TF1("gaus3", Form("[3]/[2]/2.5066*%f*exp(-0.5*((x-[0]+[1])/[2])**2) + [4]/[2]/2.5066*%f*exp(-0.5*((x-[0])/[2])**2) + [5]/[2]/2.5066*%f*exp(-0.5*((x-[0]-[1])/[2])**2)", binwidth, binwidth, binwidth), -100, 100); + #else + gaus3_fn = new TF1("gaus3", "[3]*exp(-0.5*((x-[0]+[1])/[2])**2) + [4]*exp(-0.5*((x-[0])/[2])**2) + [5]*exp(-0.5*((x-[0]-[1])/[2])**2)", -100, 100); + #endif + gaus3_fn->SetParName(0, "Mean_zero_gaus"); //mean of gaussian centered at zero, should be close to zero + gaus3_fn->SetParName(1, "Mean_offzero_gaus"); //mean of other two gaussians, should be close to 20 + gaus3_fn->SetParName(2, "Width_all"); //shared width, should be about 5 + gaus3_fn->SetParName(3, "N_negative_gaus"); //normalization for negative-centered gaussian + gaus3_fn->SetParName(4, "N_zero_gaus"); //normalization for zero-centered gaussian + gaus3_fn->SetParName(5, "N_positive_gaus"); //normalization for positive-centered gaussian + + Double_t resolutionAll, meanZeroPeak, meanNonzeroPeaks, minEvents; + param_map mymap = cfg.getParameters(); + + meanZeroPeak = dqm_algorithms::tools::GetFirstFromMap("meanZeroPeak", mymap, 0.0); + meanNonzeroPeaks = dqm_algorithms::tools::GetFirstFromMap("meanNonzeroPeaks", mymap, 23.2); + resolutionAll = dqm_algorithms::tools::GetFirstFromMap("resolutionAll", mymap, 4.57); + minEvents = dqm_algorithms::tools::GetFirstFromMap("minEvents", mymap, 5.0); + + //we DO NOT allow fits by default. If the parameter is not found, the retval is 0 + if ( dqm_algorithms::tools::GetFirstFromMap("allowFitMean", mymap, 0) == 1 ) { + + //according to Peter, this can behave strangely, so we don't allow too much horizontal translation + gaus3_fn->SetParameter(0, meanZeroPeak); + gaus3_fn->SetParLimits(0, meanZeroPeak-5, meanZeroPeak+5); + } + else + gaus3_fn->FixParameter(0, meanZeroPeak); + + if ( dqm_algorithms::tools::GetFirstFromMap("allowFitMeanNonzeroPeaks", mymap, 0) == 1 ) { + gaus3_fn->SetParameter(1, meanNonzeroPeaks); + gaus3_fn->SetParLimits(1, meanNonzeroPeaks-10, meanNonzeroPeaks+10); + } + else + gaus3_fn->FixParameter(1, meanNonzeroPeaks); + + if ( dqm_algorithms::tools::GetFirstFromMap("allowFitResolution", mymap, 0) == 1 ) { + gaus3_fn->SetParameter(2, resolutionAll); + gaus3_fn->SetParLimits(2, 1, 10); + } + else { + gaus3_fn->FixParameter(2, resolutionAll); + + } + // get some starting values for the histogram + + dqm_core::Result* result = new dqm_core::Result(); + + if (histogram->GetDimension() == 1) { + + fitSingle(histogram); + // double minSig = dqm_algorithms::tools::GetFirstFromMap("minSignificance", mymap, 0); + + try { + + result->tags_ = dqm_algorithms::tools::GetFitParams(gaus3_fn); + err_map paramErrors = dqm_algorithms::tools::GetFitParamErrors(gaus3_fn); + for (err_map::const_iterator peit = paramErrors.begin(); peit != paramErrors.end(); ++peit) { + result->tags_[(*peit).first + " Error"] = (*peit).second; + } + + } + catch ( dqm_core::Exception & ex) { + throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex); + } + } + else { //working with a 2D histogram + + int nxbin = histogram->GetNbinsX(); + Double_t minsig = dqm_algorithms::tools::GetFirstFromMap("centralPeakMinSignificance", mymap, 3.0); + + bool writeSig = (dqm_algorithms::tools::GetFirstFromMap("reportSignificance", mymap, 0) == 1); + + + unsigned int psz = (unsigned int) TMath::Log10(nxbin)+1; + + std::vector<int> goodLB; + char buf[10]; + const std::string sig_str = "SIG_LB_"; + + for (int lb = 0; lb < nxbin; lb++) { + + sprintf(buf, fmt, psz, lb); //to avoid possible leaks (?) - should see how DQ framework behaves + TH1D* proj = ((TH2*) histogram)->ProjectionY(buf, lb, lb); + Double_t good_entries = proj->GetEntries() - proj->GetBinContent(0) - proj->GetBinContent(proj->GetNbinsX()+1); + if (good_entries < minEvents) { + if (writeSig) + result->tags_[sig_str+buf] = 0; + //delete proj; //// possible HACK, NOT SURE if needed + continue; //nothing to fit here, move along + } + + // I probably need to reset parameters 0-2 if they are not fixed + if ( dqm_algorithms::tools::GetFirstFromMap("allowFitMeanZeroPeak", mymap, 0) == 1 ) + gaus3_fn->SetParameter(0, meanZeroPeak); + + if ( dqm_algorithms::tools::GetFirstFromMap("allowFitMeanNonzeroPeaks", mymap, 0) == 1 ) + gaus3_fn->SetParameter(1, meanNonzeroPeaks); + + if ( dqm_algorithms::tools::GetFirstFromMap("allowFitResolution", mymap, 0) == 1 ) + gaus3_fn->SetParameter(2, resolutionAll); + + fitSingle(proj); + +#ifdef TC_WORKBENCH + result->histos_.push_back((TH1D*)proj->Clone()); +#endif + + if (gaus3_fn->GetParameter(4) == 0) { + if (writeSig) + result->tags_[sig_str+buf] = 0; + continue; + } + Double_t sig = fabs(gaus3_fn->GetParameter(4) / gaus3_fn->GetParError(4)); + if (writeSig) + result->tags_[sig_str+buf] = sig; + + if (sig > minsig) + goodLB.push_back(lb); //this is grossly non-optimal + + //delete proj; + + } //end loop over lumi blocks + + if (goodLB.size() != 0) + multLB_writeTags(&goodLB, result, histogram); + + //goodLB->Set(count); + // result->object_ = goodLB; this needs to be done at construction time apparently + } + return result; + } + + +#ifdef PARAM_IS_AREA +#define ADJUST_VAL startVal = startVal * hist1D->GetBinWidth(1) / gaus3_fn->GetParameter(2) / 2.5066 +#else +#define ADJUST_VAL +#endif + + void TripleGaussCollFit::fitSingle(TH1* hist1D) { + + Double_t startVal; + const Double_t window = 5.0; + + Double_t offset_all = gaus3_fn->GetParameter(0); + Double_t offset_nz = gaus3_fn->GetParameter(1); + + startVal = getStartValue(hist1D, offset_all-offset_nz-window, offset_all-offset_nz+window); ADJUST_VAL; + if (startVal == 0.0) + gaus3_fn->FixParameter(3, 0.0); + else { + gaus3_fn->SetParameter(3, startVal); + // DO NOT do something like this if we are using areas!! + // gaus3_fn->SetParLimits(3, 0, 5 * startVal); + } + + startVal = getStartValue(hist1D, offset_all-window, offset_all+window); ADJUST_VAL; + if (startVal == 0.0) + gaus3_fn->FixParameter(4, 0.0); + else { + gaus3_fn->SetParameter(4, startVal); + // gaus3_fn->SetParLimits(4, 0, 100 * startVal); + } + startVal = getStartValue(hist1D, offset_all+offset_nz-window , offset_all+offset_nz+window); ADJUST_VAL; + if (startVal == 0.0) + gaus3_fn->FixParameter(5, 0.0); + else { + gaus3_fn->SetParameter(5, startVal); + // gaus3_fn->SetParLimits(5, 0, 5 * startVal); + } + + /* This is the old and obsolete method to extract limits + Double_t startVal = getStartValue(hist1D, 46, 58); //was 51-53 + if (startVal == 0.0) + gaus3_fn->FixParameter(3, 0.0); + else { + gaus3_fn->SetParameter(3, startVal); + gaus3_fn->SetParLimits(3, 0, 5 * startVal); //not sure if this sort of bound is necessary, but who knows... + } + startVal = getStartValue(hist1D, 70, 82); // was 75-77 + if (startVal == 0.0) + gaus3_fn->FixParameter(4, 0.0); + else { + gaus3_fn->SetParameter(4, startVal); + gaus3_fn->SetParLimits(4, 0, 100 * startVal); //for some reason this seems to want more + } + startVal = getStartValue(hist1D, 93, 106); //was 98-101 + if (startVal == 0.0) + gaus3_fn->FixParameter(5, 0.0); + else { + gaus3_fn->SetParameter(5, startVal); + gaus3_fn->SetParLimits(5, 0, 5 * startVal); + } */ + + hist1D->Fit(gaus3_fn, "QN"); + + } + +} //close namespace diff --git a/DataQuality/dqm_algorithms/summary/AlwaysGreenSummary.cxx b/DataQuality/dqm_algorithms/summary/AlwaysGreenSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4484c03f49e14943d02cd8285f02055b040f6723 --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/AlwaysGreenSummary.cxx @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlwaysGreenSummary.cxx + * \author Akimasa Ishikawa (akimasa.ishikawa@cern.ch) + */ + +#include <iostream> + +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/summary/AlwaysGreenSummary.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +using namespace std; + +static dqm_algorithms::summary::AlwaysGreenSummary myInstance; + +dqm_algorithms::summary::AlwaysGreenSummary::AlwaysGreenSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker( "AlwaysGreenSummary", this ); +} + +dqm_algorithms::summary::AlwaysGreenSummary::~AlwaysGreenSummary() +{ +} + +dqm_algorithms::summary::AlwaysGreenSummary * +dqm_algorithms::summary::AlwaysGreenSummary::clone() +{ + return new AlwaysGreenSummary(); +} + +dqm_core::Result * +dqm_algorithms::summary::AlwaysGreenSummary::execute( const std::string & , + const dqm_core::Result & , + const dqm_core::ParametersMap &) +{ + + dqm_core::Result *newresult = new dqm_core::Result(); + newresult->status_=dqm_core::Result::Green; + return newresult; + +} diff --git a/DataQuality/dqm_algorithms/summary/AlwaysUndefinedSummary.cxx b/DataQuality/dqm_algorithms/summary/AlwaysUndefinedSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5589a8cc6bc404d40c3ed8ef255d827408e5b236 --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/AlwaysUndefinedSummary.cxx @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlwaysUndefinedSummary.cxx + * \author Akimasa Ishikawa (akimasa.ishikawa@cern.ch) + */ + +#include <iostream> + +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/summary/AlwaysUndefinedSummary.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +using namespace std; + +static dqm_algorithms::summary::AlwaysUndefinedSummary myInstance; + +dqm_algorithms::summary::AlwaysUndefinedSummary::AlwaysUndefinedSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker( "AlwaysUndefinedSummary", this ); +} + +dqm_algorithms::summary::AlwaysUndefinedSummary::~AlwaysUndefinedSummary() +{ +} + +dqm_algorithms::summary::AlwaysUndefinedSummary * +dqm_algorithms::summary::AlwaysUndefinedSummary::clone() +{ + return new AlwaysUndefinedSummary(); +} + +dqm_core::Result * +dqm_algorithms::summary::AlwaysUndefinedSummary::execute( const std::string & , + const dqm_core::Result & , + const dqm_core::ParametersMap &) +{ + + dqm_core::Result *newresult = new dqm_core::Result(); + newresult->status_=dqm_core::Result::Undefined; + return newresult; + +} diff --git a/DataQuality/dqm_algorithms/summary/BinwiseSummary.cxx b/DataQuality/dqm_algorithms/summary/BinwiseSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3e948f51099245c624ec6322956a6afa895b553a --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/BinwiseSummary.cxx @@ -0,0 +1,311 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideByHist.cxx file takes a parameter map containing two histograms and divides one by the other. + * \author Evan Wulf + */ + +#ifndef DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX +#define DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +#include <TH1.h> +#include <TClass.h> +#include <TObjArray.h> +#include <dqm_algorithms/summary/BinwiseSummary.h> + +#include <dqm_algorithms/tools/SimpleAlgorithmConfig.h> +#include <set> +#include <vector> +#include <map> + + +#ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST +static dqm_algorithms::summary::BinwiseSummary myInstance; +#endif //#ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST + + +dqm_algorithms::summary::BinwiseSummary::BinwiseSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("BinwiseSummary",this); +} + +dqm_algorithms::summary::BinwiseSummary::~BinwiseSummary() +{ +} + +dqm_algorithms::summary::BinwiseSummary* +dqm_algorithms::summary::BinwiseSummary::clone() +{ + return new BinwiseSummary(); +} + +dqm_core::Result* +dqm_algorithms::summary::BinwiseSummary::execute( const std::string &, + const dqm_core::Result &, + const dqm_core::ParametersMap & map) +{ + + //General summary maker infrastructure: (This can be resused) + dqm_core::Result *newresult = new dqm_core::Result(); + + //Retrieve axis information for the first histogram: + int nBinsX = 0; + int nBinsY = 0; + TH1* firstBinwiseHist = 0; + + //Loop over elements of parameter map to find an example binwise status histogram, if any, + //Extract nbins x and y now so can check against these: + for (dqm_core::ParametersMap::const_iterator paramIter=map.begin();paramIter!=map.end();++paramIter){ + if ( paramIter->second->getWeight() == 0 ) { + continue; + } + dqm_core::Result * inputResult = paramIter->second->getResult().get(); + TObject* inputobject = inputResult->getObject(); + if (inputobject == 0) { + continue; + } + for (std::map<std::string,double>::const_iterator tagIter=inputResult->tags_.begin(); + tagIter != inputResult->tags_.end(); ++tagIter ) { + if( tagIter->first.find("Algorithm--BinsDiffByStrips") != std::string::npos) { + if( inputobject->IsA()->InheritsFrom("TObjArray") ) { + firstBinwiseHist = (TH1*) ((TObjArray*)inputobject)->First(); + nBinsX = firstBinwiseHist->GetNbinsX(); + nBinsY = firstBinwiseHist->GetNbinsY(); + break; + } + } + } + if( (nBinsX != 0) || (nBinsY != 0) ) { + break; + } + } + TH1 * mask = 0; + std::vector<std::pair<TH1*,float> > binwiseStatHists; + dqm_core::Result::Status status = dqm_core::Result::Undefined; + + std::map<double,std::vector<std::pair<int,float> > > standardAndGroup; + std::map<double,std::vector<std::pair<TH1*,float> > > binwiseAndGroup; + std::set<double> setOfAndGroups; + + + //Loop over elements of the parameter map to extract histograms and there roles, if any: + for (dqm_core::ParametersMap::const_iterator paramIter=map.begin();paramIter!=map.end();++paramIter){ + //If weight is 0 skip this result. Allow to "turn off" + // results in summary makers + float weight = paramIter->second->getWeight(); + if ( weight == 0 ) { + ERS_DEBUG(2,"Skip result (weight 0): "<<paramIter->first); + continue; + } + dqm_core::Result * inputResult = paramIter->second->getResult().get(); + TObject* inputobject = inputResult->getObject(); + if (inputobject == 0) { + ERS_DEBUG(2,"Empty input object, "<<paramIter->first); + status = tools::WorstCaseAddStatus(status,inputResult->status_,weight); + continue; + } + + //This seems to be a good object, use it according to it's tags: + bool isSpecialParameter = false; + double andGroup = -99999.; + TH1* binwiseStatHist = 0; + for (std::map<std::string,double>::const_iterator tagIter=inputResult->tags_.begin(); + tagIter != inputResult->tags_.end(); ++tagIter ) { + + std::string tag = tagIter->first; + size_t stringPos; + std::string tagType = "ConfParameter--Role--Mask"; + if ( (stringPos = tag.find(tagType)) != std::string::npos) { + if ( inputobject->IsA()->InheritsFrom("TH1") ) { + if( (((TH1*)inputobject)->GetNbinsX() == nBinsX) && (((TH1*)inputobject)->GetNbinsY() == nBinsY)) { + mask = (TH1*)inputobject; + } + } + isSpecialParameter = true; + break; + } + + tagType = "Algorithm--BinsDiffByStrips"; //<-The only algorithm so far which produces a binwise status. + if ( (stringPos = tag.find(tagType)) != std::string::npos) { + if( inputobject->IsA()->InheritsFrom("TObjArray") ) { + binwiseStatHist = (TH1*) ((TObjArray*) inputobject)->First(); + if( (binwiseStatHist->GetNbinsX() != nBinsX) || (binwiseStatHist->GetNbinsY() != nBinsY) ) { + binwiseStatHist = 0; + } + else { + isSpecialParameter = true; + } + } + } + tagType = "AndGroup"; + if ( (stringPos = tag.find(tagType)) != std::string::npos) { + andGroup = tagIter->second; + } + } + if( !isSpecialParameter ){ + status = tools::WorstCaseAddStatus(status,inputResult->status_,weight); + } + else { + if( andGroup == -99999. ) { + if( binwiseStatHist != 0 ) { + std::pair<TH1*,float> binStatsPair ( binwiseStatHist, weight ); + binwiseStatHists.push_back(binStatsPair); + } + } + else { + if( binwiseStatHist != 0 ) { + std::map<double,std::vector<std::pair<TH1*,float> > >::iterator fitr = binwiseAndGroup.find(andGroup); + if( fitr == binwiseAndGroup.end() ) { + //New and group, make it: + std::vector<std::pair<TH1*,float> > newAndGroup; + newAndGroup.push_back( std::make_pair( binwiseStatHist, weight ) ); + binwiseAndGroup.insert(std::make_pair(andGroup,newAndGroup)); + setOfAndGroups.insert(andGroup); + } + else { + fitr->second.push_back( std::make_pair( binwiseStatHist, weight ) ); + } + } + else { + std::map<double,std::vector<std::pair<int,float> > >::iterator fitr = standardAndGroup.find(andGroup); + if( fitr == standardAndGroup.end() ) { + //New and group, make it: + std::vector<std::pair<int,float> > newAndGroup; + newAndGroup.push_back( std::make_pair( inputResult->status_, weight ) ); + standardAndGroup.insert( std::make_pair(andGroup, newAndGroup) ); + setOfAndGroups.insert(andGroup); + } + else { + fitr->second.push_back( std::make_pair( inputResult->status_, weight ) ); + } + } + } + } + } + + //Loop over set of and groups, for those found with no binwise component do status calculation + // here and remove from set. + std::set<double>::iterator setItr = setOfAndGroups.begin(); + while (setItr != setOfAndGroups.end()) { // we cannot use a normal for-loop because we may erase the current element + std::map<double, std::vector<std::pair<TH1*,float> > >::iterator findIter = binwiseAndGroup.find(*setItr); + if( findIter == binwiseAndGroup.end() ) { + std::map<double, std::vector<std::pair<int,float> > >::iterator fsIter = standardAndGroup.find(*setItr); + if( fsIter != standardAndGroup.end() ) { + if( !fsIter->second.empty() ) { + dqm_core::Result::Status groupStatus = dqm_core::Result::Red; + float groupWeight = 0; + for( std::vector<std::pair<int,float> >::const_iterator sandItr = fsIter->second.begin(); + sandItr != fsIter->second.end(); ++sandItr ) { + groupStatus = tools::BestCaseAddStatus( groupStatus, (dqm_core::Result::Status) sandItr->first, sandItr->second ); + groupWeight += sandItr->second; + } + status = tools::WorstCaseAddStatus(status,groupStatus,groupWeight); + } + standardAndGroup.erase(fsIter); + } + setOfAndGroups.erase(setItr++); // the erased iterator will become invalid, but post-incrementing is safe + } else { + ++setItr; + } + } + if( (binwiseStatHists.size() == 0) && (setOfAndGroups.size() == 0) ) { + newresult->status_ = status; + return newresult; + } + + std::vector<std::pair<TH1*,float> >::const_iterator itr; + std::vector<std::pair<TH1*,float> >::const_iterator iBegin = binwiseStatHists.begin(); + std::vector<std::pair<TH1*,float> >::const_iterator iEnd = binwiseStatHists.end(); + + if( mask != 0 ){ + for(int ix = 1; ix <= nBinsX; ix++) { + for(int iy = 1; iy <= nBinsY; iy++) { + int bin = firstBinwiseHist->GetBin(ix,iy); + //If there is an entry in the mask histogram, we will downweight this bin: + double downWeight = 0; + if(mask->GetBinContent(bin) != 0) { + downWeight = 1; + } + for( itr = iBegin; itr != iEnd; ++itr ) { + status = tools::WorstCaseAddStatus( status,(dqm_core::Result::Status) floor(itr->first->GetBinContent(bin)), + (itr->second - downWeight) ); + } + //Iterate over addGroups: + for( std::map<double, std::vector<std::pair<TH1*,float> > >::iterator bItr = binwiseAndGroup.begin(); + bItr != binwiseAndGroup.end(); ++ bItr ) { + dqm_core::Result::Status groupStatus = dqm_core::Result::Red; + float groupWeight = 0; + for( std::vector<std::pair<TH1*,float> >::const_iterator bandItr = bItr->second.begin(); + bandItr != bItr->second.end(); ++bandItr ) { + groupStatus = tools::BestCaseAddStatus( groupStatus,(dqm_core::Result::Status) floor(bandItr->first->GetBinContent(bin)), + (bandItr->second - downWeight) ); + groupWeight += bandItr->second - downWeight; + } + std::map<double, std::vector<std::pair<int,float> > >::iterator fsIter = standardAndGroup.find(bItr->first); + if( fsIter != standardAndGroup.end() ) { + for( std::vector<std::pair<int,float> >::const_iterator sandItr = fsIter->second.begin(); + sandItr != fsIter->second.end(); ++sandItr ) { + groupStatus = tools::BestCaseAddStatus( groupStatus, (dqm_core::Result::Status) sandItr->first, sandItr->second ); + groupWeight += sandItr->second; + } + } + status = tools::WorstCaseAddStatus( status, groupStatus, groupWeight ); + + } + } + } + } + else { + for(int ix = 1; ix <= nBinsX; ix++) { + for(int iy = 1; iy <= nBinsY; iy++) { + int bin = 0; + if( ! binwiseStatHists.empty() ) { + bin = binwiseStatHists.front().first->GetBin(ix,iy); + } + else { + bin = binwiseAndGroup.begin()->second.front().first->GetBin(ix,iy); + } + + for( itr = iBegin; itr != iEnd; ++itr ) { + status = tools::WorstCaseAddStatus( status,(dqm_core::Result::Status) floor(itr->first->GetBinContent(bin)), + itr->second ); + } + + //Iterate over addGroups: + for( std::map<double, std::vector<std::pair<TH1*,float> > >::iterator bItr = binwiseAndGroup.begin(); + bItr != binwiseAndGroup.end(); ++ bItr ) { + + dqm_core::Result::Status groupStatus = dqm_core::Result::Red; + float groupWeight = 0; + for( std::vector<std::pair<TH1*,float> >::const_iterator bandItr = bItr->second.begin(); + bandItr != bItr->second.end(); ++bandItr ) { + groupStatus = tools::BestCaseAddStatus( groupStatus,(dqm_core::Result::Status) floor(bandItr->first->GetBinContent(bin)), + bandItr->second ); + groupWeight += bandItr->second; + } + std::map<double, std::vector<std::pair<int,float> > >::iterator fsIter = standardAndGroup.find(bItr->first); + if( fsIter != standardAndGroup.end() ) { + for( std::vector<std::pair<int,float> >::const_iterator sandItr = fsIter->second.begin(); + sandItr != fsIter->second.end(); ++sandItr ) { + groupStatus = tools::BestCaseAddStatus( groupStatus, (dqm_core::Result::Status) sandItr->first,sandItr->second ); + groupWeight += sandItr->second; + } + } + status = tools::WorstCaseAddStatus( status, groupStatus, groupWeight ); + } + } + } + } + newresult->status_ = status; + return newresult; +} + +#endif // #ifndef DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX diff --git a/DataQuality/dqm_algorithms/summary/DivideByHist.cxx b/DataQuality/dqm_algorithms/summary/DivideByHist.cxx new file mode 100644 index 0000000000000000000000000000000000000000..93bb6d707f1c8ec603f5f6c77377c76fb172cf86 --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/DivideByHist.cxx @@ -0,0 +1,265 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file DivideByHist.cxx file takes a parameter map containing two histograms and divides one by the other. + * \author Evan Wulf + */ + +#ifndef DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX +#define DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX + +#include <dqm_core/AlgorithmConfig.h> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +#include <TH1.h> +#include <TClass.h> +#include <dqm_algorithms/summary/DivideByHist.h> + +#include <dqm_algorithms/tools/SimpleAlgorithmConfig.h> + +#include <dqm_algorithms/Bins_Diff_FromAvg.h> + +#ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST +static dqm_algorithms::summary::DivideByHist myInstance; +#endif //#ifndef DQM_ALGORITHMS_MULTIALGORITHMTEST + + +dqm_algorithms::summary::DivideByHist::DivideByHist() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("DivideByHist",this); +} + +dqm_algorithms::summary::DivideByHist::~DivideByHist() +{ +} + +dqm_algorithms::summary::DivideByHist* +dqm_algorithms::summary::DivideByHist::clone() +{ + return new DivideByHist(); +} + +dqm_core::Result* +dqm_algorithms::summary::DivideByHist::execute( const std::string & name, + const dqm_core::Result & lastResult, + const dqm_core::ParametersMap & map) +{ + //General summary maker infrastructure: (This can be resused) + dqm_core::Result *newresult = new dqm_core::Result(); + + std::multimap<std::string,TObject*> inputs; + dqm_algorithms::tools::SimpleAlgorithmConfig algConfig; + + dqm_core::Result * overWriteResult = 0; + + //Loop over elements of the parameter map to extract histograms and there roles, if any: + for (dqm_core::ParametersMap::const_iterator iter=map.begin();iter!=map.end();++iter){ + //If weight is 0 skip this result. Allow to "turn off" + // results in summary makers + if ( iter->second->getWeight() == 0 ) { + ERS_DEBUG(2,"Skip result (weight 0): "<<iter->first); + continue; + } + TObject* inputobject = iter->second->getResult().get()->getObject(); + if (inputobject == 0) { + //This is a sign that we just don't have all the parameters yet (summary makers are called every time a parameter comes in, + // so when the first one comes, the second one isn't in yet, so we get a null pointer). + newresult->status_ = lastResult.status_; + return newresult; + } + else { + //This seems to be a good object, try to find it's role and store a pointer to it if we do: + std::string role; + for (std::map<std::string,double>::const_iterator tagIter=iter->second->getResult().get()->tags_.begin(); + tagIter != iter->second->getResult().get()->tags_.end(); ++tagIter ) { + std::string tag = tagIter->first; + size_t stringPos; + std::string tagType = "ConfParameter--Role--"; + if ( (stringPos = tag.find(tagType)) != std::string::npos) { + stringPos += tagType.length(); + role = tag.substr(stringPos); + break; + } + } + //Only keep objects with a valid role: + if(role.size() != 0) { + inputs.insert(std::pair<std::string,TObject*>(role,inputobject)); + } + } + } + + if(inputs.size() < 2) { + newresult->status_ = lastResult.status_; + return newresult; + } + + //Extract config information from result tags in the parameter map, only extract config info from the first result + //found when iterating backwards which has nonzero tags. + + std::map<std::string,double > paramVecMap; + for (dqm_core::ParametersMap::const_reverse_iterator rIter=map.rbegin() ; rIter!=map.rend();++rIter) { + if( rIter->second->getResult().get()->tags_.empty() ){ + continue; + } + for (std::map<std::string,double>::const_iterator tagIter=rIter->second->getResult().get()->tags_.begin(); + tagIter != rIter->second->getResult().get()->tags_.end(); ++tagIter ) { + std::string tag = tagIter->first; + size_t stringPos; + std::string tagType; + + tagType = "ConfParameter--Role--"; + if ( tag.find(tagType) != std::string::npos ){ + //Already dealt with, + continue; + } + tagType = "ConfParameter--OverWrite"; + if ( tag.find(tagType) != std::string::npos ){ + //This parameter wants to be overwriten, remember this for later and continue: + overWriteResult = rIter->second->getResult().get(); + //Disable updating of the parameter: + // rIter->second->stateChanged(false,false); (uncomment once dqm_core-01-10-00 is available) + continue; + } + tagType = "ConfParameter--"; + if ( (stringPos = tag.find(tagType)) != std::string::npos ){ + //This is a single member config parameter; add it: + stringPos += tagType.length(); + algConfig.addParameter( tag.substr(stringPos),tagIter->second ); + continue; + } + tagType = "GThreshold--"; + if ( (stringPos = tag.find(tagType)) != std::string::npos ){ + //This is a green threshold; add it: + stringPos += tagType.length(); + algConfig.addGreenThreshold( tag.substr(stringPos),tagIter->second ); + continue; + } + tagType = "RThreshold--"; + if ( (stringPos = tag.find(tagType)) != std::string::npos ){ + //This is a red threshold; add it: + stringPos += tagType.length(); + algConfig.addRedThreshold( tag.substr(stringPos),tagIter->second ); + continue; + } + if ( tag.find("ConfParameter[") != std::string::npos ){ + std::cerr<< "MULTIOPTION PARAMETERS NO LONGER SUPPORTED; IGNORING" << std::endl; + // //This is an element of a configuration parameter vector; we can't add it yet + // stringPos = tag.find("]--") + 3; + // paramVecMap[tag.substr(stringPos)].push_back(tagIter->second); + } + }//end loop over result tags + break; //Assume that the first non-empty set of tags is all that is needed, so continue without looking at more parameters. + }//end loop over parameters map + + //Now loop over the paramVecMap to finish the algConfig + for ( std::map<std::string,double>::const_iterator pvIter=paramVecMap.begin(); pvIter!=paramVecMap.end();pvIter++){ + algConfig.addParameter( pvIter->first, pvIter->second ); + } + + delete newresult; + newresult = execute(name,inputs,algConfig); + + // Note: this is experimental and may not work: + if ((overWriteResult != 0) && (newresult->getObject() != 0) ) { + + //A parameter wanted to have it's result overwritten with the results of this summary maker, let us do it: + overWriteResult->status_ = newresult->status_; + overWriteResult->tags_ = newresult->tags_; + + TObject* overWriteObject = overWriteResult->getObject(); + if ( (!overWriteObject->IsA()->InheritsFrom("TH1")) || (!newresult->getObject()->IsA()->InheritsFrom("TH1")) ) { + //Do nothing: overwriting a non TH1 object might be a bad idea. + } + else { + + TH1* hOverW = (TH1*) overWriteObject; + TH1* hResult = (TH1*) newresult->getObject(); + + if (hOverW->GetDimension() == hResult->GetDimension()) { + hOverW->Reset(); + hOverW->Add(hResult); + } + } + } + + return newresult; +} + +dqm_core::Result* +dqm_algorithms::summary::DivideByHist::execute(const std::string & name, + const std::multimap<std::string,TObject*> & inputs, + const dqm_core::AlgorithmConfig& config) +{ + // dqm_core::Result *newresult = new dqm_core::Result(); + dqm_core::Result *newresult(0); + + TH1 * hNumerator = 0; + TH1 * hDenominator = 0; + TH1 * hQuotient = 0; + + TObject * numero = 0; + TObject * denomino = 0; + + if( inputs.size() < 2 ){ + throw dqm_core::BadConfig( ERS_HERE, name ,"incorrect number of arguements, number of inputs for division must be at least two"); + } + + //Retrieve the Histograms to be divided, using their specified roles: + std::multimap<std::string,TObject*>::const_iterator mmItr; + + mmItr = inputs.find("Numerator"); + if ( mmItr != inputs.end() ) { + numero = mmItr->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, name, "no object with 'Role--Numerator' was specified."); + } + mmItr = inputs.find("Denominator"); + if ( mmItr != inputs.end() ) { + denomino = mmItr->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, name, "no object with 'Role--Denominator' was specified."); + } + + if( numero->IsA()->InheritsFrom("TH1") ){ + hNumerator = (TH1*) numero; + } + else { + char errorStr[64]; + sprintf(errorStr,"%s does not inherit from TH1",numero->GetName()); + throw dqm_core::BadConfig( ERS_HERE, name, errorStr); + } + if( denomino->IsA()->InheritsFrom("TH1") ){ + hDenominator = (TH1*) denomino; + } + else { + char errorStr[64]; + sprintf(errorStr,"%s does not inherit from TH1",denomino->GetName()); + throw dqm_core::BadConfig( ERS_HERE, name, errorStr); + } + + //Perform the division: + hQuotient = dqm_algorithms::tools::DivideByHistogram(hNumerator,hDenominator); + + //Modify the resultant histogram if requested by config: + dqm_algorithms::tools::ModifyHistogram(hQuotient,config); + + //Extract the name of the algorithm to run: + std::string algorithmName = dqm_algorithms::tools::ExtractAlgorithmName(config); + + //Run the algorithm: + newresult = dqm_algorithms::tools::ExecuteNamedAlgorithm(algorithmName,*hQuotient,config); + + //Make the quotient histogram the output result object + newresult->object_ = (std::auto_ptr<TObject>)(TObject*)hQuotient; + + return newresult; +} + +#endif // #ifndef DQM_ALGORITHMS_SUMMARY_DIVIDEBYHIST_CXX diff --git a/DataQuality/dqm_algorithms/summary/FractionSummary.cxx b/DataQuality/dqm_algorithms/summary/FractionSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8ba3d328d0e440e7bcda0b83d30718207026d28b --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/FractionSummary.cxx @@ -0,0 +1,66 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file FractionSummary.cxx file implements the dqm_algorithms::summary::GnamDrawersSumamry class. + * \author A. Dotti, added by R. Calkins +*/ +#include <dqm_algorithms/summary/FractionSummary.h> +#include <dqm_core/AlgorithmManager.h> + + +static dqm_algorithms::summary::FractionSummary myInstance; +dqm_algorithms::summary::FractionSummary::FractionSummary() +{ + m_fractionRed = 0.1; + m_fractionYellow = 0.1; + dqm_core::AlgorithmManager::instance().registerSummaryMaker("FractionSummary",this); +} + +dqm_algorithms::summary::FractionSummary* +dqm_algorithms::summary::FractionSummary::clone() +{ + return new FractionSummary(); +} + +dqm_core::Result* +dqm_algorithms::summary::FractionSummary::execute(const std::string&, + const dqm_core::Result&, + const dqm_core::ParametersMap& map) +{ + int g = 0 , y = 0 , r = 0 , u = 0; + dqm_core::ParametersMap::const_iterator iter = map.begin(); + for ( ; iter != map.end() ; ++iter) + { + dqm_core::Result::Status mystatus = iter->second->getResult().get()->status_; + if (mystatus == dqm_core::Result::Green) { ++g; } + else if (mystatus == dqm_core::Result::Yellow) { ++y; } + else if (mystatus == dqm_core::Result::Red) { ++r; } + else { ++u; } + } + const int total = g + y + r + u; + const double RedFraction = total ? ((double)r / total) : 0; // avoid to divide by zero (should never happen) + const double YellowFraction = total ? ((double)y / total) : 0; // avoid to divide by zero (should never happen) + + dqm_core::Result* result = new dqm_core::Result(dqm_core::Result::Undefined); + result->tags_["NGreens"] = g; + result->tags_["NYellows"] = y; + result->tags_["NReds"] = r; + result->tags_["NUndefineds"] = u; + result->tags_["RedThresh"] = m_fractionRed; + result->tags_["YellowThresh"] = m_fractionYellow; + if (RedFraction > m_fractionRed) + { + result->status_ = dqm_core::Result::Red; + } + else if (YellowFraction > m_fractionYellow) + { + result->status_ = dqm_core::Result::Yellow; + } + else if (g > u) + { + result->status_ = dqm_core::Result::Green; + } + // otherwise the status remains undefined, as constructed above + return result; +} diff --git a/DataQuality/dqm_algorithms/summary/JetWorstCaseSummary.cxx b/DataQuality/dqm_algorithms/summary/JetWorstCaseSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e45b491fbcf31e718ddc6751b752cfc7959a34a1 --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/JetWorstCaseSummary.cxx @@ -0,0 +1,87 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* JetWorstCaseSummary.cxx file makes a WorstCaseSummary from the LAr & TileCal flags, while returns only yellow/green flags if the Jet or CaloMon flags are red/yellow/green. + */ + +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/summary/JetWorstCaseSummary.h> + +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +static dqm_algorithms::summary::JetWorstCaseSummary myInstance; + +dqm_algorithms::summary::JetWorstCaseSummary::JetWorstCaseSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("JetWorstCaseSummary",this); +} + +dqm_algorithms::summary::JetWorstCaseSummary::~JetWorstCaseSummary() +{ +} + +dqm_algorithms::summary::JetWorstCaseSummary* +dqm_algorithms::summary::JetWorstCaseSummary::clone() +{ + return new JetWorstCaseSummary(); +} + +dqm_core::Result* +dqm_algorithms::summary::JetWorstCaseSummary::execute( const std::string & , + const dqm_core::Result &, + const dqm_core::ParametersMap & map) +{ + dqm_core::ParametersMap::const_iterator iter; + unsigned int red=0; + unsigned int yellow=0; + unsigned int green=0; + unsigned int undefined = 0; + unsigned int skipped = 0; + + for (iter=map.begin();iter!=map.end();iter++){ + + //If weight is 0 skip this result. Allow to "turn off" + // results in summary makers + if ( iter->second->getWeight() == 0 ) + { + ERS_DEBUG(2,"Skip result (weight 0): "<<iter->first); + ++skipped; + continue; + } + dqm_core::Result::Status status=iter->second->getResult().get()->status_; + + if( (status==dqm_core::Result::Red && (iter->first == "JetBarrel" || iter->first == "JetASide" || iter->first == "JetCSide" ||iter->first == "CaloMonBAR" || iter->first == "CaloMonECA" || iter->first == "CaloMonECC" )) || status==dqm_core::Result::Yellow) { + ++yellow; + + } else if(status==dqm_core::Result::Red) { + ++red; + } else if (status==dqm_core::Result::Green) { + ++green; + } else { + ++undefined; + } + } + + dqm_core::Result *newresult = new dqm_core::Result(); + + + if ( red > 0 ) { + newresult->status_=dqm_core::Result::Red; + } else if ( yellow > 0 ) { + newresult->status_=dqm_core::Result::Yellow; + } else if ( green > 0 ) { + newresult->status_=dqm_core::Result::Green; + } else { + newresult->status_=dqm_core::Result::Undefined; + } + newresult->tags_.insert(std::make_pair("NumRed",(double)red)); + newresult->tags_.insert(std::make_pair("NumYellow",(double)yellow)); + newresult->tags_.insert(std::make_pair("NumGreen",(double)green)); + newresult->tags_.insert(std::make_pair("NumUndefined",(double)undefined)); + newresult->tags_.insert(std::make_pair("NumExcluded",(double)skipped)); + return newresult; +} + diff --git a/DataQuality/dqm_algorithms/summary/MDTWorstCaseSummary.cxx b/DataQuality/dqm_algorithms/summary/MDTWorstCaseSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5c850e7de7ab872bbbb8b7973c76344fc8697cae --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/MDTWorstCaseSummary.cxx @@ -0,0 +1,83 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* MDTWorstCaseSummary.cxx file makes a WorstCaseSummary from the LowStat MDT flags. This loops over all results in MDT[BA][BC][EA][EC] and determines looks at ML Coverage plots, it +then computes the region coverage as a percentage of NBinsOn/TotalBins. + */ + +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/summary/MDTWorstCaseSummary.h> + +#include <string> + +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +static dqm_algorithms::summary::MDTWorstCaseSummary myInstance; + +dqm_algorithms::summary::MDTWorstCaseSummary::MDTWorstCaseSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("MDTWorstCaseSummary",this); +} + +dqm_algorithms::summary::MDTWorstCaseSummary::~MDTWorstCaseSummary() +{ +} + +dqm_algorithms::summary::MDTWorstCaseSummary* +dqm_algorithms::summary::MDTWorstCaseSummary::clone() +{ + return new MDTWorstCaseSummary(); +} + +dqm_core::Result* +dqm_algorithms::summary::MDTWorstCaseSummary::execute( const std::string & , + const dqm_core::Result &, + const dqm_core::ParametersMap & map) +{ + dqm_core::ParametersMap::const_iterator iter; + + double TotalBins = 0; + int NBins = 0; + + for (iter=map.begin();iter!=map.end();iter++){ + + std::string name = (*iter).first; + if(name.find("NumberOfHitsIn") == std::string::npos) continue; + + std::map<std::string,double> theTags = (*iter).second->getResult()->tags_; + + int nBins = 0; + double ratio = 1.; + double effCut = 1.; + for(std::map<std::string,double>::const_iterator mitr = theTags.begin(); mitr != theTags.end(); ++mitr){ + std::string parameter = (*mitr).first; + if(parameter == "NBins") { + nBins = (*mitr).second; + } + if(parameter == "NBins_%"){ + ratio = (*mitr).second; + } + if(parameter == "Effective_BinThreshold") effCut = (*mitr).second; + } + + if(ratio > 0 && effCut > 1.1) { + TotalBins += nBins/ratio*100; + NBins += nBins; + } + + } + + dqm_core::Result *newresult = new dqm_core::Result(); + + + if( TotalBins < 100) newresult->status_ = dqm_core::Result::Undefined; + else if( NBins*1./TotalBins < 0.9) newresult->status_ = dqm_core::Result::Red; + else newresult->status_ = dqm_core::Result::Green; + + return newresult; + +} + diff --git a/DataQuality/dqm_algorithms/summary/PercentSummary.cxx b/DataQuality/dqm_algorithms/summary/PercentSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e951a226247020b3224654464694faf29976418f --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/PercentSummary.cxx @@ -0,0 +1,103 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//! \file PercentSummary.cxx file makes a PercentSummary for the Parameters in the Region. +//! Valerio Consorti valerio.consorti@roma1.infn.it + + +#include <iostream> + +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/summary/PercentSummary.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +using namespace std; + +static dqm_algorithms::summary::PercentSummary myInstance; + +dqm_algorithms::summary::PercentSummary::PercentSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker( "PercentSummary", this ); +} + +dqm_algorithms::summary::PercentSummary::~PercentSummary() +{ +} + +dqm_algorithms::summary::PercentSummary * +dqm_algorithms::summary::PercentSummary::clone() +{ + return new PercentSummary(); +} + +dqm_core::Result * +dqm_algorithms::summary::PercentSummary::execute( const std::string & , + const dqm_core::Result & , + const dqm_core::ParametersMap & map) +{ + + dqm_core::ParametersMap::const_iterator iter; + double rweight=0; + double yweight=0; + double gweight=0; + + double red=0; + double yellow=0; + double green=0; + double undefined=0; + + double weight=0; + double y_percent=0; + double r_percent=0; + double ry_percent=0; + + dqm_core::Result *newresult = new dqm_core::Result(); + + for (iter=map.begin();iter!=map.end();iter++){ + dqm_core::Result::Status status=iter->second->getResult().get()->status_; + if(status==dqm_core::Result::Red) { + rweight+=iter->second->getWeight(); + red++; + } else if (status==dqm_core::Result::Yellow) { + yweight+=iter->second->getWeight(); + yellow++; + } else if (status==dqm_core::Result::Green) { + gweight+=iter->second->getWeight(); + green++; + } else{ + undefined++; + } + } + + weight=rweight+yweight+gweight; + + if( red+green+yellow == 0){ + newresult->status_=dqm_core::Result::Undefined; + return newresult; + } else{ + if(weight==0){ + y_percent=yellow/(red+green+yellow+undefined); + r_percent=red/(red+green+yellow+undefined); + ry_percent=(red+yellow)/(red+green+yellow+undefined); + } else{ + y_percent=yweight/(red+green+yellow+undefined); + r_percent=rweight/(red+green+yellow+undefined); + ry_percent=(yweight+rweight)/(red+green+yellow+undefined); + } + } + + + if (r_percent>=0.50 || (ry_percent >= 0.50 && r_percent>0)) { + newresult->status_=dqm_core::Result::Red; + }else if (y_percent >= 0.50 || (r_percent>0.25 && r_percent<0.50)) { + newresult->status_=dqm_core::Result::Yellow; + }else { + newresult->status_=dqm_core::Result::Green; + } + + return newresult; + +} diff --git a/DataQuality/dqm_algorithms/summary/SimpleSummary.cxx b/DataQuality/dqm_algorithms/summary/SimpleSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b143fb5e63ddf41999f478c2a4fb63a692b064af --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/SimpleSummary.cxx @@ -0,0 +1,93 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SimpleSummary.cxx file makes a SimpleSummary for the Parameters in the Region: returns the status with the highest total weight (relative majority) + * \author Haleh Hadavand + */ + +#include <iostream> + +#include <dqm_core/AlgorithmManager.h> + +#include <dqm_algorithms/summary/SimpleSummary.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> + +using namespace std; + +static dqm_algorithms::summary::SimpleSummary myInstance; + +dqm_algorithms::summary::SimpleSummary::SimpleSummary(){ + dqm_core::AlgorithmManager::instance().registerSummaryMaker( "SimpleSummary", this ); +} + +dqm_algorithms::summary::SimpleSummary::~SimpleSummary(){ +} + +dqm_algorithms::summary::SimpleSummary * +dqm_algorithms::summary::SimpleSummary::clone(){ + return new SimpleSummary(); +} + +dqm_core::Result * +dqm_algorithms::summary::SimpleSummary::execute( const std::string & , + const dqm_core::Result & , + const dqm_core::ParametersMap & map){ + + dqm_core::ParametersMap::const_iterator iter; + + float rweight = 0; + float yweight = 0; + float gweight = 0; + + float ngrey = 0; + float nblack = 0; + + for (iter=map.begin();iter!=map.end();iter++){ + + dqm_core::Result::Status status=iter->second->getResult().get()->status_; + + if ( status == dqm_core::Result::Red ) { + rweight+=iter->second->getWeight(); + }else if ( status == dqm_core::Result::Yellow ) { + yweight+=iter->second->getWeight(); + }else if ( status == dqm_core::Result::Green ) { + gweight+=iter->second->getWeight(); + }else if ( status == dqm_core::Result::Undefined ) { + ++ngrey; + }else if ( status==dqm_core::Result::Disabled ) { + ++nblack; + } + } + + + dqm_core::Result *newresult = new dqm_core::Result(); + + if ( nblack == map.size() ) { + newresult->status_=dqm_core::Result::Disabled; + return newresult; + } + if ( ( ngrey + nblack ) == map.size() ) { + newresult->status_=dqm_core::Result::Undefined; + return newresult; + } + + float weight = gweight > ((rweight >= yweight) ? rweight : yweight) ? gweight : ((rweight >= yweight) ? rweight : yweight); + + if ( weight == 0 ) { + newresult->status_=dqm_core::Result::Undefined; + return newresult; + } + + if ( weight == rweight ) { + newresult->status_=dqm_core::Result::Red; + }else if ( weight == yweight ) { + newresult->status_=dqm_core::Result::Yellow; + } else { + newresult->status_=dqm_core::Result::Green; + } + + return newresult; + +} diff --git a/DataQuality/dqm_algorithms/summary/WorstCaseSummary.cxx b/DataQuality/dqm_algorithms/summary/WorstCaseSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7a676bd51fa0cf91a43e7cd496541ea81389b226 --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/WorstCaseSummary.cxx @@ -0,0 +1,91 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file WorstCaseSummary.cxx file makes a WorstCaseSummary for the Parameters in the Region. + * \author Andrea Dotti +*/ +#include <dqm_core/AlgorithmManager.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> +#include <dqm_algorithms/summary/WorstCaseSummary.h> + +static dqm_algorithms::summary::WorstCaseSummary myInstance; + +dqm_algorithms::summary::WorstCaseSummary::WorstCaseSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("WorstCaseSummary",this); +} + +dqm_algorithms::summary::WorstCaseSummary::~WorstCaseSummary() +{ +} + +dqm_algorithms::summary::WorstCaseSummary* +dqm_algorithms::summary::WorstCaseSummary::clone() +{ + return new WorstCaseSummary(); +} + +dqm_core::Result* +dqm_algorithms::summary::WorstCaseSummary::execute( const std::string & , + const dqm_core::Result &, + const dqm_core::ParametersMap & map) +{ + dqm_core::ParametersMap::const_iterator iter; + unsigned int black=0; + unsigned int red=0; + unsigned int yellow=0; + unsigned int green=0; + unsigned int undefined = 0; + unsigned int skipped = 0; + + for (iter=map.begin();iter!=map.end();iter++){ + //If weight is 0 skip this result. Allow to "turn off" + // results in summary makers + if ( iter->second->getWeight() == 0 ) + { + ERS_DEBUG(2,"Skip result (weight 0): "<<iter->first); + ++skipped; + continue; + } + dqm_core::Result::Status status=iter->second->getResult().get()->status_; + if(status==dqm_core::Result::Red) { + ++red; + } else if (status==dqm_core::Result::Yellow) { + ++yellow; + } else if (status==dqm_core::Result::Green) { + ++green; + } else if (status==dqm_core::Result::Disabled) { + ++black; + } else { + ++undefined; + } + } + + dqm_core::Result *newresult = new dqm_core::Result(); + + if (black == map.size() ) { + newresult->status_=dqm_core::Result::Disabled; + return newresult; + } + + + if ( red > 0 ) { + newresult->status_=dqm_core::Result::Red; + } else if ( yellow > 0 ) { + newresult->status_=dqm_core::Result::Yellow; + } else if ( green > 0 ) { + newresult->status_=dqm_core::Result::Green; + } else { + newresult->status_=dqm_core::Result::Undefined; + } + newresult->tags_.insert(std::make_pair("NumRed",(double)red)); + newresult->tags_.insert(std::make_pair("NumYellow",(double)yellow)); + newresult->tags_.insert(std::make_pair("NumGreen",(double)green)); + newresult->tags_.insert(std::make_pair("NumUndefined",(double)undefined)); + newresult->tags_.insert(std::make_pair("NumDisabled",(double)black)); + newresult->tags_.insert(std::make_pair("NumExcluded",(double)skipped)); + return newresult; +} + diff --git a/DataQuality/dqm_algorithms/summary/WorstCaseYellow.cxx b/DataQuality/dqm_algorithms/summary/WorstCaseYellow.cxx new file mode 100644 index 0000000000000000000000000000000000000000..61ca29eb9cc9c8b383fbd21e144d96b0cff3bfdc --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/WorstCaseYellow.cxx @@ -0,0 +1,91 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file WorstCaseYellow.cxx file makes a worst case summary, with status: Red replaced by status: Yellow + * \author Andrea Dotti +*/ +#include <dqm_core/AlgorithmManager.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> +#include <dqm_algorithms/summary/WorstCaseYellow.h> + +static dqm_algorithms::summary::WorstCaseYellow myInstance; + +dqm_algorithms::summary::WorstCaseYellow::WorstCaseYellow() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("WorstCaseYellow",this); +} + +dqm_algorithms::summary::WorstCaseYellow::~WorstCaseYellow() +{ +} + +dqm_algorithms::summary::WorstCaseYellow* +dqm_algorithms::summary::WorstCaseYellow::clone() +{ + return new WorstCaseYellow(); +} + +dqm_core::Result* +dqm_algorithms::summary::WorstCaseYellow::execute( const std::string & , + const dqm_core::Result &, + const dqm_core::ParametersMap & map) +{ + dqm_core::ParametersMap::const_iterator iter; + unsigned int black=0; + unsigned int red=0; + unsigned int yellow=0; + unsigned int green=0; + unsigned int undefined = 0; + unsigned int skipped = 0; + + for (iter=map.begin();iter!=map.end();iter++){ + //If weight is 0 skip this result. Allow to "turn off" + // results in summary makers + if ( iter->second->getWeight() == 0 ) + { + ERS_DEBUG(2,"Skip result (weight 0): "<<iter->first); + ++skipped; + continue; + } + dqm_core::Result::Status status=iter->second->getResult().get()->status_; + if(status==dqm_core::Result::Red) { + ++red; + } else if (status==dqm_core::Result::Yellow) { + ++yellow; + } else if (status==dqm_core::Result::Green) { + ++green; + } else if (status==dqm_core::Result::Disabled) { + ++black; + } else { + ++undefined; + } + } + + dqm_core::Result *newresult = new dqm_core::Result(); + + if (black == map.size() ) { + newresult->status_=dqm_core::Result::Disabled; + return newresult; + } + + + if ( red > 0 ) { + newresult->status_=dqm_core::Result::Yellow; //ONLY change from WorstCaseSummary + } else if ( yellow > 0 ) { + newresult->status_=dqm_core::Result::Yellow; + } else if ( green > 0 ) { + newresult->status_=dqm_core::Result::Green; + } else { + newresult->status_=dqm_core::Result::Undefined; + } + newresult->tags_.insert(std::make_pair("NumRed",(double)red)); + newresult->tags_.insert(std::make_pair("NumYellow",(double)yellow)); + newresult->tags_.insert(std::make_pair("NumGreen",(double)green)); + newresult->tags_.insert(std::make_pair("NumUndefined",(double)undefined)); + newresult->tags_.insert(std::make_pair("NumDisabled",(double)black)); + newresult->tags_.insert(std::make_pair("NumExcluded",(double)skipped)); + return newresult; +} + diff --git a/DataQuality/dqm_algorithms/summary/WorstWBlackSummary.cxx b/DataQuality/dqm_algorithms/summary/WorstWBlackSummary.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0602d8627a0237e4b3af8559ee58c3480d0a4e10 --- /dev/null +++ b/DataQuality/dqm_algorithms/summary/WorstWBlackSummary.cxx @@ -0,0 +1,86 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file WorstWBlackSummary.cxx file makes a WorstWBlackSummary for the Parameters in the Region. + * \author Andrea Dotti +*/ +#include <dqm_core/AlgorithmManager.h> +#include <dqm_core/Result.h> +#include <dqm_core/Parameter.h> +#include <dqm_algorithms/summary/WorstWBlackSummary.h> + +static dqm_algorithms::summary::WorstWBlackSummary myInstance; + +dqm_algorithms::summary::WorstWBlackSummary::WorstWBlackSummary() +{ + dqm_core::AlgorithmManager::instance().registerSummaryMaker("WorstWBlackSummary",this); +} + +dqm_algorithms::summary::WorstWBlackSummary::~WorstWBlackSummary() +{ +} + +dqm_algorithms::summary::WorstWBlackSummary* +dqm_algorithms::summary::WorstWBlackSummary::clone() +{ + return new WorstWBlackSummary(); +} + +dqm_core::Result* +dqm_algorithms::summary::WorstWBlackSummary::execute( const std::string & , + const dqm_core::Result &, + const dqm_core::ParametersMap & map) +{ + dqm_core::ParametersMap::const_iterator iter; + unsigned int black=0; + unsigned int red=0; + unsigned int yellow=0; + unsigned int green=0; + unsigned int undefined = 0; + unsigned int skipped = 0; + + for (iter=map.begin();iter!=map.end();iter++){ + //If weight is 0 skip this result. Allow to "turn off" + // results in summary makers + if ( iter->second->getWeight() == 0 ) + { + ERS_DEBUG(2,"Skip result (weight 0): "<<iter->first); + ++skipped; + continue; + } + dqm_core::Result::Status status=iter->second->getResult().get()->status_; + if(status==dqm_core::Result::Disabled) { + ++black; + } else if(status==dqm_core::Result::Red) { + ++red; + } else if (status==dqm_core::Result::Yellow) { + ++yellow; + } else if (status==dqm_core::Result::Green) { + ++green; + } else { + ++undefined; + } + } + + dqm_core::Result *newresult = new dqm_core::Result(); + if ( black > 0) { + newresult->status_=dqm_core::Result::Disabled; + } else if ( red > 0 ) { + newresult->status_=dqm_core::Result::Red; + } else if ( yellow > 0 ) { + newresult->status_=dqm_core::Result::Yellow; + } else if ( green > 0 ) { + newresult->status_=dqm_core::Result::Green; + } else { + newresult->status_=dqm_core::Result::Undefined; + } + newresult->tags_.insert(std::make_pair("NumBlack",(double)black)); + newresult->tags_.insert(std::make_pair("NumRed",(double)red)); + newresult->tags_.insert(std::make_pair("NumYellow",(double)yellow)); + newresult->tags_.insert(std::make_pair("NumGreen",(double)green)); + newresult->tags_.insert(std::make_pair("NumUndefined",(double)undefined)); + newresult->tags_.insert(std::make_pair("NumExcluded",(double)skipped)); + return newresult; +} + diff --git a/DataQuality/dqm_algorithms/test/print_algorithms.cpp b/DataQuality/dqm_algorithms/test/print_algorithms.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9483db7cbd6830d07dcd795a0a8687433002f7e --- /dev/null +++ b/DataQuality/dqm_algorithms/test/print_algorithms.cpp @@ -0,0 +1,75 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* print_algorithms.cpp + Author Haleh Hadavand +*/ +#include <boost/program_options.hpp> + +#include <dqm_core/LibraryManager.h> +#include <dqm_core/AlgorithmManager.h> +#include <iostream> +#include <ers/ers.h> + +int main(int argc, char ** argv) +{ + boost::program_options::options_description description( "Options" ); + + description.add_options() + ( "help,h", "produce help message" ) + ( "library,l", boost::program_options::value<std::string>()->default_value( "libdqm_algorithms.so", "libdqm_algorithms.so" ), "names of DQM library" ); + + boost::program_options::variables_map arguments; + try { + boost::program_options::store( boost::program_options::parse_command_line( argc, argv, description ), arguments ); + boost::program_options::notify( arguments ); + } + catch ( boost::program_options::error & ex ) + { + std::cerr << ex.what() << std::endl; + description.print( std::cout ); + return 1; + } + + if ( arguments.count("help") ) { + std::cout << "Test application of the 'dqm' package" << std::endl; + description.print( std::cout ); + return 0; + } + + if ( !arguments.count("library") ) { + std::cerr << "'library' option is not given" << std::endl; + description.print( std::cout ); + return 2; + } + + std::string library = arguments["library"].as<std::string>(); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Uuu-f ... at last we have finished with parsing the command line + ////////////////////////////////////////////////////////////////////////////////////////////////// + + + try + { + dqm_core::LibraryManager::instance().loadLibrary( library ); + } + catch( dqm_core::Exception & ex ) + { + ers::fatal( ex ); + return -1; + } + int count=0; + std::map<std::string, dqm_core::Algorithm*> algslist = dqm_core::AlgorithmManager::instance().getAlgorithmMap(); + std::map<std::string,dqm_core::Algorithm*>::iterator iter; + for (iter=algslist.begin();iter!=algslist.end();iter++){ + ++count; + std::cout<<"*********************************************************************************************"<<std::endl; + std::cout<<"Algorithm Name '"<<iter->first<<"'"<<std::endl; + std::cout<<"---------------------------------------------------------------------------------------------"<<std::endl; + iter->second->printDescription(); + } + std::cout<<"There are "<<count<<" algorithm(s) in lib "<<library<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/test/print_summarymakers.cpp b/DataQuality/dqm_algorithms/test/print_summarymakers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9493cd278b3ca57ea418b8be6732498da943159a --- /dev/null +++ b/DataQuality/dqm_algorithms/test/print_summarymakers.cpp @@ -0,0 +1,75 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* print_algorithms.cpp + Author Haleh Hadavand +*/ +#include <boost/program_options.hpp> + +#include <dqm_core/LibraryManager.h> +#include <dqm_core/AlgorithmManager.h> +#include <iostream> +#include <ers/ers.h> + +int main(int argc, char ** argv) +{ + boost::program_options::options_description description( "Options" ); + + description.add_options() + ( "help,h", "produce help message" ) + ( "library,l", boost::program_options::value<std::string>()->default_value( "libdqm_summaries.so", "libdqm_summaries.so" ), "names of DQM library" ); + + boost::program_options::variables_map arguments; + try { + boost::program_options::store( boost::program_options::parse_command_line( argc, argv, description ), arguments ); + boost::program_options::notify( arguments ); + } + catch ( boost::program_options::error & ex ) + { + std::cerr << ex.what() << std::endl; + description.print( std::cout ); + return 1; + } + + if ( arguments.count("help") ) { + std::cout << "Test application of the 'dqm' package" << std::endl; + description.print( std::cout ); + return 0; + } + + if ( !arguments.count("library") ) { + std::cerr << "'library' option is not given" << std::endl; + description.print( std::cout ); + return 2; + } + + std::string library = arguments["library"].as<std::string>(); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Uuu-f ... at last we have finished with parsing the command line + ////////////////////////////////////////////////////////////////////////////////////////////////// + + + try + { + dqm_core::LibraryManager::instance().loadLibrary( library ); + } + catch( dqm_core::Exception & ex ) + { + ers::fatal( ex ); + return -1; + } + int count=0; + std::map<std::string, dqm_core::SummaryMaker*> algslist = dqm_core::AlgorithmManager::instance().getSummaryMakerMap(); + std::map<std::string,dqm_core::SummaryMaker*>::iterator iter; + for (iter=algslist.begin();iter!=algslist.end();iter++){ + ++count; + std::cout<<"*********************************************************************************************"<<std::endl; + std::cout<<"Summary Maker Name '"<<iter->first<<"'"<<std::endl; + std::cout<<"---------------------------------------------------------------------------------------------"<<std::endl; + //iter->second->printDescription(); + } + std::cout<<"There are "<<count<<" SummaryMakers(s) in lib "<<library<<std::endl; +} + diff --git a/DataQuality/dqm_algorithms/tools/AlgorithmHelper.cxx b/DataQuality/dqm_algorithms/tools/AlgorithmHelper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..78c1844c5e174dba04cd1cc6d3c118c6bcca1400 --- /dev/null +++ b/DataQuality/dqm_algorithms/tools/AlgorithmHelper.cxx @@ -0,0 +1,1570 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file AlgorithmHelper.cpp does basic functions to get dqm_core::Results from algorithms + * \author Haleh Hadavand + */ +#ifndef DQM_ALGORITHMS_TOOLS_ALGORITHMHELPER_CXX +#define DQM_ALGORITHMS_TOOLS_ALGORITHMHELPER_CXX + +#include <TF1.h> +#include <TH1.h> +#include <TH3F.h> +#include <TH2F.h> +#include <TH1F.h> + +#include <Math/ProbFuncMathCore.h> +#include <Math/DistFunc.h> +#include <TClass.h> +#include <iostream> +#include <dqm_algorithms/tools/AlgorithmHelper.h> +#include <ers/ers.h> + +#include <dqm_core/Result.h> + +#include <dqm_core/AlgorithmManager.h> +#include <dqm_core/LibraryManager.h> + +std::map<std::string, double > +dqm_algorithms::tools::GetFitParams(const TF1 * func ) +{ + std::map<std::string,double> fitparams; + + const int nPar =(int) func->GetNpar(); + + for ( int i = 0; i< nPar; ++i ) { + std::string name = func->GetParName( i ); + fitparams[name] = func->GetParameter( i ); + } + return fitparams; +} + +std::map<std::string, double > +dqm_algorithms::tools::GetFitParamErrors(const TF1 * func ) +{ + std::map<std::string,double> fitParamErrors; + + const int nPar =(int) func->GetNpar(); + + for ( int i = 0; i< nPar; ++i ) { + std::string name = func->GetParName( i ); + fitParamErrors[name] = func->GetParError( i ); + } + return fitParamErrors; +} + + + +dqm_core::Result * +dqm_algorithms::tools::MakeComparisons( const std::map<std::string,double> & algparams, + const std::map<std::string,double> & gthreshold, + const std::map<std::string,double> & rthreshold ) +{ + + int red=0; + int yellow=0; + int green=0; + + + if (gthreshold.size() != rthreshold.size()) { + throw dqm_core::BadConfig( ERS_HERE, "MakeComparisons", "Need same number of Red and Green Threshold" ); + } + + if (gthreshold.size() == 0 ) { + throw dqm_core::BadConfig( ERS_HERE, "MakeComparisons", "No Threshold specified" ); + } + + std::map<std::string,double>::const_iterator g_iter; + + for (g_iter=gthreshold.begin();g_iter!=gthreshold.end();g_iter++){ + + std::string name=(std::string) g_iter->first; + std::string findname=name; + double gtvalue=g_iter->second; + + if (name == "AbsMean" ) + findname="Mean"; + if (name == "AbsXMean" ) + findname="XMean"; + if (name == "AbsYMean" ) + findname="YMean"; + + + std::map<std::string,double>::const_iterator ait = algparams.find(findname); + std::map<std::string,double>::const_iterator rit = rthreshold.find(name); + double rtvalue=-999; + double avalue=-999; + + if ( ait != algparams.end() ) { + avalue=ait->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + + if ( rit != rthreshold.end() ) { + rtvalue=rit->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + + + if (name == "AbsMean" || name == "AbsXMean" || name== "AbsYMean") { + avalue = fabs(avalue); + if (gtvalue < 0 || rtvalue <0 ) { + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + } + + ERS_DEBUG(1, name<<" :red value "<<rtvalue<<" :green value "<<gtvalue<<" :param value "<<avalue); + + if (gtvalue < rtvalue) { + + if (avalue <= gtvalue ){ + ++green; + }else if(avalue < rtvalue){ + ++yellow; + }else { + ++red; + } + } + else if (gtvalue > rtvalue) { + if (avalue >= gtvalue ){ + ++green; + }else if(avalue > rtvalue){ + ++yellow; + }else { + ++red; + } + } + else { + ERS_DEBUG(0, "red threshold (" << rtvalue << ") same as green threshold "<< gtvalue <<") for parameter " << name << ": can't evaluate result"); + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + + } + ERS_DEBUG(1, "red: "<<red<<" yellow: "<<yellow<<" green: "<<green); + + + dqm_core::Result* result = new dqm_core::Result(); + + result->tags_ = algparams; + + + if (red>0) { + result->status_= dqm_core::Result::Red; + }else if (yellow>0) { + result->status_= dqm_core::Result::Yellow; + }else if (green>0) { + result->status_= dqm_core::Result::Green; + } + + return result; +} + +dqm_core::Result * +dqm_algorithms::tools::CompareWithErrors( const std::map<std::string,double> & algparams, + const std::map<std::string,double> & paramErrors, + const std::map<std::string,double> & gthreshold, + const std::map<std::string,double> & rthreshold, double minSig ) +{ + + int red = 0; + int yellow = 0; + int green = 0; + int undefined = 0; + + + if (gthreshold.size() != rthreshold.size()) { + throw dqm_core::BadConfig( ERS_HERE, "MakeComparisons", "Need same number of Red and Green Threshold" ); + } + + if (gthreshold.size() == 0 ) { + throw dqm_core::BadConfig( ERS_HERE, "MakeComparisons", "No Threshold specified" ); + } + + std::map<std::string,double>::const_iterator g_iter; + + for (g_iter=gthreshold.begin();g_iter!=gthreshold.end();g_iter++){ + + std::string name=(std::string) g_iter->first; + std::string findname=name; + double gtvalue=g_iter->second; + + if (name == "AbsMean" ) + findname="Mean"; + if (name == "AbsXMean" ) + findname="XMean"; + if (name == "AbsYMean" ) + findname="YMean"; + + + std::map<std::string,double>::const_iterator ait = algparams.find(findname); + std::map<std::string,double>::const_iterator errItr = paramErrors.find(findname); + std::map<std::string,double>::const_iterator rit = rthreshold.find(name); + + double rtvalue = -999; + double avalue = -999; + double error = 0; + + if ( ait != algparams.end() ) { + avalue=ait->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + + if ( errItr != paramErrors.end() ) { + error = errItr->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, "Problem retrieving fit param error", name ); + } + if ( error < 0 ) error = 0; + + if ( rit != rthreshold.end() ) { + rtvalue=rit->second; + } + else { + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + + + if (name == "AbsMean" || name == "AbsXMean" || name== "AbsYMean") { + avalue = fabs(avalue); + if (gtvalue < 0 || rtvalue <0 ) { + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + } + + ERS_DEBUG(1, name<<" :red value "<<rtvalue<<" :green value "<<gtvalue<<" :param value "<<avalue <<" :param error "<<error); + + double significanceBound = error * minSig; + + + if (gtvalue < rtvalue) { + + if ( avalue <= (gtvalue - significanceBound) ){ + ++green; + } + else if( avalue > (rtvalue + significanceBound) ){ + ++red; + } + else if( avalue > (gtvalue + significanceBound) ) { + ++yellow; + } + else { + ++undefined; + } + } + else if (gtvalue > rtvalue) { + if ( avalue >= (gtvalue + significanceBound) ){ + ++green; + } + else if( avalue < (rtvalue - significanceBound) ){ + ++red; + } + else if( avalue < (gtvalue - significanceBound) ){ + ++yellow; + } + else { + ++undefined; + } + } + else { + ERS_DEBUG(0, "red threshold same as green threshold: can't evaluate result"); + throw dqm_core::BadConfig( ERS_HERE, "None", name ); + } + + } + ERS_DEBUG(1, "red: "<<red<<" yellow: "<<yellow<<" green: "<<green << " undefined: " <<undefined); + + + dqm_core::Result* result = new dqm_core::Result(); + + result->tags_ = algparams; + + // We use a strung undefined here: if one of the test parameters was in the undefined region about gth, + // then the overall result will be undefined. + if (red>0) { + result->status_= dqm_core::Result::Red; + } + else if (yellow>0) { + result->status_= dqm_core::Result::Yellow; + } + else if (undefined>0) { + result->status_= dqm_core::Result::Undefined; + } + else if (green>0) { + result->status_= dqm_core::Result::Green; + } + + return result; +} + +dqm_core::Result * +dqm_algorithms::tools::GetFitResult (const TF1 * func, const dqm_core::AlgorithmConfig & config, double minSig ) +{ + std::map<std::string, double > params = GetFitParams(func); + std::map<std::string, double > greenthresh=config.getGreenThresholds(); + std::map<std::string,double>::const_iterator ait = greenthresh.find("Chi2_per_NDF"); + if ( ait != greenthresh.end() ) { + params["Chi2_per_NDF"]=func->GetChisquare()/ func->GetNDF(); + } + double subtractfrommean = GetFirstFromMap( "SubtractFromMean", config.getParameters() ); + + params["Mean"] = params["Mean"] - subtractfrommean; + dqm_core::Result * result; + std::map<std::string, double > paramErrors = GetFitParamErrors(func); + if( minSig == 0) { + result = MakeComparisons( params, config.getGreenThresholds(), config.getRedThresholds() ); + //result->tags_ = params; + } + else { + result = CompareWithErrors( params, paramErrors, config.getGreenThresholds(), config.getRedThresholds(), minSig ); + } + + result->tags_ = params; + for ( std::map<std::string,double>::const_iterator peItr = paramErrors.begin(); peItr != paramErrors.end(); ++peItr ) { + std::string errorName = peItr->first; + errorName += " Error"; + result->tags_[errorName] = peItr->second; + } + + return result; +} + +double dqm_algorithms::tools::GetFirstFromMap(const std::string ¶mName, const std::map<std::string, double > ¶ms) +{ + std::map<std::string, double >::const_iterator it = params.find(paramName); + if (it == params.end()) { + throw dqm_core::BadConfig(ERS_HERE, "None", paramName); // this is the only difference between the two overloaded versions + } else { + return it->second; + } +} + +double dqm_algorithms::tools::GetFirstFromMap(const std::string ¶mName, const std::map<std::string, double > ¶ms, double defaultValue) +{ + std::map<std::string, double >::const_iterator it = params.find(paramName); + if (it == params.end()) { + return defaultValue; // this is the only difference between the two overloaded versions + } else { + return it->second; + } +} + +std::vector<int> dqm_algorithms::tools::GetBinRange(const TH1 *h, const std::map<std::string, double > ¶ms) +{ + std::vector<int> range; + TAxis *xAxis = h->GetXaxis(); + TAxis *yAxis = h->GetYaxis(); + + if (h->GetDimension() > 2) { + throw dqm_core::BadConfig(ERS_HERE, h->GetName(), "histogram has more than 2 dimensions"); + } + + const double notFound = -99999; + const double xmin = dqm_algorithms::tools::GetFirstFromMap("xmin", params, notFound); + const double xmax = dqm_algorithms::tools::GetFirstFromMap("xmax", params, notFound); + const double ymin = dqm_algorithms::tools::GetFirstFromMap("ymin", params, notFound); + const double ymax = dqm_algorithms::tools::GetFirstFromMap("ymax", params, notFound); + const int xlow = (xmin == notFound) ? 1 : xAxis->FindBin(xmin); + const int xhigh = (xmax == notFound) ? xAxis->GetNbins() : xAxis->FindBin(xmax); + const int ylow = (ymin == notFound) ? 1 : yAxis->FindBin(ymin); + const int yhigh = (ymax == notFound) ? yAxis->GetNbins() : yAxis->FindBin(ymax); + + if (xlow>xhigh) { + char temp[128]; + sprintf(temp,"Bin Range Error: xmin = %.3g, xmax = %.3g",xmin,xmax); + throw dqm_core::BadConfig( ERS_HERE, h->GetName(), temp ); + } + if (ylow>yhigh) { + char temp[128]; + sprintf(temp,"Bin Range Error: xmin = %.3g, xmax = %.3g",xmin,xmax); + throw dqm_core::BadConfig( ERS_HERE, h->GetName(), temp ); + } + + range.push_back(xlow); + range.push_back(xhigh); + range.push_back(ylow); + range.push_back(yhigh); + return range; +} + +void +dqm_algorithms::tools::PublishBin(const TH1 * histogram, int x, int y, double inputcont, dqm_core::Result *result) { + + std::string name = histogram->GetName(); + double xbin = histogram->GetXaxis()->GetBinCenter(x); + std::string xbinlabel = (std::string)(histogram->GetXaxis()->GetBinLabel(x)); + if (histogram->GetDimension() == 2){ + double ybin = histogram->GetYaxis()->GetBinCenter(y); + std::string ybinlabel = (std::string)(histogram->GetYaxis()->GetBinLabel(y)); + std::string badbin = Form("x-axis %s(%f) y-axis %s(%f))",xbinlabel.c_str(),xbin,ybinlabel.c_str(),ybin); + result->tags_[badbin.c_str()] = inputcont; + ERS_DEBUG(1,"x bin "<<xbin<<" y bin "<<ybin <<" value "<<inputcont); + } else { + std::string badbin = Form("%s(%f)",xbinlabel.c_str(),xbin); + result->tags_[badbin.c_str()] = inputcont; + ERS_DEBUG(1,"x bin "<<xbin<<" value "<<inputcont); + } +} + + +TH1* +dqm_algorithms::tools::DivideByHistogram(const TH1* hNumerator, const TH1* hDenominator) +{ + + TH1 * hResult = 0; + + int hNdimension = hNumerator->GetDimension(); + int hDdimension = hDenominator->GetDimension(); + + if( hDdimension == hNdimension ) { + if( (hNumerator->GetNbinsX() != hDenominator->GetNbinsX()) || (hNumerator->GetNbinsY() != hDenominator->GetNbinsY()) || + (hNumerator->GetNbinsZ() != hNumerator->GetNbinsZ()) ) { + throw dqm_core::BadConfig( ERS_HERE, "DivideByHistogram", "number of bins do not match"); + } + //since the dimensions match, use the root TH1 division method + //as recommended in root documentation, we call Sumw2 first to keep the errors well behaved: + + if( hNdimension == 1) { + hResult = BookHistogramByExample(hNumerator,"hQuotient","Result of Division of One Histogram By Another",XAxis); + } + else if ( hNdimension == 2 ) { + hResult = BookHistogramByExample(hNumerator,"hQuotient","Result of Division of One Histogram By Another",XYAxes); + } + else if ( hNdimension == 3 ) { + hResult = BookHistogramByExample(hNumerator,"hQuotient","Result of Division of One Histogram By Another",XYZAxes); + } + else { + throw dqm_core::BadConfig( ERS_HERE, "DivideByHistogram", "Histograms with dimension greater than 3 are not supported"); + } + hResult->Sumw2(); + + hResult->Divide(hNumerator,hDenominator); + } + else if ( hNdimension > hDdimension ) { + //Handle division for case where denominator has lower dimension than numerator: + //There are only a few possibilities, hNdimension = 2 or 3, hDdimension = 1 or 2. + + TAxis* xax = hNumerator->GetXaxis(); + int nbinsx = xax->GetNbins(); + TAxis* yax = hNumerator->GetYaxis(); + int nbinsy = yax->GetNbins(); + TAxis* zax = hNumerator->GetZaxis(); + int nbinsz = zax->GetNbins(); + + if( nbinsx != hDenominator->GetNbinsX() ) { + throw dqm_core::BadConfig( ERS_HERE, "DivideByHistogram", "number of bins in x-axis do not match"); + } + if( (hDdimension == 2) && (nbinsy != hDenominator->GetNbinsY()) ) { + throw dqm_core::BadConfig( ERS_HERE, "DivideByHistogram", "number of bins in y-axis do not match"); + } + + double numeratorCont = 0; + double denominatorCont = 0; + double numeratorError = 0; + double denominatorError = 0; + + if(hNdimension == 2) { + hResult = BookHistogramByExample(hNumerator,"hQuotient","Result of Division of One Histogram By Another",XYAxes); + } + else if(hNdimension == 3) { + hResult = BookHistogramByExample(hNumerator,"hQuotient","Result of Division of One Histogram By Another",XYZAxes); + } + else { + throw dqm_core::BadConfig( ERS_HERE, "DivideByHistogram", "Histograms with dimension greater than 3 are not supported"); + } + + for (int i=1; i <= nbinsx; i++) { + if( hDdimension == 1){ + denominatorCont = hDenominator->GetBinContent(i); + denominatorError = hDenominator->GetBinError(i); + } + for (int j=1; j <= nbinsy; j++) { + if( hDdimension == 2){ + denominatorCont = hDenominator->GetBinContent(i,j); + denominatorError = hDenominator->GetBinError(i,j); + } + if( hNdimension == 2){ + numeratorCont = hNumerator->GetBinContent(i,j); + numeratorError = hNumerator->GetBinError(i,j); + if(denominatorCont != 0){ + hResult->SetBinContent(i,j,numeratorCont/denominatorCont); + hResult->SetBinError(i,j,sqrt( ( pow(numeratorError,2)/pow(denominatorCont,2) ) + + ( pow(denominatorError,2) * pow(numeratorCont,2) / pow(denominatorCont,4) ) ) ); + } + } + else { + for (int k=1; k <= nbinsz; k++) { + numeratorCont = hNumerator->GetBinContent(i,j,k); + numeratorError = hNumerator->GetBinError(i,j,k); + if(denominatorCont != 0){ + hResult->SetBinContent(i,j,k,numeratorCont/denominatorCont); + hResult->SetBinError(i,j,k,sqrt( ( pow(numeratorError,2)/pow(denominatorCont,2) ) + + ( pow(denominatorError,2) * pow(numeratorCont,2) / pow(denominatorCont,4) ) ) ); + } + } + } + } + } + } + else { + //Handle division for case where the numerator has lower dimension than the denominator + //There are only a few possibilities, hNdimension = 1 or 2, hDdimension = 2 or 3. + + TAxis* xax = hDenominator->GetXaxis(); + int nbinsx = xax->GetNbins(); + TAxis* yax = hDenominator->GetYaxis(); + int nbinsy = yax->GetNbins(); + TAxis* zax = hDenominator->GetZaxis(); + int nbinsz = zax->GetNbins(); + + if( nbinsx != hNumerator->GetNbinsX() ) { + throw dqm_core::BadConfig( ERS_HERE, "number of bins in x-axis", "do not match"); + } + if( (hNdimension == 2) && (nbinsy != hNumerator->GetNbinsY()) ) { + throw dqm_core::BadConfig( ERS_HERE, "number of bins in y-axis", "do not match"); + } + + double denominatorCont = 0; + double numeratorCont = 0; + double denominatorError = 0; + double numeratorError = 0; + + if(hDdimension == 2) { + hResult = BookHistogramByExample(hDenominator,"hQuotient","Result of Division of One Histogram By Another",XYAxes); + } + else if(hDdimension == 3) { + hResult = BookHistogramByExample(hDenominator,"hQuotient","Result of Division of One Histogram By Another",XYZAxes); + } + else { + throw dqm_core::BadConfig( ERS_HERE, "DivideByHistogram", "Histograms with dimension greater than 3 are not supported"); + } + + // Always loop so at to handle over/underflows too + for (int i=1; i <= nbinsx; i++) { + if( hNdimension == 1){ + numeratorCont = hNumerator->GetBinContent(i); + numeratorError = hNumerator->GetBinError(i); + } + for (int j=1; j <= nbinsy; j++) { + if( hNdimension == 2){ + numeratorCont = hNumerator->GetBinContent(i,j); + numeratorError = hNumerator->GetBinError(i,j); + } + if( hDdimension == 2){ + denominatorCont = hDenominator->GetBinContent(i,j); + denominatorError = hDenominator->GetBinError(i,j); + if(denominatorCont != 0){ + hResult->SetBinContent(i,j,numeratorCont/denominatorCont); + hResult->SetBinError(i,j,sqrt( ( pow(numeratorError,2)/pow(denominatorCont,2) ) + + ( pow(denominatorError,2) * pow(numeratorCont,2) / pow(denominatorCont,4) ) ) ); + } + } + else { + for (int k=1; k <= nbinsz; k++) { + denominatorCont = hDenominator->GetBinContent(i,j,k); + denominatorError = hDenominator->GetBinError(i,j,k); + if(denominatorCont != 0){ + hResult->SetBinContent(i,j,k,numeratorCont/denominatorCont); + hResult->SetBinError(i,j,sqrt( ( pow(numeratorError,2)/pow(denominatorCont,2) ) + + ( pow(denominatorError,2) * pow(numeratorCont,2) / pow(denominatorCont,4) ) ) ); + } + } + } + } + } + } + return hResult; +} + +std::string +dqm_algorithms::tools::ExtractAlgorithmName(const dqm_core::AlgorithmConfig& config) +{ + // Function to extract the name of an auxiliary algorithm specified through an algorithm configuration parameter + // Uses syntax AuxAlgName::[Algorithm Name] = [value], where value is ignored. + + std::string algNameTag = "AuxAlgName--"; + std::string algName = "None"; + + if (config.getParameters().empty()){ + throw dqm_core::BadConfig( ERS_HERE, "ExtractAlgorithmName","called with an empty config file"); + } + + std::map<std::string,double > confParams = config.getParameters();//Copy is necessary as AlgorithmConfig does not return map by reference (bug?) + for ( std::map<std::string,double >::const_iterator itr = confParams.begin();itr != confParams.end();++itr ) { + size_t stringPos; + if ( (stringPos = itr->first.find(algNameTag)) != std::string::npos ){ + stringPos += algNameTag.length(); + algName = itr->first.substr(stringPos); + } + } + + return algName; +} + +dqm_core::Result * +dqm_algorithms::tools::ExecuteNamedAlgorithm(const std::string & name, const TObject & object, const dqm_core::AlgorithmConfig & config) +{ + // Function to find and execute the named algorithm + dqm_core::Algorithm* algorithm = 0; + + if (name.compare("None") == 0 ) { + throw dqm_core::BadConfig( ERS_HERE,"no auxiliary algorithm specified", name); + } + + try { + algorithm = dqm_core::AlgorithmManager::instance().getAlgorithm(name); + } + catch( dqm_core::Exception& ex ) { + throw dqm_core::BadConfig( ERS_HERE,"unable to get algorithm of this name", name); + } + + return algorithm->execute(name,object,config); +} + + +void +dqm_algorithms::tools::ModifyHistogram(TH1 * histogram, const dqm_core::AlgorithmConfig & config) +{ + if (config.getParameters().empty()){ + //Nothing to do + return; + } + std::map<std::string,double > confParams = config.getParameters();//Copy is necessary as AlgorithmConfig does not return map by reference (bug?) + for ( std::map<std::string,double >::const_iterator itr = confParams.begin();itr != confParams.end();++itr ) { + if ( itr->first.find("MultiplyHistogramByValue") != std::string::npos ){ + histogram->Scale(itr->second); + continue; + } + if ( itr->first.find("DivideHistogramByValue") != std::string::npos ){ + histogram->Scale( (1./itr->second) ); + continue; + } + size_t stringPos; + std::string configTag = "SetHistogramTitle"; + if ( (stringPos = itr->first.find(configTag)) != std::string::npos ){ + stringPos += configTag.length(); + histogram->SetTitle( (itr->first.substr(stringPos)).c_str() ); + continue; + } + } +} + +TH1* +dqm_algorithms::tools::BookHistogramByExample(const TH1* histogram, const std::string& name, const std::string& title, AxisType axisType){ + + switch (axisType) { + case XYAxes: + + if (histogram->GetDimension() == 1){ + throw dqm_core::BadConfig( ERS_HERE, name,"can't make a 2D histogram from a 1D histogram"); + } + TH2F * resultXY; + if(histogram->GetXaxis()->IsVariableBinSize()) { + resultXY = new TH2F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXbins()->GetArray(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXbins()->GetArray()); + } + else { + resultXY = new TH2F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXmin(),histogram->GetXaxis()->GetXmax(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXmin(),histogram->GetYaxis()->GetXmax()); + } + + resultXY->SetXTitle(histogram->GetXaxis()->GetTitle()); + resultXY->SetYTitle(histogram->GetYaxis()->GetTitle()); + return (TH1*) resultXY; + + case YAxis: + + if (histogram->GetDimension() == 1){ + throw dqm_core::BadConfig( ERS_HERE, name, "can't extract a Y-Axis from a 1D histogram"); + } + TH1F *resultY; + if(histogram->GetYaxis()->IsVariableBinSize()) { + resultY = new TH1F(name.c_str(),title.c_str(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXbins()->GetArray()); + } + else { + resultY = new TH1F(name.c_str(),title.c_str(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXmin(),histogram->GetYaxis()->GetXmax()); + } + resultY->SetXTitle(histogram->GetYaxis()->GetTitle()); + return (TH1*) resultY; + + case XYZAxes: + + if (histogram->GetDimension() < 3){ + throw dqm_core::BadConfig( ERS_HERE, name, "can't make a 3D histrogram without at least a 3D histogram"); + } + TH3F *resultXYZ; + if(histogram->GetXaxis()->IsVariableBinSize()) { + resultXYZ = new TH3F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXbins()->GetArray(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXbins()->GetArray(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXbins()->GetArray()); + } + else { + resultXYZ = new TH3F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXmin(),histogram->GetXaxis()->GetXmax(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXmin(),histogram->GetYaxis()->GetXmax(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXmin(),histogram->GetZaxis()->GetXmax()); + } + resultXYZ->SetXTitle(histogram->GetXaxis()->GetTitle()); + resultXYZ->SetYTitle(histogram->GetYaxis()->GetTitle()); + resultXYZ->SetZTitle(histogram->GetZaxis()->GetTitle()); + return resultXYZ; + + case XZAxes: + + if (histogram->GetDimension() < 3){ + throw dqm_core::BadConfig( ERS_HERE, name,"can't extract a Z-Axis from a dimension < 3 histogram"); + } + TH2F * resultXZ; + if(histogram->GetXaxis()->IsVariableBinSize()) { + resultXZ = new TH2F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXbins()->GetArray(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXbins()->GetArray()); + } + else { + resultXZ = new TH2F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXmin(),histogram->GetXaxis()->GetXmax(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXmin(),histogram->GetZaxis()->GetXmax()); + } + resultXZ->SetXTitle(histogram->GetXaxis()->GetTitle()); + resultXZ->SetYTitle(histogram->GetZaxis()->GetTitle()); + return (TH1*) resultXZ; + + case YZAxes: + + if (histogram->GetDimension() < 3){ + throw dqm_core::BadConfig( ERS_HERE, name,"can't extract a Z-Axis from a dimension < 3 histogram"); + } + TH2F * resultYZ; + if(histogram->GetYaxis()->IsVariableBinSize()) { + resultYZ = new TH2F(name.c_str(),title.c_str(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXbins()->GetArray(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXbins()->GetArray()); + } + else { + resultYZ = new TH2F(name.c_str(),title.c_str(), + histogram->GetNbinsY(),histogram->GetYaxis()->GetXmin(),histogram->GetYaxis()->GetXmax(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXmin(),histogram->GetZaxis()->GetXmax()); + } + resultYZ->SetXTitle(histogram->GetYaxis()->GetTitle()); + resultYZ->SetYTitle(histogram->GetZaxis()->GetTitle()); + return (TH1*) resultYZ; + + case ZAxis: + + if (histogram->GetDimension() < 3){ + throw dqm_core::BadConfig( ERS_HERE, name, "can't extract a Z-Axis from a dimension < 3 histogram"); + } + TH1F *resultZ; + if(histogram->GetZaxis()->IsVariableBinSize()) { + resultZ = new TH1F(name.c_str(),title.c_str(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXbins()->GetArray()); + } + else { + resultZ = new TH1F(name.c_str(),title.c_str(), + histogram->GetNbinsZ(),histogram->GetZaxis()->GetXmin(),histogram->GetZaxis()->GetXmax()); + } + resultZ->SetXTitle(histogram->GetZaxis()->GetTitle()); + return (TH1*) resultZ; + + case XAxis: + default: + + TH1F *resultX; + if(histogram->GetXaxis()->IsVariableBinSize()) { + resultX = new TH1F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXbins()->GetArray()); + } + else { + resultX = new TH1F(name.c_str(),title.c_str(), + histogram->GetNbinsX(),histogram->GetXaxis()->GetXmin(),histogram->GetXaxis()->GetXmax()); + } + resultX->SetXTitle(histogram->GetXaxis()->GetTitle()); + return (TH1*) resultX ; + } + +} + +void +dqm_algorithms::tools::handleReference( const TObject& ro , + TObject*& firstReference , + TObject*& secondReference ) +{ + if ( ro.InheritsFrom("TH1") ) + { + //Simple reference + firstReference = const_cast<TObject*>(&ro); + secondReference = 0; + return; + } + else if ( ro.InheritsFrom("TCollection") ) + { + //The reference is a collection of TObjects + const TCollection* coll = static_cast<const TCollection*>(&ro); + TIterator* it = coll->MakeIterator(); + TObject* content = it->Next(); + if ( content == 0 || content->InheritsFrom("TH1") == kFALSE ) + { + throw dqm_core::BadRefHist(ERS_HERE,"handleReference"," Could not retreive reference"); + } + firstReference = static_cast<TH1 *>(content); + Int_t csize = coll->GetEntries(); + if ( csize == 1 ) + { + //Only one element, no secondReference is available. + secondReference = 0; + return; + } + else if ( coll->GetEntries() == 2 ) + { + //The collection is a pair, the second reference will be used directly + secondReference = it->Next(); + return; + } + else + { + //This case is more complex, we basically want to create a new collection without the first element + secondReference = static_cast<TObject*>( (coll->IsA())->New() );//Create a new container of the same class as the original one + if ( secondReference == 0 || secondReference->InheritsFrom("TCollection") == kFALSE ) + { + throw dqm_core::BadRefHist(ERS_HERE,"handleReference"," Could not retreive reference"); + } + while ( (content = it->Next()) )//start from second element, since we already called Next() + { + static_cast<TCollection*>(secondReference)->Add(content); + } + return; + } + } + else + { + //This kind of reference is not supported + throw dqm_core::BadRefHist(ERS_HERE,"handleReference"," Could not retreive reference"); + } +} + + + +void +dqm_algorithms::tools::findOutliers( std::vector<binContainer>& input, double& mean, double& scale, int& nIn, + int nIterations, double exponent, double threshold, double SBCF, double nStop) { + + int size = input.size(); + if(size < 2) { + return; + } + + if (nStop < 0) nStop = 0; + if (SBCF < 0) SBCF = 0; + + std::vector<binContainer>::const_iterator cbegin = input.begin(); + std::vector<binContainer>::const_iterator cend = input.end(); + + std::vector<binContainer>::iterator begin = input.begin(); + std::vector<binContainer>::iterator end = input.end(); + + nIn = 0; + mean = 0; + scale = 0; + + double newMean = 0; + double newScale = 0; + for ( int j = 0; j < nIterations ; j++ ) { + mean = newMean; + scale = newScale; + + int newNin = 0; + double sum = 0; + //Loop to test, counting and summing elements that pass: + for ( std::vector<binContainer>::iterator it = begin; it != end; ++it ) { + //The Test: + it->test = ( (fabs(it->value - mean) < (threshold * scale) ) || (j==0) ); + if ( it->test ) { + sum += it->value; + newNin++; + } + } + int nOut = size - newNin; + // Check if the iteration process is complete (or failed): + if (newNin < (2 + nStop + SBCF * nOut) ) { + return; + } + newMean = newNin ? (sum / newNin) : 0; // avoid to divide by zero (should never happen) + // Check if the iteration process has stabilized: + if ( (newNin == nIn) && (newMean == mean) ) { + return; + } + nIn = newNin; + + // Calculate the scale parameter: + double scaleSum = 0; + for ( std::vector<binContainer>::const_iterator it = cbegin; it != cend; ++it ) { + if(it->test) { + scaleSum += pow( fabs(it->value - newMean) , exponent ); + } + } + newScale = pow( scaleSum / (nIn - 1 - (SBCF * nOut) ), 1/exponent); + } + return; +} + +void +dqm_algorithms::tools::findOutliersUsingErrors( std::vector<binContainer>& input, double& mean, double& meanError, int& nIn, double minDiff, int minNin ) { + + + //Perform outlier determination using the bin errors and the relative pull on the mean, + // Taken from algorithm by Michele Petteni + + if( minDiff < 0 ) minDiff = 0; + if( minNin < 2) minNin = 3; + + nIn = input.size(); + if(nIn < minNin) { + return; + } + meanError = 0; + + + std::vector<binContainer>::iterator begin = input.begin(); + std::vector<binContainer>::iterator end = input.end(); + + //First pass: calucalate the mean: + double sum = 0; + double sumError2 = 0; + for( std::vector<binContainer>::iterator it = begin; it != end; ++it ) { + sum += it->value; + sumError2 += pow(it->error,2); + it->test = true; + } + mean = sum / nIn; + meanError = sqrt( sumError2/ nIn ); + //Loop to tag and remove outliers: + while( nIn > 2 ) { + + //Use map for ordering by distance from mean: + std::map<double,binContainer*> absDiffMap; + for( std::vector<binContainer>::iterator it = begin; it != end; ++it ) { + if( it->test ) { + absDiffMap[ fabs( it->value - mean ) ] = &(*it); + } + } + + //If max(absDiff) < minDiff, this is not considered an outlier: we are done. + std::map<double,binContainer*>::iterator outlierCandidate = absDiffMap.end(); + outlierCandidate--;//<- the last element in a map is the largest. + if( outlierCandidate->first < minDiff ) { + return; + } + + //Find the mean and its error if we exclude the outlier candidate: + double newMean = 0; + double newMeanError = 0; + sum = 0; + for( std::map<double,binContainer*>::iterator it = absDiffMap.begin(); it != outlierCandidate; ++it) { + sum += it->second->value; + sumError2 += pow(it->second->error,2); + } + newMean = sum/(nIn - 1); + newMeanError = sqrt( sumError2/(nIn - 2) ); + + double meanShift = fabs( mean - newMean ); + + //If the shift is bigger than the new error the candidate is an outlier: mark it and move on to the next one. + if( meanShift > newMeanError ) { + outlierCandidate->second->test = false; + mean = newMean; + meanError = newMeanError; + nIn--; + } + else { + return; + } + } +} + +dqm_algorithms::tools::binCluster +dqm_algorithms::tools::buildCluster( binContainer& seed, const std::vector<std::vector<binContainer*> >& binMap, + const std::vector<double>& xValues, const std::vector<double>& yValues, double threshold, int topology ) { + + binCluster cluster = {0.,0.,xValues[seed.ix],yValues[seed.iy],-1.,0,seed.ix,seed.ix,seed.iy,seed.iy}; + std::list<binContainer*> binsToCheck; + std::vector<binContainer*> binsInCluster; + binsToCheck.push_back(&seed); + double pvpX = 0; + double pvpY = 0; + double error2 = 0; + + double maxDistanceX = -1; + double maxDistanceY = -1; + int ixRangeMax = (int)xValues.size() - 2; + int iyRangeMax = (int)yValues.size() - 2; + + switch(topology) { + case CylinderX: + maxDistanceY = (yValues.back() - yValues.front()) / 2; + break; + case CylinderY: + maxDistanceX = (xValues.back() - xValues.front()) / 2; + break; + case Torus: + maxDistanceX = (xValues.back() - xValues.front()) / 2; + maxDistanceY = (yValues.back() - yValues.front()) / 2; + break; + } + + while( binsToCheck.size() != 0) { + + std::list<binContainer*> newNeighbors; + for( std::list<binContainer*>::const_iterator bin = binsToCheck.begin(); bin != binsToCheck.end(); ++bin ) { + + //If bin is a null pointer, continue to the next bin: + if( *bin == 0) { + continue; + } + + //If the bin passes the threshold, add its values to the clusters and its neighbors to the list of bins to look at: + //(As long as it hasn't already been added to another cluster or otherwise excluded) + if( ( fabs((*bin)->value) > (threshold + 5*(*bin)->error ) ) && ( (*bin)->test == 0 ) && ((*bin)->error >= 0) ) { + //Add bin to cluster: + binsInCluster.push_back(*bin); + (*bin)->test = 10; + + cluster.value += (*bin)->value; + error2 += pow( (*bin)->error, 2); + cluster.n++; + + int ix = (*bin)->ix; + int iy = (*bin)->iy; + double xPosition = xValues[ix]; + double yPosition = yValues[iy]; + + //Adjust position information if it looks like we may have jumped a discontinuity + // and such discontinuities are expected. Also check for max, min ix, iy: + if( (maxDistanceX > 0) && (fabs(xPosition - cluster.x) > maxDistanceX) ) { + //Correct for topological mapping difficulties: + if( xPosition < maxDistanceX ) { + xPosition += 2 * maxDistanceX; + if( (ix + ixRangeMax) > cluster.ixmax ) { + cluster.ixmax = ix + ixRangeMax; + } + } + else { + xPosition -= 2 * maxDistanceX; + if( (ix - ixRangeMax) < cluster.ixmin ) { + cluster.ixmin = ix - ixRangeMax; + } + } + } + else { + //No topological difficulties: + if( ix < cluster.ixmin ) { + cluster.ixmin = ix; + } + if( ix > cluster.ixmax ) { + cluster.ixmax = ix; + } + } + + if( (maxDistanceY > 0) && (fabs(yPosition - cluster.y) > maxDistanceY) ) { + //Correct for topological mapping difficulties: + if( yPosition < maxDistanceY ) { + yPosition += 2 * maxDistanceY; + if( (iy + iyRangeMax) > cluster.iymax ) { + cluster.iymax = iy + iyRangeMax; + } + } + else { + yPosition -= 2 * maxDistanceY; + if( (iy - iyRangeMax) < cluster.iymin ) { + cluster.iymin = iy - iyRangeMax; + } + } + } + else { + //No topological difficulties: + if( iy < cluster.iymin ) { + cluster.iymin = iy; + } + if( iy > cluster.iymax ) { + cluster.iymax = iy; + } + } + + pvpX += xPosition * (*bin)->value; + pvpY += yPosition * (*bin)->value; + + + //Find neighbors + newNeighbors.push_back( binMap[ix+1][iy+1] ); + newNeighbors.push_back( binMap[ix+1][iy] ); + newNeighbors.push_back( binMap[ix+1][iy-1] ); + + newNeighbors.push_back( binMap[ix][iy+1] ); + newNeighbors.push_back( binMap[ix][iy-1] ); + + newNeighbors.push_back( binMap[ix-1][iy+1] ); + newNeighbors.push_back( binMap[ix-1][iy] ); + newNeighbors.push_back( binMap[ix-1][iy-1] ); + + + } + }//End looping over binsToCheck (last set of neighbors) + + //Remove repeated references to the same bin: + newNeighbors.unique(); + //Perpare to check the cluster's new neighbors: + binsToCheck = newNeighbors; + + cluster.x = pvpX / cluster.value; + cluster.y = pvpY / cluster.value; + }//Finished finding bins in cluster + + //Assume that the input errors are uncorrelated (or that the caller will deal with this) + cluster.error = sqrt( error2 ); + + //loop to calculate the radius of the cluster (the value weighted average distance from its center) + double dvpSum = 0; + for(std::vector<binContainer*>::const_iterator bin = binsInCluster.begin(); bin != binsInCluster.end(); ++bin) { + double xDistance = fabs( xValues[(*bin)->ix] - cluster.x ); + double yDistance = fabs( yValues[(*bin)->iy] - cluster.y ); + if (maxDistanceX > 0 && (xDistance > maxDistanceX) ) { + xDistance = 2 * maxDistanceX - xDistance; + } + if (maxDistanceY > 0 && (yDistance > maxDistanceY) ) { + yDistance = 2 * maxDistanceY - yDistance; + } + + dvpSum += (*bin)->value * sqrt( pow( xValues[(*bin)->ix] - cluster.x,2) + pow(yValues[(*bin)->iy] - cluster.y,2) ); + } + cluster.radius = dvpSum / cluster.value; + + //Check that positions are within the bounds of the histogram and correct + while( cluster.ixmin < 1 ){ + cluster.ixmin += ixRangeMax; + } + while( cluster.ixmax > ixRangeMax ){ + cluster.ixmax -= ixRangeMax; + } + while( cluster.iymin < 1 ){ + cluster.iymin += iyRangeMax; + } + while( cluster.iymax > iyRangeMax ){ + cluster.iymax -= iyRangeMax; + } + + if( cluster.x < xValues.front() ) { + cluster.x += 2 * maxDistanceX; + } + if( cluster.x > xValues.back() ) { + cluster.x -= 2 * maxDistanceX; + } + if( cluster.y < yValues.front() ) { + cluster.y += 2 * maxDistanceY; + } + if( cluster.y > yValues.back() ) { + cluster.y -= 2 * maxDistanceY; + } + + + return cluster; +} + + +//Method to map bins in binContainer based on binContainer::ix, binContainer::iy, and chosen topology +std::vector<std::vector<dqm_algorithms::tools::binContainer*> > +dqm_algorithms::tools::makeBinMap(std::vector<dqm_algorithms::tools::binContainer>& bins, int ixmax, int iymax, int topology) { + + std::vector<binContainer*> emptyVector; + for(int iy = 0; iy <= iymax + 1; ++iy) { + binContainer* emptyPointer = 0; + emptyVector.push_back(emptyPointer); + } + std::vector<std::vector<binContainer*> > binMap; + for(int ix = 0; ix <= ixmax + 1; ++ix) { + binMap.push_back(emptyVector); + } + switch(topology) { + //The mapping depends on the topology of the histogram. + case CylinderX: + //Cylinder About X-Axis (default topology), wraps max Y to min Y. + //Connect iy == 1 with iy == iymax while leaving hard (null pointer) walls at ix = 0 and ix = imax+1: + for (std::vector<binContainer>::iterator it = bins.begin(); it != bins.end(); ++it) { + binMap[it->ix][it->iy] = &(*it); + if(it->iy == 1){ + binMap[it->ix][iymax+1] = &(*it); + } + else if(it->iy == iymax){ + binMap[it->ix][0] = &(*it); + } + } + break; + + case CylinderY: + //Cylinder About Y-Axis + //Connect ix == 1 with ix == ixmax while leaving hard (null pointer) walls at iy = 0 and iy = imax+1: + for (std::vector<binContainer>::iterator it = bins.begin(); it != bins.end(); ++it) { + binMap[it->ix][it->iy] = &(*it); + if(it->ix == 1){ + binMap[ixmax+1][it->iy] = &(*it); + } + else if(it->ix == ixmax){ + binMap[0][it->iy] = &(*it); + } + } + break; + + case Torus: + //Torus: + //Connect iy == 1 with iy == iymax and ix == 1 with ix == ixmax + for (std::vector<binContainer>::iterator it = bins.begin(); it != bins.end(); ++it) { + binMap[it->ix][it->iy] = &(*it); + if(it->ix == 1){ + binMap[ixmax+1][it->iy] = &(*it); + if(it->iy == 1){ + binMap[ixmax+1][iymax+1] = &(*it); + } + if(it->iy == iymax){ + binMap[ixmax+1][0] = &(*it); + } + } + else if(it->ix == ixmax){ + binMap[0][it->iy] = &(*it); + if(it->iy == 1){ + binMap[0][iymax+1] = &(*it); + } + if(it->iy == iymax){ + binMap[0][0] = &(*it); + } + } + if(it->iy == 1){ + binMap[it->ix][iymax+1] = &(*it); + } + else if(it->iy == iymax){ + binMap[it->ix][0] = &(*it); + } + } + break; + + default: + //Rectangle: + //Treat the histogram as a simple rectangle, leaving null pointers at its boundaries: + for (std::vector<binContainer>::iterator it = bins.begin(); it != bins.end(); ++it) { + binMap[it->ix][it->iy] = &(*it); + } + } + return binMap; +} + +//An attempt to generalize the status combination process with the use of weights: +//Worst Case: +dqm_core::Result::Status +dqm_algorithms::tools::WorstCaseAddStatus(dqm_core::Result::Status baseStatus, dqm_core::Result::Status addedStatus, float weight) { + //-- Acts analogously to a logical OR -- (Red <-> True, etc.) + + if(baseStatus == dqm_core::Result::Red) { + return dqm_core::Result::Red; + } + //apply the "weight" to addedstatus only: + if( weight <= 0 ) { + return baseStatus; + } + + if( weight <= 0.25 ) { + if( addedStatus == dqm_core::Result::Yellow ) { + addedStatus = dqm_core::Result::Green; + } + } + if( weight <= 0.5 ) { + if( addedStatus == dqm_core::Result::Red) { + addedStatus = dqm_core::Result::Yellow; + } + } + + if(addedStatus == dqm_core::Result::Red) { + return dqm_core::Result::Red; + } + + if(baseStatus == dqm_core::Result::Disabled) { + return addedStatus; + } + if(addedStatus == dqm_core::Result::Disabled) { + return baseStatus; + } + if(baseStatus == dqm_core::Result::Undefined) { + return addedStatus; + } + if(addedStatus == dqm_core::Result::Undefined) { + return baseStatus; + } + + if( (baseStatus == dqm_core::Result::Green) && (addedStatus == dqm_core::Result::Green) ) { + return dqm_core::Result::Green; + } + + return dqm_core::Result::Yellow; +} +//Best Case: +dqm_core::Result::Status +dqm_algorithms::tools::BestCaseAddStatus(dqm_core::Result::Status baseStatus, dqm_core::Result::Status addedStatus, float weight) { + //-- Acts analogously to a logical AND -- (Red <-> True, etc.) + + //apply the "weight" to addedstatus only: (same scheme as in WorstCaseAddStatus) + if( weight <= 0 ) { + return baseStatus; + } + if( weight <= 0.25 ) { + if( addedStatus == dqm_core::Result::Yellow ) { + addedStatus = dqm_core::Result::Green; + } + } + if( weight <= 0.5 ) { + if( addedStatus == dqm_core::Result::Red) { + addedStatus = dqm_core::Result::Yellow; + } + } + + if( (baseStatus == dqm_core::Result::Disabled) || (addedStatus == dqm_core::Result::Disabled) ) { + return dqm_core::Result::Disabled; + } + + if( (baseStatus == dqm_core::Result::Undefined) || (addedStatus == dqm_core::Result::Undefined) ) { + return dqm_core::Result::Undefined; + } + + if( (baseStatus == dqm_core::Result::Green) || (addedStatus == dqm_core::Result::Green) ) { + return dqm_core::Result::Green; + } + + if( (baseStatus == dqm_core::Result::Red) && (addedStatus == dqm_core::Result::Red) ) { + return dqm_core::Result::Red; + } + + return dqm_core::Result::Yellow; + +} + + +std::pair<double,double> +dqm_algorithms::tools::CalcBinsProbChisq(std::vector<double> inputval,std::vector<double> inputerr,std::vector<double> x0,std::vector<double> x0err){ + + double chisq = 0.; + std::vector<double>::iterator iter_vals = inputval.begin(); + std::vector<double>::iterator iter_err = inputerr.begin(); + + std::vector<double>::iterator iter_x0 = x0.begin(); + std::vector<double>::iterator iter_x0err = x0err.begin(); + + int ndf = 0; + for ( ; iter_vals != inputval.end(); ++iter_vals,++iter_err,++iter_x0,++iter_x0err){ + if (fabs(*iter_err) > 1.0e-5 || fabs(*iter_x0err) > 1.0e-5){ + double chisq_cont = pow(((*iter_vals)-(*iter_x0)),2.)/(pow(*iter_err,2.0)+pow(*iter_x0err,2.0)); + ++ndf; + chisq += chisq_cont; + } + } + + double prob = ROOT::Math::chisquared_cdf_c(chisq,ndf); + double sigma_chisq = ROOT::Math::normal_quantile_c(prob,1.); + return std::make_pair(prob,sigma_chisq); +} + +std::pair<double,double> +dqm_algorithms::tools::CalcBinsProbChisq(std::vector<double> inputval,std::vector<double> inputerr,double x0,double x0_err){ + + double chisq = 0.; + std::vector<double>::iterator iter_vals = inputval.begin(); + std::vector<double>::iterator iter_err = inputerr.begin(); + int ndf = 0; + for ( ; iter_vals != inputval.end(); ++iter_vals,++iter_err){ + if (fabs(*iter_err) > 1.0e-5){ + double chisq_cont = pow(((*iter_vals)-x0),2.)/(pow(*iter_err,2.0)+pow(x0_err,2.0)); + ++ndf; + chisq += chisq_cont; + } + } + + double prob = ROOT::Math::chisquared_cdf_c(chisq,ndf); + double sigma_chisq = ROOT::Math::normal_quantile_c(prob,1.); + return std::make_pair(prob,sigma_chisq); +} + +void +dqm_algorithms::tools::MergePastMinStat(std::vector<std::vector<tools::binContainer> >& strips, int minStat) { + //Method to merge neighboring vectors so that all non-empty vectors have a size of at least minStat + //If two vectors are equally close to the vector with size < minstat, it will be merged with the one + //with the smallest size. + + if(strips.size() < 2) { + return; + } + + std::vector<std::vector<tools::binContainer> >::iterator begining = strips.begin(); + std::vector<std::vector<tools::binContainer> >::iterator ending = strips.end(); + --ending; + + while ( begining != ending ) { + std::vector<std::vector<tools::binContainer> >::iterator minBinsItr = begining; + for( std::vector<std::vector<tools::binContainer> >::iterator itr = begining; itr != (ending+1); ++itr ) { + if( (!itr->empty()) && ((itr->size() < minBinsItr->size()) || minBinsItr->empty()) ) { + minBinsItr = itr; + } + } + + if( ((int)minBinsItr->size()) < minStat ) { + if( minBinsItr == begining ) { + //Merge right + std::vector<std::vector<tools::binContainer> >::iterator mergeStripItr = minBinsItr; + ++mergeStripItr; + while( mergeStripItr->empty() ) { + ++mergeStripItr; + if( mergeStripItr == ending ) break; + } + mergeStripItr->insert( mergeStripItr->end(), minBinsItr->begin(), minBinsItr->end() ); + minBinsItr->clear(); + begining = mergeStripItr; + } + else if( minBinsItr == ending ) { + //Merge left + std::vector<std::vector<tools::binContainer> >::iterator mergeStripItr = minBinsItr; + --mergeStripItr; + while( mergeStripItr->empty() ) { + --mergeStripItr; + if( mergeStripItr == begining ) break; + } + mergeStripItr->insert( mergeStripItr->end(), minBinsItr->begin(), minBinsItr->end() ); + minBinsItr->clear(); + ending = mergeStripItr; + } + else { + //Merge with the smallest of nearest neighbors: + std::vector<std::vector<tools::binContainer> >::iterator mergeLeftItr = minBinsItr; + std::vector<std::vector<tools::binContainer> >::iterator mergeRightItr = minBinsItr; + --mergeLeftItr; + ++mergeRightItr; + while( mergeLeftItr->empty() && mergeRightItr->empty() ) { + --mergeLeftItr; + ++mergeRightItr; + } + if( mergeLeftItr->empty() ) { + mergeRightItr->insert( mergeRightItr->end(), minBinsItr->begin(), minBinsItr->end() ); + minBinsItr->clear(); + } + else if( mergeRightItr->empty() ) { + mergeLeftItr->insert( mergeLeftItr->end(), minBinsItr->begin(), minBinsItr->end() ); + minBinsItr->clear(); + } + else { + if( mergeLeftItr->size() < mergeRightItr->size() ) { + mergeLeftItr->insert( mergeLeftItr->end(), minBinsItr->begin(), minBinsItr->end() ); + minBinsItr->clear(); + } + else { + mergeRightItr->insert( mergeRightItr->end(), minBinsItr->begin(), minBinsItr->end() ); + minBinsItr->clear(); + } + } + } + } + else { + break; + } + } +} + +void +dqm_algorithms::tools::MakeBinTag( const binContainer& bin, std::string & tag ) { + if(bin.error < 0) { + return; + } + tag += "(eta,phi)[err]= ("; + FormatToSize(bin.x,6,tag,true); + tag += ","; + FormatToSize(bin.y,6,tag,true); + tag += ")["; + FormatToSize(bin.error,5,tag,false); + tag += "]"; +} + +void +dqm_algorithms::tools::FormatToSize( double value, int size, std::string & str, bool showSign) { + //Method to append size characters representing value to string str + + char temp[35]; + + if( value == 0 ) { + int prec = size - 2; + if(prec < 0) prec = 0; + sprintf(temp,"%.*f",prec,value); + str += temp; + return; + } + + std::string format; + if(showSign) { + format = "%+0*.*"; + } + else { + format = "%0*.*"; + } + + int order = (int) floor( log10(fabs(value)) ); + + if( (size > 34) || (size < 1) || ((size < 5) && (order > size)) ) { + size = 5; + } + + int prec = 0; + if( (value > 0) && !showSign ) { + if( ( (abs(order) > (size-3)) || (order < -2) ) && (size > 4) ) { + prec = size-6; + if(prec < 0) prec = 0; + format += "e"; + } + else if( order == -1 ) { + prec = size - 2; + if(prec < 0) prec = 0; + format += "f"; + } + else { + prec = size - order -2; + if(prec > (size - 2) ) prec = size - 2; + if(prec < 0) prec = 0; + format += "f"; + } + } + else { + if( ( (abs(order) > (size-3)) || (order < -2) ) && (size > 4) ) { + prec = size-7; + if(prec < 0) prec = 0; + format += "e"; + } + else if( order == -1 ) { + prec = size - 3; + if(prec < 0) prec = 0; + format += "f"; + } + else { + prec = size - order -3; + if(prec > (size - 3) ) prec = size - 3; + if(prec < 0) prec = 0; + format += "f"; + } + } + + sprintf(temp,format.c_str(),size,prec,value); + + str += temp; +} + +#endif // #ifndef DQM_ALGORITHMS_TOOLS_ALGORITHMHELPER_CXX diff --git a/DataQuality/dqm_algorithms/tools/DumpConfig.cxx b/DataQuality/dqm_algorithms/tools/DumpConfig.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9ed7f64bb89015b38ff29daf3365c43171a49617 --- /dev/null +++ b/DataQuality/dqm_algorithms/tools/DumpConfig.cxx @@ -0,0 +1,247 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include <vector> +#include <dqm_algorithms/tools/DumpConfig.h> + +using namespace std; + +dqm_algorithms::tools::DumpConfig::DumpConfig(std::string ParameterName,dqm_core::test::DummyAlgorithmConfig & config, std::string algorithmname, std::string histogramname, std::string reffilename,std::string refhistogramname, float weight, std::string regionname){ +_ParameterName=ParameterName; + _config=config; + _algorithmname=algorithmname; + _histogramname=histogramname; + _weight=weight; + _refhistogramname=refhistogramname; + _reffilename=reffilename; + _regionname=regionname; + +} + +dqm_algorithms::tools::DumpConfig::~DumpConfig(){ +} + +void +dqm_algorithms::tools::DumpConfig::DumpRegion() { + _myfile<<"<obj class=\"DQRegion\" id=\""+_regionname+"\">\n"; + _myfile<<"<attr name=\"InputDataSource\" type=\"string\">\"\"</attr>\n"; + _myfile<<"<attr name=\"Weight\" type=\"float\">1</attr>\n"; + _myfile<<"<attr name=\"Action\" type=\"string\">\"\"</attr>\n"; + _myfile<<"<rel name=\"Algorithm\">\"DQAlgorithm\" \"SimpleSummary\"</rel>\n"; + _myfile<<"<rel name=\"AlgorithmParameters\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"References\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"GreenThresholds\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"RedThresholds\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"DQRegions\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"DQParameters\" num=\"1\">\n"; + _myfile<<" \"DQParameter\" \""+_ParameterName+"\"\n"; + _myfile<<"</rel>\n"; +_myfile<<"</obj>\n\n"; + +} + +void +dqm_algorithms::tools::DumpConfig::DumpAgent() { + _myfile<<"<obj class=\"DQAgent\" id=\""+_regionname+"\">\n"; + _myfile<<"<attr name=\"Parameters\" type=\"string\">\"-n "+_regionname+" -p ${TDAQ_PARTITION}\"</attr>\n"; + _myfile<<"<attr name=\"RestartParameters\" type=\"string\">\"-n "+_regionname+" -p ${TDAQ_PARTITION}\"</attr>\n"; + _myfile<<"<attr name=\"ControlledByOnline\" type=\"bool\">1</attr>\n"; + _myfile<<"<attr name=\"IfDies\" type=\"enum\">\"Restart\"</attr>\n"; + _myfile<<"<attr name=\"IfFailed\" type=\"enum\">\"Restart\"</attr>\n"; + _myfile<<"<attr name=\"StartAt\" type=\"enum\">\"Boot\"</attr>\n"; + _myfile<<"<attr name=\"StopAt\" type=\"enum\">\"Shutdown\"</attr>\n"; + _myfile<<"<attr name=\"InitTimeout\" type=\"u32\">0</attr>\n"; + _myfile<<"<attr name=\"StartIn\" type=\"string\">\"\"</attr>\n"; + _myfile<<"<attr name=\"InputDevice\" type=\"string\">\"\"</attr>\n"; + _myfile<<"<attr name=\"Logging\" type=\"bool\">1</attr>\n"; + _myfile<<"<rel name=\"InitializationDependsFrom\" num=\"0\">\n"; + _myfile<<"</rel>\n"; + _myfile<<"<rel name=\"ShutdownDependsFrom\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"Program\">\"Binary\" \"dqmf_agent\"</rel>\n"; + _myfile<<"<rel name=\"ExplicitTag\">\"\" \"\"</rel>\n"; + _myfile<<"<rel name=\"Uses\" num=\"0\"></rel>\n"; + _myfile<<"<rel name=\"ProcessEnvironment\" num=\"0\">\n"; + _myfile<<"</rel>\n"; + _myfile<<"<rel name=\"RunsOn\">\"\" \"\"</rel>\n"; + _myfile<<"<rel name=\"DQRegions\" num=\"1\">\n"; + _myfile<<" \"DQRegion\" \""+_regionname+"\"\n"; + _myfile<<"</rel>\n"; +_myfile<<"</obj>\n"; + + +} + + +void +dqm_algorithms::tools::DumpConfig::WriteThresholdFromMap(std::map<std::string,double> object,std::string _ParameterName,std::string Name){ + int objsize=object.size(); + char line[500]; +sprintf(line, "<rel name=\"%sThresholds\" num=\"%d\">\n", Name.c_str(),objsize); + _myfile<<line; + std::map<std::string,double>::const_iterator iter; + + for (iter=object.begin();iter!=object.end();iter++){ + if (Name == "Red"){ + red_id.push_back(Name+"Thresh_"+_ParameterName+"_"+iter->first); + }else { + green_id.push_back(Name+"Thresh_"+_ParameterName+"_"+iter->first); + } + + _myfile <<" \"DQThreshold\" \""+Name+"Thresh_"+_ParameterName+"_"+iter->first+"\"\n"; + + } + _myfile<<"</rel>\n"; + +} + +void +dqm_algorithms::tools::DumpConfig::DumpThresholds(){ + + std::map<std::string,double>::iterator iter; + int count=0; + char line[500]; + std::map<std::string,double> thresh; + std::vector<std::string> id; + for (int i=0; i<2;++i){ + if (i== 0 ) { + thresh=gthresh; + id=green_id; + }else { + thresh=rthresh; + id=red_id; + } + + for (iter=thresh.begin();iter!=thresh.end();iter++){ + _myfile<<"<obj class=\"DQThreshold\" id=\""+id[count]+"\">\n"; + _myfile<<" <attr name=\"Name\" type=\"string\">\""+iter->first+"\"</attr>\n"; + sprintf(line, " <attr name=\"Value\" type=\"double\">%4.2f</attr>\n</obj>\n\n",iter->second); + _myfile<<line; + ++count; + } + count=0; + } + +} + +void +dqm_algorithms::tools::DumpConfig::DumpParams(){ + + std::map<std::string,double>::const_iterator iter; + char pline[500]; + int count=0; + + for (iter=params.begin();iter!=params.end();iter++){ + _myfile<<"<obj class=\"DQAlgorithmParameter\" id=\""+param_id[count]+"\">\n"; + _myfile<<" <attr name=\"Name\" type=\"string\">\""+iter->first+"\"</attr>\n"; + sprintf(pline, " <attr name=\"Value\" type=\"double\" num=\"1\">%4.2f</attr>\n</obj>\n\n",iter->second); + _myfile<<pline; + ++count; + } + +} + + + +void +dqm_algorithms::tools::DumpConfig::DumpOnlineConfig(std::string filename, bool dumpAgent) { + + _myfile.open(filename.c_str()); + //open file + int length; + char * buffer; + + ifstream is; + is.open ("../share/oks-xml-header.txt", ios::in ); + + // get length of file: + is.seekg (0, ios::end); + length = is.tellg(); + is.seekg (0, ios::beg); + + // allocate memory: + buffer = new char [length]; + + // read data as a block: + is.read (buffer,length); + is.close(); + + _myfile.write (buffer,length); + + delete[] buffer; + + if (_regionname != ""){ + DumpRegion(); + if (dumpAgent) { + DumpAgent(); + } + } + + _myfile << "<obj class=\"DQParameter\" id=\""+_ParameterName+"\">\n"; + _myfile <<"<attr name=\"InputDataSource\" type=\"string\">\"Histogramming.PT."+_histogramname+"\"</attr>\n"; + + char weightline [500]; + sprintf(weightline, "<attr name=\"Weight\" type=\"float\">%f</attr>\n", _weight); + _myfile<<weightline; + _myfile <<"<rel name=\"Algorithm\"> \"DQAlgorithm\" \""+_algorithmname+"\"</rel>\n"; + _myfile <<"<attr name=\"Action\" type=\"string\">\"\"</attr>\n"; + + // Parameters.... + params=_config.getParameters(); + int paramsize=params.size(); + + char paramsline [500]; + sprintf(paramsline, "<rel name=\"AlgorithmParameters\" num=\"%d\">\n", paramsize); +_myfile <<paramsline; + + std::map<std::string,double>::const_iterator iter; + for (iter=params.begin();iter!=params.end();iter++){ + _myfile <<" \"DQAlgorithmParameter\" \"Params_"+_ParameterName+"_"+iter->first+"\"\n"; + param_id.push_back("Params_"+_ParameterName+"_"+iter->first); + } + _myfile<<"</rel>\n"; + + // Reference histogram + if (_refhistogramname == "" && _reffilename=="") { + _myfile<<"<rel name=\"References\" num=\"0\"> </rel>\n"; + }else { + _myfile<<"<rel name=\"References\" num=\"1\">\"DQReference\" \"ref_"+_ParameterName+"\"</rel>\n"; + } + + //Green Threshold............ + gthresh=_config.getGreenThresholds(); + WriteThresholdFromMap(gthresh,_ParameterName,"Green"); + + //Red Threshold............ + rthresh=_config.getRedThresholds(); + DumpConfig::WriteThresholdFromMap(rthresh,_ParameterName,"Red"); + + _myfile<<"</obj>\n\n\n"; + +//References + if (_refhistogramname != "" && _reffilename != "") { + _myfile<<"<obj class=\"DQReference\" id=\"ref_"+_ParameterName+"\">\n"; + _myfile<<"<attr name=\"Reference\" type=\"string\">\""+_reffilename+":"+_refhistogramname+"\"</attr>\n"; + _myfile<<"<attr name=\"ExternalConditionName\" type=\"string\">\"\"</attr>\n"; + _myfile<<"<attr name=\"ExternalConditionValue\" type=\"double\">0</attr>\n"; + _myfile<<"</obj>\n\n"; +} + DumpThresholds(); + + DumpParams(); + + + _myfile<<"</oks-data>"; + + _myfile.close(); + +} + +void +dqm_algorithms::tools::DumpConfig::DumpOfflineConfig(std::string filename) { + + _myfile.open(filename.c_str()); + + _myfile.close(); + +} diff --git a/DataQuality/dqm_algorithms/tools/SimpleAlgorithmConfig.cxx b/DataQuality/dqm_algorithms/tools/SimpleAlgorithmConfig.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bc77c932e885f096e10e911eb427a25f03484f59 --- /dev/null +++ b/DataQuality/dqm_algorithms/tools/SimpleAlgorithmConfig.cxx @@ -0,0 +1,82 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! \file SimpleAlgorithmConfig Defines the class SimpleAlgorithmConfig a concrete simple implementation of dqm_core::AlgorithmConfig + * \author andrea.dotti@cern.ch + */ +#include <dqm_algorithms/tools/SimpleAlgorithmConfig.h> + +dqm_algorithms::tools::SimpleAlgorithmConfig::SimpleAlgorithmConfig() : + dqm_core::AlgorithmConfig() , ref_(0) +{ + //Empty +} + +dqm_algorithms::tools::SimpleAlgorithmConfig::SimpleAlgorithmConfig( TObject * ref ) : + dqm_core::AlgorithmConfig() , ref_(ref) +{ + //Empty +} + +#ifndef __MAKECINT__ + +dqm_algorithms::tools::SimpleAlgorithmConfig::SimpleAlgorithmConfig(const AlgorithmConfig& conf): + dqm_core::AlgorithmConfig() +{ + //Copy configuration in this + ref_ = conf.getReference(); + param_ = conf.getParameters(); + green_ = conf.getGreenThresholds(); + red_ = conf.getRedThresholds(); +} +#endif + +TObject* +dqm_algorithms::tools::SimpleAlgorithmConfig::getReference() const +{ + return ref_; +} + +const std::map<std::string, double>& +dqm_algorithms::tools::SimpleAlgorithmConfig::getParameters() const +{ + return param_; +} + +const std::map<std::string, double>& +dqm_algorithms::tools::SimpleAlgorithmConfig::getGreenThresholds() const +{ + return green_; +} + +const std::map<std::string, double>& +dqm_algorithms::tools::SimpleAlgorithmConfig::getRedThresholds() const +{ + return red_; +} + +void +dqm_algorithms::tools::SimpleAlgorithmConfig::setReference(TObject* o) +{ + ref_ = o; +} + +void +dqm_algorithms::tools::SimpleAlgorithmConfig::addParameter(std::string key, double value) +{ + param_.insert( std::make_pair(key,value) ); +} + +void +dqm_algorithms::tools::SimpleAlgorithmConfig::addGreenThreshold(std::string key, double value) +{ + green_.insert( std::make_pair(key,value) ); +} + +void +dqm_algorithms::tools::SimpleAlgorithmConfig::addRedThreshold(std::string key, double value) +{ + red_.insert( std::make_pair(key,value) ); +} + diff --git a/DataQuality/dqm_algorithms/workbench/Run_To_Get_Tags.h b/DataQuality/dqm_algorithms/workbench/Run_To_Get_Tags.h new file mode 100644 index 0000000000000000000000000000000000000000..914cd7d3fa40228c25cfb3f7640b43f792c0eacf --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/Run_To_Get_Tags.h @@ -0,0 +1,10 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// use as root -l Workbench.C Run_To_Get_Tags.h+ ... +#include <map> + +std::map<std::string, double> instance; +void Run_To_Get_Tags() { +} diff --git a/DataQuality/dqm_algorithms/workbench/TestAddReference.C b/DataQuality/dqm_algorithms/workbench/TestAddReference.C new file mode 100644 index 0000000000000000000000000000000000000000..142f85ef63dd8b279186de39f43f0f57462a8203 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestAddReference.C @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestAddReference() +{ + TH1F* hin = new TH1F("hin","hin",100,-1,1); + hin->FillRandom("gaus",10000); + hin->SetBinContent(50,0); + hin->SetBinContent(51,0); + hin->SetBinContent(52,0); + hin->SetLineWidth(2); + hin->Draw(); + TH1F* href= new TH1F("href","href",100,-1,1); + href->SetBinContent(50,100); + href->SetBinContent(51,100); + href->SetBinContent(52,100); + href->SetLineStyle(2); + href->SetLineWidth(2); + href->SetLineColor(kRed); + href->Draw("same"); + //dqm_algorithms::AddReference * algorithm = new dqm_algorithms::AddReference_All_Bins_Filled(); + dqm_algorithms::AddReference * algorithm = new dqm_algorithms::AddReference_Bins_Diff_FromAvg(); + + dqm_core::test::DummyAlgorithmConfig* aconfig = new dqm_core::test::DummyAlgorithmConfig(href); + aconfig->addParameter("MinStat",100); + aconfig->addParameter("Coeff",1); + aconfig->addParameter("NSigma",1); + aconfig->addGreenThreshold("NBins",10); + aconfig->addRedThreshold("NBins",20); + dqm_core::Result* result = algorithm->execute("test",*hin,*aconfig); + std::cout<<"Result "<<result->status_<<std::endl; + TObject* o = result->getObject(); + std::cout<<o->GetName()<<" "<<((TObjArray*)o)->GetEntries()<<std::endl; + //TH1* modifiedhisto = (TH1*)result->getObject(); + //modifiedhisto->SetLineColor(kBlue); + //modifiedhisto->Draw("same"); + algorithm->printDescription(); +} diff --git a/DataQuality/dqm_algorithms/workbench/TestAlgorithm.C b/DataQuality/dqm_algorithms/workbench/TestAlgorithm.C new file mode 100644 index 0000000000000000000000000000000000000000..b83109c362f9daf1eeb8577727f5e4bba3680ad8 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestAlgorithm.C @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * TestAlgorithm() +{ + dqm_algorithms::Simple_gauspluspol1_Fit * algorithm = new dqm_algorithms::Simple_gauspluspol1_Fit(); + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -2, 2 ); + histogram->FillRandom( "gaus", 1000 ); + + //dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + dqm_algorithms::tools::SimpleAlgorithmConfig * aconfig = new dqm_algorithms::tools::SimpleAlgorithmConfig( ); + aconfig->addGreenThreshold("AbsMean",0.01); + aconfig->addRedThreshold("AbsMean",0.05); + aconfig->addGreenThreshold("Sigma",1); + aconfig->addRedThreshold("Sigma",5); + aconfig->addGreenThreshold("Constant",1); + aconfig->addRedThreshold("Constant",5); + aconfig->addGreenThreshold("Chi2_per_NDF",1); + aconfig->addRedThreshold("Chi2_per_NDF",5); + aconfig->addParameter("xmin",-1); + aconfig->addParameter("xmax",1); + aconfig->addParameter("SubtractFromMean",0.2); + //aconfig->addParameter("Verbose",); + + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + std::cout << "Result " << result->status_ << std::endl; + //Usage: + //dqm_algorithms::tools::DumpConfig(string ParameterName, dqm_core::test::DummyAlgorithmConfig& config, string algorithmname, string histogramname, string reffilename = , string refhistogramname = , float weight = 1., string regionname = ) + dqm_algorithms::tools::DumpConfig *n=new dqm_algorithms::tools::DumpConfig("test",*aconfig,"Simple_gaus_Fit","histogram","","",1.0,"regname"); + n->DumpOnlineConfig("test.data.xml"); + return histogram; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestBasicHist.C b/DataQuality/dqm_algorithms/workbench/TestBasicHist.C new file mode 100644 index 0000000000000000000000000000000000000000..0275fe42650f31800eddf75d2541d06d01f2884d --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestBasicHist.C @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * TestBasicHist() +{ + //dqm_algorithms::All_Bins_Filled * algorithm = new dqm_algorithms::All_Bins_Filled(); + //dqm_algorithms::Histogram_Not_Empty * algorithm = new dqm_algorithms::Histogram_Not_Empty(); + dqm_algorithms::Histogram_Empty * algorithm = new dqm_algorithms::Histogram_Empty(); + //dqm_algorithms::No_OverFlows * algorithm = new dqm_algorithms::No_OverFlows(); + //dqm_algorithms::No_UnderFlows * algorithm = new dqm_algorithms::No_UnderFlows(); + + + //TH2F * histogram = new TH2F( "histogram", "Simple Gaussian Histogram", 100, -2, 2,100,-2,2); + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -2, 2); + //histogram->FillRandom( "gaus", 1000 ); + //histogram->SetBinContent(0,1); + //histogram->SetBinContent(100,101,1); + + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + + + //aconfig->addParameter("MinStat",1000); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + + std::cout << "Result " << result->status_ << std::endl; + + return histogram; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestBinContentCompAlgorithm.C b/DataQuality/dqm_algorithms/workbench/TestBinContentCompAlgorithm.C new file mode 100644 index 0000000000000000000000000000000000000000..0de2ed8c78e57ebd22cbb180db6569396bcaec8e --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestBinContentCompAlgorithm.C @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include<map> +#include<vector> +#include<string> + +dqm_core::Result * TestBinContentCompAlgorithm() +{ + dqm_algorithms::BinContentComp * algorithm = new dqm_algorithms::BinContentComp(); + + TH1F *histogram=new TH1F("histogram","histogram",100,-1,1); + TH1F *ref=new TH1F("ref","ref",100,-1,1); + + histogram->FillRandom("gaus",1000); + ref->FillRandom("pol1",10000); + + // dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(ref); + dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(); + + aconfig->addParameter("NSigma",1); + aconfig->addParameter("Ignore0",1); + aconfig->addParameter("xmin",-2.0); + aconfig->addParameter("xmax",-1.0); + aconfig->addParameter("ymin",1.0); + aconfig->addParameter("ymax",2.0); + aconfig->addParameter("Value",100); + aconfig->addParameter("PublishBins",1); + aconfig->addGreenThreshold("NBins",1); + aconfig->addRedThreshold("NBins",33); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + + std::cout << "Result " << result->status_<< std::endl; + return result; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestBinsDiffByStrips.C b/DataQuality/dqm_algorithms/workbench/TestBinsDiffByStrips.C new file mode 100644 index 0000000000000000000000000000000000000000..0b3a78c22eea6145ae07c3ae3f740cf0dcbdcc08 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestBinsDiffByStrips.C @@ -0,0 +1,327 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * TestBinsDiffByStrips() +{ + //Macro for testing and tuneing the BinsDiffByStrips algorithm. + + //Algorithm red/green threhsolds for bins: + const double binYellowThreshold = 3; + const double binRedThreshold = 10; + + + const double redCellFractionLow = 0.001; + const double redCellFractionHigh = 0.3; + const double yellowCellFractionLow = 0.001; + const double yellowCellFractionHigh = 0.3; + + const double fpk = -0.5; + + + const double maxRedCellLimit = 100000000.; //Maximum possible value of power law distributed red cells; + const int nbinx = 2000; + const int nbiny = 500; + + //Settings for testing by varying iteration parameters (for optimization): + const int nTestingIntervalsA = 4; + const double testRangeLowA = 0.265; + const double testRangeHighA = 0.295; + const int nTestingIntervalsB = 16; + const double testRangeLowB = 1.8; + const double testRangeHighB = 2.2; + + const int nTestsPerInterval = 40; + + bool useOutlierFindingWithErrors = false; + + //Iteration parameters: + double iterDeviationThreshold = 2.075; + double iVarExponent = 0.275; + double sbcf = 0.4; + double cStop = 25; + + double paramA = testRangeLowA; + + TH2F * scorePlot = new TH2F("scorePlot","Test Score versus sbcf",nTestingIntervalsA,testRangeLowA,testRangeHighA,nTestingIntervalsB,testRangeLowB,testRangeHighB); + + for (int ka=1; ka<=nTestingIntervalsA; ka++){ + double paramB = testRangeLowB; + + //Decide which parameters to vary here: + iVarExponent = paramA; + + for (int kb=1; kb<=nTestingIntervalsB; kb++){ + + // and here: + iterDeviationThreshold = paramB; + + double scoreSum = 0.; + double scoreSum2 = 0.; + + for (int l=0; l<nTestsPerInterval; l++) { + + dqm_algorithms::BinsDiffByStrips * algorithm = new dqm_algorithms::BinsDiffByStrips(); + + //Build the test histogram: + inputHistogram = new TH2F("inputHistogram","TProfile2D for testing BinsDiffByStrips",nbinx,0.,nbinx*1.,nbiny,0.,nbiny*1.); + trueBinStatus = new TH2F("trueBinStatus","Bad Bins Added to Input Histogram", + inputHistogram->GetNbinsX(),inputHistogram->GetXaxis()->GetXmin(),inputHistogram->GetXaxis()->GetXmax(), + inputHistogram->GetNbinsY(),inputHistogram->GetYaxis()->GetXmin(),inputHistogram->GetYaxis()->GetXmax()); + + TRandom3 rand(0); + int nTrueReds = 0; + int nTrueYellows = 0; + int nTrueGreens = 0; + + + + for(int i=1; i<=nbinx; i++) { + //Test the algorithms for a variety of bin numbers and fraction of red, yellow bins, + double inputRedCellFraction = pow( ((pow(redCellFractionHigh,fpk) - pow(redCellFractionLow,fpk))*rand.Rndm() + pow(redCellFractionLow,fpk) ), 1/fpk); + double inputYellowCellFraction = pow( ((pow(yellowCellFractionHigh,fpk) - pow(yellowCellFractionLow,fpk))*rand.Rndm() + pow(yellowCellFractionLow,fpk) ), 1/fpk); + double filledBinFraction = pow(rand.Rndm(),2); //We do not fill all the bins in each slice, + + for(int j=1; j<=(nbiny*filledBinFraction); j++) { + int bin = inputHistogram->GetBin(i,j); + + double binContent = 0; + double binError = 0; + + double binVariance = 10; + double binMean = 50; + + double minRedBin = binRedThreshold * binVariance; + double minYellowBin = binYellowThreshold * binVariance; + + //Change the mean and statistics for red, yellow bins. + if ( rand.Rndm() < inputRedCellFraction ) { + //Red bins are added with a mean following an inverse squared power law distribution, with lower limit at binRedThreshold * variance: + binContent = binMean + 1 / ( (1/maxRedCellLimit - 1/minRedBin)*rand.Rndm() + 1/minRedBin ); + binError = binContent * rand.Rndm() / 10; //Random fractional error of up to 10% + trueBinStatus->SetBinContent(bin,1.); + nTrueReds++; + } + else if ( rand.Rndm() < (inputYellowCellFraction /(1 - inputRedCellFraction)) ) { + //Yellow bins are added with a mean evenly distributed between binYellowThreshold and binRedThreshold; + binContent = binMean + minYellowBin + (minRedBin - minYellowBin) * rand.Rndm(); + binError = binContent * rand.Rndm() / 10; //Random fractional error of up to 10% + trueBinStatus->SetBinContent(bin,2.); + nTrueYellows++; + } + else { + trueBinStatus->SetBinContent(bin,3.); + //Green bins are filled to simulate the result of binStat measurements of values with a true variance of binVariance: + int binStat = 100000; //Attempt to test algorithm over wide range of statistics: + if(binStat != 0){ + binContent = rand.Gaus(binMean,binVariance); + if( useOutlierFindingWithErrors ) { + binError = binVariance; + } + else { + binError = binContent / sqrt(binStat); + } + } + nTrueGreens++; + } + + //Finally, smear the bin content by its error and add it to the histogram: + if(binError != 0){ + //binContent = rand.Gaus(binContent,binError); + inputHistogram->SetBinContent(i,j,binContent); + inputHistogram->SetBinError(i,j,binError); + } + } + } + + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + + //These are optional parameterms + + if(useOutlierFindingWithErrors) { + aconfig->addParameter("TestConsistencyWithErrors",1); + } + + aconfig->addParameter("MinStat",10); + aconfig->addParameter("PublishBins",1); + + aconfig->addParameter("nIterations", 100 ); + aconfig->addParameter("IterVariationExponent", iVarExponent); + aconfig->addParameter("IterDeviationThresh", iterDeviationThreshold); + aconfig->addParameter("IterScaleBiasCorrectionFactor", sbcf); + aconfig->addParameter("IterBreakConstant", cStop); + + aconfig->addParameter("useStripsOfConstantY", 1.0 ); + + // Threshold for number of bins N sigma aways from average + aconfig->addGreenThreshold("MaxDeviation",binYellowThreshold); + aconfig->addRedThreshold("MaxDeviation",binRedThreshold); + + dqm_core::Result * result = algorithm->execute( "test", *inputHistogram, *aconfig ); + + if(result->status_ < 1) continue; + + TObjArray * resultList = (TObjArray*)result->getObject(); + TH2F* binwiseStatus = (TH2F*) resultList->First()->Clone(); + + //outputInput = (TH2F*) resultList->At(1)->Clone(); + //normalizedBins = (TH2F*) resultList->At(2)->Clone(); + //sliceAverageHist = (TH1F*) resultList->At(3)->Clone(); + //sliceVarianceHist = (TH1F*) resultList->At(4)->Clone(); + + //Loop over true bad bins and binwise status to determine efficiency and quality: + int trueRedsFound = 0; + int trueYellowsFound = 0; + int trueGreensFound = 0; + + int greensFlaggedRed = 0; + + int greensFlaggedYellow = 0; + int redsFlaggedYellow = 0; + + int redsFlaggedGreen = 0; + int yellowsFlaggedGreen = 0; + int yellowsFlaggedRed = 0; + + int nFlaggedUndefined = 0; + int nFlaggedDisabled = 0; + + for(int i=1; i<=nbinx; i++) { + for(int j=1; j<=nbiny; j++) { + float testStatus = binwiseStatus->GetBinContent(i,j); + float trueStatus = trueBinStatus->GetBinContent(i,j); + + switch (testStatus) { + case 1: + if(trueStatus == 1){ + trueRedsFound++; + } + else if(trueStatus == 3){ + greensFlaggedRed++; + } + else if(trueStatus == 2){ + yellowsFlaggedRed++; + } + break; + case 2: + if(trueStatus == 2){ + trueYellowsFound++; + } + else { + if(trueStatus == 1){ + redsFlaggedYellow++; + } + else if(trueStatus == 3){ + greensFlaggedYellow; + } + } + break; + case 3: + if(trueStatus == 1){ + redsFlaggedGreen++; + } + else if(trueStatus == 2){ + yellowsFlaggedGreen++; + } + else trueGreensFound++; + break; + case 0: + nFlaggedUndefined++; + break; + case -1: + nFlaggedDisabled++; + break; + } + } + } + + double redTaggingEfficiency; + double redYellowTagginEfficiency; + if (nTrueReds != 0){ + redTaggingEfficiency = (1. * trueRedsFound) / nTrueReds; + redYellowTagginEfficiency = (1.0 *trueRedsFound + redsFlaggedYellow) / nTrueReds; + } + else { + redTaggingEfficiency = -1; + redYellowTagginEfficiency = -1; + } + + + + + double yellowTaggingEfficiency; + if (nTrueYellows != 0){ + yellowTaggingEfficiency = (1. * trueYellowsFound) / nTrueYellows; + } + else { + yellowTaggingEfficiency = -1; + } + + std::cout << "-------------------------------------------------------------------" << std::endl; + std::cout << std::endl; + std::cout << "iVarExponent = " << iVarExponent << std::endl; + std::cout << "iterDeviationThreshold = " << iterDeviationThreshold << std::endl; + std::cout << "ScaleBiasCorrectionFactor = " << sbcf << std::endl; + std::cout << "cStop = " << cStop << std::endl; + + std::cout << "Result = " << result->status_ << std::endl; + + std::cout << std::endl; + std::cout << "Of the " << nTrueReds << " red bins produced, " << trueRedsFound << " where flagged as red, giving an efficiency of: " << redTaggingEfficiency << std::endl; + std::cout << trueRedsFound + redsFlaggedYellow << " red bins where flagged as red or yellow, yielding a total efficiency of: " << redYellowTagginEfficiency << std::endl; + std::cout << "Of the " << nTrueYellows << " yellow bins produced, " << trueYellowsFound << " where found, giving an efficiency of: " << yellowTaggingEfficiency << std::endl; + + std::cout << std:: endl << redsFlaggedGreen << " red bins where flagged green, while" << std::endl; + std::cout << greensFlaggedRed << " green bins where flagged red." << std::endl; + + std::cout << std:: endl << greensFlaggedYellow << " green bins and " << redsFlaggedYellow << " red bins where flagged as yellow" << std:: endl; + std::cout << "while " << yellowsFlaggedGreen << " yellow bins where flagged as green and " << yellowsFlaggedRed << " yellow bins where flagged as red." << std::endl; + std::cout << trueGreensFound << " bins where correctly identified as green." << std::endl; + std::cout << nFlaggedUndefined << " bins where given no defined status, while " << nFlaggedDisabled << " bins where excluded from being tested." << std::endl; + + //A somewhat arbitrary score to summarize the level of sucess: + double testScore = 0; + if( nTrueReds != 0 ) { + testScore += ( ( 20. * trueRedsFound + 5. * redsFlaggedYellow - 2.0 * redsFlaggedGreen ) / nTrueReds ); + } + if( nTrueYellows != 0 ) { + testScore += ( ( 2. * trueYellowsFound - 1.0 * yellowsFlaggedRed - 0.1 * yellowsFlaggedGreen ) / nTrueYellows ); + } + if( nTrueGreens != 0 ) { + testScore += ( ( - 10000000. * greensFlaggedRed - 1000000. * greensFlaggedYellow + trueGreensFound ) / nTrueGreens ); + } + + std::cout << std::endl << "This corresponds to a score of " << testScore << " for the algorithm." << std::endl; + std::cout << std::endl; + + scoreSum += testScore; + scoreSum2 += pow(testScore,2); + + delete inputHistogram; + delete trueBinStatus; + delete binwiseStatus; + // delete outputInput; + // delete normalizedBins; + // delete sliceAverageHist; + // delete sliceVarianceHist; + + delete aconfig; + delete algorithm; + delete result; + } + + double AverageScore = scoreSum/nTestsPerInterval; + double AvgScoreError = sqrt( scoreSum2 /nTestsPerInterval - AverageScore * AverageScore ); + int thisBin = scorePlot->GetBin(ka,kb); + scorePlot->SetBinContent(thisBin,AverageScore); + scorePlot->SetBinError(thisBin,AvgScoreError); + paramB += (testRangeHighB - testRangeLowB)/nTestingIntervalsB; + } + paramA += (testRangeHighA - testRangeLowA)/nTestingIntervalsA; + } + + scorePlot->Draw(); + + + return scorePlot; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestChi2Algorithm.C b/DataQuality/dqm_algorithms/workbench/TestChi2Algorithm.C new file mode 100644 index 0000000000000000000000000000000000000000..3836bc76959caf54dc793bfb0bf1412aec403b6d --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestChi2Algorithm.C @@ -0,0 +1,19 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestChi2Algorithm() +{ + + dqm_algorithms::Chi2Test_Chi2 * algorithm = new dqm_algorithms::Chi2Test_Chi2(); + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -2, 2 ); + histogram->FillRandom( "gaus", 1000 ); + + + dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(histogram); + aconfig->addGreenThreshold("Chi2",.9); + aconfig->addRedThreshold("Chi2",.3); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + algorithm->printDescription(); + std::cout << "Result " << result->status_<< std::endl; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestDivideBin.C b/DataQuality/dqm_algorithms/workbench/TestDivideBin.C new file mode 100644 index 0000000000000000000000000000000000000000..1f8d47eadf1911beda7c0176f9a4f6068cc1d25b --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestDivideBin.C @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * TestDivideBin() +{ + + dqm_algorithms::DivideBin * algorithm = new dqm_algorithms::DivideBin(); + + TH1F* hin = new TH1F("hin","hin",100,-1,1); + hin->FillRandom("gaus",10000); + hin->SetBinContent(50,100); + hin->SetBinContent(51,200); + hin->SetBinContent(52,300); + hin->Draw(); + + + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig(hin); + aconfig->addParameter("MinStat",100); + aconfig->addParameter("xmin",51); + aconfig->addParameter("xmax",52); + aconfig->addGreenThreshold("Threshold",0.95); + aconfig->addRedThreshold("Threshold",0.75); + + dqm_core::Result * result = algorithm->execute( "test", *hin, *aconfig ); + algorithm->printDescription(); + + return hin; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestDivideReference.C b/DataQuality/dqm_algorithms/workbench/TestDivideReference.C new file mode 100644 index 0000000000000000000000000000000000000000..c0e2f7cab65b0942db619d1e28ffcfb76620a86e --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestDivideReference.C @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestDivideReference() +{ + TH1F* hin = new TH1F("hin","hin",100,-1,1); + hin->FillRandom("gaus",10000); + hin->SetBinContent(50,0); + hin->SetBinContent(51,0); + hin->SetBinContent(52,0); + hin->SetLineWidth(2); + hin->Draw(); + TH1F* href= new TH1F("href","href",100,-1,1); + for ( Int_t bin = href->GetXaxis()->GetFirst() ; bin<=href->GetXaxis()->GetLast();++bin) + href->SetBinContent(bin,10); + + href->SetLineStyle(2); + href->SetLineWidth(2); + href->SetLineColor(kRed); + href->Draw("same"); + //dqm_algorithms::AddReference * algorithm = new dqm_algorithms::AddReference_All_Bins_Filled(); + //dqm_algorithms::DivideReference * algorithm = new dqm_algorithms::DivideReference_Bins_Diff_FromAvg(); + dqm_algorithms::DivideReference * algorithm = new dqm_algorithms::DivideReference_BinContentComp(); + //Let's now create a reference of two histograms + TObjArray* references = new TObjArray(2); + references->Add(href); + TH1* hh = hin->Clone(); + hh->Divide(href); + references->Add(hh); + dqm_core::test::DummyAlgorithmConfig* aconfig = new dqm_core::test::DummyAlgorithmConfig(references); + //dqm_core::test::DummyAlgorithmConfig* aconfig = new dqm_core::test::DummyAlgorithmConfig(href); + aconfig->addParameter("MinStat",100); + aconfig->addParameter("NSigma",0.1); + aconfig->addParameter("Coeff",1); + aconfig->addGreenThreshold("NBins",10); + aconfig->addRedThreshold("NBins",20); + dqm_core::Result* result = algorithm->execute("test",*hin,*aconfig); + std::cout<<"Result "<<result->status_<<std::endl; + TObject* o = result->getObject(); + std::cout<<o->GetName()<<" "<<((TObjArray*)o)->GetEntries()<<std::endl; + TObjArray* results = (TObjArray*)o; + TH1* modifiedhisto = (TH1*)results->At(1); + modifiedhisto->SetLineColor(kBlue); + modifiedhisto->Draw("same"); + algorithm->printDescription(); +} diff --git a/DataQuality/dqm_algorithms/workbench/TestGraph.C b/DataQuality/dqm_algorithms/workbench/TestGraph.C new file mode 100644 index 0000000000000000000000000000000000000000..59568c850cd8600a0f701414fdc9595006d8b3f9 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestGraph.C @@ -0,0 +1,43 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestGraph() +{ + dqm_algorithms::GraphTest* algorithm = new dqm_algorithms::GraphTest(); + TFile* f=TFile::Open("../share/Test.root");//##filename##); + TObject* obj=f->Get("LBA19_hi_tails_5");//##histoname##); + ((TGraphAsymmErrors*)obj)->SetPointError(23,0,0,0.5,0.5);// Set big errors on one point + // Creating a reference object... + TGraphAsymmErrors* ref = new TGraphAsymmErrors(48); + ref->SetNameTitle("reference","reference"); + for ( int i = 0;i<48; ++i) + { + ref->SetPoint(i,i+0.5,1.); + ref->SetPointError(i,0,0,0.15,0.15); + } + // Turn off three deadempty channels + ref->SetPointError(31,0,0,0,0); + ref->SetPointError(32,0,0,0,0); + ref->SetPointError(43,0,0,0,0); + TCanvas* c=new TCanvas; + obj->Draw("AP"); + ref->Draw("P"); + + dqm_core::test::DummyAlgorithmConfig* aconfig=new dqm_core::test::DummyAlgorithmConfig();//ref); + //aconfig->addGreenThreshold("XErrHigh",0.); + //aconfig->addGreenThreshold("XErrLow",0.); + aconfig->addGreenThreshold("YErrHigh",0.3); + aconfig->addGreenThreshold("YErrLow",0.3); + //aconfig->addGreenThreshold("NBins",0); + //aconfig->addGreenThreshold("DistFactor",1.); + //aconfig->addRedThreshold("XErrHigh",0.); + //aconfig->addRedThreshold("XErrLow",0.); + aconfig->addRedThreshold("YErrHigh",0.4); + aconfig->addRedThreshold("YErrLow",0.4); + //aconfig->addRedThreshold("NBins",3); + //aconfig->addRedThreshold("DistFactor",1.); + dqm_core::Result* result = algorithm->execute("test",*obj,*aconfig); + std::cout<<result->status_<<std::endl; + +} diff --git a/DataQuality/dqm_algorithms/workbench/TestJarqueBera.C b/DataQuality/dqm_algorithms/workbench/TestJarqueBera.C new file mode 100644 index 0000000000000000000000000000000000000000..d4ec108bc64906f505800d0941bfb6e03a8e4c5c --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestJarqueBera.C @@ -0,0 +1,21 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestJarqueBera() +{ + + dqm_algorithms::JarqueBeraTest_Prob * algorithm = new dqm_algorithms::JarqueBeraTest_Prob(); + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -10, 10 ); + histogram->FillRandom( "gaus", 1000 ); + + histogram->Draw(); + + dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(); + aconfig->addGreenThreshold("P",0.90); + aconfig->addRedThreshold("P",0.1); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + algorithm->printDescription(); + std::cout << "Result " << result->status_<< std::endl; + //std::cout<<*result<<std::endl; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestKurtosis.C b/DataQuality/dqm_algorithms/workbench/TestKurtosis.C new file mode 100644 index 0000000000000000000000000000000000000000..59ecb1d2d72d85d71ec2602699cd1361dc7e4a91 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestKurtosis.C @@ -0,0 +1,19 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestKurtosis() +{ + + dqm_algorithms::KurtosisTest_LessThanAbs * algorithm = new dqm_algorithms::KurtosisTest_LessThanAbs(); + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -2, 2 ); + histogram->FillRandom( "gaus", 10000 ); + std::cout<<"Kurtosis Value:"<<histogram->GetKurtosis()<<std::endl; + + dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(); + aconfig->addGreenThreshold("K",0.2); + aconfig->addRedThreshold("K",0.5); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + algorithm->printDescription(); + std::cout << "Result " << result->status_<< std::endl; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestMaskedBinRow.C b/DataQuality/dqm_algorithms/workbench/TestMaskedBinRow.C new file mode 100644 index 0000000000000000000000000000000000000000..248dec2d082dec1ba6a9ef540f193bbde9235bba --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestMaskedBinRow.C @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include<map> +#include<vector> +#include<string> + +dqm_core::Result * TestMaskedBinRowAlgorithm() +//void TestMaskedBinRowAlgorithm() +{ + dqm_algorithms::MaskedBinRow * algorithm = new dqm_algorithms::MaskedBinRow(); + + TH2F *histogram=new TH2F("histogram","histogram",10,-1,1,10,-1,1); + TH2F *ref=new TH2F("ref","ref",10,-1,1,10,-1,1); + + for(int i=1; i<11;i++){ + for(int j=1; j<11;j++){ + histogram->SetBinContent(i,j,0); + histogram->SetBinContent(i,1,4); + histogram->SetBinContent(4,10,3); + histogram->SetBinContent(3,3,5); + histogram->SetBinContent(4,3,5); + histogram->SetBinContent(5,3,5); + + ref->SetBinContent(i,j,0); + ref->SetBinContent(i,3,2); + + } +} +ref->Draw("text"); +new TCanvas(); +histogram->Draw("text"); + + + dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(ref); + + aconfig->addParameter("MaskedBin",10); + aconfig->addParameter("OkBin",1); + aconfig->addParameter("TestRows",0); + aconfig->addGreenThreshold("BinThreshold",1); + aconfig->addRedThreshold("BinThreshold",10); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + + std::cout << "Result " << result->status_<< std::endl; + return result; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestReferenceMasking.C b/DataQuality/dqm_algorithms/workbench/TestReferenceMasking.C new file mode 100644 index 0000000000000000000000000000000000000000..2aa298a44e78d9582b9467630f8ca4d0a25f223a --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestReferenceMasking.C @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestReferenceMasking() +{ + bool test1 = true; + //Make an histogram with 3 "hot" bins + TH1F* hin = new TH1F("hin","hin",100,-1,1); + if (test1) hin->FillRandom("gaus",10000); + else hin->FillRandom("pol0",10000); + hin->SetBinContent(50,200); + hin->SetBinContent(51,200); + hin->SetBinContent(52,200); + hin->SetLineWidth(2); + hin->Draw(); + //The reference contains the bins to be "masked" + TH1F* href= new TH1F("href","href",100,-1,1); + href->SetBinContent(50,100);//It's important that the content is !=0 + href->SetBinContent(51,100);//Doesn't matter what is the content + href->SetBinContent(52,100); + href->SetLineStyle(2); + href->SetLineWidth(2); + href->SetLineColor(kRed); + href->Draw("same"); + dqm_core::Algorithm* algorithm; + //Count number of bins abobe a threshold + if (test1) algorithm = new dqm_algorithms::ReferenceMasking_Bins_GreaterThan_Threshold(); + else algorithm = new dqm_algorithms::ReferenceMasking_Bins_Diff_FromAvg(); + + dqm_core::test::DummyAlgorithmConfig* aconfig = new dqm_core::test::DummyAlgorithmConfig(href); + aconfig->addParameter("MinStat",100); + aconfig->addParameter("C",0);//Fill masked bins with "C", in this case 0 + if ( test1 ) { + aconfig->addParameter("BinThreshold",150); + aconfig->addGreenThreshold("NBins",1); + aconfig->addRedThreshold("NBins",4); + } else { + aconfig->addParameter("NSigma",3); + aconfig->addGreenThreshold("NBins",10); + aconfig->addRedThreshold("NBins",20); + } + dqm_core::Result* result = algorithm->execute("test",*hin,*aconfig); + std::cout<<"Result "<<result->status_<<std::endl; + TH1* modifiedhisto = (TH1*)result->getObject(); + modifiedhisto->SetLineColor(kBlue); + modifiedhisto->SetLineStyle(3); + modifiedhisto->Draw("same"); + algorithm->printDescription(); +} diff --git a/DataQuality/dqm_algorithms/workbench/TestRepeatAlgorithm_AddReference.C b/DataQuality/dqm_algorithms/workbench/TestRepeatAlgorithm_AddReference.C new file mode 100644 index 0000000000000000000000000000000000000000..da3a9924b2161876ac49d51e0cf1ed5cf0336128 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestRepeatAlgorithm_AddReference.C @@ -0,0 +1,66 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef __CINT__ +#include <map> +#include <iostream> +#include "TH1F.h" +#include "dqm_algorithms/RepeatAlgorithm.h" +#endif + +TestRepeatAlgorithm_AddReference() +{ + TH1F* hin = new TH1F("hin","hin",100,-1,1); + hin->FillRandom("gaus",10000); + hin->SetBinContent(50,0); + hin->SetBinContent(51,0); + hin->SetBinContent(52,0); + hin->SetLineWidth(2); + hin->Draw(); + TH1F* href1= new TH1F("href1","href1",100,-1,1); + href1->SetBinContent(50,100); + href1->SetBinContent(51,100); + href1->SetBinContent(52,100); + href1->SetLineStyle(2); + href1->SetLineWidth(2); + href1->SetLineColor(kRed); + href1->Draw("same"); + TH1F* href2= new TH1F("href2","href2",100,-1,1); + href2->SetBinContent(50,-100); + href2->SetBinContent(51,-100); + href2->SetBinContent(52,-100); + href2->SetLineStyle(2); + href2->SetLineWidth(2); + href2->SetLineColor(kOrange); + href2->Draw("same"); + //dqm_algorithms::AddReference * algorithm = new dqm_algorithms::AddReference_All_Bins_Filled(); + dqm_algorithms::RepeatAlgorithm * algorithm = new dqm_algorithms::RepeatAlgorithm(); + // dqm_algorithms::AddReference * algorithm = new dqm_algorithms::AddReference_Bins_Diff_FromAvg(); + + TObjArray objarr; + objarr.Add(href1); objarr.Add(href2); + dqm_core::test::DummyAlgorithmConfig* aconfig = new dqm_core::test::DummyAlgorithmConfig(&objarr); + aconfig->addParameter("AuxAlgName--AddReference_Bins_Diff_FromAvg", 1); + aconfig->addParameter("MinStat",100); + aconfig->addParameter("Coeff",1); + aconfig->addParameter("NSigma",1); + aconfig->addGreenThreshold("NBins",62); + aconfig->addRedThreshold("NBins",70); + dqm_core::Result* result = algorithm->execute("test",*hin,*aconfig); + std::cout<<"Result status "<<result->status_<<std::endl; + // std::map<std::string,double> tags =result->tags_; + // std::cout << result->tags_.size() << std::endl; + // int count(0); + // for (std::map<std::string,double>::const_iterator imap = result->tags_.begin(); + // imap != result->tags_.end() && count < result->tags_.size(); ++imap, ++count) { + // std::cout << imap->first << " " << imap->second << std::endl; + // } + //TObject* o = result->getObject(); + //std::cout<<o->GetName()<<" "<<((TObjArray*)o)->GetEntries()<<std::endl; + // o->Print("all"); + //TH1* modifiedhisto = (TH1*)result->getObject(); + //modifiedhisto->SetLineColor(kBlue); + //modifiedhisto->Draw("same"); + algorithm->printDescription(); +} diff --git a/DataQuality/dqm_algorithms/workbench/TestSideBand.C b/DataQuality/dqm_algorithms/workbench/TestSideBand.C new file mode 100644 index 0000000000000000000000000000000000000000..f509950fdec7b3ab0812712938b120327c95f376 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestSideBand.C @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1* TestSideBand() +{ + // Create and fill a gaussian histogram + TH1* hrnd = new TH1F("hRandom","Test Histogram",100,-5,5); + hrnd->FillRandom("gaus",10000); + // Create algorithms and configure them + dqm_algorithms::SideBand_Absolute* algo1 = new dqm_algorithms::SideBand_Absolute(); + dqm_algorithms::SideBand* algo2 = new dqm_algorithms::SideBand_Relative(); + + dqm_core::test::DummyAlgorithmConfig* conf1 = new dqm_core::test::DummyAlgorithmConfig(); + dqm_core::test::DummyAlgorithmConfig* conf2 = new dqm_core::test::DummyAlgorithmConfig(); + + conf1->addParameter("UseUnderFlow",1); + conf1->addParameter("UseOverFlow",1); + conf1->addParameter("Min",-3); + conf1->addParameter("Max",3); + conf2->addParameter("UseUnderFlow",1); + conf2->addParameter("UseOverFlow",1); + conf2->addParameter("Min",-3); + conf2->addParameter("Max",3); + + conf1->addGreenThreshold("Threshold",20); + conf1->addRedThreshold("Threshold",30); + conf2->addGreenThreshold("Threshold",0.1); + conf2->addRedThreshold("Threshold",0.05); + + //dqm_core::Result* result1 = algo1->execute("absoluteTest",*hrnd,*conf1); + dqm_core::Result* result2 = algo2->execute("relativeTest",*hrnd,*conf2); + //std::cout<<"Result absoluteTest: "<<result1->status_<<std::endl; + std::cout <<"Result relativeTest: "<<result2->status_<<std::endl; + return hrnd; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestSkewness.C b/DataQuality/dqm_algorithms/workbench/TestSkewness.C new file mode 100644 index 0000000000000000000000000000000000000000..a3795fac78623d8579fa90ef55384039c98fae7e --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestSkewness.C @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TestSkewness() +{ + + dqm_algorithms::SkewnessTest_LessThan * algorithm = new dqm_algorithms::SkewnessTest_LessThan(); + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -5, 5 ); + histogram->FillRandom( "gaus", 5000 ); + for (int i =0 ; i<100 ; ++i) + histogram->Fill( -2.5 ); + histogram->Draw(); + + std::cout<<"Skewness Value:"<<histogram->GetSkewness()<<std::endl; + + dqm_core::test::DummyAlgorithmConfig *aconfig = new dqm_core::test::DummyAlgorithmConfig(); + aconfig->addGreenThreshold("S",-0.1); + aconfig->addRedThreshold("S",-0.09); + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + algorithm->printDescription(); + std::cout << "Result " << result->status_<< std::endl; +} diff --git a/DataQuality/dqm_algorithms/workbench/TestStat.C b/DataQuality/dqm_algorithms/workbench/TestStat.C new file mode 100644 index 0000000000000000000000000000000000000000..d74f1f6853d009eef77f0bc4d9f986aa682b2803 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/TestStat.C @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * TestStat() +{ + // dqm_algorithms::CheckHisto_RMS * algorithm = new dqm_algorithms::CheckHisto_RMS(); + dqm_algorithms::CheckHisto_Mean * algorithm = new dqm_algorithms::CheckHisto_Mean(); + + + TH2F * histogram = new TH2F( "histogram", "Simple Gaussian Histogram", 100, -2, 2,100,-2,2); + histogram->FillRandom( "gaus", 1000 ); + + + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + + // These are optional Parameters + aconfig->addParameter("MinStat",1000); + aconfig->addParameter("xmin",-2); + aconfig->addParameter("xmax",1.4); + aconfig->addParameter("ymin",-1.8); + aconfig->addParameter("ymax",1.6); + + // Threshold names for CheckHisto_Mean() algorithm + aconfig->addGreenThreshold("AbsXMean",1); + aconfig->addRedThreshold("AbsXMean",5); + aconfig->addGreenThreshold("AbsYMean",1); + aconfig->addRedThreshold("AbsYMean",5); + + // Threshold names for CheckHisto_Mean() algorithm if want to check actual Mean and not it's absolute value + //aconfig->addGreenThreshold("XMean",1); + //aconfig->addRedThreshold("XMean",5); + //aconfig->addGreenThreshold("YMean",1); + //aconfig->addRedThreshold("YMean",5); + + // Threshold names for CheckHisto_RMS() algorithm + // aconfig->addGreenThreshold("XRMS",1); + // aconfig->addRedThreshold("XRMS",5); + // aconfig->addGreenThreshold("YRMS",1); + // aconfig->addRedThreshold("YRMS",5); + + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + + std::cout << "Result " << result->status_ << std::endl; + + return histogram; +} diff --git a/DataQuality/dqm_algorithms/workbench/Test_Bins_diffavg.C b/DataQuality/dqm_algorithms/workbench/Test_Bins_diffavg.C new file mode 100644 index 0000000000000000000000000000000000000000..cfea5d7ac8c4fe6562815e8c361ff4006ea69d87 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/Test_Bins_diffavg.C @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * Test_Bins_diffavg() +{ + dqm_algorithms::Bins_Diff_FromAvg * algorithm = new dqm_algorithms::Bins_Diff_FromAvg(); + + + + TH1F * histogram = new TH1F( "histogram", "Simple Gaussian Histogram", 100, -2, 2); + histogram->FillRandom( "pol0", 1000 ); + + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + + //These are optional parameterms + aconfig->addParameter("MinStat",1000); + aconfig->addParameter("xmin",-2); + aconfig->addParameter("xmax",-1); + aconfig->addParameter("ymin",-1.8); + aconfig->addParameter("ymax",-1.6); + aconfig->addParameter("GreaterThan",1); + aconfig->addParameter("LessThan",1); + aconfig->addParameter("PublishBins",1); + + //Needed Parameter; check for bins N sigma away from average + aconfig->addParameter("NSigma",2); + + // Threshold for number of bins N sigma aways from average + aconfig->addGreenThreshold("NBins",2); + aconfig->addRedThreshold("NBins",10); + + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + TH1* h=result->getObject(); + h->Print("All"); + std::cout << "Result " << result->status_ << std::endl; + + return histogram; +} diff --git a/DataQuality/dqm_algorithms/workbench/Test_gauspluspol1_Fit.C b/DataQuality/dqm_algorithms/workbench/Test_gauspluspol1_Fit.C new file mode 100644 index 0000000000000000000000000000000000000000..52a00db612bd9d45de05575557ad32e560c13f8e --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/Test_gauspluspol1_Fit.C @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +TH1 * Test_gauspluspol1_Fit() +{ + dqm_algorithms::Simple_gauspluspol1_Fit * algorithm = new dqm_algorithms::Simple_gauspluspol1_Fit(); + + TH1F * histogram = new TH1F( "histogram", "Simple pol1sian Histogram", 100, -2, 2 ); + histogram->FillRandom( "gaus", 1000 ); + histogram->FillRandom( "pol1", 1000 ); + + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + + // Optional Parameters, Fit range + aconfig->addParameter("MinStat",1000); + aconfig->addParameter("xmin",-1); + aconfig->addParameter("xmax",1); + + // Thresholds for Fit Parameters...Only put thresholds on values you'd like to check....others will not be checked + + // Threshold for gaus fit parameters + aconfig->addGreenThreshold("Sigma",2); + aconfig->addRedThreshold("Sigma",3); + aconfig->addGreenThreshold("AbsMean",1); + aconfig->addRedThreshold("AbsMean",5); + // Threshold names if want to check actual Mean and not it's absolute value + //aconfig->addGreenThreshold("Mean",1); + //aconfig->addRedThreshold("Mean",5); + //aconfig->addGreenThreshold("Constant",1); + //aconfig->addRedThreshold("Constant",5); + + //Threshold for pol1 fit parameters + //aconfig->addGreenThreshold("pol1[0]",9); + //aconfig->addRedThreshold("pol1[0]",20); + //aconfig->addGreenThreshold("pol1[1]",9); + //aconfig->addRedThreshold("pol1[1]",20); + + dqm_core::Result * result = algorithm->execute( "test", *histogram, *aconfig ); + + std::cout << "Result " << result->status_ << std::endl; + + return histogram; +} diff --git a/DataQuality/dqm_algorithms/workbench/Test_sinusoid_fit.C b/DataQuality/dqm_algorithms/workbench/Test_sinusoid_fit.C new file mode 100644 index 0000000000000000000000000000000000000000..621a514c1ed05b7b82678b842d9b9dbdb2b19daf --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/Test_sinusoid_fit.C @@ -0,0 +1,78 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//Test_sinusoid_fit.C +// Macro to test the sinusoid fit +// Cristobal Cuenca Almenar, November 29th 2009 + +int Test_sinusoid_fit() +{ + + //load create + gSystem->Load( "libdqm_core.so" ); + gSystem->Load( "libdqm_dummy.so" ); + gSystem->Load( "libdqm_tools.so" ); + gSystem->Load( "libdqm_algorithms.so" ); + gROOT->ProcessLine( ".include .." ); + + + TCanvas* c = new TCanvas(); + c->Divide(2,1); + + + //algo + dqm_algorithms::Simple_sinusoid_Fit * algorithm = new dqm_algorithms::Simple_sinusoid_Fit(); + + + //create function to fill the histogram + c->cd(1); + TF1* f_sinusoid = new TF1("pep","[0]*sin(x) + [1]*cos(x)",-TMath::Pi(),TMath::Pi()); + f_sinusoid->SetParameters(4.0,2.0); + f_sinusoid->Draw(); + + + //create histogram + TH1F * histogram = new TH1F( "histogram", "Simple sinusoid histogram", 100, -4.0, 4.0 ); + //TH1F * histogram = new TH1F( "histogram", "Simple sinusoid histogram", 100, -TMath::Pi(),TMath::Pi() ); + for (int iBin=1; iBin<=100; iBin++) { + histogram->SetBinContent(iBin, f_sinusoid->Eval(histogram->GetBinLowEdge(iBin))); + } + c->cd(2); + histogram->Draw(); + + + //dummy configuration + dqm_core::test::DummyAlgorithmConfig * aconfig = new dqm_core::test::DummyAlgorithmConfig( ); + + // Optional Parameters, Fit range + aconfig->addParameter("MinStat",100); + //aconfig->addParameter("xmin",-1); + //aconfig->addParameter("xmax",1); + + // Thresholds for Fit Parameters...Only put thresholds on values you'd like to check....others will not be checked + // Threshold for s1 and s2 + aconfig->addGreenThreshold("s1",3.5); + aconfig->addRedThreshold("s1",2.5); + aconfig->addGreenThreshold("s2",1.0); + aconfig->addRedThreshold("s2",0.0); + + + //run check + dqm_core::Result * result = algorithm->execute( "sinusoid1", *histogram, *aconfig ); + std::cout << "Result " << result->status_ << std::endl; + + //can't read maps... so no tags +// std::map<std::string,double> tags = result->tags_; +// std::cout<<" tags.size()="<<tags.size(); + +// std::map<std::string,double>::iterator it=tags.begin(); +// int i=0; +// for ( ; it!=tags.end(); it++, i++) +// std::cout<<"Tag "<<i +// <<" named "<<it->first +// <<" value "<<it->second<<std::endl; + + + return 1; +} diff --git a/DataQuality/dqm_algorithms/workbench/Workbench.C b/DataQuality/dqm_algorithms/workbench/Workbench.C new file mode 100644 index 0000000000000000000000000000000000000000..1c0cfda2eaaf9541e6e3c62c9535eec474e7acb7 --- /dev/null +++ b/DataQuality/dqm_algorithms/workbench/Workbench.C @@ -0,0 +1,15 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +void Workbench() +{ + gSystem->Load( "libdqm_core.so" ); + gSystem->Load( "libdqm_dummy.so" ); + gSystem->Load( "libCintex.so" ); + Cintex::Enable(); + gSystem->Load( "libdqm_tools.so" ); + gSystem->Load( "libdqm_algorithms.so" ); + gROOT->ProcessLine( ".include .." ); +}