diff --git a/Modules/TPC/CMakeLists.txt b/Modules/TPC/CMakeLists.txt index e8e9b53a95..a5c22a3444 100644 --- a/Modules/TPC/CMakeLists.txt +++ b/Modules/TPC/CMakeLists.txt @@ -38,7 +38,8 @@ target_sources(O2QcTPC PRIVATE src/PID.cxx src/TrackClusters.cxx src/VDriftCalibReductor.cxx src/SeparationPowerReductor.cxx - src/TimeGainCalibReductor.cxx) + src/TimeGainCalibReductor.cxx + src/DCSPTempReductor.cxx) target_include_directories( O2QcTPC @@ -97,6 +98,7 @@ add_root_dictionary(O2QcTPC include/TPC/VDriftCalibReductor.h include/TPC/SeparationPowerReductor.h include/TPC/TimeGainCalibReductor.h + include/TPC/DCSPTempReductor.h LINKDEF include/TPC/LinkDef.h) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/TPC @@ -180,4 +182,5 @@ install(FILES run/tpcQCPID_sampled.json run/tpcQCvDriftTrending.json run/tpcQCTrending_separationpower.json run/tpcQCTimeGainCalibTrending.json + run/tpcDCSPTempTrending.json DESTINATION etc) diff --git a/Modules/TPC/include/TPC/DCSPTempReductor.h b/Modules/TPC/include/TPC/DCSPTempReductor.h new file mode 100644 index 0000000000..0cdad5f1d6 --- /dev/null +++ b/Modules/TPC/include/TPC/DCSPTempReductor.h @@ -0,0 +1,64 @@ +// 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 DCSPTempReductor.h +/// \author Marcel Lesch +/// + +#ifndef QUALITYCONTROL_DCSPTEMPREDUCTOR_H +#define QUALITYCONTROL_DCSPTEMPREDUCTOR_H + +#include "QualityControl/ReductorConditionAny.h" +#include + +namespace o2::quality_control_modules::tpc +{ + +/// \brief A Reductor for calibration objects of the TPC DCS temperatures +/// +/// A Reductor for TPC DCS temperatures. +/// It produces a branch in the format: +/// "tempSensor[18]/F:tempSensorErr[18]:tempMeanPerSide[2]:tempMeanPerSideErr[2]:tempGradXPerSide[2]:tempGradXPerSideErr[2]:tempGradYPerSide[2]:tempGradYPerSideErr[2]" +/// tempSensor[i] is the raw sensor temperature for each of the 18 sensores +/// tempMeanPerSide[i] is the mean temperature per TPC-Side (0: A-Side, 1: C-Side) +/// tempGradXPerSide[i] is the temperature gradient in x direction per TPC-Side (0: A-Side, 1: C-Side) +/// tempGradYPerSide[i] is the temperature gradient in y direction per TPC-Side (0: A-Side, 1: C-Side) + +class DCSPTempReductor : public quality_control::postprocessing::ReductorConditionAny +{ + public: + DCSPTempReductor() = default; + ~DCSPTempReductor() = default; + + void* getBranchAddress() override; + const char* getBranchLeafList() override; + bool update(ConditionRetriever& retriever) override; + + private: + struct { + Float_t tempSensor[18]; + Float_t tempSensorErr[18]; // uncertainties + + Float_t tempMeanPerSide[2]; + Float_t tempMeanPerSideErr[2]; // uncertainties + + Float_t tempGradXPerSide[2]; + Float_t tempGradXPerSideErr[2]; // uncertainties + + Float_t tempGradYPerSide[2]; + Float_t tempGradYPerSideErr[2]; // uncertainties + } mStats; +}; + +} // namespace o2::quality_control_modules::tpc + +#endif // QUALITYCONTROL_DCSPTEMPREDUCTOR_H diff --git a/Modules/TPC/include/TPC/LinkDef.h b/Modules/TPC/include/TPC/LinkDef.h index 93756d99cc..21565f1ee4 100644 --- a/Modules/TPC/include/TPC/LinkDef.h +++ b/Modules/TPC/include/TPC/LinkDef.h @@ -43,6 +43,7 @@ #pragma link C++ class o2::quality_control_modules::tpc::VDriftCalibReductor + ; #pragma link C++ class o2::quality_control_modules::tpc::SeparationPowerReductor + ; #pragma link C++ class o2::quality_control_modules::tpc::TimeGainCalibReductor + ; +#pragma link C++ class o2::quality_control_modules::tpc::DCSPTempReductor + ; #pragma link C++ function o2::quality_control_modules::tpc::addAndPublish + ; #pragma link C++ function o2::quality_control_modules::tpc::toVector + ; diff --git a/Modules/TPC/include/TPC/Utility.h b/Modules/TPC/include/TPC/Utility.h index 59474b5c51..bfc17727a0 100644 --- a/Modules/TPC/include/TPC/Utility.h +++ b/Modules/TPC/include/TPC/Utility.h @@ -107,5 +107,11 @@ void calculateStatistics(const double* yValues, const double* yErrors, bool useE /// \param mean double&, reference to double that should store mean /// \param stddevOfMean double&, reference to double that should store stddev of mean void retrieveStatistics(std::vector& values, std::vector& errors, bool useErrors, double& mean, double& stddevOfMean); + +/// \brief Calculates mean and stddev from a vector +/// \param values std::vector& vector that contains the data points +/// \param mean float&, reference to float that should store mean +/// \param stddev float&, reference to float that should store stddev of mean +void calcMeanAndStddev(const std::vector& values, float& mean, float& stddev); } // namespace o2::quality_control_modules::tpc #endif // QUALITYCONTROL_TPCUTILITY_H \ No newline at end of file diff --git a/Modules/TPC/run/tpcDCSPTempTrending.json b/Modules/TPC/run/tpcDCSPTempTrending.json new file mode 100644 index 0000000000..943d8dc8c8 --- /dev/null +++ b/Modules/TPC/run/tpcDCSPTempTrending.json @@ -0,0 +1,116 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "ccdb-test.cern.ch:8080", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "", + "type": "", + "start": "", + "end": "" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "ccdb-test.cern.ch:8080" + }, + "postprocessing": { + "periodSeconds": "10" + } + }, + "postprocessing": { + "TemperatureQC": { + "active": "true", + "resumeTrend": "false", + "className": "o2::quality_control::postprocessing::TrendingTask", + "moduleName": "QualityControl", + "detectorName": "TPC", + "producePlotsOnUpdate": "true", + "dataSources": [ + { + "type": "condition", + "path": "TPC/Calib/", + "names": [ "Temperature" ], + "reductorName": "o2::quality_control_modules::tpc::DCSPTempReductor", + "moduleName": "QcTPC" + } + ], + "plots": [ + { + "name": "Temp_Mean_ASide", + "title": "Mean Temperature A Side", + "varexp": "Temperature.tempMeanPerSide[0]:time", + "selection": "", + "option": "*L", + "graphAxisLabel": "mean temp A Side:time", + "graphErrors": "Temperature.tempMeanPerSideErr[0]:0" + }, + { + "name": "Temp_GradX_ASide", + "title": "GradX Temperature A Side", + "varexp": "Temperature.tempGradXPerSide[0]:time", + "selection": "", + "option": "*L", + "graphAxisLabel": "gradX temp A Side:time", + "graphErrors": "Temperature.tempGradXPerSideErr[0]:0" + }, + { + "name": "Temp_GradY_ASide", + "title": "GradY Temperature A Side", + "varexp": "Temperature.tempGradYPerSide[0]:time", + "selection": "", + "option": "*L", + "graphAxisLabel": "gradY temp A Side:time", + "graphErrors": "Temperature.tempGradYPerSideErr[0]:0" + }, + { + "name": "Temp_Mean_CSide", + "title": "Mean Temperature C Side", + "varexp": "Temperature.tempMeanPerSide[1]:time", + "selection": "", + "option": "*L", + "graphAxisLabel": "mean temp C Side:time", + "graphErrors": "Temperature.tempMeanPerSideErr[1]:0" + }, + { + "name": "Temp_GradX_CSide", + "title": "GradX Temperature C Side", + "varexp": "Temperature.tempGradXPerSide[1]:time", + "selection": "", + "option": "*L", + "graphAxisLabel": "gradX temp C Side:time", + "graphErrors": "Temperature.tempGradXPerSideErr[1]:0" + }, + { + "name": "Temp_GradY_CSide", + "title": "GradY Temperature C Side", + "varexp": "Temperature.tempGradYPerSide[1]:time", + "selection": "", + "option": "*L", + "graphAxisLabel": "gradY temp C Side:time", + "graphErrors": "Temperature.tempGradYPerSideErr[1]:0" + } + ], + "initTrigger": [ + "userorcontrol" + ], + "updateTrigger": [ + "foreachlatest:ccdb:TPC/Calib/Temperature/" + ], + "stopTrigger": [ + "userorcontrol" + ] + } + } + } + } + \ No newline at end of file diff --git a/Modules/TPC/src/DCSPTempReductor.cxx b/Modules/TPC/src/DCSPTempReductor.cxx new file mode 100644 index 0000000000..717f98510f --- /dev/null +++ b/Modules/TPC/src/DCSPTempReductor.cxx @@ -0,0 +1,83 @@ +// 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 DCSPTempReductor.cxx +/// \author Marcel Lesch +/// + +#include "TPC/DCSPTempReductor.h" +#include "DataFormatsTPC/DCS.h" +#include "TPC/Utility.h" + +namespace o2::quality_control_modules::tpc +{ + +void* DCSPTempReductor::getBranchAddress() +{ + return &mStats; +} + +const char* DCSPTempReductor::getBranchLeafList() +{ + return "tempSensor[18]/F:tempSensorErr[18]:tempMeanPerSide[2]:tempMeanPerSideErr[2]:tempGradXPerSide[2]:tempGradXPerSideErr[2]:tempGradYPerSide[2]:tempGradYPerSideErr[2]"; +} + +bool DCSPTempReductor::update(ConditionRetriever& retriever) +{ + if (auto dcstemp = retriever.retrieve()) { + + int sensorCounter = 0; + std::vector sensorData[18]; + for (const auto& sensor : dcstemp->raw) { + for (const auto& value : sensor.data) { + sensorData[sensorCounter].emplace_back(value.value); + } + calcMeanAndStddev(sensorData[sensorCounter], mStats.tempSensor[sensorCounter], mStats.tempSensorErr[sensorCounter]); + sensorCounter++; + if (sensorCounter > 17) + break; + } + + std::vector sideData[3]; // 0 mean, 1 gradX, 2 gradY + + // A-Side + for (const auto& value : dcstemp->statsA.data) { + sideData[0].emplace_back(value.value.mean); + sideData[1].emplace_back(value.value.gradX); + sideData[2].emplace_back(value.value.gradY); + } + + calcMeanAndStddev(sideData[0], mStats.tempMeanPerSide[0], mStats.tempMeanPerSideErr[0]); + calcMeanAndStddev(sideData[1], mStats.tempGradXPerSide[0], mStats.tempGradXPerSideErr[0]); + calcMeanAndStddev(sideData[2], mStats.tempGradYPerSide[0], mStats.tempGradYPerSideErr[0]); + + for (int iCount = 0; iCount < 3; iCount++) { + sideData[iCount].clear(); + } + + // C-Side + for (const auto& value : dcstemp->statsC.data) { + sideData[0].emplace_back(value.value.mean); + sideData[1].emplace_back(value.value.gradX); + sideData[2].emplace_back(value.value.gradY); + } + + calcMeanAndStddev(sideData[0], mStats.tempMeanPerSide[1], mStats.tempMeanPerSideErr[1]); + calcMeanAndStddev(sideData[1], mStats.tempGradXPerSide[1], mStats.tempGradXPerSideErr[1]); + calcMeanAndStddev(sideData[2], mStats.tempGradYPerSide[1], mStats.tempGradYPerSideErr[1]); + + return true; + } + return false; +} + +} // namespace o2::quality_control_modules::tpc \ No newline at end of file diff --git a/Modules/TPC/src/Utility.cxx b/Modules/TPC/src/Utility.cxx index dffb2b4c75..a0548a1988 100644 --- a/Modules/TPC/src/Utility.cxx +++ b/Modules/TPC/src/Utility.cxx @@ -341,4 +341,27 @@ void retrieveStatistics(std::vector& values, std::vector& errors } } +void calcMeanAndStddev(const std::vector& values, float& mean, float& stddev) +{ + if (values.size() == 0) { + mean = 0.; + stddev = 0.; + return; + } + + // Mean + const float sum = std::accumulate(values.begin(), values.end(), 0.0); + mean = sum / values.size(); + + // Stddev + if (values.size() == 1) { // we only have one point -> no stddev + stddev = 0.; + } else { // for >= 2 points, we calculate the spread + std::vector diff(values.size()); + std::transform(values.begin(), values.end(), diff.begin(), [mean](auto x) { return x - mean; }); + const auto sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.f); + stddev = std::sqrt(sq_sum / (values.size() * (values.size() - 1.))); + } +} + } // namespace o2::quality_control_modules::tpc \ No newline at end of file