diff --git a/Modules/Common/include/Common/Utils.h b/Modules/Common/include/Common/Utils.h index 5a84b88a2c..bc8728af34 100644 --- a/Modules/Common/include/Common/Utils.h +++ b/Modules/Common/include/Common/Utils.h @@ -17,9 +17,8 @@ #define QC_MODULE_COMMON_UTILS_H #include -#include -#include +#include "QualityControl/QcInfoLogger.h" #include "QualityControl/CustomParameters.h" namespace o2::quality_control_modules::common @@ -34,24 +33,36 @@ template T stringToType(const std::string& param) { T retVal{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same_v) { retVal = std::stoi(param); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same_v) { + retVal = std::stol(param); + } else if constexpr (std::is_same_v) { + retVal = std::stoll(param); + } else if constexpr (std::is_same_v) { + retVal = static_cast(std::stoul(param)); + } else if constexpr (std::is_same_v) { + retVal = std::stoul(param); + } else if constexpr (std::is_same_v) { + retVal = std::stoull(param); + } else if constexpr (std::is_same_v) { retVal = param; - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same_v) { retVal = std::stof(param); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same_v) { retVal = std::stod(param); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same_v) { + retVal = std::stold(param); + } else if constexpr (std::is_same_v) { if ((param == "true") || (param == "True") || (param == "TRUE") || (param == "1")) { retVal = true; } else if ((param == "false") || (param == "False") || (param == "FALSE") || (param == "0")) { retVal = false; } else { - LOG(error) << "Cannot parse boolean."; + ILOG(Fatal) << "Cannot decode boolean value from param '" << param << "'" << ENDM; } } else { - LOG(error) << "Template type not supported"; + static_assert(false, "Unsupported type!"); } return retVal; } @@ -67,10 +78,11 @@ T getFromConfig(const quality_control::core::CustomParameters& params, const std { const auto itParam = params.find(name.data()); if (itParam == params.end()) { - LOGP(warning, "Missing parameter. Please add '{}': '' to the 'taskParameters'. Using default value {}.", name.data(), retVal); + ILOG(Info, Trace) << "Default parameter - " << name << ": " << retVal << ENDM; } else { const auto& param = itParam->second; - return internal::stringToType(param); + retVal = internal::stringToType(param); + ILOG(Info, Trace) << "Custom parameter - " << name << ": " << retVal << ENDM; } return retVal; } @@ -89,7 +101,7 @@ T getFromExtendedConfig(const quality_control::core::Activity& activity, const q if (auto param = params.atOptional(name, activity)) { parameter = param.value(); } else { - if constexpr (std::is_same::value) { + if constexpr (std::is_same_v) { parameter = params.atOrDefaultValue(name, retVal); } else { parameter = params.atOrDefaultValue(name, std::to_string(retVal)); diff --git a/Modules/GLO/CMakeLists.txt b/Modules/GLO/CMakeLists.txt index 0f4d2b425e..5bcb337d41 100644 --- a/Modules/GLO/CMakeLists.txt +++ b/Modules/GLO/CMakeLists.txt @@ -1,73 +1,80 @@ # ---- Library ---- -# add_compile_options(-O0 -g -fPIC) add_library(O2QcGLO) -target_sources(O2QcGLO PRIVATE src/ITSTPCmatchingCheck.cxx src/MeanVertexValidator.cxx src/MeanVertexPostProcessing.cxx src/MeanVertexCheck.cxx src/VertexingQcTask.cxx src/ITSTPCMatchingTask.cxx src/DataCompressionQcTask.cxx src/CTFSizeTask.cxx) +target_sources( + O2QcGLO + PRIVATE src/ITSTPCMatchingTask.cxx + src/ITSTPCmatchingCheck.cxx + src/Reductors.cxx + src/MeanVertexValidator.cxx + src/MeanVertexPostProcessing.cxx + src/MeanVertexCheck.cxx + src/VertexingQcTask.cxx + src/DataCompressionQcTask.cxx + src/CTFSizeTask.cxx) target_include_directories( O2QcGLO - PUBLIC $ - $ + PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) -target_link_libraries(O2QcGLO - PUBLIC - O2QualityControl - O2::Steer - O2::DataFormatsGlobalTracking - O2::DataFormatsITS - O2::DataFormatsCalibration - O2::GlobalTracking - O2::GLOQC - O2QcCommon) +target_link_libraries( + O2QcGLO + PUBLIC O2QualityControl + O2::Steer + O2::DataFormatsGlobalTracking + O2::DataFormatsITS + O2::DataFormatsCalibration + O2::GlobalTracking + O2::GLOQC + O2QcCommon) -install(TARGETS O2QcGLO - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install( + TARGETS O2QcGLO + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # install json files -install(FILES ITSTPCmatchedTracks_external.json - ITSTPCmatchedTracks.json - ITSTPCmatchedTracks_direct.json - vertexing-qc-direct.json - vertexing-qc-direct-mc.json - vertexing-qc.json - vertexing-qc-mc.json - dataCompression-qc.json - glo-mean-vtx-post-processing.json - DESTINATION etc - ) +install( + FILES ITSTPCmatchedTracks_external.json + ITSTPCmatchedTracks.json + ITSTPCmatchedTracks_direct.json + vertexing-qc-direct.json + vertexing-qc-direct-mc.json + vertexing-qc.json + vertexing-qc-mc.json + dataCompression-qc.json + glo-mean-vtx-post-processing.json + DESTINATION etc) -add_root_dictionary(O2QcGLO - HEADERS - include/GLO/MeanVertexValidator.h - include/GLO/MeanVertexPostProcessing.h - include/GLO/MeanVertexCheck.h - include/GLO/VertexingQcTask.h - include/GLO/ITSTPCMatchingTask.h - include/GLO/DataCompressionQcTask.h - include/GLO/CTFSizeTask.h - include/GLO/ITSTPCmatchingCheck.h - LINKDEF include/GLO/LinkDef.h) +add_root_dictionary( + O2QcGLO + HEADERS include/GLO/MeanVertexValidator.h + include/GLO/MeanVertexPostProcessing.h + include/GLO/MeanVertexCheck.h + include/GLO/VertexingQcTask.h + include/GLO/DataCompressionQcTask.h + include/GLO/CTFSizeTask.h + include/GLO/ITSTPCMatchingTask.h + include/GLO/ITSTPCmatchingCheck.h + include/GLO/Reductors.h + LINKDEF include/GLO/LinkDef.h) -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/GLO - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/QualityControl") +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/GLO DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/QualityControl") # ---- Test(s) ---- -#set(TEST_SRCS test/testQcGLO.cxx) # uncomment to reenable the test which was empty +# set(TEST_SRCS test/testQcGLO.cxx) # uncomment to reenable the test which was empty foreach(test ${TEST_SRCS}) get_filename_component(test_name ${test} NAME) string(REGEX REPLACE ".cxx" "" test_name ${test_name}) add_executable(${test_name} ${test}) - target_link_libraries(${test_name} - PRIVATE O2QcGLO Boost::unit_test_framework) + target_link_libraries(${test_name} PRIVATE O2QcGLO Boost::unit_test_framework) add_test(NAME ${test_name} COMMAND ${test_name}) - set_property(TARGET ${test_name} - PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests) + set_property(TARGET ${test_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests) set_tests_properties(${test_name} PROPERTIES TIMEOUT 20) endforeach() diff --git a/Modules/GLO/README.md b/Modules/GLO/README.md new file mode 100644 index 0000000000..5366fbfba2 --- /dev/null +++ b/Modules/GLO/README.md @@ -0,0 +1,91 @@ +# GLO +Documents the available task in the module and their parameters. +## ITS-TPC Matching Task +### Parameters +#### MC + - `isMC=false` produce additional MC plots + - `useTrkPID=false` propagate tracks with their pid hypothesis +#### ITS + - `minPtITSCut=0.1f` minimum ITS track momentum + - `etaITSCut=1.4f` maximum ITS track eta + - `minNITSClustersCut=0` minimum number of ITS clusters + - `maxChi2PerClusterITS=1e10f` maximum chi2/ITS cluster +#### TPC + - `minPtTPCCut=0.1f` minimum TPC track momentum + - `etaITSCut=1.4f` maximum ITS track eta + - `minTPCClustersCut=60` minimum number of TPC clusters + - `minDCACut=100.f` minimum TPC track DCA Z + - `minDCACutY=10.f` minimum TPC track DCA Y +#### ITS-TPC + - `minPtCut=0.1f` minimum ITS-TPC momentum + - `maxPtCut=20.f` maximum ITS-TPC momentum + - `etaCut=1.4f` maximum ITS-TPC track eta +#### Additional sync parameters + - `isSync=false` synchronous processing, needed for all following parameters +#### MTC ratios + - `doMTCRatios=false` produce MTC ratio plots +#### K0s + - `doK0QC=false` produce K0s plots + - `maxK0Eta=0.8f` maximum K0s eta + - `refitK0=false` refit K0 prongs + - `cutK0Mass=0.05f` cut around K0s peak + - `trackSourcesK0` SVertexer input sources + - `publishK0s3D=false` publish 3D cycle,integral histograms + - `splitK0sMassOccupancy=float` splitting point in TPC occupancy to define low and high region by default off + - `splitK0sMassPt=float` splitting point in pt to define low and high region by default off + + K0Fitter options +#### ITS-PV + - `doPVITSQC=false` produce ITS vs PV plots (not implemented yet) + +## ITS-TPC Matching Check +### Parameters +#### Pt + - `showPt=false` show check on MTC pt + - `thresholdPt=0.5f` threshold on MTC pt + - `minPt=1.0f` check range left + - `maxPt=1.999f` check range right +#### Phi + - `showPhi=false` show check on MTC phi + - `thresholdPhi=0.3f` threshold on MTC phi +#### Eta + - `showEta=false` show check on MTC eta + - `thresholdEta=0.4f` threshold on MTC eta + - `minEta=-0.8f` check range left + - `maxEta=0.8f` check range right +#### K0 + - `showK0s=false` show check on K0s mass + - `acceptableK0sRError=0.2f` acceptable relative error to pdg value + - `acceptableK0sUncertainty=0.2f` acceptable uncertainty to pdg value + + K0Fitter options +#### Other + - `limitRanges=5` maximum number of bad intervals shown + +## K0sFitReductor +Trends mean and sigma of fit. +### Output + - `mean` aggregated mass value + - `sigma` aggregated sigma value + +## MTCReductor +Trends MTC at given pt. +### Output + - `mtc` mtc efficiency +### Parameters + - `pt` take value at this pt + +## PVITSReductor +Trends constant + slope of straight line fit in given range. +### Output + - `pol0` constant + - `pol1` slope +### Parameters + - `r0` start fit range + - `r1` end fit range + +## K0Fitter +Does a `pol2 + Gaus` fit. +### Parameters + - `k0sBackgroundRejLeft=0.48` reject region in background fit from left side of mass peak + - `k0sBackgroundRejRight=0.51` reject region in background fit to right side of mass peak + - `k0sBackgroundRangeLeft=0.45` absolute left range to fit background + - `k0sBackgroundRangeRight=0.54` absolute right range to fit background diff --git a/Modules/GLO/glo-itstpc-mtch-qcmn-test.json b/Modules/GLO/glo-itstpc-mtch-qcmn-test.json index ac06a47743..21f836789b 100644 --- a/Modules/GLO/glo-itstpc-mtch-qcmn-test.json +++ b/Modules/GLO/glo-itstpc-mtch-qcmn-test.json @@ -10,21 +10,20 @@ "maxObjectSize": "20000000" }, "Activity": { - "number": "48", - "type": "2" + "number": "", + "type": "", + "beamType": "PbPb" }, "monitoring": { "url": "infologger:///debug?qc" }, - "consul": { - "url": "" - }, - "conditionDB": { - "url": "alice-ccdb.cern.ch" - }, "infologger": { "filterDiscardDebug": "false", "filterDiscardLevel": "0" + }, + "postprocessing": { + "periodSeconds": 0.01, + "matchAnyRunNumber": "true" } }, "tasks": { @@ -33,35 +32,33 @@ "className": "o2::quality_control_modules::glo::ITSTPCMatchingTask", "moduleName": "QcGLO", "detectorName": "GLO", - "cycleDurationSeconds": "60", + "cycleDurationSeconds": "1", "maxNumberCycles": "-1", "dataSource": { "type": "direct", "query_comment": "checking every matched track", - "query": "trackITSTPC:GLO/TPCITS/0;trackITSTPCABREFS:GLO/TPCITSAB_REFS/0;trackITSTPCABCLID:GLO/TPCITSAB_CLID/0;trackTPC:TPC/TRACKS;trackTPCClRefs:TPC/CLUSREFS;trackITS:ITS/TRACKS/0;trackITSROF:ITS/ITSTrackROF/0;trackITSClIdx:ITS/TRACKCLSID/0;alpparITS:ITS/ALPIDEPARAM/0?lifetime=condition&ccdb-path=ITS/Config/AlpideParam" + "query": "tofcluster:TOF/CLUSTERS/0;matchITSTPCTRDTOF:TOF/MTC_ITSTPCTRD/0;matchTPCTRDTOF/TOF/MTC_TPCTRD/0;matchITSTPCTOF:TOF/MTC_ITSTPC/0;matchTPCTOF:TOF/MTC_TPC/0;trackTPCTOF:TOF/TOFTRACKS_TPC/0;trigTPCTRD:TRD/TRGREC_TPC/0;trackTPCTRD:TRD/MATCH_TPC/0;trigITSTPCTRD:TRD/TRGREC_ITSTPC/0;trackITSTPCTRD:TRD/MATCH_ITSTPC/0;p2decay3body:GLO/PVTX_3BODYREFS/0;decay3body:GLO/DECAYS3BODY/0;decay3bodyIdx:GLO/DECAYS3BODY_IDX/0;p2cascs:GLO/PVTX_CASCREFS/0;cascs:GLO/CASCS/0;cascsIdx:GLO/CASCS_IDX/0;p2v0s:GLO/PVTX_V0REFS/0;v0s:GLO/V0S/0;v0sIdx:GLO/V0S_IDX/0;pvtx_tref:GLO/PVTX_TRMTCREFS/0;pvtx_trmtc:GLO/PVTX_TRMTC/0;pvtx:GLO/PVTX/0;trackITSTPC:GLO/TPCITS/0;trackITSTPCABREFS:GLO/TPCITSAB_REFS/0;trackITSTPCABCLID:GLO/TPCITSAB_CLID/0;trackTPC:TPC/TRACKS;trackTPCClRefs:TPC/CLUSREFS;trackITS:ITS/TRACKS/0;trackITSROF:ITS/ITSTrackROF/0;trackITSClIdx:ITS/TRACKCLSID/0;alpparITS:ITS/ALPIDEPARAM/0?lifetime=condition&ccdb-path=ITS/Config/AlpideParam;SVParam:GLO/SVPARAM/0?lifetime=condition&ccdb-path=GLO/Config/SVertexerParam;clusTPC:TPC/CLUSTERNATIVE;clusTPCshmap:TPC/CLSHAREDMAP/0;trigTPC:TPC/TRIGGERWORDS/0;clusTPCoccmap:TPC/TPCOCCUPANCYMAP/0" }, "taskParameters": { "GID": "ITS-TPC,ITS", "verbose": "false", - "minPtCut": "0.1f", - "etaCut": "1.4f", + "doMTCRatios": "true", + "doK0QC": "true", + "doPVITSQC": "true", "isSync": "true", - "minNTPCClustersCut": "60", - "minDCACut": "100.f", - "minDCACutY": "10.f" + "trackSourcesK0": "ITS,TPC,ITS-TPC,ITS-TPC-TOF,TPC-TOF,TPC-TRD,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TOF,ITS-TPC-TRD-TOF" }, "grpGeomRequest": { "geomRequest": "None", - "askGRPECS": "false", - "askGRPLHCIF": "false", + "askGRPECS": "true", + "askGRPLHCIF": "true", "askGRPMagField": "true", "askMatLUT": "false", "askTime": "false", "askOnceAllButField": "true", "needPropagatorD": "false" }, - "saveObjectsToFile": "ITSTPCmatched.root", - "": "For debugging, path to the file where to save. If empty or missing it won't save." + "saveObjectsToFile": "ITSTPCmatched.root" } }, "checks": { @@ -78,7 +75,13 @@ "MOs": [ "mFractionITSTPCmatch_ITS_Hist", "mFractionITSTPCmatchPhi_ITS_Hist", - "mFractionITSTPCmatchEta_ITS_Hist" + "mFractionITSTPCmatchEta_ITS_Hist", + "mK0sMassVsPtVsOcc_Integral_pmass", + "mK0sMassVsPtVsOcc_Cycle_pmass", + "mK0sMassVsPtVsOcc_Cycle_pmass_lowOcc", + "mK0sMassVsPtVsOcc_Cycle_pmass_lowPt", + "mK0sMassVsPtVsOcc_Cycle_pmass_highOcc", + "mK0sMassVsPtVsOcc_Cycle_pmass_highPt" ] } ], @@ -86,15 +89,235 @@ "default": { "default": { "showPt": "true", - "thresholdPt": "0.5", + "showEta": "true", "showPhi": "true", - "thresholdPhi": "0.3", - "showEta": "1", - "thresholdEta": "0.4" + "showK0s": "true" } } } } + }, + "postprocessing": { + "K0sMassTrend": { + "active": "true", + "className": "o2::quality_control::postprocessing::TrendingTask", + "moduleName": "QcGLO", + "detectorName": "GLO", + "resumeTrend": "false", + "initTrigger": [ + "once" + ], + "updateTrigger": [ + "newobject:qcdb:GLO/MO/ITSTPCMatchingTask/gloFitK0sMassSignal" + ], + "stopTrigger": [ + "usercontrol" + ], + "dataSources": [ + { + "type": "repository", + "path": "GLO/MO/ITSTPCMatchingTask", + "names": [ + "gloFitK0sMassSignal" + ], + "reductorName": "o2::quality_control_modules::glo::K0sFitReductor", + "moduleName": "QcGLO" + } + ], + "plots": [ + { + "name": "glo_k0s_mass_trending", + "title": "Fitted K0s mass", + "varexp": "gloFitK0sMassSignal.mean:time", + "option": "*L", + "graphYRange": "0.45:0.55", + "graphAxisLabel": "K0s mass (GeV/c^{2}):time" + }, + { + "name": "glo_k0s_sigma_trending", + "title": "Fitted K0s sigma", + "varexp": "gloFitK0sMassSignal.sigma:time", + "option": "*L", + "graphYRange": "0:0.01", + "graphAxisLabel": "#sigma_{K0s mass (GeV/c^{2})}:time" + } + ] + }, + "K0sYieldTrend": { + "active": "true", + "className": "o2::quality_control::postprocessing::TrendingTask", + "moduleName": "QcGLO", + "detectorName": "GLO", + "resumeTrend": "false", + "initTrigger": [ + "once" + ], + "updateTrigger": [ + "newobject:qcdb:GLO/MO/ITSTPCMatchingTask/gloFitK0sMassSignal" + ], + "stopTrigger": [ + "usercontrol" + ], + "dataSources": [ + { + "type": "repository", + "path": "GLO/MO/ITSTPCMatchingTask", + "names": [ + "gloFitK0sMassSignal" + ], + "reductorName": "o2::quality_control_modules::glo::K0sFitReductor", + "moduleName": "QcGLO" + } + ], + "plots": [ + { + "name": "glo_k0s_yield_trending", + "title": "Fitted K0s yield", + "varexp": "gloFitK0sMassSignal.yield:time", + "option": "*L", + "graphAxisLabel": "K0s Yield:time" + } + ] + }, + "MTCTrend1": { + "active": "true", + "className": "o2::quality_control::postprocessing::TrendingTask", + "moduleName": "QcGLO", + "detectorName": "GLO", + "resumeTrend": "false", + "initTrigger": [ + "once" + ], + "updateTrigger": [ + "newobject:qcdb:GLO/MO/ITSTPCMatchingTask/mFractionITSTPCmatch_ITS_Hist" + ], + "stopTrigger": [ + "usercontrol" + ], + "dataSources": [ + { + "type": "repository", + "path": "GLO/MO/ITSTPCMatchingTask", + "names": [ + "mFractionITSTPCmatch_ITS_Hist" + ], + "reductorName": "o2::quality_control_modules::glo::MTCReductor", + "reductorParameters": { + "default": { + "default": { + "pt": "1.5" + } + } + }, + "moduleName": "QcGLO" + } + ], + "plots": [ + { + "name": "glo_mtc_pt15_trending", + "title": "MTC at #it{p}_{T}=1.5 trending", + "varexp": "mFractionITSTPCmatch_ITS_Hist.mtc:time", + "option": "*L", + "graphYRange": "0:1.02", + "graphAxisLabel": "MTC:time" + } + ] + }, + "MTCTrend2": { + "active": "true", + "className": "o2::quality_control::postprocessing::TrendingTask", + "moduleName": "QcGLO", + "detectorName": "GLO", + "resumeTrend": "false", + "initTrigger": [ + "once" + ], + "updateTrigger": [ + "newobject:qcdb:GLO/MO/ITSTPCMatchingTask/mFractionITSTPCmatch_ITS_Hist" + ], + "stopTrigger": [ + "usercontrol" + ], + "dataSources": [ + { + "type": "repository", + "path": "GLO/MO/ITSTPCMatchingTask", + "names": [ + "mFractionITSTPCmatch_ITS_Hist" + ], + "reductorName": "o2::quality_control_modules::glo::MTCReductor", + "reductorParameters": { + "default": { + "default": { + "pt": "0.5" + } + } + }, + "moduleName": "QcGLO" + } + ], + "plots": [ + { + "name": "glo_mtc_pt05_trending", + "title": "MTC at #it{p}_{T}=0.5 trending", + "varexp": "mFractionITSTPCmatch_ITS_Hist.mtc:time", + "option": "*L", + "graphYRange": "0:1.02", + "graphAxisLabel": "MTC:time" + } + ] + }, + "PVITSTrend": { + "active": "true", + "className": "o2::quality_control::postprocessing::TrendingTask", + "moduleName": "QcGLO", + "detectorName": "GLO", + "resumeTrend": "false", + "initTrigger": [ + "once" + ], + "updateTrigger": [ + "newobject:qcdb:GLO/MO/ITSTPCMatchingTask/mPVNContVsITSTracks_Cycle_pfx" + ], + "stopTrigger": [ + "usercontrol" + ], + "dataSources": [ + { + "type": "repository", + "path": "GLO/MO/ITSTPCMatchingTask", + "names": [ + "mPVNContVsITSTracks_Cycle_pfx" + ], + "reductorName": "o2::quality_control_modules::glo::PVITSReductor", + "reductorParameters": { + "default": { + "default": { + "r0": "1000", + "r1": "7000" + } + } + }, + "moduleName": "QcGLO" + } + ], + "plots": [ + { + "name": "glo_pvits_pol0_trending", + "title": "PV-ITS Fit pol0 trending", + "varexp": "mPVNContVsITSTracks_Cycle_pfx.pol0:time", + "option": "*L", + "graphAxisLabel": "pol0:time" + }, + { + "name": "glo_pvits_pol1_trending", + "title": "PV-ITS Fit pol1 trending", + "varexp": "mPVNContVsITSTracks_Cycle_pfx.pol1:time", + "option": "*L", + "graphAxisLabel": "pol1:time" + } + ] + } } } } diff --git a/Modules/GLO/include/GLO/Helpers.h b/Modules/GLO/include/GLO/Helpers.h new file mode 100644 index 0000000000..68fdc5e7e1 --- /dev/null +++ b/Modules/GLO/include/GLO/Helpers.h @@ -0,0 +1,130 @@ +// 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 QC_MODULE_GLO_HELPERS_H +#define QC_MODULE_GLO_HELPERS_H + +#include "QualityControl/QcInfoLogger.h" +#include "QualityControl/CustomParameters.h" +#include "QualityControl/Activity.h" +#include "Common/Utils.h" + +#include + +#include + +#include +#include + +namespace o2::quality_control_modules::glo::helpers +{ + +// Simple class to fit K0s mass +struct K0sFitter { + enum Parameters : uint8_t { + // Background + Pol0 = 0, + Pol1 = 1, + Pol2 = 2, + // K0s + Amplitude = 3, + Mass = 4, + Sigma = 5, + }; + static constexpr auto mMassK0s{ o2::constants::physics::MassK0Short }; + double mBackgroundRangeLeft{ 0.45 }; + double mBackgroundRangeRight{ 0.54 }; + struct FitBackground { + static constexpr int mNPar{ 3 }; + double mRejLeft{ 0.48 }; + double mRejRight{ 0.51 }; + double operator()(double* x, double* p) const + { + if (x[0] > mRejLeft && x[0] < mRejRight) { + TF1::RejectPoint(); + return 0; + } + return p[0] + (p[1] * x[0]) + (p[2] * x[0] * x[0]); + } + } mFitBackground; + std::unique_ptr mBackground; + std::unique_ptr mSignalAndBackground; + + void init(o2::quality_control::core::CustomParameters const& pars) + { + mFitBackground.mRejLeft = common::getFromConfig(pars, "k0sBackgroundRejLeft", 0.48); + mFitBackground.mRejRight = common::getFromConfig(pars, "k0sBackgroundRejRight", 0.51); + mBackgroundRangeLeft = common::getFromConfig(pars, "k0sBackgroundRangeLeft", 0.45); + mBackgroundRangeRight = common::getFromConfig(pars, "k0sBackgroundRangeRight", 0.54); + initImpl(); + } + + void init(o2::quality_control::core::CustomParameters const& pars, o2::quality_control::core::Activity const& activity) + { + mFitBackground.mRejLeft = common::getFromExtendedConfig(activity, pars, "k0sBackgroundRejLeft", 0.48); + mFitBackground.mRejRight = common::getFromExtendedConfig(activity, pars, "k0sBackgroundRejRight", 0.51); + mBackgroundRangeLeft = common::getFromExtendedConfig(activity, pars, "k0sBackgroundRangeLeft", 0.45); + mBackgroundRangeRight = common::getFromExtendedConfig(activity, pars, "k0sBackgroundRangeRight", 0.54); + initImpl(); + } + + void initImpl() + { + mBackground.reset(new TF1("gloFitK0sMassBackground", mFitBackground, mBackgroundRangeLeft, mBackgroundRangeRight, mFitBackground.mNPar)); + mSignalAndBackground.reset(new TF1("gloFitK0sMassSignal", "[0] + [1] * x + [2] * x * x + gaus(3)", mBackgroundRangeLeft, mBackgroundRangeRight)); + } + + bool fit(TH1* h, bool add = false) + { + if (h->GetEntries() == 0) { + ILOG(Warning, Devel) << "Cannot fit empty histogram: " << h->GetName() << ENDM; + return false; + } + Int_t res = h->Fit(mBackground.get(), "RNQ"); + if (res) { + ILOG(Warning, Devel) << "Failed k0s background fit for histogram: " << h->GetName() << ENDM; + return false; + } + mSignalAndBackground->SetParameter(Parameters::Pol0, mBackground->GetParameter(Parameters::Pol0)); + mSignalAndBackground->SetParameter(Parameters::Pol1, mBackground->GetParameter(Parameters::Pol1)); + mSignalAndBackground->SetParameter(Parameters::Pol2, mBackground->GetParameter(Parameters::Pol2)); + mSignalAndBackground->SetParameter(Parameters::Amplitude, h->GetMaximum() - mBackground->Eval(mMassK0s)); + mSignalAndBackground->SetParameter(Parameters::Mass, mMassK0s); + mSignalAndBackground->SetParameter(Parameters::Sigma, 0.005); + mSignalAndBackground->SetParLimits(Parameters::Sigma, 1e-6, 1); + h->Fit(mSignalAndBackground.get(), (add) ? "RMQ" : "RMQ0"); + return true; + } + + auto getMass() const noexcept + { + return mSignalAndBackground->GetParameter(4); + } + + auto getSigma() const noexcept + { + return mSignalAndBackground->GetParameter(5); + } + + auto getUncertainty() const noexcept + { + return std::abs(mMassK0s - getMass()) / getSigma(); + } + + auto getRelativeError() const noexcept + { + return std::abs(mMassK0s - getMass()) / mMassK0s; + } +}; + +} // namespace o2::quality_control_modules::glo::helpers + +#endif diff --git a/Modules/GLO/include/GLO/ITSTPCMatchingTask.h b/Modules/GLO/include/GLO/ITSTPCMatchingTask.h index 7aede08136..af148c5aac 100644 --- a/Modules/GLO/include/GLO/ITSTPCMatchingTask.h +++ b/Modules/GLO/include/GLO/ITSTPCMatchingTask.h @@ -20,8 +20,16 @@ #include "QualityControl/TaskInterface.h" #include "GLOQC/MatchITSTPCQC.h" #include "Common/TH1Ratio.h" +#include "GLO/Helpers.h" +#include "GLO/Reductors.h" + +#include #include +#include + +#include +#include using namespace o2::quality_control::core; @@ -33,12 +41,6 @@ namespace o2::quality_control_modules::glo class ITSTPCMatchingTask final : public TaskInterface { public: - /// \brief Constructor - ITSTPCMatchingTask() = default; - /// Destructor - ~ITSTPCMatchingTask() override = default; - - // Definition of the methods for the template method pattern void initialize(o2::framework::InitContext& ctx) override; void startOfActivity(const Activity& activity) override; void startOfCycle() override; @@ -48,11 +50,30 @@ class ITSTPCMatchingTask final : public TaskInterface void reset() override; private: + template + static constexpr T OptValue = std::numeric_limits::max(); + o2::gloqc::MatchITSTPCQC mMatchITSTPCQC; + bool mIsSync{ false }; + bool mIsPbPb{ false }; + + bool mDoMTCRatios{ false }; std::unique_ptr mEffPt; std::unique_ptr mEffEta; std::unique_ptr mEffPhi; + + bool mDoK0s{ false }; + bool mPublishK0s3D{ false }; + float mSplitTPCOccupancy{ OptValue }; + float mSplitPt{ OptValue }; + std::unique_ptr mK0sCycle; + std::unique_ptr mK0sIntegral; + helpers::K0sFitter mK0sFitter; + + bool mDoPVITS{ false }; + std::unique_ptr mPVITSCycle; + std::unique_ptr mPVITSIntegral; }; } // namespace o2::quality_control_modules::glo diff --git a/Modules/GLO/include/GLO/ITSTPCmatchingCheck.h b/Modules/GLO/include/GLO/ITSTPCmatchingCheck.h index 45b9c52ae5..98090b46a5 100644 --- a/Modules/GLO/include/GLO/ITSTPCmatchingCheck.h +++ b/Modules/GLO/include/GLO/ITSTPCmatchingCheck.h @@ -9,10 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// /// \file ITSTPCmatchingCheck.h +/// \brief Check for ITS-TPC sync. matching efficiency /// \author felix.schlepper@cern.ch -/// #ifndef QC_MODULE_GLO_GLOITSTPCMATCHINGCHECK_H #define QC_MODULE_GLO_GLOITSTPCMATCHINGCHECK_H @@ -20,33 +19,35 @@ #include "QualityControl/CheckInterface.h" #include "QualityControl/Quality.h" +#include "GLO/Helpers.h" + #include -#include namespace o2::quality_control_modules::glo { /// \brief Check for ITS-TPC sync. matching efficiency /// \author felix.schlepper@cern.ch -class ITSTPCmatchingCheck : public o2::quality_control::checker::CheckInterface +class ITSTPCmatchingCheck final : public o2::quality_control::checker::CheckInterface { public: - Quality check(std::map>* moMap) override; - void beautify(std::shared_ptr mo, Quality checkResult = Quality::Null) override; - void startOfActivity(const Activity& activity) override; + Quality check(std::map>* moMap) final; + void beautify(std::shared_ptr mo, Quality checkResult = Quality::Null) final; + void startOfActivity(const Activity& activity) final; private: - std::vector> findRanges(const std::vector& nums); + static std::vector> findRanges(const std::vector& nums) noexcept; + std::shared_ptr mActivity; // Pt - bool mShowPt{ true }; + bool mShowPt{ false }; float mMinPt{ 1. }; float mMaxPt{ 1.999 }; float mThresholdPt{ 0.5 }; // Phi - bool mShowPhi{ true }; + bool mShowPhi{ false }; float mThresholdPhi{ 0.3 }; // Eta @@ -55,7 +56,17 @@ class ITSTPCmatchingCheck : public o2::quality_control::checker::CheckInterface float mMinEta{ -0.8 }; float mMaxEta{ 0.8 }; - ClassDefOverride(ITSTPCmatchingCheck, 1); + // K0s + bool mShowK0s{ false }; + float mAccRelError{ 0.02 }; + float mAccUncertainty{ 2 }; + helpers::K0sFitter mK0sFitter; + + // Other + int mLimitRange{ -1 }; + bool mIsPbPb{ false }; + + ClassDefOverride(ITSTPCmatchingCheck, 2); }; } // namespace o2::quality_control_modules::glo diff --git a/Modules/GLO/include/GLO/LinkDef.h b/Modules/GLO/include/GLO/LinkDef.h index db72a3196f..8abcb91cf0 100644 --- a/Modules/GLO/include/GLO/LinkDef.h +++ b/Modules/GLO/include/GLO/LinkDef.h @@ -3,16 +3,18 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::quality_control_modules::glo::VertexingQcTask + ; -#pragma link C++ class o2::quality_control_modules::glo::ITSTPCMatchingTask + ; +#pragma link C++ class o2::quality_control_modules::glo::CTFSize + ; #pragma link C++ class o2::quality_control_modules::glo::DataCompressionQcTask + ; #pragma link C++ class o2::quality_control_modules::glo::MeanVertexPostProcessing + ; - #pragma link C++ class o2::quality_control_modules::glo::MeanVertexCheck + ; #pragma link C++ class o2::quality_control_modules::glo::MeanVertexValidator + ; +#pragma link C++ class o2::quality_control_modules::glo::VertexingQcTask + ; -#pragma link C++ class o2::quality_control_modules::glo::CTFSize + ; +#pragma link C++ class o2::quality_control_modules::glo::ITSTPCMatchingTask + ; #pragma link C++ class o2::quality_control_modules::glo::ITSTPCmatchingCheck + ; +#pragma link C++ class o2::quality_control_modules::glo::K0sFitReductor + ; +#pragma link C++ class o2::quality_control_modules::glo::MTCReductor + ; +#pragma link C++ class o2::quality_control_modules::glo::PVITSReductor + ; #endif diff --git a/Modules/GLO/include/GLO/Reductors.h b/Modules/GLO/include/GLO/Reductors.h new file mode 100644 index 0000000000..0965268a91 --- /dev/null +++ b/Modules/GLO/include/GLO/Reductors.h @@ -0,0 +1,67 @@ +// 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 QUALITYCONTROL_K0SFITREDUCTOR_H +#define QUALITYCONTROL_K0SFITREDUCTOR_H + +#include "QualityControl/ReductorTObject.h" + +#include + +namespace o2::quality_control_modules::glo +{ + +class K0sFitReductor final : public quality_control::postprocessing::ReductorTObject +{ + void* getBranchAddress() final { return &mStats; }; + const char* getBranchLeafList() final { return "yield/F:mean/F:sigma/F"; }; + void update(TObject* obj) final; + + private: + struct { + Float_t yield{ -1. }; + Float_t mean{ -1. }; + Float_t sigma{ -1. }; + } mStats; +}; + +class MTCReductor final : public quality_control::postprocessing::ReductorTObject +{ + void* getBranchAddress() final { return &mStats; }; + const char* getBranchLeafList() final; + void update(TObject* obj) final; + + private: + struct { + Float_t mtc{ -1. }; + } mStats; + + Float_t mPt{ -1. }; +}; + +class PVITSReductor final : public quality_control::postprocessing::ReductorTObject +{ + void* getBranchAddress() final { return &mStats; }; + const char* getBranchLeafList() final; + void update(TObject* obj) final; + + private: + struct { + Float_t pol0{ 0. }; + Float_t pol1{ 0. }; + } mStats; + + Float_t mR0{ 0 }, mR1{ 0 }; +}; + +} // namespace o2::quality_control_modules::glo + +#endif diff --git a/Modules/GLO/src/ITSTPCMatchingTask.cxx b/Modules/GLO/src/ITSTPCMatchingTask.cxx index 9f58d7ee5e..b9730292fc 100644 --- a/Modules/GLO/src/ITSTPCMatchingTask.cxx +++ b/Modules/GLO/src/ITSTPCMatchingTask.cxx @@ -14,112 +14,65 @@ /// \author Chiara Zampolli /// -#include -#include +#include +#include #include "QualityControl/QcInfoLogger.h" #include "GLO/ITSTPCMatchingTask.h" #include "Common/Utils.h" + #include #include -#include using matchType = o2::gloqc::MatchITSTPCQC::matchType; +using namespace o2::quality_control_modules::common; namespace o2::quality_control_modules::glo { void ITSTPCMatchingTask::initialize(o2::framework::InitContext& /*ctx*/) { - ILOG(Debug, Devel) << "initialize ITSTPCMatchingTask" << ENDM; // QcInfoLogger is used. FairMQ logs will go to there as well. - - if (auto param = mCustomParameters.find("isMC"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - isMC (= use of MC info): " << param->second << ENDM; - mMatchITSTPCQC.setUseMC(o2::quality_control::core::decodeBool(param->second)); - } + ILOG(Debug, Devel) << "initialize ITSTPCMatchingTask" << ENDM; - if (auto param = mCustomParameters.find("useTrkPID"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - useTrkPID (= add plots for tracking PID): " << param->second << ENDM; - mMatchITSTPCQC.setUseTrkPID(o2::quality_control::core::decodeBool(param->second)); - } - - /////////////////////////////// Track selections for MatchITSTPCQC //////////////////////////////// + // MC + mMatchITSTPCQC.setUseMC(getFromConfig(mCustomParameters, "isMC", false)); + mMatchITSTPCQC.setUseTrkPID(getFromConfig(mCustomParameters, "useTrkPID", false)); // ITS track - if (auto param = mCustomParameters.find("minPtITSCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minPtITSCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMinPtITSCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("etaITSCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - etaITSCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setEtaITSCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("minNITSClustersCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minNITSClustersCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMinNClustersITS(atoi(param->second.c_str())); - } - if (auto param = mCustomParameters.find("maxChi2PerClusterITS"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - maxChi2PerClusterITS (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMaxChi2PerClusterITS(atof(param->second.c_str())); - } - // TO DO: define an agreed way to implement the setter for ITS matching (min. # layers, which layers) - // [...] --> exploit the method TrackCuts::setRequireHitsInITSLayers(...) + mMatchITSTPCQC.setMinPtITSCut(getFromConfig(mCustomParameters, "minPtITSCut", 0.1f)); + mMatchITSTPCQC.setEtaITSCut(getFromConfig(mCustomParameters, "etaITSCut", 1.4f)); + mMatchITSTPCQC.setMinNClustersITS(getFromConfig(mCustomParameters, "minNITSClustersCut", 0)); + mMatchITSTPCQC.setMaxChi2PerClusterITS(getFromConfig(mCustomParameters, "maxChi2PerClusterITS", 1e10f)); // TPC track - if (auto param = mCustomParameters.find("minPtTPCCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minPtTPCCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMinPtTPCCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("etaTPCCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - etaTPCCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setEtaTPCCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("minNTPCClustersCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minNTPCClustersCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMinNTPCClustersCut(atoi(param->second.c_str())); - } - if (auto param = mCustomParameters.find("minDCACut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minDCACut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMinDCAtoBeamPipeDistanceCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("minDCACutY"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minDCACutY (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMinDCAtoBeamPipeYCut(atof(param->second.c_str())); - } + mMatchITSTPCQC.setMinPtTPCCut(getFromConfig(mCustomParameters, "minPtTPCCut", 0.1f)); + mMatchITSTPCQC.setEtaTPCCut(getFromConfig(mCustomParameters, "etaTPCCut", 1.4f)); + mMatchITSTPCQC.setMinNTPCClustersCut(getFromConfig(mCustomParameters, "minNTPCClustersCut", 60)); + mMatchITSTPCQC.setMinDCAtoBeamPipeDistanceCut(getFromConfig(mCustomParameters, "minDCACut", 100.f)); + mMatchITSTPCQC.setMinDCAtoBeamPipeYCut(getFromConfig(mCustomParameters, "minDCACutY", 10.f)); // ITS-TPC kinematics - if (auto param = mCustomParameters.find("minPtCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - minPtCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setPtCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("maxPtCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - maxPtCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setMaxPtCut(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("etaCut"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - EtaCut (for track selection): " << param->second << ENDM; - mMatchITSTPCQC.setEtaCut(atof(param->second.c_str())); - } - - /////////////////////////////// Options for K0 //////////////////////////////// - if (auto param = mCustomParameters.find("doK0QC"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - doK0QC (= do K0 QC): " << param->second << ENDM; - mMatchITSTPCQC.setDoK0QC(o2::quality_control::core::decodeBool(param->second)); - } - - if (auto param = mCustomParameters.find("trackSourcesK0"); param != mCustomParameters.end()) { - mMatchITSTPCQC.setTrkSources(o2::dataformats::GlobalTrackID::getSourcesMask(param->second)); - } - - if (auto param = mCustomParameters.find("maxK0Eta"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - maxK0Eta (for K0 selection): " << param->second << ENDM; - mMatchITSTPCQC.setMaxK0Eta(atof(param->second.c_str())); - } - if (auto param = mCustomParameters.find("refitK0"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - refitK0 ( enable refit K0s): " << param->second << ENDM; - mMatchITSTPCQC.setRefitK0(o2::quality_control::core::decodeBool(param->second)); - } - if (auto param = mCustomParameters.find("cutK0Mass"); param != mCustomParameters.end()) { - ILOG(Debug, Devel) << "Custom parameter - cutK0Mass (cut on the distance to the PDG mass): " << param->second << ENDM; - mMatchITSTPCQC.setCutK0Mass(atof(param->second.c_str())); - } + mMatchITSTPCQC.setPtCut(getFromConfig(mCustomParameters, "minPtCut", 0.1f)); + mMatchITSTPCQC.setMaxPtCut(getFromConfig(mCustomParameters, "maxPtCut", 20.f)); + mMatchITSTPCQC.setEtaCut(getFromConfig(mCustomParameters, "etaCut", 1.4f)); + // Sync + mIsSync = common::getFromConfig(mCustomParameters, "isSync", false); + // MTC ratios + mDoMTCRatios = common::getFromConfig(mCustomParameters, "doMTCRatios", false); + // K0s + mMatchITSTPCQC.setDoK0QC((mDoK0s = getFromConfig(mCustomParameters, "doK0QC", false))); + if (mIsSync && mDoK0s) { + mMatchITSTPCQC.setMaxK0Eta(getFromConfig(mCustomParameters, "maxK0Eta", 0.8f)); + mMatchITSTPCQC.setRefitK0(getFromConfig(mCustomParameters, "refitK0", true)); + mMatchITSTPCQC.setCutK0Mass(getFromConfig(mCustomParameters, "cutK0Mass", 0.05f)); + if (auto param = mCustomParameters.find("trackSourcesK0"); param != mCustomParameters.end()) { + mMatchITSTPCQC.setTrkSources(o2::dataformats::GlobalTrackID::getSourcesMask(param->second)); + } + + mPublishK0s3D = getFromConfig(mCustomParameters, "publishK0s3D", false); + mSplitTPCOccupancy = getFromConfig(mCustomParameters, "splitK0sMassOccupancy", mSplitTPCOccupancy); + mSplitPt = getFromConfig(mCustomParameters, "splitK0sMassPt", mSplitPt); + mK0sFitter.init(mCustomParameters); + } + // PV + mDoPVITS = common::getFromConfig(mCustomParameters, "doPVITSQC", false); mMatchITSTPCQC.initDataRequest(); mMatchITSTPCQC.init(); @@ -130,6 +83,7 @@ void ITSTPCMatchingTask::startOfActivity(const Activity& activity) { ILOG(Debug, Devel) << "startOfActivity " << activity.mId << ENDM; mMatchITSTPCQC.reset(); + mIsPbPb = activity.mBeamType == "PbPb"; } void ITSTPCMatchingTask::startOfCycle() @@ -150,41 +104,130 @@ void ITSTPCMatchingTask::endOfCycle() mMatchITSTPCQC.finalize(); // Sync Mode - if (common::getFromConfig(mCustomParameters, "isSync", false)) { - auto makeRatio = [](TEfficiency* eff) { - std::string name = eff->GetName(); - name += "_Hist"; - auto ratio = std::make_unique(name.c_str(), eff->GetTitle(), - eff->GetPassedHistogram()->GetXaxis()->GetNbins(), - eff->GetPassedHistogram()->GetXaxis()->GetXmin(), - eff->GetPassedHistogram()->GetXaxis()->GetXmax()); - ratio->SetBit(TH1::EStatusBits::kNoStats); - if (!ratio->getNum()->Add(eff->GetPassedHistogram())) { - ILOG(Error) << "Add operation for numerator histogram of " << name << " failed; efficiency will be skewed" << ENDM; + if (mIsSync) { + if (mDoMTCRatios) { + auto makeRatio = [](std::unique_ptr& ratio, TEfficiency* eff) { + if (ratio) { + ratio->Reset(); + } else { + std::string name = eff->GetName(); + name += "_Hist"; + ratio = std::make_unique(name.c_str(), eff->GetTitle(), + eff->GetPassedHistogram()->GetXaxis()->GetNbins(), + eff->GetPassedHistogram()->GetXaxis()->GetXmin(), + eff->GetPassedHistogram()->GetXaxis()->GetXmax()); + } + ratio->SetBit(TH1::EStatusBits::kNoStats); + if (!ratio->getNum()->Add(eff->GetPassedHistogram())) { + ILOG(Error) << "Add operation for numerator histogram of " << ratio->GetName() << " failed; efficiency will be skewed" << ENDM; + } + if (!ratio->getDen()->Add(eff->GetTotalHistogram())) { + ILOG(Error) << "Add operation for denominator histogram of " << ratio->GetName() << " failed; efficiency will be skewed" << ENDM; + } + ratio->GetXaxis()->SetTitle(eff->GetPassedHistogram()->GetXaxis()->GetTitle()); + ratio->GetYaxis()->SetTitle(eff->GetPassedHistogram()->GetYaxis()->GetTitle()); + ratio->Sumw2(); + ratio->setHasBinominalErrors(); + ratio->update(); + }; + + // Pt + makeRatio(mEffPt, mMatchITSTPCQC.getFractionITSTPCmatch(gloqc::MatchITSTPCQC::ITS)); + getObjectsManager()->startPublishing(mEffPt.get(), PublicationPolicy::Once); + getObjectsManager()->setDefaultDrawOptions(mEffPt->GetName(), "logx"); + + // Eta + makeRatio(mEffEta, mMatchITSTPCQC.getFractionITSTPCmatchEta(gloqc::MatchITSTPCQC::ITS)); + getObjectsManager()->startPublishing(mEffEta.get(), PublicationPolicy::Once); + + // Phi + makeRatio(mEffPhi, mMatchITSTPCQC.getFractionITSTPCmatchPhi(gloqc::MatchITSTPCQC::ITS)); + getObjectsManager()->startPublishing(mEffPhi.get(), PublicationPolicy::Once); + } + + if (mDoPVITS) { + // const auto* h = (mIsPbPb) ? mMatchITSTPCQC.getHistoPVNContVsITSTracksPbPb() : mMatchITSTPCQC.getHistoPVNContVsITSTracks(); + // if (!h) { + // ILOG(Fatal) << "Could not retrieve pv ITS histogram!" << ENDM; + // } + + // mPVITSCycle.reset(); + // mPVITSCycle.reset(dynamic_cast(h->Clone("mPVNContVsITSTracks_Cycle"))); + // if (!mPVITSCycle) { + // ILOG(Fatal) << "Could not retrieve pv ITS histogram for current cycle!" << ENDM; + // } + // if (!mPVITSIntegral) { + // mPVITSIntegral.reset(dynamic_cast(h->Clone("mPVNContVsITSTracks_Integral"))); + // if (!mPVITSIntegral) { + // ILOG(Fatal) << "Could not retrieve pv ITS histogram for integral!" << ENDM; + // } + // } + // if (mPVITSCycle->GetEntries() != h->GetEntries()) { + // mPVITSCycle->Reset(); + // mPVITSCycle->Add(h, mPVITSCycle.get(), 1., -1.); + // mPVITSIntegral->Reset(); + // mPVITSIntegral->Add(h); + + // getObjectsManager()->startPublishing(mPVITSCycle.get(), PublicationPolicy::Once); + // getObjectsManager()->startPublishing(mPVITSIntegral.get(), PublicationPolicy::Once); + // getObjectsManager()->startPublishing(mPVITSCycle->ProfileX(), PublicationPolicy::Once); + // getObjectsManager()->startPublishing(mPVITSIntegral->ProfileX(), PublicationPolicy::Once); + // } + } + + if (mDoK0s) { + const auto* k0s = (mIsPbPb) ? mMatchITSTPCQC.getHistoK0MassVsPtVsOccPbPb() : mMatchITSTPCQC.getHistoK0MassVsPtVsOccpp(); + if (!k0s) { + ILOG(Fatal) << "Could not retrieve k0s histogram for beam type: " << mIsPbPb << ENDM; + } + + mK0sCycle.reset(); + mK0sCycle.reset(dynamic_cast(k0s->Clone("mK0sMassVsPtVsOcc_Cycle"))); + if (!mK0sCycle) { + ILOG(Fatal) << "Could not retrieve k0s histogram for current cycle" << ENDM; + } + if (!mK0sIntegral) { + mK0sIntegral.reset(dynamic_cast(k0s->Clone("mK0sMassVsPtVsOcc_Integral"))); + if (!mK0sIntegral) { + ILOG(Fatal) << "Could not retrieve k0s histogram integral" << ENDM; + } } - if (!ratio->getDen()->Add(eff->GetTotalHistogram())) { - ILOG(Error) << "Add operation for denominator histogram of " << name << " failed; efficiency will be skewed" << ENDM; + if (k0s->GetEntries() != mK0sIntegral->GetEntries()) { + mK0sCycle->Reset(); + mK0sCycle->Add(k0s, mK0sIntegral.get(), 1., -1.); + mK0sIntegral->Reset(); + mK0sIntegral->Add(k0s); + + if (mPublishK0s3D) { + getObjectsManager()->startPublishing(mK0sCycle.get(), PublicationPolicy::Once); + getObjectsManager()->startPublishing(mK0sIntegral.get(), PublicationPolicy::Once); + } + + TH1D* h{ nullptr }; + getObjectsManager()->startPublishing((h = mK0sCycle->ProjectionY("mK0sMassVsPtVsOcc_Cycle_pmass")), PublicationPolicy::Once); + + if (mSplitTPCOccupancy != OptValue) { + auto splitOccBin = mK0sCycle->GetZaxis()->FindBin(mSplitTPCOccupancy); + getObjectsManager()->startPublishing(mK0sCycle->ProjectionY("mK0sMassVsPtVsOcc_Cycle_pmass_lowOcc", 0, -1, 0, splitOccBin - 1), PublicationPolicy::Once); + getObjectsManager()->startPublishing(mK0sCycle->ProjectionY("mK0sMassVsPtVsOcc_Cycle_pmass_highOcc", 0, -1, splitOccBin), PublicationPolicy::Once); + } + + if (mSplitPt != OptValue) { + auto splitPtBin = mK0sCycle->GetXaxis()->FindBin(mSplitPt); + getObjectsManager()->startPublishing(mK0sCycle->ProjectionY("mK0sMassVsPtVsOcc_Cycle_pmass_lowPt", 0, splitPtBin - 1), PublicationPolicy::Once); + getObjectsManager()->startPublishing(mK0sCycle->ProjectionY("mK0sMassVsPtVsOcc_Cycle_pmass_highPt", splitPtBin), PublicationPolicy::Once); + } + + if (mK0sFitter.fit(h)) { + if (mDoPVITS && mPVITSCycle->GetEntries() != 0) { + mK0sFitter.mSignalAndBackground->SetParameter(helpers::K0sFitter::Parameters::Pol0, mPVITSCycle->GetEntries()); + } + getObjectsManager()->startPublishing(mK0sFitter.mSignalAndBackground.get(), PublicationPolicy::Once); + } + + getObjectsManager()->startPublishing((h = mK0sIntegral->ProjectionY("mK0sMassVsPtVsOcc_Integral_pmass")), PublicationPolicy::Once); } - ratio->GetXaxis()->SetTitle(eff->GetPassedHistogram()->GetXaxis()->GetTitle()); - ratio->GetYaxis()->SetTitle(eff->GetPassedHistogram()->GetYaxis()->GetTitle()); - ratio->Sumw2(); - ratio->setHasBinominalErrors(); - ratio->update(); - return ratio; - }; - - // Pt - mEffPt = makeRatio(mMatchITSTPCQC.getFractionITSTPCmatch(gloqc::MatchITSTPCQC::ITS)); - getObjectsManager()->startPublishing(mEffPt.get(), PublicationPolicy::Once); - getObjectsManager()->setDefaultDrawOptions(mEffPt->GetName(), "logx"); - - // Eta - mEffEta = makeRatio(mMatchITSTPCQC.getFractionITSTPCmatchEta(gloqc::MatchITSTPCQC::ITS)); - getObjectsManager()->startPublishing(mEffEta.get(), PublicationPolicy::Once); - - // Phi - mEffPhi = makeRatio(mMatchITSTPCQC.getFractionITSTPCmatchPhi(gloqc::MatchITSTPCQC::ITS)); - getObjectsManager()->startPublishing(mEffPhi.get(), PublicationPolicy::Once); + } } } diff --git a/Modules/GLO/src/ITSTPCmatchingCheck.cxx b/Modules/GLO/src/ITSTPCmatchingCheck.cxx index 31ff915b37..c2ef7ce2e9 100644 --- a/Modules/GLO/src/ITSTPCmatchingCheck.cxx +++ b/Modules/GLO/src/ITSTPCmatchingCheck.cxx @@ -9,35 +9,30 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// /// \file ITSTPCmatchingCheck.cxx /// \author felix.schlepper@cern.ch -/// #include "GLO/ITSTPCmatchingCheck.h" #include "QualityControl/MonitorObject.h" #include "QualityControl/Quality.h" +#include +#include #include "QualityControl/QcInfoLogger.h" #include "Common/Utils.h" #include #include +#include #include #include #include #include -#include #include #include -#include #include -#include -#include - +#include #include -#include -#include "fmt/format.h" using namespace std; using namespace o2::quality_control; @@ -52,10 +47,10 @@ Quality ITSTPCmatchingCheck::check(std::mapGetName(); - if (mShowPt && mo->getName() == "mFractionITSTPCmatch_ITS_Hist") { + if (mShowPt && moName == "mFractionITSTPCmatch_ITS_Hist") { auto* eff = dynamic_cast(mo->getObject()); if (eff == nullptr) { ILOG(Error) << "Failed cast for ITSTPCmatch_ITS check!" << ENDM; @@ -84,18 +79,20 @@ Quality ITSTPCmatchingCheck::check(std::mapGetXaxis()->GetBinLowEdge(binLow), up = eff->GetXaxis()->GetBinUpEdge(binUp); - cBins += fmt::format("{:.1f}-{:.1f},", low, up); + if (mLimitRange >= 0 && ranges.size() > mLimitRange) { + result.updateMetadata("checkPtBins", "too many bad bins"); + } else { + for (const auto& [binLow, binUp] : ranges) { + float low = eff->GetXaxis()->GetBinLowEdge(binLow), up = eff->GetXaxis()->GetBinUpEdge(binUp); + cBins += std::format("{:.1f}-{:.1f},", low, up); + } + cBins.pop_back(); // remove last `,` + cBins += " (GeV/c)"; + result.updateMetadata("checkPtBins", cBins); } - cBins.pop_back(); // remove last `,` - cBins += " (GeV/c)"; - result.updateMetadata("checkPtBins", cBins); } } - } - - if (mShowPhi && mo->getName() == "mFractionITSTPCmatchPhi_ITS_Hist") { + } else if (mShowPhi && moName == "mFractionITSTPCmatchPhi_ITS_Hist") { auto* eff = dynamic_cast(mo->getObject()); if (eff == nullptr) { ILOG(Error) << "Failed cast for ITSTPCmatchPhi_ITS check!" << ENDM; @@ -122,19 +119,21 @@ Quality ITSTPCmatchingCheck::check(std::mapGetXaxis()->GetBinLowEdge(binLow), up = eff->GetXaxis()->GetBinUpEdge(binUp); - cBins += fmt::format("{:.1f}-{:.1f},", low, up); + if (mLimitRange >= 0 && ranges.size() > mLimitRange) { + result.updateMetadata("checkPhiBins", "too many bad bins"); + } else { + std::string cBins{ "Bad matching efficiency in: " }; + for (const auto& [binLow, binUp] : ranges) { + float low = eff->GetXaxis()->GetBinLowEdge(binLow), up = eff->GetXaxis()->GetBinUpEdge(binUp); + cBins += std::format("{:.1f}-{:.1f},", low, up); + } + cBins.pop_back(); // remove last `,` + cBins += " (rad)"; + result.updateMetadata("checkPhiBins", cBins); } - cBins.pop_back(); // remove last `,` - cBins += " (rad)"; - result.updateMetadata("checkPhiBins", cBins); } } - } - - if (mShowEta && mo->getName() == "mFractionITSTPCmatchEta_ITS_Hist") { + } else if (mShowEta && moName == "mFractionITSTPCmatchEta_ITS_Hist") { auto* eff = dynamic_cast(mo->getObject()); if (eff == nullptr) { ILOG(Error) << "Failed cast for ITSTPCmatchEta_ITS check!" << ENDM; @@ -161,13 +160,17 @@ Quality ITSTPCmatchingCheck::check(std::mapGetXaxis()->GetBinLowEdge(binLow), up = eff->GetXaxis()->GetBinUpEdge(binUp); - cBins += fmt::format("{:.1f}-{:.1f},", low, up); + if (mLimitRange >= 0 && ranges.size() > mLimitRange) { + result.updateMetadata("checkEtaBins", "too many bad bins"); + } else { + std::string cBins{ "Bad matching efficiency in: " }; + for (const auto& [binLow, binUp] : ranges) { + float low = eff->GetXaxis()->GetBinLowEdge(binLow), up = eff->GetXaxis()->GetBinUpEdge(binUp); + cBins += std::format("{:.1f}-{:.1f},", low, up); + } + cBins.pop_back(); // remove last `,` + result.updateMetadata("checkEtaBins", cBins); } - cBins.pop_back(); // remove last `,` - result.updateMetadata("checkEtaBins", cBins); } } } @@ -195,7 +198,9 @@ void ITSTPCmatchingCheck::beautify(std::shared_ptr mo, Quality ch return; } - if (mShowPt && mo->getName() == "mFractionITSTPCmatch_ITS_Hist") { + const auto name = mo->getName(); + + if (mShowPt && name == "mFractionITSTPCmatch_ITS_Hist") { auto* eff = dynamic_cast(mo->getObject()); if (eff == nullptr) { ILOG(Error) << "Failed cast for ITSTPCmatch_ITS_Hist beautify!" << ENDM; @@ -250,11 +255,11 @@ void ITSTPCmatchingCheck::beautify(std::shared_ptr mo, Quality ch auto* good = new TPolyMarker(); good->SetMarkerColor(kGreen); good->SetMarkerStyle(25); - good->SetMarkerSize(2); + good->SetMarkerSize(1); auto* bad = new TPolyMarker(); bad->SetMarkerColor(kRed); bad->SetMarkerStyle(25); - bad->SetMarkerSize(2); + bad->SetMarkerSize(1); auto binLow = eff->FindFixBin(mMinPt), binUp = eff->FindFixBin(mMaxPt); for (int iBin = binLow; iBin <= binUp; ++iBin) { auto x = eff->GetBinCenter(iBin); @@ -296,9 +301,7 @@ void ITSTPCmatchingCheck::beautify(std::shared_ptr mo, Quality ch msg->AddText("Not-handled Quality flag, don't panic..."); } eff->GetListOfFunctions()->Add(msg); - } - - if (mShowPhi && mo->getName() == "mFractionITSTPCmatchPhi_ITS_Hist") { + } else if (mShowPhi && name == "mFractionITSTPCmatchPhi_ITS_Hist") { auto* eff = dynamic_cast(mo->getObject()); if (eff == nullptr) { ILOG(Error) << "Failed cast for ITSTPCmatchPhi_ITS_Hist beautify!" << ENDM; @@ -379,9 +382,7 @@ void ITSTPCmatchingCheck::beautify(std::shared_ptr mo, Quality ch msg->AddText("Not-handled Quality flag, don't panic..."); } eff->GetListOfFunctions()->Add(msg); - } - - if (mShowEta && mo->getName() == "mFractionITSTPCmatchEta_ITS_Hist") { + } else if (mShowEta && name == "mFractionITSTPCmatchEta_ITS_Hist") { auto* eff = dynamic_cast(mo->getObject()); if (eff == nullptr) { ILOG(Error) << "Failed cast for ITSTPCmatchEta_ITS_Hist beautify!" << ENDM; @@ -480,6 +481,54 @@ void ITSTPCmatchingCheck::beautify(std::shared_ptr mo, Quality ch msg->AddText("Not-handled Quality flag, don't panic..."); } eff->GetListOfFunctions()->Add(msg); + } else if (mShowK0s && (name.starts_with("mK0sMassVsPtVsOcc_Cycle_pmass") || name.starts_with("mK0sMassVsPtVsOcc_Integral_pmass"))) { + auto* h = dynamic_cast(mo->getObject()); + if (!h) { + ILOG(Error) << "Failed cast for " << name << " beautify!" << ENDM; + return; + } + auto isCycle = name.find("Cycle") != std::string::npos; + auto isHigh = name.find("high") != std::string::npos; + auto isLow = name.find("low") != std::string::npos; + auto isOcc = name.ends_with("Occ"); + auto isPt = name.ends_with("Pt"); + auto msg = new TPaveText(0.6, 0.6, 0.88, 0.88, "NDC;NB"); + if (!isLow && !isHigh) { + h->SetTitle(Form("K0s invariant mass (integrated over #it{p}_{T} and occupancy, %s);K0s mass (GeV/c^{2});entries", (isCycle) ? "last cycle" : "integrated")); + } else { + h->SetTitle(Form("K0s invariant mass (integrated over%s#it{p}_{T} and%soccupancy, last cycle);K0s mass (GeV/c^{2});entries", + (isPt) ? ((isLow) ? " low " : " high ") : " ", + (isOcc) ? ((isLow) ? " low " : " high ") : " ")); + } + if (!mK0sFitter.fit(h, true)) { + msg->AddText("Fit: Failed"); + msg->SetFillColor(kRed); + msg->SetTextColor(kWhite); + } else { + auto unc = mK0sFitter.getUncertainty(); + auto rerr = mK0sFitter.getRelativeError(); + auto max = h->GetMaximum(), min = h->GetMinimum(), textp{ (max - min) * 0.1 }; + auto l = new TLine(mK0sFitter.mMassK0s, 0, mK0sFitter.mMassK0s, max); + l->SetLineStyle(kDotted); + h->GetListOfFunctions()->Add(l); + auto t = new TText(mK0sFitter.mMassK0s - 0.025, textp, "PDG K0s"); + h->GetListOfFunctions()->Add(t); + if (unc > mAccUncertainty || rerr > mAccRelError) { + msg->AddText("Fit: BAD"); + msg->AddText("Not converged"); + msg->AddText(Form("Discrepant %.2f", unc)); + msg->AddText(Form("RError %.2f%%", rerr * 1e2)); + msg->SetFillColor(kRed); + msg->SetTextColor(kWhite); + } else { + msg->AddText("Fit: GOOD"); + msg->AddText(Form("Mass %.1f #pm %.1f (MeV)", mK0sFitter.getMass() * 1e3, mK0sFitter.getSigma() * 1e3)); + msg->AddText(Form("Consistent %.2f", unc)); + msg->AddText(Form("RError %.2f%%", rerr * 1e2)); + msg->SetFillColor(kGreen); + } + } + h->GetListOfFunctions()->Add(msg); } } @@ -487,31 +536,38 @@ void ITSTPCmatchingCheck::startOfActivity(const Activity& activity) { mActivity = make_shared(activity); - mShowPt = common::getFromExtendedConfig(activity, mCustomParameters, "showPt", true); - if (mShowPt) { + if ((mShowPt = common::getFromExtendedConfig(activity, mCustomParameters, "showPt", false))) { mThresholdPt = common::getFromExtendedConfig(activity, mCustomParameters, "thresholdPt", 0.5f); mMinPt = common::getFromExtendedConfig(activity, mCustomParameters, "minPt", 1.0f); mMaxPt = common::getFromExtendedConfig(activity, mCustomParameters, "maxPt", 1.999f); } - mShowPhi = common::getFromExtendedConfig(activity, mCustomParameters, "showPhi", true); - if (mShowPt) { + if ((mShowPhi = common::getFromExtendedConfig(activity, mCustomParameters, "showPhi", false))) { mThresholdPhi = common::getFromExtendedConfig(activity, mCustomParameters, "thresholdPhi", 0.3f); } - mShowEta = common::getFromExtendedConfig(activity, mCustomParameters, "showEta", false); - if (mShowEta) { + if ((mShowEta = common::getFromExtendedConfig(activity, mCustomParameters, "showEta", false))) { mThresholdEta = common::getFromExtendedConfig(activity, mCustomParameters, "thresholdEta", 0.4f); mMinEta = common::getFromExtendedConfig(activity, mCustomParameters, "minEta", -0.8f); mMaxEta = common::getFromExtendedConfig(activity, mCustomParameters, "maxEta", 0.8f); } + + if ((mShowK0s = common::getFromExtendedConfig(activity, mCustomParameters, "showK0s", false))) { + mAccRelError = common::getFromExtendedConfig(activity, mCustomParameters, "acceptableK0sRError", 0.2f); + mAccUncertainty = common::getFromExtendedConfig(activity, mCustomParameters, "acceptableK0sUncertainty", 2.f); + mK0sFitter.init(mCustomParameters, activity); + } + + mLimitRange = common::getFromExtendedConfig(activity, mCustomParameters, "limitRanges", 5); + mIsPbPb = activity.mBeamType == "Pb-Pb"; } -std::vector> ITSTPCmatchingCheck::findRanges(const std::vector& nums) +std::vector> ITSTPCmatchingCheck::findRanges(const std::vector& nums) noexcept { std::vector> ranges; - if (nums.empty()) + if (nums.empty()) { return ranges; + } int start = nums[0]; int end = start; @@ -520,11 +576,11 @@ std::vector> ITSTPCmatchingCheck::findRanges(const std::vect if (nums[i] == end + 1) { end = nums[i]; } else { - ranges.push_back(std::make_pair(start, end)); + ranges.emplace_back(start, end); start = end = nums[i]; } } - ranges.push_back(std::make_pair(start, end)); // Add the last range + ranges.emplace_back(start, end); // Add the last range return ranges; } diff --git a/Modules/GLO/src/Reductors.cxx b/Modules/GLO/src/Reductors.cxx new file mode 100644 index 0000000000..9d85cae250 --- /dev/null +++ b/Modules/GLO/src/Reductors.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. + +#include "Common/Utils.h" + +#include "GLO/Reductors.h" +#include "GLO/Helpers.h" + +#include +#include +#include +#include +#include + +namespace o2::quality_control_modules::glo +{ + +void K0sFitReductor::update(TObject* obj) +{ + auto f = dynamic_cast(obj); + if (!f) { + return; + } + + mStats.mean = (Float_t)f->GetParameter(helpers::K0sFitter::Parameters::Mass); + mStats.sigma = (Float_t)f->GetParameter(helpers::K0sFitter::Parameters::Sigma); + if (auto ncol = (Float_t)f->GetParameter(helpers::K0sFitter::Parameters::Pol0); ncol > 0.) { + mStats.yield = (Float_t)f->GetParameter(helpers::K0sFitter::Parameters::Amplitude) * mStats.sigma / ncol; + } else { + mStats.yield = -1; + } +} + +const char* MTCReductor::getBranchLeafList() +{ + mPt = common::internal::stringToType(mCustomParameters.atOrDefaultValue("pt", "0")); + + return "mtc/F"; +}; + +void MTCReductor::update(TObject* obj) +{ + auto h = dynamic_cast(obj); + if (!h) { + return; + } + + mStats.mtc = (float)h->GetBinContent(h->FindBin(mPt)); +} + +const char* PVITSReductor::getBranchLeafList() +{ + mR0 = common::internal::stringToType(mCustomParameters.atOrDefaultValue("r0", "0")); + mR1 = common::internal::stringToType(mCustomParameters.atOrDefaultValue("r1", "0")); + + return "pol0/F:pol1/F"; +}; + +void PVITSReductor::update(TObject* obj) +{ + auto p = dynamic_cast(obj); + if (!p) { + return; + } + + auto res = p->Fit("pol1", "QSNC", "", mR0, mR1); + if ((Int_t)res != 0) { + return; + } + + mStats.pol0 = (Float_t)res->Parameter(0); + mStats.pol1 = (Float_t)res->Parameter(1); +} + +} // namespace o2::quality_control_modules::glo