From fe09b8bfd09cb5cd61dae7afe42343bd5ebb9280 Mon Sep 17 00:00:00 2001 From: lucaquaglia15 <44832940+lucaquaglia15@users.noreply.github.com> Date: Fri, 22 Jul 2022 11:21:35 +0200 Subject: [PATCH] ZDC TDC calibration (#9403) * TDC calib * Please consider the following formatting changes * TDC calib 2.0 * Modified white spaces * TDC calib white spaces 2.0 * Final TDC calib commit * Please consider the following formatting changes Co-authored-by: ALICE Action Bot --- .../ZDC/base/include/ZDCBase/Constants.h | 1 + Detectors/ZDC/calib/CMakeLists.txt | 18 ++ .../ZDC/calib/include/ZDCCalib/TDCCalib.h | 43 +++- .../calib/include/ZDCCalib/TDCCalibConfig.h | 46 +++- .../ZDC/calib/include/ZDCCalib/TDCCalibData.h | 44 ++++ .../ZDC/calib/include/ZDCCalib/TDCCalibEPN.h | 79 +++++++ .../calib/include/ZDCCalib/TDCCalibEPNSpec.h | 58 +++++ .../ZDC/calib/include/ZDCCalib/TDCCalibSpec.h | 63 ++++++ Detectors/ZDC/calib/src/TDCCalib.cxx | 206 ++++++++++++++++++ Detectors/ZDC/calib/src/TDCCalibConfig.cxx | 143 ++++++++++++ Detectors/ZDC/calib/src/TDCCalibData.cxx | 61 ++++++ Detectors/ZDC/calib/src/TDCCalibEPN.cxx | 164 ++++++++++++++ Detectors/ZDC/calib/src/TDCCalibEPNSpec.cxx | 150 +++++++++++++ Detectors/ZDC/calib/src/TDCCalibSpec.cxx | 172 +++++++++++++++ Detectors/ZDC/calib/src/ZDCCalibLinkDef.h | 2 + .../calib/src/zdc-tdccalib-epn-workflow.cxx | 46 ++++ .../ZDC/calib/src/zdc-tdccalib-workflow.cxx | 43 ++++ Detectors/ZDC/macro/CMakeLists.txt | 6 + Detectors/ZDC/macro/CreateTDCCalib.C | 2 +- Detectors/ZDC/macro/CreateTDCCalibConfig.C | 68 ++++++ Detectors/ZDC/macro/InspectCCDBFile.C | 4 + .../include/ZDCReconstruction/ZDCTDCParam.h | 1 - 22 files changed, 1395 insertions(+), 25 deletions(-) create mode 100644 Detectors/ZDC/calib/include/ZDCCalib/TDCCalibData.h create mode 100644 Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPN.h create mode 100644 Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPNSpec.h create mode 100644 Detectors/ZDC/calib/include/ZDCCalib/TDCCalibSpec.h create mode 100644 Detectors/ZDC/calib/src/TDCCalib.cxx create mode 100644 Detectors/ZDC/calib/src/TDCCalibConfig.cxx create mode 100644 Detectors/ZDC/calib/src/TDCCalibData.cxx create mode 100644 Detectors/ZDC/calib/src/TDCCalibEPN.cxx create mode 100644 Detectors/ZDC/calib/src/TDCCalibEPNSpec.cxx create mode 100644 Detectors/ZDC/calib/src/TDCCalibSpec.cxx create mode 100644 Detectors/ZDC/calib/src/zdc-tdccalib-epn-workflow.cxx create mode 100644 Detectors/ZDC/calib/src/zdc-tdccalib-workflow.cxx create mode 100644 Detectors/ZDC/macro/CreateTDCCalibConfig.C diff --git a/Detectors/ZDC/base/include/ZDCBase/Constants.h b/Detectors/ZDC/base/include/ZDCBase/Constants.h index 1cd6a0c5c74df..ddcfdad0d8fa2 100644 --- a/Detectors/ZDC/base/include/ZDCBase/Constants.h +++ b/Detectors/ZDC/base/include/ZDCBase/Constants.h @@ -247,6 +247,7 @@ const std::string CCDBPathConfigSim = "ZDC/Config/Sim"; const std::string CCDBPathConfigModule = "ZDC/Config/Module"; const std::string CCDBPathRecoConfigZDC = "ZDC/Calib/RecoConfigZDC"; const std::string CCDBPathTDCCalib = "ZDC/Calib/TDCCalib"; +const std::string CCDBPathTDCCalibConfig = "ZDC/Calib/TDCCalibConfig"; const std::string CCDBPathTDCCorr = "ZDC/Calib/TDCCorr"; const std::string CCDBPathEnergyCalib = "ZDC/Calib/EnergyCalib"; const std::string CCDBPathTowerCalib = "ZDC/Calib/TowerCalib"; diff --git a/Detectors/ZDC/calib/CMakeLists.txt b/Detectors/ZDC/calib/CMakeLists.txt index 1abb7750d0d40..bdabe027f56f0 100644 --- a/Detectors/ZDC/calib/CMakeLists.txt +++ b/Detectors/ZDC/calib/CMakeLists.txt @@ -23,6 +23,12 @@ o2_add_library(ZDCCalib src/InterCalibSpec.cxx src/InterCalibEPN.cxx src/InterCalibEPNSpec.cxx + src/TDCCalibConfig.cxx + src/TDCCalibEPN.cxx + src/TDCCalibEPNSpec.cxx + src/TDCCalibSpec.cxx + src/TDCCalibData.cxx + src/TDCCalib.cxx src/WaveformCalibConfig.cxx src/WaveformCalib.cxx src/WaveformCalibSpec.cxx @@ -54,6 +60,8 @@ o2_target_root_dictionary(ZDCCalib include/ZDCCalib/BaselineCalibConfig.h include/ZDCCalib/InterCalibData.h include/ZDCCalib/InterCalibConfig.h + include/ZDCCalib/TDCCalibConfig.h + include/ZDCCalib/TDCCalibData.h include/ZDCCalib/WaveformCalibConfig.h include/ZDCCalib/WaveformCalibData.h include/ZDCCalib/WaveformCalibParam.h @@ -83,3 +91,13 @@ o2_add_executable(baselinecalib-workflow COMPONENT_NAME zdc SOURCES src/zdc-baselinecalib-workflow.cxx PUBLIC_LINK_LIBRARIES O2::ZDCWorkflow O2::ZDCCalib O2::DetectorsCalibration) + +o2_add_executable(tdccalib-epn-workflow + COMPONENT_NAME zdc + SOURCES src/zdc-tdccalib-epn-workflow.cxx + PUBLIC_LINK_LIBRARIES O2::ZDCWorkflow O2::ZDCCalib O2::DetectorsCalibration) + +o2_add_executable(tdccalib-workflow + COMPONENT_NAME zdc + SOURCES src/zdc-tdccalib-workflow.cxx + PUBLIC_LINK_LIBRARIES O2::ZDCWorkflow O2::ZDCCalib O2::DetectorsCalibration) diff --git a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalib.h b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalib.h index 04f2d012c5b66..42099eb0714c9 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalib.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalib.h @@ -16,18 +16,29 @@ #include #include #include +#include #include "ZDCBase/Constants.h" #include "DataFormatsZDC/RecEvent.h" -#include "ZDCReconstruction/ZDCEnergyParam.h" -#include "ZDCCalib/InterCalibConfig.h" +#include "ZDCReconstruction/ZDCTDCParam.h" +#include "ZDCCalib/TDCCalibConfig.h" +#include "CCDB/CcdbObjectInfo.h" //added by me +#include "CommonDataFormat/FlatHisto1D.h" +#include "CommonDataFormat/FlatHisto2D.h" +#include "ZDCCalib/TDCCalibData.h" +#include "ZDCReconstruction/ZDCTowerParam.h" + #ifndef ALICEO2_ZDC_TDCCALIB_H_ #define ALICEO2_ZDC_TDCCALIB_H_ namespace o2 { namespace zdc { -class InterCalib + +class TDCCalib //after { + + using CcdbObjectInfo = o2::ccdb::CcdbObjectInfo; //added by me + public: TDCCalib() = default; int init(); @@ -36,26 +47,36 @@ class InterCalib const gsl::span& energy, const gsl::span& tdc, const gsl::span& info); // Calibration of RUN3 data + int process(const TDCCalibData& data); // Calibration of RUN3 data - aggregator node int endOfRun(); // Perform minimization - int process(const char* hname, int ic); // Calibration of RUN2 data - void replay(int ih, THnSparse* hs, int ic); // Test of calibration using RUN2 data - int mini(int ih); + double extractShift(int ih); + void add(int ih, o2::dataformats::FlatHisto1D& h1); int write(const std::string fn = "ZDCTDCCalib.root"); - static void fcn(int& npar, double* gin, double& chi, double* par, int iflag); + const ZDCTDCParam& getTDCParamUpd() const { return mTDCParamUpd; }; + CcdbObjectInfo& getCcdbObjectInfo() { return mInfo; } void setTDCParam(const ZDCTDCParam* param) { mTDCParam = param; }; const ZDCTDCParam* getTDCParam() const { return mTDCParam; }; void setTDCCalibConfig(const TDCCalibConfig* param) { mTDCCalibConfig = param; }; const TDCCalibConfig* getTDCCalibConfig() const { return mTDCCalibConfig; }; + void setVerbosity(int v) { mVerbosity = v; } + int getVerbosity() const { return mVerbosity; } + private: - std::array, NTDCChannels> mHTDC{}; - std::array, NTDCChannels> mMn{}; + std::array*, NTDCChannels> mCTDC{}; //array of FlatHisto1D, number of elements = NTDCChannles (= 10), defined in constants.h {} means defined but not initialized + std::array, NTDCChannels> mHCTDC{}; //copy of flat histo 1D in TH1F to use root functions bool mInitDone = false; - static std::mutex mMtx; /// mutex for critical section + bool mSaveDebugHistos = true; + const TDCCalibConfig* mTDCCalibConfig = nullptr; /// Configuration of TDC calibration, this line has been swapped with the following one to be consistent with intercalibration const ZDCTDCParam* mTDCParam = nullptr; /// TDC calibration object - const TDCCalibConfig* mTDCCalibConfig = nullptr; /// Configuration of TDC calibration + int32_t mVerbosity = DbgMinimal; + + TDCCalibData mData; + ZDCTDCParam mTDCParamUpd; /// Updated TDC calibration object, added by me + CcdbObjectInfo mInfo; /// CCDB Info, added by me + void assign(int ih, bool ismod); /// Assign updated calibration object, added by me }; } // namespace zdc } // namespace o2 diff --git a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibConfig.h b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibConfig.h index e4e91bd010643..fcf29da1f4b61 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibConfig.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibConfig.h @@ -9,36 +9,43 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef O2_ZDC_INTERCALIBCONFIG_H +#ifndef O2_ZDC_TDCCALIBCONFIG_H #define O2_ZDC_TDCCALIBCONFIG_H #include "ZDCBase/Constants.h" #include #include +#include #include /// \file TDCCalibConfig.h /// \brief Configuration of ZDC TDC calibration procedure -/// \author P. Cortese +/// \author L. Quaglia namespace o2 { namespace zdc { struct TDCCalibConfig { + static constexpr int NTDCChannels = 10; //number of TDC channels double cutLow[NTDCChannels] = {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; double cutHigh[NTDCChannels] = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; - int nb[NH] = {0}; /// Number of bins - double amin[NH] = {0}; /// minimum - double amax[NH] = {0}; /// maximum - double l_bnd[NH] = {0.1, 0.1, 0.1, 0.1, 0.1}; - double u_bnd[NH] = {10., 10., 10., 10., 10.}; - double l_bnd_o[NH] = {-20., -20., -20., -20., -20.}; - double u_bnd_o[NH] = {20., 20., 20., 20., 20.}; - double step_o[NH] = {0., 0., 0., 0., 0.}; - double min_e[NH] = {0., 0., 0., 0., 0.}; + bool enabled[NTDCChannels] = {true, true, true, true, true, true, true, true, true, true}; //ZNAC, ZNAS, ZPAC, ZPAS, ZEM1, ZEM2, ZNCC, ZNCS, ZPCC, ZPCS + int nb1[NTDCChannels] = {0}; /// 1D histogram: number of bins + double amin1[NTDCChannels] = {0}; /// minimum + double amax1[NTDCChannels] = {0}; /// maximum + int nb2[NTDCChannels] = {0}; /// 2D histogram: number of bins + double amin2[NTDCChannels] = {0}; /// minimum + double amax2[NTDCChannels] = {0}; /// maximum + double l_bnd[NTDCChannels] = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1}; + double u_bnd[NTDCChannels] = {10., 10., 10., 10., 10., 10., 10., 10., 10., 10.}; + double l_bnd_o[NTDCChannels] = {-20., -20., -20., -20., -20., -20., -20., -20., -20., -20.}; + double u_bnd_o[NTDCChannels] = {20., 20., 20., 20., 20., 20., 20., 20., 20., 20.}; + double step_o[NTDCChannels] = {0}; + double min_e[NTDCChannels] = {0}; + std::string desc = ""; void print() const; void resetCuts(); @@ -58,7 +65,22 @@ struct TDCCalibConfig { void setBinning2D(int nb, double amin, double amax); void setBinning1D(int ih, int nb, double amin, double amax); void setBinning2D(int ih, int nb, double amin, double amax); - ClassDefNV(TDCCalibConfig, 1); + void setDescription(std::string d) { desc = d; } + void enable(bool c0, bool c1, bool c2, bool c3, bool c4, bool c5, bool c6, bool c7, bool c8, bool c9) + { + enabled[0] = c0; + enabled[1] = c1; + enabled[2] = c2; + enabled[3] = c3; + enabled[4] = c4; + enabled[5] = c5; + enabled[6] = c6; + enabled[7] = c7; + enabled[8] = c8; + enabled[9] = c9; + } + + ClassDefNV(TDCCalibConfig, 3); }; } // namespace zdc } // namespace o2 diff --git a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibData.h b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibData.h new file mode 100644 index 0000000000000..23996947d3318 --- /dev/null +++ b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibData.h @@ -0,0 +1,44 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef _ZDC_TDCCALIB_DATA_H +#define _ZDC_TDCCALIB_DATA_H + +#include "ZDCBase/Constants.h" +#include +#include + +/// \file TDCCalibData.h +/// \brief TDC calibration intermediate data +/// \author luca.quaglia@cern.ch + +namespace o2 +{ +namespace zdc +{ + +struct TDCCalibData { + static constexpr int NTDC = 10; /// ZNAC, ZNAS, ZPAC, ZPAS, ZEM1, ZEM2, ZNCC, ZNCS, ZPCC, ZPCS + uint64_t mCTimeBeg = 0; /// Time of processed time frame + uint64_t mCTimeEnd = 0; /// Time of processed time frame + static constexpr const char* CTDC[NTDC] = {"ZNAC", "ZNAS", "ZPAC", "ZPAS", "ZEM1", "ZEM2", "ZNCC", "ZNCS", "ZPCC", "ZPCS"}; + int entries[NTDC] = {0}; + TDCCalibData& operator+=(const TDCCalibData& other); + int getEntries(int ih) const; + void print() const; + void setCreationTime(uint64_t ctime); + ClassDefNV(TDCCalibData, 1); +}; + +} // namespace zdc +} // namespace o2 + +#endif diff --git a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPN.h b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPN.h new file mode 100644 index 0000000000000..e5a8888effa14 --- /dev/null +++ b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPN.h @@ -0,0 +1,79 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include +#include +#include +#include +#include "ZDCBase/Constants.h" +#include "CommonDataFormat/FlatHisto1D.h" +#include "CommonDataFormat/FlatHisto2D.h" +#include "DataFormatsZDC/RecEvent.h" +#include "ZDCReconstruction/ZDCEnergyParam.h" +#include "ZDCReconstruction/ZDCTowerParam.h" +#include "ZDCReconstruction/ZDCTDCParam.h" //added by me +#include "ZDCCalib/TDCCalibData.h" +#include "ZDCCalib/TDCCalibConfig.h" + +#ifndef ALICEO2_ZDC_TDCCALIBEPN_H_ +#define ALICEO2_ZDC_TDCCALIBEPN_H_ +namespace o2 +{ +namespace zdc +{ +class TDCCalibEPN +{ + public: + TDCCalibEPN() = default; + int init(); + static constexpr int HtdcZNAC = 0; + static constexpr int HtdcZNAS = 1; + static constexpr int HtdcZPAC = 2; + static constexpr int HtdcZPAS = 3; + static constexpr int HtdcZEM1 = 4; + static constexpr int HtdcZEM2 = 5; + static constexpr int HtdcZNCC = 6; + static constexpr int HtdcZNCS = 7; + static constexpr int HtdcZPCC = 8; + static constexpr int HtdcZPCS = 9; + static constexpr int NTDC = TDCCalibData::NTDC; + void clear(int ih = -1); + int process(const gsl::span& bcrec, + const gsl::span& energy, + const gsl::span& tdc, + const gsl::span& info); // Calibration of RUN3 data + int endOfRun(); // End of TDCCalib + int write(const std::string fn = "ZDCTDCCalibEPN.root"); + + void fill1D(int iTDC, int nHits, o2::zdc::RecEventFlat ev); //function to fill histograms; + + void setTDCCalibConfig(const TDCCalibConfig* param) { mTDCCalibConfig = param; }; + const TDCCalibConfig* getTDCCalibConfig() const { return mTDCCalibConfig; }; + void setSaveDebugHistos() { mSaveDebugHistos = true; } + void setDontSaveDebugHistos() { mSaveDebugHistos = false; } + void setVerbosity(int val) { mVerbosity = val; } + TDCCalibData mData; + TDCCalibData& getData() { return mData; } + std::array*, NTDC> mTDC{}; + + private: + bool mInitDone = false; + bool mSaveDebugHistos = true; + int32_t mVerbosity = DbgMinimal; + const TDCCalibConfig* mTDCCalibConfig = nullptr; /// Configuration of intercalibration +}; +} // namespace zdc +} // namespace o2 + +#endif \ No newline at end of file diff --git a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPNSpec.h b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPNSpec.h new file mode 100644 index 0000000000000..2f68b10c09554 --- /dev/null +++ b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibEPNSpec.h @@ -0,0 +1,58 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TDCCalibEPNSpec.h +/// @brief ZDC TDC calibration pre-processing on EPN +/// @author luca.quaglia@cern.ch + +#ifndef O2_ZDC_TDCCALIBEPN_SPEC +#define O2_ZDC_TDCCALIBEPN_SPEC + +#include +#include "Framework/Logger.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/Task.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsZDC/ZDCTDCData.h" +#include "ZDCCalib/TDCCalibData.h" +#include "ZDCCalib/TDCCalibEPN.h" +#include "ZDCCalib/TDCCalibConfig.h" + +namespace o2 +{ +namespace zdc +{ + +class TDCCalibEPNSpec : public o2::framework::Task +{ + public: + TDCCalibEPNSpec(); + TDCCalibEPNSpec(const int verbosity); + ~TDCCalibEPNSpec() override = default; + void init(o2::framework::InitContext& ic) final; + void updateTimeDependentParams(o2::framework::ProcessingContext& pc); + void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final; + void run(o2::framework::ProcessingContext& pc) final; + void endOfStream(o2::framework::EndOfStreamContext& ec) final; + + private: + int mVerbosity = DbgMinimal; // Verbosity level + bool mInitialized = false; // Connect once to CCDB during initialization + TDCCalibEPN mWorker; // TDC calibration object (was mTDCCalibEPN, modified after discussion with Pietro 20 June 2022) + TStopwatch mTimer; +}; + +framework::DataProcessorSpec getTDCCalibEPNSpec(); + +} // namespace zdc +} // namespace o2 + +#endif \ No newline at end of file diff --git a/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibSpec.h b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibSpec.h new file mode 100644 index 0000000000000..3e5a81b8447c6 --- /dev/null +++ b/Detectors/ZDC/calib/include/ZDCCalib/TDCCalibSpec.h @@ -0,0 +1,63 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TDCCalibSpec.h +/// @brief ZDC TDC calibratin +/// @author luca.quaglia@cern.ch + +#ifndef O2_ZDC_TDCCALIB_SPEC +#define O2_ZDC_TDCCALIB_SPEC + +#include +#include "Framework/Logger.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/DataAllocator.h" +#include "Framework/Task.h" +#include "CommonDataFormat/FlatHisto1D.h" +#include "DataFormatsZDC/ZDCTDCData.h" +#include "CommonUtils/NameConf.h" +#include "ZDCCalib/TDCCalib.h" +#include "ZDCCalib/TDCCalibData.h" +#include "ZDCCalib/TDCCalibConfig.h" +#include "DetectorsCalibration/Utils.h" +#include "CCDB/CcdbObjectInfo.h" + +namespace o2 +{ +namespace zdc +{ + +class TDCCalibSpec : public o2::framework::Task +{ + public: + TDCCalibSpec(); + TDCCalibSpec(const int verbosity); + ~TDCCalibSpec() override = default; + void init(o2::framework::InitContext& ic) final; + void updateTimeDependentParams(o2::framework::ProcessingContext& pc); + void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final; + void run(o2::framework::ProcessingContext& pc) final; + void endOfStream(o2::framework::EndOfStreamContext& ec) final; + void sendOutput(o2::framework::DataAllocator& output); + + private: + int mVerbosity = DbgMinimal; // Verbosity level + bool mInitialized = false; // Connect once to CCDB during initialization + TDCCalib mWorker; // TDC calibration object + TStopwatch mTimer; +}; + +framework::DataProcessorSpec getTDCCalibSpec(); + +} // namespace zdc +} // namespace o2 + +#endif diff --git a/Detectors/ZDC/calib/src/TDCCalib.cxx b/Detectors/ZDC/calib/src/TDCCalib.cxx new file mode 100644 index 0000000000000..e005ae445ef0b --- /dev/null +++ b/Detectors/ZDC/calib/src/TDCCalib.cxx @@ -0,0 +1,206 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CommonUtils/MemFileHelper.h" +#include "ZDCCalib/TDCCalibData.h" +#include "ZDCCalib/TDCCalib.h" +#include "ZDCReconstruction/ZDCTDCParam.h" +#include "Framework/Logger.h" +#include "CCDB/CcdbApi.h" + +using namespace o2::zdc; + +int TDCCalib::init() +{ + if (mTDCCalibConfig == nullptr) { + LOG(fatal) << "o2::zdc::TDCCalib: missing configuration object"; + return -1; + } + clear(); + auto* cfg = mTDCCalibConfig; + int ih = 0; + // clang-format off + for (int i = 0; i < TDCCalibData::NTDC; i++) { + mCTDC[i] = new o2::dataformats::FlatHisto1D(cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]); //sum of TF histograms + ih++; + } + // clang-format on + mInitDone = true; + return 0; +} + +//______________________________________________________________________________ +// Update calibration coefficients +int TDCCalib::endOfRun() +{ + if (mVerbosity > DbgZero) { + LOGF(info, "Computing TDC Calibration coefficients"); + } + for (int ih = 0; ih < TDCCalibData::NTDC; ih++) { + LOGF(info, "%s %i events and cuts (%g:%g)", TDCCalibData::CTDC[ih], mData.entries[ih], mTDCCalibConfig->cutLow[ih], mTDCCalibConfig->cutHigh[ih]); + + if (!mTDCCalibConfig->enabled[ih]) { + LOGF(info, "DISABLED processing of RUN3 data for ih = %d: %s", ih, TDCCalibData::CTDC[ih]); + assign(ih, false); + } + + else if (mData.entries[ih] >= mTDCCalibConfig->min_e[ih]) { //if number of events > minimum value accpeted -> process + LOGF(info, "Processed RUN3 data for ih = %d: %s", ih, TDCCalibData::CTDC[ih]); + assign(ih, true); + } else { + LOGF(info, "FAILED processing RUN3 data for ih = %d: %s: TOO FEW EVENTS: %g", ih, TDCCalibData::CTDC[ih], 5); //instead of 5 put number of events + assign(ih, false); + } + } + + auto clName = o2::utils::MemFileHelper::getClassName(mTDCParamUpd); + mInfo.setObjectType(clName); + auto flName = o2::ccdb::CcdbApi::generateFileName(clName); + mInfo.setFileName(flName); + mInfo.setPath(CCDBPathTDCCalib); + std::map md; + md["config"] = mTDCCalibConfig->desc; + mInfo.setMetaData(md); + uint64_t starting = mData.mCTimeBeg; + if (starting >= 10000) { + starting = starting - 10000; // start 10 seconds before + } + uint64_t stopping = mData.mCTimeEnd + 10000; // stop 10 seconds after + mInfo.setStartValidityTimestamp(starting); + mInfo.setEndValidityTimestamp(stopping); + + if (mSaveDebugHistos) { + write(); + } + return 0; +} + +//______________________________________________________________________________ +// Update calibration object for the ten TDCs +// ismod=false if it was not possible to update the calibration coefficients +// due to low statistics +// ismod=true if the calibration was updated +void TDCCalib::assign(int ih, bool ismod) +{ + if (ih >= 0 && ih <= 9) { + auto oldval = mTDCParam->getShift(ih); //old value from calibration object (TDCCalib) + if (ismod == true) { //ismod == true + auto val = oldval; + auto shift = extractShift(ih); + //Change wrt previous shift + val = val + shift; + if (val < 0) { //negative value or = 25ns shift is not acceptable + LOGF(error, "Negative value of shift: %8.6f not acceptable", val); + } + + else if (val >= 25) { + LOGF(error, "Value of shift: %8.6f >= 25 ns not acceptable", val); + } + + if (mVerbosity > DbgZero) { + LOGF(info, "%s updated %8.6f -> %8.6f", TDCCalibData::CTDC[ih], oldval, val); + } + mTDCParamUpd.setShift(ih, val); + } + + else { //ismod == false + if (mVerbosity > DbgZero) { + LOGF(info, "%s NOT CHANGED %8.6f", TDCCalibData::CTDC[ih], oldval); + } + mTDCParamUpd.setShift(ih, oldval); + } + } + + else { //TDC index out of range + LOG(fatal) << "TDCCalib::assign accessing not existing ih = " << ih; + } +} + +void TDCCalib::clear(int ih) +{ + int ihstart = 0; + int ihstop = TDCCalibData::NTDC; + + for (int32_t ii = ihstart; ii < ihstop; ii++) { + if (mCTDC[ii]) { + mCTDC[ii]->clear(); + } + } +} + +int TDCCalib::process(const TDCCalibData& data) +{ + if (!mInitDone) { + init(); + } + mData += data; + return 0; +} + +void TDCCalib::add(int ih, o2::dataformats::FlatHisto1D& h1) +{ + if (!mInitDone) { + init(); + } + + constexpr int nh = TDCCalibData::NTDC; + + if (ih >= 0 && ih < nh) { + mCTDC[ih]->add(h1); + } else { + LOG(error) << "TDCCalib::add: unsupported FlatHisto1D " << ih; + } +} + +double TDCCalib::extractShift(int ih) +{ + // Extract the TDC shift + auto h1 = mCTDC[ih]->createTH1F(TDCCalibData::CTDC[ih]); // createTH1F(histo_name) + //h1->Draw("HISTO"); + int nEntries = h1->GetEntries(); + std::cout << nEntries << std::endl; + if ((ih >= 0 && ih <= 9) && (nEntries >= mTDCCalibConfig->min_e[ih])) { //TDC number is ok and more than minimum entries + double avgShift = h1->GetMean(); + return avgShift; + } else { + LOG(error) << "TDCCalib::extractShift TDC out of range " << ih; + return 0; + } +} + +int TDCCalib::write(const std::string fn) +{ + TDirectory* cwd = gDirectory; + TFile* f = new TFile(fn.data(), "recreate"); + if (f->IsZombie()) { + LOG(error) << "Cannot create file: " << fn; + return 1; + } + for (int32_t ih = 0; ih < TDCCalibData::NTDC; ih++) { + if (mCTDC[ih]) { + auto p = mCTDC[ih]->createTH1F(TDCCalibData::CTDC[ih]); // createTH1F(histo_name) + p->SetTitle(TDCCalibData::CTDC[ih]); + p->Write("", TObject::kOverwrite); + } + } + + f->Close(); + cwd->cd(); + return 0; +} diff --git a/Detectors/ZDC/calib/src/TDCCalibConfig.cxx b/Detectors/ZDC/calib/src/TDCCalibConfig.cxx new file mode 100644 index 0000000000000..7ca0254161ec9 --- /dev/null +++ b/Detectors/ZDC/calib/src/TDCCalibConfig.cxx @@ -0,0 +1,143 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Framework/Logger.h" +#include "ZDCCalib/TDCCalibConfig.h" + +using namespace o2::zdc; + +void TDCCalibConfig::print() const +{ + const char* hn[NTDCChannels] = {"ZNAC", "ZNAS", "ZPAC", "ZPAS", "ZEM1", "ZEM2", "ZNCC", "ZNCS", "ZPCC", "ZPCS"}; + for (Int_t ih = 0; ih < NTDCChannels; ih++) { + LOG(info) << hn[ih] << " limits = (" << cutLow[ih] << " : " << cutHigh[ih] << ")"; + } + for (Int_t ih = 0; ih < NTDCChannels; ih++) { + LOG(info) << hn[ih] << " booking 1D = (" << nb1[ih] << ", " << amin1[ih] << ", " << amax1[ih] << ")"; + } + for (Int_t ih = 0; ih < NTDCChannels; ih++) { + LOG(info) << hn[ih] << " booking 2D = (" << nb2[ih] << ", " << amin2[ih] << ", " << amax2[ih] << ")"; + } +} + +void TDCCalibConfig::setMinEntries(double val) +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + min_e[ih] = val; + } +} + +void TDCCalibConfig::setMinEntries(int ih, double val) +{ + min_e[ih] = val; +} + +void TDCCalibConfig::resetCuts() +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + cutLow[ih] = -std::numeric_limits::infinity(); + cutHigh[ih] = std::numeric_limits::infinity(); + } +} + +void TDCCalibConfig::resetCutLow() +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + cutLow[ih] = -std::numeric_limits::infinity(); + } +} + +void TDCCalibConfig::resetCutHigh() +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + cutHigh[ih] = std::numeric_limits::infinity(); + } +} + +void TDCCalibConfig::resetCutLow(int ih) +{ + cutLow[ih] = -std::numeric_limits::infinity(); +} + +void TDCCalibConfig::resetCutHigh(int ih) +{ + cutHigh[ih] = std::numeric_limits::infinity(); +} + +void TDCCalibConfig::setCutLow(double val) +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + cutLow[ih] = val; + } +} + +void TDCCalibConfig::setCutHigh(double val) +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + cutHigh[ih] = val; + } +} + +void TDCCalibConfig::setCutLow(int ih, double val) +{ + cutLow[ih] = val; +} + +void TDCCalibConfig::setCutHigh(int ih, double val) +{ + cutHigh[ih] = val; +} + +void TDCCalibConfig::setCuts(double low, double high) +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + cutLow[ih] = low; + cutHigh[ih] = high; + } +} + +void TDCCalibConfig::setCuts(int ih, double low, double high) +{ + cutHigh[ih] = low; + cutLow[ih] = high; +} + +void TDCCalibConfig::setBinning1D(int nb, double amin, double amax) +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + nb1[ih] = nb; + amin1[ih] = amin; + amax1[ih] = amax; + } +} + +void TDCCalibConfig::setBinning2D(int nb, double amin, double amax) +{ + for (int32_t ih = 0; ih < NTDCChannels; ih++) { + nb2[ih] = nb; + amin2[ih] = amin; + amax2[ih] = amax; + } +} + +void TDCCalibConfig::setBinning1D(int ih, int nb, double amin, double amax) +{ + nb1[ih] = nb; + amin1[ih] = amin; + amax1[ih] = amax; +} + +void TDCCalibConfig::setBinning2D(int ih, int nb, double amin, double amax) +{ + nb2[ih] = nb; + amin2[ih] = amin; + amax2[ih] = amax; +} diff --git a/Detectors/ZDC/calib/src/TDCCalibData.cxx b/Detectors/ZDC/calib/src/TDCCalibData.cxx new file mode 100644 index 0000000000000..0fe929a95b129 --- /dev/null +++ b/Detectors/ZDC/calib/src/TDCCalibData.cxx @@ -0,0 +1,61 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Framework/Logger.h" +#include "ZDCCalib/TDCCalibData.h" + +using namespace o2::zdc; + +void TDCCalibData::print() const +{ + for (int i = 0; i < NTDC; i++) { + LOGF(info, "%s", CTDC[i]); + } +} + +TDCCalibData& TDCCalibData::operator+=(const TDCCalibData& other) +{ + + for (int32_t ih = 0; ih < NTDC; ih++) { + entries[ih] += other.entries[ih]; + } + + if (mCTimeBeg == 0 || other.mCTimeBeg < mCTimeBeg) { + mCTimeBeg = other.mCTimeBeg; + } + if (other.mCTimeEnd > mCTimeEnd) { + mCTimeEnd = other.mCTimeEnd; + } + //#ifdef O2_ZDC_DEBUG + LOGF(info, "TDCCalibData [%llu : %llu]: %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d", mCTimeBeg, mCTimeEnd, CTDC[0], getEntries(0), CTDC[1], getEntries(1), + CTDC[2], getEntries(2), CTDC[3], getEntries(3), CTDC[4], getEntries(4), CTDC[5], getEntries(5), CTDC[6], getEntries(6), CTDC[7], getEntries(7), + CTDC[8], getEntries(8), CTDC[9], getEntries(9)); + //#endif + return *this; +} + +void TDCCalibData::setCreationTime(uint64_t ctime) +{ + mCTimeBeg = ctime; + mCTimeEnd = ctime; +#ifdef O2_ZDC_DEBUG + LOGF(info, "TDCCalibData::setCreationTime %llu", ctime); +#endif +} + +int TDCCalibData::getEntries(int ih) const +{ + if (ih < 0 || ih >= NTDC) { + LOGF(error, "TDCCalibData::getEntries ih = %d is out of range", ih); + return 0; + } + return entries[ih]; +} diff --git a/Detectors/ZDC/calib/src/TDCCalibEPN.cxx b/Detectors/ZDC/calib/src/TDCCalibEPN.cxx new file mode 100644 index 0000000000000..8805111393c2d --- /dev/null +++ b/Detectors/ZDC/calib/src/TDCCalibEPN.cxx @@ -0,0 +1,164 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ZDCCalib/TDCCalibData.h" +#include "ZDCCalib/TDCCalibEPN.h" +#include "ZDCCalib/TDCCalib.h" +#include "ZDCReconstruction/ZDCEnergyParam.h" +#include "ZDCReconstruction/ZDCTowerParam.h" +#include "ZDCReconstruction/ZDCTDCParam.h" //added by me +#include "Framework/Logger.h" + +using namespace o2::zdc; + +int TDCCalibEPN::init() +{ + if (mTDCCalibConfig == nullptr) { + LOG(fatal) << "o2::zdc::TDCCalibEPN: missing configuration object"; + return -1; + } + clear(); + auto* cfg = mTDCCalibConfig; + int ih; + // clang-format off + for (int iTDC = 0; iTDC < NTDC; iTDC++) { + mTDC[iTDC] = new o2::dataformats::FlatHisto1D(cfg->nb1[iTDC],cfg->amin1[iTDC],cfg->amax1[iTDC]); + } + + // clang-format on + mInitDone = true; + return 0; +} + +//----// + +int TDCCalibEPN::process(const gsl::span& RecBC, + const gsl::span& Energy, + const gsl::span& TDCData, + const gsl::span& Info) +{ + if (!mInitDone) { + init(); + } + LOG(info) << "o2::zdc::TDCCalibEPN processing " << RecBC.size() << " b.c. @ TS " << mData.mCTimeBeg << " : " << mData.mCTimeEnd; + o2::zdc::RecEventFlat ev; + ev.init(RecBC, Energy, TDCData, Info); + while (ev.next()) { + if (ev.getNInfo() > 0) { + auto& decodedInfo = ev.getDecodedInfo(); + for (uint16_t info : decodedInfo) { + uint8_t ch = (info >> 10) & 0x1f; + uint16_t code = info & 0x03ff; + // hmsg->Fill(ch, code); + } + if (mVerbosity > DbgMinimal) { + ev.print(); + } + // Need clean data (no messages) + // We are sure there is no pile-up in any channel (too restrictive?) + continue; + } + if (ev.getNEnergy() > 0 && ev.mCurB.triggers == 0) { + LOGF(info, "%9u.%04u Untriggered bunch", ev.mCurB.ir.orbit, ev.mCurB.ir.bc); + // Skip! + continue; + } + + //Fill 1d histograms with tdc values. Check if channel is acquired or not + for (int itdc = 0; itdc < NTDC; itdc++) { //loop over all TDCs + int nhits = ev.NtdcV(itdc); + + if (nhits > 0) { + //call fill function to fill histo + fill1D(itdc, nhits, ev); + } + } + } + return 0; +} + +//----// + +int TDCCalibEPN::endOfRun() +{ + if (mVerbosity > DbgZero) { + LOGF(info, "TDCCalibEPN::endOfRun ts (%llu:%llu)", mData.mCTimeBeg, mData.mCTimeEnd); + std::cout << "End of run here" << std::endl; + for (int ih = 0; ih < NTDC; ih++) { + LOGF(info, "%s %i events and cuts (%g:%g)", TDCCalibData::CTDC[ih], mData.entries[ih], mTDCCalibConfig->cutLow[ih], mTDCCalibConfig->cutHigh[ih]); + } + } + if (mSaveDebugHistos) { + write(); + } + return 0; +} + +//----// + +void TDCCalibEPN::clear(int ih) +{ + int ihstart = 0; + int ihstop = NTDC; + + for (int32_t ii = ihstart; ii < ihstop; ii++) { + if (mTDC[ii]) { + mTDC[ii]->clear(); + } + } +} + +//----// + +void TDCCalibEPN::fill1D(int iTDC, int nHits, o2::zdc::RecEventFlat ev) +{ + //Get TDC values + float tdcVal[nHits]; + for (int i = 0; i < nHits; i++) { + tdcVal[i] = ev.tdcV(iTDC, i); + } + + //Fill histo + for (int hit = 0; hit < nHits; hit++) { + mTDC[iTDC]->fill(tdcVal[hit]); + } + mData.entries[iTDC] += nHits; +} + +//----// + +int TDCCalibEPN::write(const std::string fn) +{ + TDirectory* cwd = gDirectory; + TFile* f = new TFile(fn.data(), "recreate"); + if (f->IsZombie()) { + LOG(error) << "Cannot create file: " << fn; + return 1; + } + for (int32_t ih = 0; ih < NTDC; ih++) { + if (mTDC[ih]) { + auto p = mTDC[ih]->createTH1F(TDCCalibData::CTDC[ih]); + p->SetTitle(TDCCalibData::CTDC[ih]); + p->Write("", TObject::kOverwrite); + } + } + f->Close(); + cwd->cd(); + return 0; +} \ No newline at end of file diff --git a/Detectors/ZDC/calib/src/TDCCalibEPNSpec.cxx b/Detectors/ZDC/calib/src/TDCCalibEPNSpec.cxx new file mode 100644 index 0000000000000..3f4849c39b507 --- /dev/null +++ b/Detectors/ZDC/calib/src/TDCCalibEPNSpec.cxx @@ -0,0 +1,150 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TDCCalibEPNSpec.cxx +/// @brief EPN Spec file for TDC calibration +/// @author luca.quaglia@cern.ch + +#include +#include +#include +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "Framework/Logger.h" +#include "Framework/ControlService.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/CCDBParamSpec.h" +#include "Framework/DataRefUtils.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DataFormatsZDC/BCData.h" +#include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/OrbitData.h" +#include "DataFormatsZDC/RecEvent.h" +#include "ZDCBase/ModuleConfig.h" +#include "CommonUtils/NameConf.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "ZDCReconstruction/RecoConfigZDC.h" +#include "ZDCReconstruction/ZDCEnergyParam.h" +#include "ZDCReconstruction/ZDCTowerParam.h" +#include "ZDCCalib/TDCCalibEPNSpec.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ + +TDCCalibEPNSpec::TDCCalibEPNSpec() +{ + mTimer.Stop(); + mTimer.Reset(); +} + +TDCCalibEPNSpec::TDCCalibEPNSpec(const int verbosity) : mVerbosity(verbosity) +{ + mTimer.Stop(); + mTimer.Reset(); +} + +void TDCCalibEPNSpec::init(o2::framework::InitContext& ic) +{ + mVerbosity = ic.options().get("verbosity-level"); + mWorker.setVerbosity(mVerbosity); +} + +void TDCCalibEPNSpec::updateTimeDependentParams(ProcessingContext& pc) +{ + // we call these methods just to trigger finaliseCCDB callback + pc.inputs().get("tdccalibconfig"); //added by me +} + +void TDCCalibEPNSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) +{ + if (matcher == ConcreteDataMatcher("ZDC", "TDCCALIBCONFIG", 0)) { + auto* config = (const o2::zdc::TDCCalibConfig*)obj; + if (mVerbosity > DbgZero) { + LOG(info) << "Loaded TDCCalib configuration object"; + config->print(); + } + mWorker.setTDCCalibConfig(config); + } +} + +void TDCCalibEPNSpec::run(ProcessingContext& pc) +{ + if (!mInitialized) { + mInitialized = true; + updateTimeDependentParams(pc); + mTimer.Stop(); + mTimer.Reset(); + mTimer.Start(false); + } + //auto config = pc.inputs().get("tdccalibconfig"); + const auto ref = pc.inputs().getFirstValid(true); + auto creationTime = DataRefUtils::getHeader(ref)->creation; // approximate time in ms + mWorker.getData().setCreationTime(creationTime); + + auto bcrec = pc.inputs().get>("bcrec"); + auto energy = pc.inputs().get>("energy"); //maybe not needed for TDC configuration + auto tdc = pc.inputs().get>("tdc"); + auto info = pc.inputs().get>("info"); + + // Process reconstructed data + mWorker.process(bcrec, energy, tdc, info); + + // Send debug histograms and intermediate calibration data + o2::framework::Output output("ZDC", "TDCCALIBDATA", 0, Lifetime::Timeframe); + pc.outputs().snapshot(output, mWorker.mData); + char outputd[o2::header::gSizeDataDescriptionString]; + for (int ih = 0; ih < TDCCalibData::NTDC; ih++) { + snprintf(outputd, o2::header::gSizeDataDescriptionString, "TDC_1DH%d", ih); + o2::framework::Output output("ZDC", outputd, 0, Lifetime::Timeframe); + pc.outputs().snapshot(output, mWorker.mTDC[ih]->getBase()); + } +} + +void TDCCalibEPNSpec::endOfStream(EndOfStreamContext& ec) +{ + mWorker.endOfRun(); + mTimer.Stop(); + LOGF(info, "ZDC EPN TDC calibration total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); //added by me +} + +framework::DataProcessorSpec getTDCCalibEPNSpec() +{ + std::vector inputs; + inputs.emplace_back("bcrec", "ZDC", "BCREC", 0, Lifetime::Timeframe); + inputs.emplace_back("energy", "ZDC", "ENERGY", 0, Lifetime::Timeframe); + inputs.emplace_back("tdc", "ZDC", "TDCDATA", 0, Lifetime::Timeframe); + inputs.emplace_back("info", "ZDC", "INFO", 0, Lifetime::Timeframe); + inputs.emplace_back("tdccalibconfig", "ZDC", "TDCCALIBCONFIG", 0, Lifetime::Condition, o2::framework::ccdbParamSpec(o2::zdc::CCDBPathTDCCalibConfig.data())); + + std::vector outputs; + outputs.emplace_back("ZDC", "TDCCALIBDATA", 0, Lifetime::Timeframe); //added by me + char outputd[o2::header::gSizeDataDescriptionString]; + + for (int ih = 0; ih < TDCCalibData::NTDC; ih++) { + snprintf(outputd, o2::header::gSizeDataDescriptionString, "TDC_1DH%d", ih); + outputs.emplace_back("ZDC", outputd, 0, Lifetime::Timeframe); + } + + return DataProcessorSpec{ + "zdc-tdccalib-epn", + inputs, + outputs, + AlgorithmSpec{adaptFromTask()}, + o2::framework::Options{{"verbosity-level", o2::framework::VariantType::Int, 0, {"Verbosity level"}}}}; +} + +} // namespace zdc +} // namespace o2 \ No newline at end of file diff --git a/Detectors/ZDC/calib/src/TDCCalibSpec.cxx b/Detectors/ZDC/calib/src/TDCCalibSpec.cxx new file mode 100644 index 0000000000000..f153fb81a9266 --- /dev/null +++ b/Detectors/ZDC/calib/src/TDCCalibSpec.cxx @@ -0,0 +1,172 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TDCalibSpec.cxx +/// @brief cxx file associated to TDCCalibSpec.h +/// @author luca.quaglia@cern.ch + +#include +#include +#include +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "CCDB/CcdbApi.h" +#include "Framework/Logger.h" +#include "Framework/ControlService.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/CCDBParamSpec.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DataFormatsZDC/BCData.h" +#include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/OrbitData.h" +#include "DataFormatsZDC/RecEvent.h" +#include "ZDCBase/ModuleConfig.h" +#include "CommonUtils/NameConf.h" +#include "CommonUtils/MemFileHelper.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "ZDCReconstruction/RecoConfigZDC.h" +#include "ZDCReconstruction/ZDCTDCParam.h" +#include "ZDCCalib/TDCCalibConfig.h" +#include "ZDCCalib/TDCCalibSpec.h" +#include "ZDCCalib/TDCCalibData.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ + +TDCCalibSpec::TDCCalibSpec() +{ + mTimer.Stop(); + mTimer.Reset(); +} + +TDCCalibSpec::TDCCalibSpec(const int verbosity) : mVerbosity(verbosity) +{ + mTimer.Stop(); + mTimer.Reset(); +} + +void TDCCalibSpec::init(o2::framework::InitContext& ic) +{ + mVerbosity = ic.options().get("verbosity-level"); + mWorker.setVerbosity(mVerbosity); + mTimer.Start(false); +} + +void TDCCalibSpec::updateTimeDependentParams(ProcessingContext& pc) +{ + // we call these methods just to trigger finaliseCCDB callback + pc.inputs().get("tdccalib"); + pc.inputs().get("tdccalibconfig"); +} + +void TDCCalibSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) +{ + if (matcher == ConcreteDataMatcher("ZDC", "TDCCALIB", 0)) { + // TDC calibration object + auto* config = (const o2::zdc::ZDCTDCParam*)obj; + if (mVerbosity > DbgZero) { + config->print(); + } + mWorker.setTDCParam(config); + } + if (matcher == ConcreteDataMatcher("ZDC", "TDCCALIBCONFIG", 0)) { + // TDC calibration configuration + auto* config = (const o2::zdc::TDCCalibConfig*)obj; + if (mVerbosity > DbgZero) { + config->print(); + } + mWorker.setTDCCalibConfig(config); + } +} + +void TDCCalibSpec::run(ProcessingContext& pc) +{ + if (!mInitialized) { + mInitialized = true; + updateTimeDependentParams(pc); + mTimer.Stop(); + mTimer.Reset(); + mTimer.Start(false); + } + + auto data = pc.inputs().get("tdccalibdata"); + mWorker.process(data); + for (int ih = 0; ih < TDCCalibData::NTDC; ih++) { + o2::dataformats::FlatHisto1D histoView(pc.inputs().get>(fmt::format("tdc_1dh{}", ih).data())); + mWorker.add(ih, histoView); + } +} + +void TDCCalibSpec::endOfStream(EndOfStreamContext& ec) +{ + mWorker.endOfRun(); + mTimer.Stop(); + sendOutput(ec.outputs()); + LOGF(info, "ZDC TDC calibration total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); //added by me +} + +//________________________________________________________________ +void TDCCalibSpec::sendOutput(o2::framework::DataAllocator& output) +{ + // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output + // TODO in principle, this routine is generic, can be moved to Utils.h + using clbUtils = o2::calibration::Utils; + const auto& payload = mWorker.getTDCParamUpd(); //new + auto& info = mWorker.getCcdbObjectInfo(); + auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info); //new + LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size() + << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp(); + if (mVerbosity > DbgMinimal) { + payload.print(); + } + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "ZDC_TDCcalib", 0}, *image.get()); // vector + output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "ZDC_TDCcalib", 0}, info); // root-serlized + // TODO: reset the outputs once they are already sent (is it necessary?) + // mWorker.init(); +} + +framework::DataProcessorSpec getTDCCalibSpec() +{ + using device = o2::zdc::TDCCalibSpec; + using clbUtils = o2::calibration::Utils; + + std::vector inputs; + inputs.emplace_back("tdccalibconfig", "ZDC", "TDCCALIBCONFIG", 0, Lifetime::Condition, o2::framework::ccdbParamSpec(fmt::format("{}", o2::zdc::CCDBPathTDCCalibConfig.data()))); + inputs.emplace_back("tdccalib", "ZDC", "TDCCALIB", 0, Lifetime::Condition, o2::framework::ccdbParamSpec(fmt::format("{}", o2::zdc::CCDBPathTDCCalib.data()))); + inputs.emplace_back("tdccalibdata", "ZDC", "TDCCALIBDATA", 0, Lifetime::Timeframe); + + char outputa[o2::header::gSizeDataDescriptionString]; + char outputd[o2::header::gSizeDataDescriptionString]; + for (int ih = 0; ih < TDCCalibData::NTDC; ih++) { + snprintf(outputa, o2::header::gSizeDataDescriptionString, "tdc_1dh%d", ih); + snprintf(outputd, o2::header::gSizeDataDescriptionString, "TDC_1DH%d", ih); + inputs.emplace_back(outputa, "ZDC", outputd, 0, Lifetime::Timeframe); + } + + std::vector outputs; + outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "ZDC_TDCcalib"}, Lifetime::Sporadic); + outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "ZDC_TDCcalib"}, Lifetime::Sporadic); + + return DataProcessorSpec{ + "zdc-tdc-calib", + inputs, + outputs, + AlgorithmSpec{adaptFromTask()}, + Options{{"verbosity-level", o2::framework::VariantType::Int, 1, {"Verbosity level"}}}}; +} + +} // namespace zdc +} // namespace o2 \ No newline at end of file diff --git a/Detectors/ZDC/calib/src/ZDCCalibLinkDef.h b/Detectors/ZDC/calib/src/ZDCCalibLinkDef.h index 5db849700c0ab..67b057fe36a7b 100644 --- a/Detectors/ZDC/calib/src/ZDCCalibLinkDef.h +++ b/Detectors/ZDC/calib/src/ZDCCalibLinkDef.h @@ -19,6 +19,8 @@ #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::zdc::CalibParamZDC> + ; #pragma link C++ class o2::zdc::InterCalibData + ; #pragma link C++ class o2::zdc::InterCalibConfig + ; +#pragma link C++ class o2::zdc::TDCCalibConfig + ; +#pragma link C++ class o2::zdc::TDCCalibData + ; #pragma link C++ class o2::zdc::WaveformCalibConfig + ; #pragma link C++ class o2::zdc::WaveformCalibChData + ; #pragma link C++ class o2::zdc::WaveformCalibData + ; diff --git a/Detectors/ZDC/calib/src/zdc-tdccalib-epn-workflow.cxx b/Detectors/ZDC/calib/src/zdc-tdccalib-epn-workflow.cxx new file mode 100644 index 0000000000000..55d586651538a --- /dev/null +++ b/Detectors/ZDC/calib/src/zdc-tdccalib-epn-workflow.cxx @@ -0,0 +1,46 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Framework/DataProcessorSpec.h" +#include "CommonUtils/ConfigurableParam.h" +#include "DetectorsRaw/HBFUtilsInitializer.h" +#include "ZDCCalib/TDCCalibEPNSpec.h" + +using namespace o2::framework; + +// ------------------------------------------------------------------ +void customize(std::vector& policies) +{ + o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); +} + +// we need to add workflow options before including Framework/runDataProcessing +void customize(std::vector& workflowOptions) +{ + // option allowing to set parameters + std::string keyvaluehelp("Semicolon separated key=value strings ..."); + workflowOptions.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {keyvaluehelp}}); + o2::raw::HBFUtilsInitializer::addConfigOption(workflowOptions); +} + +// ------------------------------------------------------------------ + +#include "Framework/runDataProcessing.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) +{ + o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); + WorkflowSpec specs; + specs.emplace_back(o2::zdc::getTDCCalibEPNSpec()); + // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit + o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); + return specs; +} \ No newline at end of file diff --git a/Detectors/ZDC/calib/src/zdc-tdccalib-workflow.cxx b/Detectors/ZDC/calib/src/zdc-tdccalib-workflow.cxx new file mode 100644 index 0000000000000..43c0d561a6e66 --- /dev/null +++ b/Detectors/ZDC/calib/src/zdc-tdccalib-workflow.cxx @@ -0,0 +1,43 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Framework/DataProcessorSpec.h" +#include "Framework/CallbacksPolicy.h" +#include "DetectorsRaw/HBFUtilsInitializer.h" +#include "ZDCCalib/TDCCalibSpec.h" + +using namespace o2::framework; + +// ------------------------------------------------------------------ +void customize(std::vector& policies) +{ + o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); +} + +// we need to add workflow options before including Framework/runDataProcessing +void customize(std::vector& workflowOptions) +{ + // option allowing to set parameters + o2::raw::HBFUtilsInitializer::addConfigOption(workflowOptions); +} + +// ------------------------------------------------------------------ + +#include "Framework/runDataProcessing.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) +{ + WorkflowSpec specs; + specs.emplace_back(o2::zdc::getTDCCalibSpec()); + // configure dpl timer to inject correct firstTFOrbit: start from the 1st orbit of TF containing 1st sampled orbit + //o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); + return specs; +} \ No newline at end of file diff --git a/Detectors/ZDC/macro/CMakeLists.txt b/Detectors/ZDC/macro/CMakeLists.txt index 0c2d265aa66e5..0b4f5e01d6d40 100644 --- a/Detectors/ZDC/macro/CMakeLists.txt +++ b/Detectors/ZDC/macro/CMakeLists.txt @@ -38,6 +38,12 @@ o2_add_test_root_macro(CreateTDCCalib.C O2::SimulationDataFormat O2::CCDB LABELS zdc) +o2_add_test_root_macro(CreateTDCCalibConfig.C + PUBLIC_LINK_LIBRARIES O2::ZDCBase O2::ZDCReconstruction + O2::SimulationDataFormat O2::CCDB + O2::ZDCCalib + LABELS zdc) + o2_add_test_root_macro(CreateEnergyCalib.C PUBLIC_LINK_LIBRARIES O2::ZDCBase O2::ZDCReconstruction O2::SimulationDataFormat O2::CCDB diff --git a/Detectors/ZDC/macro/CreateTDCCalib.C b/Detectors/ZDC/macro/CreateTDCCalib.C index 857887b32d610..70b3e49032264 100644 --- a/Detectors/ZDC/macro/CreateTDCCalib.C +++ b/Detectors/ZDC/macro/CreateTDCCalib.C @@ -28,7 +28,7 @@ void CreateTDCCalib(long tmin = 0, long tmax = -1, std::string ccdbHost = "", fl // Shortcuts: internal, external, test, local, root o2::zdc::ZDCTDCParam conf; - // TODO: extract shift from TDC spectra + conf.setShift(o2::zdc::TDCZNAC, def_shift); conf.setShift(o2::zdc::TDCZNAS, def_shift); conf.setShift(o2::zdc::TDCZPAC, def_shift); diff --git a/Detectors/ZDC/macro/CreateTDCCalibConfig.C b/Detectors/ZDC/macro/CreateTDCCalibConfig.C new file mode 100644 index 0000000000000..4aafbf555f088 --- /dev/null +++ b/Detectors/ZDC/macro/CreateTDCCalibConfig.C @@ -0,0 +1,68 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) + +#include "Framework/Logger.h" +#include "CCDB/CcdbApi.h" +#include +#include +#include + +#endif + +#include "ZDCBase/Helpers.h" +#include "ZDCBase/Constants.h" +#include "ZDCCalib/TDCCalibConfig.h" + +using namespace o2::zdc; +using namespace std; + +void CreateTDCCalibConfig(long tmin = 0, long tmax = -1, std::string ccdbHost = "") +{ + + // This object allows for the configuration of the TDC calibration of the common PM + // and the sum of each calorimeter and the two ZEMs + + TDCCalibConfig conf; + + // Enable TDC calibration for all calorimeters + // If TDC calibration is disabled the calibration coefficients + // are copied from previous valid object and flagged as not modified + // ZNAC ZNAS ZPAC ZPAS ZEM1 ZECM2 ZNCC ZNCS ZPCC ZPCS + conf.enable(true, true, true, true, true, true, true, true, true, true); + + // Set the binning + conf.setBinning1D(100, -5, 5); + conf.setBinning2D(50, -5, 5); + + conf.setDescription("Simulated data"); + + //conf.setMinEntries(100); //To be decided the number of minimum entries + + conf.print(); + + std::string ccdb_host = ccdbShortcuts(ccdbHost, conf.Class_Name(), CCDBPathTDCCalibConfig); + + if (endsWith(ccdb_host, ".root")) { + TFile f(ccdb_host.data(), "recreate"); + f.WriteObjectAny(&conf, conf.Class_Name(), "ccdb_object"); + f.Close(); + return; + } + + o2::ccdb::CcdbApi api; + map metadata; // can be empty + api.init(ccdb_host.c_str()); + LOG(info) << "CCDB server: " << api.getURL(); + // store abitrary user object in strongly typed manner + api.storeAsTFileAny(&conf, CCDBPathTDCCalibConfig, metadata, tmin, tmax); +} \ No newline at end of file diff --git a/Detectors/ZDC/macro/InspectCCDBFile.C b/Detectors/ZDC/macro/InspectCCDBFile.C index 1af179831d09b..1c467991e5617 100644 --- a/Detectors/ZDC/macro/InspectCCDBFile.C +++ b/Detectors/ZDC/macro/InspectCCDBFile.C @@ -78,6 +78,10 @@ void InspectCCDBFile() o2::zdc::InterCalibConfig* ob = (o2::zdc::InterCalibConfig*)key->ReadObj(); printf("%s %s %d %s @ %s\n", "OBJ", key->GetName(), key->GetCycle(), key->GetTitle(), o2::zdc::CCDBPathInterCalibConfig.data()); ob->print(); + } else if (cn.EqualTo("o2::zdc::TDCCalibConfig")) { + o2::zdc::TDCCalibConfig* ob = (o2::zdc::TDCCalibConfig*)key->ReadObj(); + printf("%s %s %d %s @ %s\n", "OBJ", key->GetName(), key->GetCycle(), key->GetTitle(), o2::zdc::CCDBPathTDCCalibConfig.data()); + ob->print(); } else if (cn.EqualTo("o2::zdc::BaselineCalibConfig")) { o2::zdc::BaselineCalibConfig* ob = (o2::zdc::BaselineCalibConfig*)key->ReadObj(); printf("%s %s %d %s @ %s\n", "OBJ", key->GetName(), key->GetCycle(), key->GetTitle(), o2::zdc::CCDBPathBaselineCalibConfig.data()); diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/ZDCTDCParam.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/ZDCTDCParam.h index a5c53b624fa25..32f10ccb4036b 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/ZDCTDCParam.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/ZDCTDCParam.h @@ -25,7 +25,6 @@ namespace o2 namespace zdc { struct ZDCTDCParam { - //std::array tdcShift{} float tdc_shift[NTDCChannels] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Correction of TDC position (ns) float tdc_calib[NTDCChannels] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // Correction factor of TDC amplitude void setShift(uint32_t ich, float val);