From d413fefb98aae289dbb315ed64f4a9dc93e6472a Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 12 Feb 2021 15:29:46 +0000 Subject: [PATCH 01/27] OMARichRefIndex - refractor runCalibration method to add method that takes histogram pointers instead of saveset --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 310 +++++++++++-------- Rich/RichOnlineCalib/src/OMARichRefIndex.h | 49 ++- 2 files changed, 218 insertions(+), 141 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 029646596..da87f69a3 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -140,7 +140,7 @@ StatusCode OMARichRefIndex::initialize() { StatusCode OMARichRefIndex::execute() { return StatusCode::SUCCESS; } //============================================================================= -// Analyze +// Analyze //============================================================================= StatusCode OMARichRefIndex::analyze( std::string& SaveSet, std::string Task ) { if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Analyze" << endmsg; @@ -285,160 +285,149 @@ StatusCode OMARichRefIndex::analyze( std::string& SaveSet, std::string Task ) { } //============================================================================= -// Run the calibration +// Run Calibration from histo pointers //============================================================================= -void OMARichRefIndex::runCalibration( const std::string& type, const RunAndSaveSet& data, const bool publishCalib, +void OMARichRefIndex::runCalibration( const std::string& type, // + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib, // ICameraTool::MessageLevel level ) { + // Save the run number - m_runNumber = data.run; + m_runNumber = runNumber; - // Open Saveset - std::unique_ptr hfile( TFile::Open( data.saveset.c_str(), "READ" ) ); - if ( hfile && !hfile->IsZombie() ) { + if ( m_createPDFsummary ) { printCanvas( "[" ); } + bool keepPDF = false; - if ( m_createPDFsummary ) { printCanvas( "[" ); } - bool keepPDF = false; + // Is this a final calibration ? + const bool isFinal = ( type == "Final EOR" || type == "Final" ); - // Is this a final calibration ? - const bool isFinal = ( type == "Final EOR" || type == "Final" ); + // Loop over radiators + for ( const auto& rad : m_rads ) { - // Loop over radiators - for ( const auto& rad : m_rads ) { + // the histogram name to fit + cameraTool()->Append( "TEXT", "Fit for " + rad ); - // the histogram name to fit - const std::string radHistName = m_HistBase + rad + "/" + m_ResPlot; - cameraTool()->Append( "TEXT", "Fit for " + radHistName ); + // try and load the histogram + auto radHist = histos[rad]; + if ( radHist ) { - // try and load the histogram - auto radHist = (TH1D*)hfile->Get( radHistName.c_str() ); - if ( radHist ) { - // check the histogram stats. - const auto histStats = radHist->GetEntries(); - const bool betterHistStats = histStats > m_histStats[rad]; - - // Make sure axis titles are set.. - if ( radHist->GetXaxis() ) { radHist->GetXaxis()->SetTitle( "delta(Cherenkov Theta) / rad" ); } - if ( radHist->GetYaxis() ) { radHist->GetYaxis()->SetTitle( "Entries" ); } - - // send the histogram to camera - sendToCamera( radHist, data.run ); - - // Draw to canvas - draw( radHist ); - - // save fit result; - FitResult savedFitResult; - - double scale = 1.0; - if ( checkCKThetaStats( radHist ) ) { - // Flag PDF should be kept, as at least one fit had enough stats. - keepPDF = true; - // run the fit - const auto fitresult = fitCKThetaHistogram( radHist, rad ); - if ( fitresult.fitOK ) { - savedFitResult = fitresult; - m_cachedCalibCount[rad] = 0; // Normal calibration, so reset count to 0 - scale = nScaleFromShift( fitresult.ckShift, rad ); - std::ostringstream mess; - mess << rad << " n-1 shift = " << fitresult.ckShift << " scale = " << scale; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - level = ICameraTool::WARNING; - ++m_cachedCalibCount[rad]; // Count cached calibrations - scale = getLastRefIndexSF( rad ); - std::ostringstream mess; - mess << "Fit FAILED. Using scale from previous run " << scale; - } - if ( publishCalib || betterHistStats ) { - if ( !updateRefIndexSF( data.run, rad, scale ) ) { - level = ICameraTool::ERROR; - std::ostringstream mess; - mess << "Failed to update " << rad << " ref index scale"; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - // update the stats for this histogram - m_histStats[rad] = histStats; - } - } - } else // not enough statistics, take the one from previous run - { + // check the histogram stats. + const auto histStats = radHist->GetEntries(); + const bool betterHistStats = histStats > m_histStats[rad]; + + // Make sure axis titles are set.. + if ( radHist->GetXaxis() ) { radHist->GetXaxis()->SetTitle( "delta(Cherenkov Theta) / rad" ); } + if ( radHist->GetYaxis() ) { radHist->GetYaxis()->SetTitle( "Entries" ); } + + // send the histogram to camera + sendToCamera( radHist, runNumber ); + + // Draw to canvas + draw( radHist ); + + // save fit result; + FitResult savedFitResult; + + double scale = 1.0; + if ( checkCKThetaStats( radHist ) ) { + // Flag PDF should be kept, as at least one fit had enough stats. + keepPDF = true; + // run the fit + const auto fitresult = fitCKThetaHistogram( radHist, rad ); + if ( fitresult.fitOK ) { + savedFitResult = fitresult; + m_cachedCalibCount[rad] = 0; // Normal calibration, so reset count to 0 + scale = nScaleFromShift( fitresult.ckShift, rad ); + std::ostringstream mess; + mess << rad << " n-1 shift = " << fitresult.ckShift << " scale = " << scale; + cameraTool()->Append( "TEXT", mess.str() ); + } else { level = ICameraTool::WARNING; ++m_cachedCalibCount[rad]; // Count cached calibrations scale = getLastRefIndexSF( rad ); std::ostringstream mess; - mess << "Not enough statistics for " << rad << " -> Using scale from previous run " << scale; - cameraTool()->Append( "TEXT", mess.str() ); - debug() << mess.str() << endmsg; + mess << "Fit FAILED. Using scale from previous run " << scale; } - - // if a final OK calibration, write to CK resolution summary - if ( savedFitResult.fitOK && isFinal ) { writeCKThetaLog( rad, savedFitResult, data.run ); } - - // publish results. Only if histogram did not have 0 entries - if ( 0 != radHist->GetEntries() && ( publishCalib || betterHistStats ) ) { - if ( m_cachedCalibCount[rad] > m_maxCachedCalibs ) { - level = ICameraTool::WARNING; - std::ostringstream mess; - mess << "Too many (" << m_cachedCalibCount[rad] << ") cached calibrations in a row."; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - if ( !xmlWriter( type, data.run, scale, rad ) ) { + if ( publishCalib || betterHistStats ) { + if ( !updateRefIndexSF( runNumber, rad, scale ) ) { level = ICameraTool::ERROR; std::ostringstream mess; - mess << "Failed to write xml file for " << rad; + mess << "Failed to update " << rad << " ref index scale"; warning() << mess.str() << endmsg; cameraTool()->Append( "TEXT", mess.str() ); } else { - std::ostringstream mess; - mess << "Successfully wrote and published xml file for " << rad; - cameraTool()->Append( "TEXT", mess.str() ); + // update the stats for this histogram + m_histStats[rad] = histStats; } - } else { - const std::string mess = "XML Writing is DISABLED for this saveset"; - info() << mess << endmsg; - cameraTool()->Append( "TEXT", mess ); } - - if ( msgLevel( MSG::DEBUG ) ) debug() << "Scale factor for " << rad << ": " << scale << endmsg; - - } else { - level = ICameraTool::ERROR; + } else // not enough statistics, take the one from previous run + { + level = ICameraTool::WARNING; + ++m_cachedCalibCount[rad]; // Count cached calibrations + scale = getLastRefIndexSF( rad ); std::ostringstream mess; - mess << "Failed to load histogram '" << radHistName << "'"; - warning() << mess.str() << endmsg; + mess << "Not enough statistics for " << rad << " -> Using scale from previous run " << scale; cameraTool()->Append( "TEXT", mess.str() ); + debug() << mess.str() << endmsg; } - } // Loop over radiators + // if a final OK calibration, write to CK resolution summary + if ( savedFitResult.fitOK && isFinal ) { writeCKThetaLog( rad, savedFitResult, runNumber ); } - if ( m_createPDFsummary ) { - // close the PDF - printCanvas( "]" ); - // if not enough stats, remove the file - if ( !keepPDF ) { - const std::string mess = "Not enough stats. for calibration to run. Will remove PDF"; + // publish results. Only if histogram did not have 0 entries + if ( 0 != radHist->GetEntries() && ( publishCalib || betterHistStats ) ) { + if ( m_cachedCalibCount[rad] > m_maxCachedCalibs ) { + level = ICameraTool::WARNING; + std::ostringstream mess; + mess << "Too many (" << m_cachedCalibCount[rad] << ") cached calibrations in a row."; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + if ( !xmlWriter( type, runNumber, scale, rad ) ) { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to write xml file for " << rad; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + std::ostringstream mess; + mess << "Successfully wrote and published xml file for " << rad; + cameraTool()->Append( "TEXT", mess.str() ); + } + } else { + const std::string mess = "XML Writing is DISABLED for this saveset"; info() << mess << endmsg; cameraTool()->Append( "TEXT", mess ); - printCanvas( "DELETE" ); } - } - // close the saveset file - hfile->Close(); + if ( msgLevel( MSG::DEBUG ) ) debug() << "Scale factor for " << rad << ": " << scale << endmsg; - } else { - level = ICameraTool::ERROR; - std::ostringstream mess; - mess << "Failed to open '" << data.saveset << "'"; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); + } else { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to load histogram for '" << rad << "'"; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + + } // Loop over radiators + + if ( m_createPDFsummary ) { + // close the PDF + printCanvas( "]" ); + // if not enough stats, remove the file + if ( !keepPDF ) { + const std::string mess = "Not enough stats. for calibration to run. Will remove PDF"; + info() << mess << endmsg; + cameraTool()->Append( "TEXT", mess ); + printCanvas( "DELETE" ); + } } // send camera message and gaudi message std::ostringstream mess; - mess << type << " Refractive index calibration for Run " << data.run; + mess << type << " Refractive index calibration for Run " << runNumber; if ( ICameraTool::ERROR != level ) { mess << " was SUCCESSFUL"; } else { @@ -454,6 +443,62 @@ void OMARichRefIndex::runCalibration( const std::string& type, const RunAndSaveS } } +//============================================================================= +// Run the calibration from a saveset +//============================================================================= +void OMARichRefIndex::runCalibration( const std::string& type, // + const RunAndSaveSet& data, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { + + // Save the run number + m_runNumber = data.run; + + // Open Saveset + std::unique_ptr hfile( TFile::Open( data.saveset.c_str(), "READ" ) ); + if ( hfile && !hfile->IsZombie() ) { + + // hist for each radiator + RadHists rHists; + + // load the histos + for ( const auto& rad : m_rads ) { + + // the histogram name to fit + const std::string radHistName = m_HistBase + rad + "/" + m_ResPlot; + cameraTool()->Append( "TEXT", "Fit for " + radHistName ); + + // try and load the histogram + auto radHist = (TH1D*)hfile->Get( radHistName.c_str() ); + // if OK save. + if ( radHist ) { + rHists[rad] = radHist; + } else { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to load histogram '" << radHistName << "'"; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } + + // run calib + runCalibration( type, rHists, data.run, publishCalib, level ); + + // close the saveset file + hfile->Close(); + + } else { + level = ICameraTool::ERROR; + std::ostringstream info, mess; + info << "Failed to open '" << data.saveset << "'"; + warning() << info.str() << endmsg; + cameraTool()->Append( "TEXT", info.str() ); + mess << type << " Refractive index calibration for Run " << data.run; + cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); + } +} + //============================================================================= // Finalize //============================================================================= @@ -472,8 +517,10 @@ StatusCode OMARichRefIndex::finalize() { //============================================================================= // Fitting histogram //============================================================================= -OMARichRefIndex::FitResult OMARichRefIndex::fitCKThetaHistogram( TH1* hist, const std::string& rad, - const bool testFit ) const { +OMARichRefIndex::FitResult // +OMARichRefIndex::fitCKThetaHistogram( TH1* hist, // + const std::string& rad, // + const bool testFit ) const { // Do the fit const auto irad = ( "Rich1Gas" == rad ? Rich::Rich1Gas : Rich::Rich2Gas ); auto fitRes = ( !testFit ? m_ckFitter.fit( *hist, irad ) : m_testCkFitter.fit( *hist, irad ) ); @@ -666,7 +713,9 @@ double OMARichRefIndex::getLastRefIndexSF( const std::string& rad ) { //============================================================================= -bool OMARichRefIndex::updateRefIndexSF( const unsigned int runNumber, const std::string& rad, const double scale ) { +bool OMARichRefIndex::updateRefIndexSF( const unsigned int runNumber, // + const std::string& rad, // + const double scale ) { bool OK = true; const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : "Rich2Gas" == rad ? m_Rich2TaskName : "UNKNOWN" ); @@ -704,7 +753,9 @@ bool OMARichRefIndex::updateRefIndexSF( const unsigned int runNumber, const std: //============================================================================= -bool OMARichRefIndex::xmlWriter( const std::string& type, const unsigned int runNumber, const double scale, +bool OMARichRefIndex::xmlWriter( const std::string& type, // + const unsigned int runNumber, // + const double scale, // const std::string& rad ) { // Get version const auto version = setVersion( runNumber, rad ); @@ -835,7 +886,8 @@ bool OMARichRefIndex::writeToDimSummaryFile( const std::string& mess ) const { //============================================================================= -bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, const FitResult& fitResult, +bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, // + const FitResult& fitResult, // const unsigned int runNumber ) const { // Path to the summary file const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" ); @@ -864,8 +916,9 @@ bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, const FitResult& //============================================================================= -std::pair OMARichRefIndex::setVersion( const unsigned int runNumber, - const std::string& rad ) { +std::pair // +OMARichRefIndex::setVersion( const unsigned int runNumber, // + const std::string& rad ) { bool OK = true; unsigned long long version( 0 ); @@ -955,13 +1008,10 @@ std::pair OMARichRefIndex::setVersion( const unsigned // Get the last line from an input file stream std::string OMARichRefIndex::getLastLine( std::fstream& in ) { std::fstream::pos_type pos = in.tellg(); - std::fstream::pos_type lastPos; while ( in >> std::ws && ignoreline( in, lastPos ) ) { pos = lastPos; } - in.clear(); in.seekg( pos ); - std::string line; std::getline( in, line ); return line; diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.h b/Rich/RichOnlineCalib/src/OMARichRefIndex.h index 186a3bfd2..3124150e2 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.h +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.h @@ -98,13 +98,28 @@ private: std::string saveset{""}; }; -private: //============================================================================= - /// Run Calibration + /// Run Calibration from saveset //============================================================================= - void runCalibration( const std::string& type, const RunAndSaveSet& data, const bool publishCalib = true, - ICameraTool::MessageLevel level = ICameraTool::INFO ); + void runCalibration( const std::string& type, // + const RunAndSaveSet& data, // + const bool publishCalib = true, // + ICameraTool::MessageLevel level = ICameraTool::INFO ); + +public: + /// Type for radiator resolution histograms + using RadHists = std::map; + //============================================================================= + /// Run Calibration from histo pointers + //============================================================================= + void runCalibration( const std::string& type, // + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib = true, // + ICameraTool::MessageLevel level = ICameraTool::INFO ); + +private: //============================================================================= /// Load camera tool on demand //============================================================================= @@ -116,7 +131,9 @@ private: //============================================================================= /// Fit the histogram //============================================================================= - FitResult fitCKThetaHistogram( TH1* hist, const std::string& rad, const bool testFit = false ) const; + FitResult fitCKThetaHistogram( TH1* hist, // + const std::string& rad, // + const bool testFit = false ) const; //============================================================================= // Make a pull plot from a histogram and a given function @@ -156,7 +173,8 @@ private: //============================================================================= /// Function to calculate scale factor //============================================================================= - inline double nScaleFromShift( const double& shift, const std::string& rad ) const { + inline double nScaleFromShift( const double& shift, // + const std::string& rad ) const { // the slope parameter for the given RICH const double slope = ( "Rich1Gas" == rad ? m_RefIndexSlope[0] : m_RefIndexSlope[1] ); // Calculate and return the scale factor @@ -171,17 +189,23 @@ private: //============================================================================= /// Function to update ref index scale //============================================================================= - bool updateRefIndexSF( const unsigned int runNumber, const std::string& rad, const double scale ); + bool updateRefIndexSF( const unsigned int runNumber, // + const std::string& rad, // + const double scale ); //============================================================================= /// Function to write out xml file //============================================================================= - bool xmlWriter( const std::string& type, const unsigned int runNumber, const double scale, const std::string& rad ); + bool xmlWriter( const std::string& type, // + const unsigned int runNumber, // + const double scale, // + const std::string& rad ); //============================================================================= /// Functions to get the last line //============================================================================= - inline std::istream& ignoreline( std::fstream& in, std::fstream::pos_type& pos ) { + inline std::istream& ignoreline( std::fstream& in, // + std::fstream::pos_type& pos ) { pos = in.tellg(); return in.ignore( std::numeric_limits::max(), '\n' ); } @@ -192,7 +216,8 @@ private: //============================================================================= /// Function to set version number //============================================================================= - std::pair setVersion( const unsigned int runNumber, const std::string& rad ); + std::pair setVersion( const unsigned int runNumber, // + const std::string& rad ); //============================================================================= /// Append a histogram to a camera message with run number added to title @@ -322,7 +347,9 @@ private: bool writeToDimSummaryFile( const std::string& mess ) const; /// Write to the CK theta resolution summary log - bool writeCKThetaLog( const std::string& rad, const FitResult& fitResult, const unsigned int runNumber ) const; + bool writeCKThetaLog( const std::string& rad, // + const FitResult& fitResult, // + const unsigned int runNumber ) const; private: /// CAMERA reporting tool -- GitLab From a4fdf7304ca62531126bf7aae39bc1e2085558f8 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 16 Feb 2021 15:54:32 +0000 Subject: [PATCH 02/27] Update CMake configuration to depend on Moore --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43abcbf97..d080c0b2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,6 @@ find_package(GaudiProject) # Declare project name and version gaudi_project(Panoptes v7r3 USE Online v6r5 - Rec v21r6 + Moore v51r2 DATA FieldMap VERSION v5r* ParamFiles) -- GitLab From 92dcc47929cbe3e816f9a8f90e28659c1cc6e917 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 16 Feb 2021 15:55:02 +0000 Subject: [PATCH 03/27] Add some QM tests --- Rich/Panoptes/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Rich/Panoptes/CMakeLists.txt b/Rich/Panoptes/CMakeLists.txt index ee2502b29..6d96a374b 100644 --- a/Rich/Panoptes/CMakeLists.txt +++ b/Rich/Panoptes/CMakeLists.txt @@ -46,3 +46,4 @@ endforeach() gaudi_env(SET PANOPTESOPTS \${PANOPTESROOT}/options) +gaudi_add_test(QMTest QMTEST) -- GitLab From 68326c900489b0d655a7e05f3af00b1e133b1530 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 16 Feb 2021 20:35:44 +0000 Subject: [PATCH 04/27] Use RichFutureRecBase --- .../tests/qmtest/rich_ref_index_calib.qmt | 36 +++++++++++++++++++ Rich/Panoptes/tests/refs/empty.ref | 0 .../tests/refs/rich_ref_index_calib.ref | 0 Rich/RichOnlineCalib/CMakeLists.txt | 7 ++-- 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt create mode 100644 Rich/Panoptes/tests/refs/empty.ref create mode 100644 Rich/Panoptes/tests/refs/rich_ref_index_calib.ref diff --git a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt new file mode 100644 index 000000000..d21baaf09 --- /dev/null +++ b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt @@ -0,0 +1,36 @@ + + + + +gaudirun.py +1200 + + $MOOREROOT/tests/options/mdf_input_and_conds.py + $MOOREROOT/tests/options/download_mdf_input.py + $MOOREROOT/tests/options/multi_threaded_4_threads.py + $PANOPTESROOT/options/RichRefIndexCalib.py + +../rich_ref_index_calib.ref +../refs/empty.ref + + +from Moore.qmtest.exclusions import ref_preprocessor +validateWithReference(preproc = ref_preprocessor) + +from Moore.qmtest.exclusions import remove_known_warnings +countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0}, + stdout=remove_known_warnings(stdout)) + + + diff --git a/Rich/Panoptes/tests/refs/empty.ref b/Rich/Panoptes/tests/refs/empty.ref new file mode 100644 index 000000000..e69de29bb diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref new file mode 100644 index 000000000..e69de29bb diff --git a/Rich/RichOnlineCalib/CMakeLists.txt b/Rich/RichOnlineCalib/CMakeLists.txt index 524eb2b06..30548b9c4 100644 --- a/Rich/RichOnlineCalib/CMakeLists.txt +++ b/Rich/RichOnlineCalib/CMakeLists.txt @@ -8,14 +8,13 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### -################################################################################ -# Package: RichOnlineCalib -################################################################################ + gaudi_subdir(RichOnlineCalib v1r2) gaudi_depends_on_subdirs(Online/OMAlib Online/Camera Rich/RichKernel + Rich/RichFutureRecBase Rich/RichRecUtils Rich/RichMonitoringTools) @@ -28,6 +27,6 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} gaudi_add_module(RichOnlineCalib src/*.cpp INCLUDE_DIRS ROOT Rich/RichKernel Rich/RichRecUtils Rich/RichMonitoringTools Online/OMAlib Online/Camera Online/EventBuilder - LINK_LIBRARIES RichKernelLib RichRecUtils RichMonitoringToolsLib CameraLib OMAlib) + LINK_LIBRARIES RichKernelLib RichRecUtils RichMonitoringToolsLib RichFutureRecBase CameraLib OMAlib) gaudi_env(SET RICHONLINECALIBOPTS \${RICHONLINECALIBROOT}/options) -- GitLab From 96fcce93a152b47c1e30408592a9d308e16d5f48 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 16 Feb 2021 20:37:34 +0000 Subject: [PATCH 05/27] Update ref. index calibration tool, add new algorithm to run directly from photon objects --- Rich/Panoptes/options/RichRefIndexCalib.py | 24 + Rich/Panoptes/python/Panoptes/calibration.py | 94 ++++ Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 86 +++- Rich/RichOnlineCalib/src/OMARichRefIndex.h | 7 +- .../RichOnlineCalib/src/RichRefIndexCalib.cpp | 475 ++++++++++++++++++ 5 files changed, 658 insertions(+), 28 deletions(-) create mode 100644 Rich/Panoptes/options/RichRefIndexCalib.py create mode 100644 Rich/Panoptes/python/Panoptes/calibration.py create mode 100644 Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp diff --git a/Rich/Panoptes/options/RichRefIndexCalib.py b/Rich/Panoptes/options/RichRefIndexCalib.py new file mode 100644 index 000000000..e30ee6b35 --- /dev/null +++ b/Rich/Panoptes/options/RichRefIndexCalib.py @@ -0,0 +1,24 @@ +############################################################################### +# (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, 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. # +############################################################################### +from Moore import options, run_reconstruction +from Panoptes.calibration import standalone_rich_ref_index_calib +from PyConf.Tools import TrackMasterFitter +from RecoConf.hlt2_tracking import make_hlt2_tracks + +#import ROOT +#ROOT.PyConfig.ShutDown = False + +options.histo_file = "RichRefIndexCalib.root" + +with TrackMasterFitter.bind(FastMaterialApproximation=True),\ + make_hlt2_tracks.bind(use_pr_kf=True, light_reco=True, fast_reco=True): + run_reconstruction(options, standalone_rich_ref_index_calib) + diff --git a/Rich/Panoptes/python/Panoptes/calibration.py b/Rich/Panoptes/python/Panoptes/calibration.py new file mode 100644 index 000000000..81e8b5e51 --- /dev/null +++ b/Rich/Panoptes/python/Panoptes/calibration.py @@ -0,0 +1,94 @@ +############################################################################### +# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, 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. # +############################################################################### + +from PyConf.tonic import configurable +from PyConf.application import make_odin +from PyConf.Algorithms import ( + TracksToSelection, Rich__Future__Rec__SIMDRecoSummary as RecSummary, + Rich__Future__Rec__Calib__RefIndexCalib as RefIndexCalib) + +from RecoConf.hlt2_tracking import make_hlt2_tracks +from RecoConf.rich_reconstruction import ( + default_rich_reco_options, make_rich_photons, get_radiator_bool_opts, + get_detector_bool_opts) +from RecoConf.standalone import reco_prefilters + +from Moore.config import Reconstruction + + +@configurable +def standalone_rich_ref_index_calib(): + """ RICH the track and RICH reco for refractive index calibration + """ + + print("RICH Refractive Index Calibration") + + # Make the tracks + hlt2_tracks = make_hlt2_tracks() + track_version = "v1" + #print("Available Track Types", hlt2_tracks.keys()) + + # The output data nodes + data = [] + + # Get the fitted long tracks to use + tks = hlt2_tracks["BestLong"] + + # Default RICH reco options + reco_opts = default_rich_reco_options() + + # Enable online mode for wider CK theta side bands and forcing n-1 scale to 1 + reco_opts["PhotonSelection"] = "Online" + + # Turn off scale factors so they can be determined. + reco_opts["DisableRefInScaleFactor"] = True + + # Track selection + tkSel = TracksToSelection(InputLocation=tks[track_version]) + + # RICH photon reco (PID not needed here) + conf = make_rich_photons( + track_name="Long", + input_tracks=tkSel.OutputLocation, + options=reco_opts) + + # The detector and radiator options + rad_opts = get_radiator_bool_opts(reco_opts, "Long") + det_opts = get_detector_bool_opts(reco_opts, "Long") + + # Create working event summary of reco info + recSum = RecSummary( + name="RichRecSummaryLong", + Detectors=det_opts, + Radiators=rad_opts, + TrackSegmentsLocation=conf["TrackSegments"], + TrackToSegmentsLocation=conf["SelectedTrackToSegments"], + PhotonToParentsLocation=conf["PhotonToParents"], + DetectablePhotonYieldLocation=conf["DetectableYields"], + SignalPhotonYieldLocation=conf["SignalYields"], + PhotonSignalsLocation=conf["PhotonSignals"], + RichSIMDPixelSummariesLocation=conf["RichSIMDPixels"]) + + # Calibration algorithm + calib = RefIndexCalib( + name="RichRefCalibLong", + Detectors=det_opts, + Radiators=rad_opts, + ODINLocation=make_odin(), + TracksLocation=tkSel.OutputLocation, + TrackSegmentsLocation=conf["TrackSegments"], + CherenkovPhotonLocation=conf["CherenkovPhotons"], + CherenkovAnglesLocation=conf["SignalCKAngles"], + SummaryTracksLocation=recSum.SummaryTracksLocation, + PhotonToParentsLocation=conf["PhotonToParents"]) + data += [calib] + + return Reconstruction('rich_ref_index_calib', data, reco_prefilters()) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index da87f69a3..0e66bd530 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -63,12 +63,16 @@ OMARichRefIndex::OMARichRefIndex( const std::string& name, ISvcLocator* pSvcLoca declareProperty( "RunNumHistSize", m_runNumHistSize = 100 ); - declareProperty( "RunTestFit", m_runTestFit = true ); + declareProperty( "RunTestFit", m_runTestFit = false ); declareProperty( "TestMaxShiftError", m_testCkFitter.params().MaxShiftError ); declareProperty( "TestMaxSigmaError", m_testCkFitter.params().MaxSigmaError ); declareProperty( "TestRichFitMin", m_testCkFitter.params().RichFitMin ); declareProperty( "TestRichFitMax", m_testCkFitter.params().RichFitMax ); - declareProperty( "TestRichFitTypes", m_testCkFitter.params().RichFitTypes = {{{"Hyperbolic"}, {"Hyperbolic"}}} ); + declareProperty( "TestRichFitTypes", + m_testCkFitter.params().RichFitTypes = {{{"AsymNormal:Hyperbolic", "AsymNormal:FreeNPol"}, + {"AsymNormal:Hyperbolic", "AsymNormal:FreeNPol"}}} ); + + // setProperty( "OutputLevel", MSG::VERBOSE ).ignore(); // Partition const char* partitionName = getenv( "PARTITION" ); @@ -79,15 +83,28 @@ OMARichRefIndex::OMARichRefIndex( const std::string& name, ISvcLocator* pSvcLoca // Initialization //============================================================================= StatusCode OMARichRefIndex::initialize() { + // Set the flag to indicate we are in the initalize() call m_inInit = true; + // initialise OMALib + auto sc = AnalysisTask::initialize(); + if ( sc.isFailure() ) return sc; + + // Initialise the calibration writer + configureCalib(); + + // turn off the initialize flag + m_inInit = false; + + return sc; +} + +void OMARichRefIndex::configureCalib() { + // ROOT style for PDFs if ( m_createPDFsummary ) { setStyle(); } - StatusCode sc = AnalysisTask::initialize(); - if ( sc.isFailure() ) return sc; - // Sometimes its neccessary to perform some file system operations // Do them here as then they run as Online and have full file permissions... // Keep lines here just as future examples ... @@ -96,6 +113,14 @@ StatusCode OMARichRefIndex::initialize() { if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg; + // Can we write to the configured path for condition data + if ( !createDir( m_xmlFilePath ) ) { + const auto curPath = boost::filesystem::current_path().string(); + warning() << "Cannot write to '" << m_xmlFilePath << "' -> Resetting to '" << curPath << "'" << endmsg; + m_xmlFilePath = curPath; + } + info() << "Writing conditions data to " << m_xmlFilePath << endmsg; + // Fix file permissions ... // fixFilePermissions(); @@ -104,17 +129,23 @@ StatusCode OMARichRefIndex::initialize() { // Publish service if ( !m_disableDIMpublish ) { - // Initialise scale factors to last known values - m_Rich1RefIndex = getLastRefIndexSF( "Rich1Gas" ); - m_Rich2RefIndex = getLastRefIndexSF( "Rich2Gas" ); - // Initialise the publish service - sc = serviceLocator()->service( "LHCb::PublishSvc", m_pPublishSvc, false ); - if ( sc.isSuccess() && m_pPublishSvc ) { - m_pPublishSvc->declarePubItem( m_Rich1TaskName, m_Rich1PubString ); - m_pPublishSvc->declarePubItem( m_Rich2TaskName, m_Rich2PubString ); - m_pPublishSvc->declarePubItem( m_Rich1ScaleTaskName, m_Rich1RefIndex ); - m_pPublishSvc->declarePubItem( m_Rich2ScaleTaskName, m_Rich2RefIndex ); - info() << "PublishSvc initialized" << endmsg; + // Is the DIM DNS node defined ? + if ( !getenv( "DIM_DNS_NODE" ) ) { + warning() << "DIM_DNS_NODE not defined. Disabling DIM publishing" << endmsg; + m_disableDIMpublish = true; + } else { + // Initialise scale factors to last known values + m_Rich1RefIndex = getLastRefIndexSF( "Rich1Gas" ); + m_Rich2RefIndex = getLastRefIndexSF( "Rich2Gas" ); + // Initialise the publish service + auto sc = serviceLocator()->service( "LHCb::PublishSvc", m_pPublishSvc, false ); + if ( sc.isSuccess() && m_pPublishSvc ) { + m_pPublishSvc->declarePubItem( m_Rich1TaskName, m_Rich1PubString ); + m_pPublishSvc->declarePubItem( m_Rich2TaskName, m_Rich2PubString ); + m_pPublishSvc->declarePubItem( m_Rich1ScaleTaskName, m_Rich1RefIndex ); + m_pPublishSvc->declarePubItem( m_Rich2ScaleTaskName, m_Rich2RefIndex ); + info() << "PublishSvc initialized" << endmsg; + } } } @@ -126,12 +157,6 @@ StatusCode OMARichRefIndex::initialize() { // send a message to camera to say we are ready cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, "Initialized" ); - - // turn off the initialize flag - m_inInit = false; - - // return - return sc; } //============================================================================= @@ -293,6 +318,8 @@ void OMARichRefIndex::runCalibration( const std::string& type, // const bool publishCalib, // ICameraTool::MessageLevel level ) { + info() << "Starting n-1 calibration for run " << runNumber << " ..." << endmsg; + // Save the run number m_runNumber = runNumber; @@ -418,7 +445,7 @@ void OMARichRefIndex::runCalibration( const std::string& type, // printCanvas( "]" ); // if not enough stats, remove the file if ( !keepPDF ) { - const std::string mess = "Not enough stats. for calibration to run. Will remove PDF"; + const std::string mess = "Not enough statistics for calibration to run. Will remove PDF"; info() << mess << endmsg; cameraTool()->Append( "TEXT", mess ); printCanvas( "DELETE" ); @@ -531,8 +558,10 @@ OMARichRefIndex::fitCKThetaHistogram( TH1* hist, // auto& backFunc = fitRes.bkgFitFunc; // make the pads for the plots - auto upPad = std::make_unique( "U", "", 0., 0.25, 1., 1. ); - auto dnPad = std::make_unique( "L", "", 0., 0., 1., 0.25 ); + static unsigned long long iI{0}; + const auto iS = std::to_string(iI++); + auto upPad = std::make_unique( ("U"+iS).c_str(), ("U"+iS).c_str(), 0., 0.25, 1., 1. ); + auto dnPad = std::make_unique( ("L"+iS).c_str(), ("L"+iS).c_str(), 0., 0., 1., 0.25 ); // upPad->SetTopMargin(0.05); upPad->SetBottomMargin( 0.1 ); dnPad->SetTopMargin( 0.05 ); @@ -613,7 +642,8 @@ OMARichRefIndex::fitCKThetaHistogram( TH1* hist, // std::unique_ptr OMARichRefIndex::makePullPlot( TH1& hist, TF1& func ) const { // make the new plot with the same bins and range std::ostringstream id; - id << hist.GetName() << "Pull"; + static unsigned long long iI{0}; + id << hist.GetName() << "Pull" << iI++; auto h = std::make_unique( id.str().c_str(), "", // no title hist.GetNbinsX(), hist.GetXaxis()->GetXmin(), hist.GetXaxis()->GetXmax() ); @@ -718,7 +748,9 @@ bool OMARichRefIndex::updateRefIndexSF( const unsigned int runNumber, // const double scale ) { bool OK = true; - const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : "Rich2Gas" == rad ? m_Rich2TaskName : "UNKNOWN" ); + const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : // + "Rich2Gas" == rad ? m_Rich2TaskName : // + "UNKNOWN" ); const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); const boost::filesystem::path filename( m_RefIndexSFLog ); diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.h b/Rich/RichOnlineCalib/src/OMARichRefIndex.h index 3124150e2..642f93b43 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.h +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.h @@ -83,6 +83,8 @@ public: StatusCode analyze( std::string& SaveSet, std::string Task ) override; ///< Algorithm analyze + void configureCalib(); ///< Configure the calibration output + private: /// Fit Result object using FitResult = Rich::Rec::CKResolutionFitter::FitResult; @@ -331,7 +333,10 @@ private: } /// Delete the current TCanvas - inline void deleteCanvas() const { m_canvas.reset( nullptr ); } + inline void deleteCanvas() const { + //if ( m_canvas.get() ) { m_canvas->Delete(); } + //m_canvas.reset( nullptr ); + } /// Get the path to write summaries to inline std::string summaryPath() const { diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp new file mode 100644 index 000000000..874890376 --- /dev/null +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -0,0 +1,475 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +// Gaudi +#include "GaudiKernel/ParsersFactory.h" +#include "GaudiKernel/PhysicalConstants.h" +#include "GaudiKernel/StdArrayAsProperty.h" +#include "GaudiUtils/Aida2ROOT.h" + +// base class +#include "RichFutureRecBase/RichRecHistoAlgBase.h" + +// Gaudi Functional +#include "GaudiAlg/Consumer.h" + +// Event Model +#include "Event/ODIN.h" +#include "RichFutureRecEvent/RichRecCherenkovAngles.h" +#include "RichFutureRecEvent/RichRecCherenkovPhotons.h" +#include "RichFutureRecEvent/RichRecPhotonPredictedPixelSignals.h" +#include "RichFutureRecEvent/RichRecRelations.h" +#include "RichFutureRecEvent/RichSummaryEventData.h" + +// Rich Utils +#include "RichUtils/RichPDIdentifier.h" +#include "RichUtils/RichTrackSegment.h" +#include "RichUtils/ZipRange.h" + +// Track selector +#include "TrackInterfaces/ITrackSelector.h" + +// RichDet +#include "RichDet/DeRichSystem.h" + +// CAMERA +#include "Camera/ICameraTool.h" + +// Local +#include "OMARichRefIndex.h" + +// ROOT +#include + +// STD +#include +#include +#include +#include +#include + +namespace Rich::Future::Rec::Calib { + + // Use the functional framework + using namespace Gaudi::Functional; + + /** @class RefIndexCalib RichRefIndexCalib.h + * + * Runs the RICH refractive index calibration directly from photon objects + * + * @author Chris Jones + * @date 2021-02-15 + */ + + class RefIndexCalib final : public Consumer> { + + public: + /// Standard constructor + RefIndexCalib( const std::string& name, ISvcLocator* pSvcLocator ) + : Consumer( name, pSvcLocator, + {KeyValue{"ODINLocation", LHCb::ODINLocation::Default}, + KeyValue{"TracksLocation", LHCb::TrackLocation::Default}, + KeyValue{"SummaryTracksLocation", Summary::TESLocations::Tracks}, + KeyValue{"PhotonToParentsLocation", Relations::PhotonToParentsLocation::Default}, + KeyValue{"TrackSegmentsLocation", LHCb::RichTrackSegmentLocation::Default}, + KeyValue{"CherenkovAnglesLocation", CherenkovAnglesLocation::Signal}, + KeyValue{"CherenkovPhotonLocation", SIMDCherenkovPhotonLocation::Default}} ) { + + // print some stats on the final plots + setProperty( "HistoPrint", true ).ignore(); + setProperty( "NBins1DHistos", 150 ).ignore(); + // setProperty( "OutputLevel", MSG::VERBOSE ).ignore(); + + // make owned insrance of calibration writer + m_refInCalib = std::make_unique( name + ".CondWriter", pSvcLocator ); + + // Partition name + const char* partition = getenv( "PARTITION" ); + if ( partition ) { + m_partition = std::string( partition ); + m_Name += m_partition; + m_onlyOneRichPart = ( "RICH1" == m_partition || "RICH2" == m_partition ); + m_okToPublish = ( m_partition != "RICH" && m_partition != "RICH1" // + && m_partition != "RICH2" && m_partition != "FEST" ); + } + } + + public: + /// Functional operator + void operator()( const LHCb::ODIN& odin, // + const LHCb::Track::Selection& tracks, // + const Summary::Track::Vector& sumTracks, // + const Relations::PhotonToParents::Vector& photToSegPix, // + const LHCb::RichTrackSegment::Vector& segments, // + const CherenkovAngles::Vector& expTkCKThetas, // + const SIMDCherenkovPhoton::Vector& photons ) const override; + + /// Initalize + StatusCode initialize() override { + auto sc = Consumer::initialize(); + if ( !sc ) return sc; + m_refInCalib->configureCalib(); + return sc; + } + + /// Finalize + StatusCode finalize() override { + runCalibration(); + return Consumer::finalize(); + } + + protected: + /// Pre-Book all histograms + StatusCode prebookHistograms() override; + + private: + /// Reset histograms following running a calibration + void resetHistograms() const { + // reset run event count + m_nEventsThisRun = 0; + // reset histograms + for ( const auto rad : activeRadiators() ) { + if ( h_ckResAll[rad] ) { h_ckResAll[rad]->Reset(); } + } + } + + /// End of calibration reset + void resetCalibCounters() const { + m_nEventsSinceCalib = 0; // reset event count for next time + m_runNumber = 0; // correctly determine the next run number + m_timeLastCalib = time( nullptr ); // reset the last calibration time to now + } + + /// Run the HPD calibration ... + void runCalibration( const std::string& type = "Final" ) const; + + private: + // properties and tools + + /// minimum beta value for tracks + Gaudi::Property> m_minBeta{this, "MinBeta", {0.0f, 0.0f, 0.0f}}; + + /// maximum beta value for tracks + Gaudi::Property> m_maxBeta{this, "MaxBeta", {999.99f, 999.99f, 999.99f}}; + + /// Min theta limit for histos for each rad + Gaudi::Property> m_ckThetaMin{this, "ChThetaRecHistoLimitMin", {0.150f, 0.010f, 0.010f}}; + + /// Max theta limit for histos for each rad + Gaudi::Property> m_ckThetaMax{this, "ChThetaRecHistoLimitMax", {0.325f, 0.056f, 0.033f}}; + + /// Histogram ranges for CK resolution plots + Gaudi::Property> m_ckResRange{this, "CKResHistoRange", {0.025f, 0.007f, 0.004f}}; + + /// Minimum number of events for a calibration + Gaudi::Property m_minEventsForCalib{this, "MinEventsForCalib", 100}; + + /// Time interval to send periodic calibration updates + Gaudi::Property m_minTimeBetweenCalibs{this, "MinTimeBetweenCalibs", 16 * 60}; // 16 mins + + /** Track selector. + * Longer term should get rid of this and pre-filter the input data instead. + */ + ToolHandle m_tkSel{this, "TrackSelector", "TrackSelector"}; + + /// Camera messaging + mutable ToolHandle m_cameraTool{this, "CameraTool", "CameraTool"}; + + private: + // cached data + + /// mutex lock + mutable std::mutex m_updateLock; + + // CK theta histograms + RadiatorArray h_ckResAll = {{}}; + + /// The partition name + std::string m_partition; + + /// Algorithm name + partition + std::string m_Name; + + /// Run number for camera run change messages + mutable unsigned int m_lastRunNumberCamera{0}; + + /// Run number for last processed run + mutable unsigned int m_runNumber{0}; + + /// Total overall number of events seen + mutable unsigned long long m_nEvts{0}; + + /// Number of events seen since last calibration was run... + mutable unsigned long long m_nEventsSinceCalib{0}; + + /// Total number of events in current run + mutable unsigned long long m_nEventsThisRun{0}; + + /** List of all previously calibrated runs for the current process + * with the number of events used for that calibration */ + mutable std::map m_processedRuns; + + /// The time the last calibration was run + mutable time_t m_timeLastCalib{0}; + + /// cache if this monitor is running on only one RICH detector + bool m_onlyOneRichPart{false}; + + /// cache if it is OK to publish calibrations + bool m_okToPublish{true}; + + private: + // Calibration utility + std::unique_ptr m_refInCalib; + }; + +} // namespace Rich::Future::Rec::Calib + +using namespace Rich::Future::Rec::Calib; + +//----------------------------------------------------------------------------- + +StatusCode RefIndexCalib::prebookHistograms() { + + bool ok = true; + + // Loop over radiators + for ( const auto rad : activeRadiators() ) { + + // book histogram for calibration + ok &= saveAndCheck( h_ckResAll[rad], Gaudi::Utils::Aida2ROOT::aida2root( + richHisto1D( HID( "ckResAll", rad ), // + "Rec-Exp CKTheta - All photons", // + -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // + "delta(Cherenkov theta) / rad" ) ) ); + + } // active rad loop + + return StatusCode{ok}; +} + +//----------------------------------------------------------------------------- + +void RefIndexCalib::operator()( const LHCb::ODIN& odin, // + const LHCb::Track::Selection& tracks, // + const Summary::Track::Vector& sumTracks, // + const Relations::PhotonToParents::Vector& photToSegPix, // + const LHCb::RichTrackSegment::Vector& segments, // + const CherenkovAngles::Vector& expTkCKThetas, // + const SIMDCherenkovPhoton::Vector& photons ) const { + + // the lock + std::lock_guard lock( m_updateLock ); + + // ================================================================================= + // Do we need to run a calibration ? + // ================================================================================= + + // Current run number + const auto RunNumber = odin.runNumber(); + + // Send info on new runs to camera + if ( UNLIKELY( RunNumber != m_lastRunNumberCamera ) ) { + // check to see if this is one we have seen in the past. + // protects against 'flip flopping' run numbers online that can be + // seen at run changes. + if ( UNLIKELY( m_processedRuns.find( RunNumber ) == m_processedRuns.end() ) ) { + m_lastRunNumberCamera = RunNumber; + std::ostringstream m; + m << "=============> New Run " << RunNumber << " <============="; + info() << m.str() << endmsg; + m_cameraTool->SendAndClearTS( ICameraTool::INFO, m_Name, m.str() ); + } + } + + // Check to see if a calibration should be run due to a new run being detected + if ( UNLIKELY( m_runNumber != 0 && m_runNumber != RunNumber ) ) { + std::ostringstream mess; + mess << "Change to Run " << RunNumber << " detected"; + m_cameraTool->SendAndClearTS( ICameraTool::WARNING, m_Name, mess.str() ); + info() << mess.str() << endmsg; + runCalibration(); + resetHistograms(); + } + + // update cached run number + m_runNumber = RunNumber; + + // count events + ++m_nEvts; + + // First event printout + if ( UNLIKELY( 1 == m_nEvts ) ) { + m_cameraTool->SendAndClearTS( ICameraTool::INFO, m_Name, "First event seen" ); + // set last time to now. + m_timeLastCalib = time( nullptr ); + } + + // run periodic calibration ? + if ( UNLIKELY( m_nEventsSinceCalib >= m_minEventsForCalib && m_minTimeBetweenCalibs > 0 ) ) { + // current time + const time_t currentTime = time( nullptr ); + // time since last calibration + const time_t deltaT = ( currentTime - m_timeLastCalib ); + if ( UNLIKELY( deltaT >= m_minTimeBetweenCalibs ) ) { + // Print message on the number of events seen and the rate + struct tm* timeinfo = localtime( &deltaT ); + std::ostringstream messageS; + messageS << "Seen " << m_nEventsSinceCalib << " events in past "; + if ( timeinfo->tm_hour - 1 > 0 ) { messageS << timeinfo->tm_hour - 1 << " hours "; } + if ( timeinfo->tm_min > 0 ) { messageS << timeinfo->tm_min << " mins "; } + if ( timeinfo->tm_sec > 0 ) { messageS << timeinfo->tm_sec << " secs "; } + messageS << "( " << (double)( m_nEventsSinceCalib ) / (double)( deltaT ) << " Evt/s )"; + m_cameraTool->SendAndClearTS( ICameraTool::INFO, m_Name, messageS.str() ); + info() << messageS.str() << endmsg; + + // run periodic calibration, no histogram reset... + runCalibration( "Periodic" ); + } + } + + // count events since last calibration was made + ++m_nEventsSinceCalib; + + // count events this run + ++m_nEventsThisRun; + + // ================================================================================= + // Fill the histograms + // ================================================================================= + + // loop over tracks + for ( const auto&& [tk, sumTk] : Ranges::ConstZip( tracks, sumTracks ) ) { + // Is this track selected ? + if ( !m_tkSel.get()->accept( *tk ) ) continue; + + // loop over photons for this track + for ( const auto photIn : sumTk.photonIndices() ) { + // photon data + const auto& phot = photons[photIn]; + const auto& rels = photToSegPix[photIn]; + // the segment for this photon + const auto& seg = segments[rels.segmentIndex()]; + + // get the expected CK theta values for this segment + const auto& expCKangles = expTkCKThetas[rels.segmentIndex()]; + + // Radiator info + const auto rad = seg.radiator(); + if ( !radiatorIsActive( rad ) ) continue; + + // Segment momentum + const auto pTot = seg.bestMomentumMag(); + + // The PID type to assume. Just use Pion here. + const auto pid = Rich::Pion; + + // beta + const auto beta = richPartProps()->beta( pTot, pid ); + + // selection cuts + const auto betaC = ( beta >= m_minBeta[rad] && beta <= m_maxBeta[rad] ); + + // expected CK theta + const auto thetaExp = expCKangles[pid]; + + // Loop over scalar entries in SIMD photon + for ( std::size_t i = 0; i < SIMDCherenkovPhoton::SIMDFP::Size; ++i ) { + // Select valid entries + if ( phot.validityMask()[i] ) { + + // reconstructed theta + const auto thetaRec = phot.CherenkovTheta()[i]; + // delta theta + const auto deltaTheta = thetaRec - thetaExp; + + // fill resolution histos + if ( betaC ) { h_ckResAll[rad]->Fill( deltaTheta ); } + + } // valid scalars + } // SIMD loop + } + } +} + +void RefIndexCalib::runCalibration( const std::string& type ) const { + + // check run number is reasonable + if ( UNLIKELY( 0 == m_runNumber ) ) { + // if we have also seen events, something is wrong... + if ( UNLIKELY( m_nEventsSinceCalib > 0 ) ) { + std::ostringstream mess; + mess << "Undefined run number !! -> " << type << " calibration aborted"; + warning() << mess.str() << endmsg; + m_cameraTool->SendAndClearTS( ICameraTool::ERROR, m_Name, mess.str() ); + } + resetHistograms(); + return; + } + + // Only do anything if some events have been seen since last time. + if ( UNLIKELY( 0 == m_nEventsSinceCalib ) ) { + std::ostringstream mess; + mess << "No events processed for run " << m_runNumber << " -> " << type << " calibration aborted"; + warning() << mess.str() << endmsg; + m_cameraTool->SendAndClearTS( ICameraTool::WARNING, m_Name, mess.str() ); + resetHistograms(); + return; + } + + // Is this a previously calibrated run + const auto iRunCalData = m_processedRuns.find( m_runNumber ); + if ( iRunCalData != m_processedRuns.end() ) { + std::ostringstream m; + m << "Previous #Events = " << iRunCalData->second << " New #Events = " << m_nEventsThisRun; + m_cameraTool->Append( "TEXT", m.str() ); + info() << m.str() << endmsg; + // Do we now have more events to calibrate with than last time ? + if ( iRunCalData->second >= m_nEventsThisRun ) { + std::ostringstream t; + t << "Already calibrated run " << m_runNumber << " -> Processing skipped"; + m_cameraTool->SendAndClearTS( ICameraTool::INFO, m_Name, t.str() ); + info() << t.str() << endmsg; + resetCalibCounters(); + return; + } + } + { + std::ostringstream m; + m << "Running calibration update with " << m_nEventsThisRun << " events"; + m_cameraTool->Append( "TEXT", m.str() ); + } + + // save this run in the processed list with number of events used. + m_processedRuns[m_runNumber] = m_nEventsThisRun; + + // run calibration here... + OMARichRefIndex::RadHists hists{{"Rich1Gas", h_ckResAll[Rich::Rich1Gas]}, // + {"Rich2Gas", h_ckResAll[Rich::Rich2Gas]}}; + m_refInCalib->runCalibration( type, hists, m_runNumber ); + + // reset various counters for the next run + resetCalibCounters(); +} + +//----------------------------------------------------------------------------- + +// Declaration of the Algorithm Factory +DECLARE_COMPONENT( RefIndexCalib ) + +//----------------------------------------------------------------------------- -- GitLab From 85a5bb32230372e992f8f7ec908318cc238ee053 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 16 Feb 2021 20:38:47 +0000 Subject: [PATCH 06/27] Add qm test for ref. index calibration --- Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt index d21baaf09..5a85076c2 100644 --- a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt +++ b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt @@ -21,7 +21,7 @@ Make sure HLT2 configures and runs without errors on raw data. $MOOREROOT/tests/options/multi_threaded_4_threads.py $PANOPTESROOT/options/RichRefIndexCalib.py -../rich_ref_index_calib.ref +../refs/rich_ref_index_calib.ref ../refs/empty.ref -- GitLab From 96e8b4ee75bb752afc3c0df8cf6c1aaddd543ce0 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 14:20:50 +0000 Subject: [PATCH 07/27] Move calibration writing to standalone gaudi tool, shared between OMA and algorithm instances --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 1180 +---------------- Rich/RichOnlineCalib/src/OMARichRefIndex.h | 486 ------- .../RichOnlineCalib/src/RichRefIndexCalib.cpp | 28 +- .../src/RichRefIndexCalibWriter.cpp | 1150 ++++++++++++++++ .../src/RichRefIndexCalibWriter.h | 498 +++++++ 5 files changed, 1712 insertions(+), 1630 deletions(-) delete mode 100644 Rich/RichOnlineCalib/src/OMARichRefIndex.h create mode 100644 Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp create mode 100644 Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 0e66bd530..b05c7c479 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -8,1155 +8,77 @@ * granted to it by virtue of its status as an Intergovernmental Organization * * or submit itself to any jurisdiction. * \*****************************************************************************/ -#include "OMARichRefIndex.h" -//----------------------------------------------------------------------------- -// Implementation file for class : OMARichRefIndex -// -// 2014-04-10 : Jibo He -//----------------------------------------------------------------------------- +// Array properties +#include "GaudiKernel/ParsersFactory.h" +#include "GaudiKernel/StdArrayAsProperty.h" -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -OMARichRefIndex::OMARichRefIndex( const std::string& name, ISvcLocator* pSvcLocator ) - : AnalysisTask( name, pSvcLocator ), m_Name( name ) { - declareProperty( "Rich1TaskName", m_Rich1TaskName = "Rich1/Calib" ); - declareProperty( "Rich2TaskName", m_Rich2TaskName = "Rich2/Calib" ); - declareProperty( "Rich1ScaleTaskName", m_Rich1ScaleTaskName = "Rich1RefIndex" ); - declareProperty( "Rich2ScaleTaskName", m_Rich2ScaleTaskName = "Rich2RefIndex" ); - - declareProperty( "EoRSignal", m_EoRSignal = "-EOR" ); - - declareProperty( "HistBase", m_HistBase = "RICH/RiCKResLongTight/" ); - declareProperty( "ResPlot", m_ResPlot = "ckResAll" ); - - declareProperty( "RichRads", m_rads = {"Rich1Gas", "Rich2Gas"} ); - - declareProperty( "minEntries", m_minEntries = 100000 ); - - declareProperty( "nPolFull", m_ckFitter.params().RichNPol ); - declareProperty( "MaxShiftError", m_ckFitter.params().MaxShiftError ); - declareProperty( "MaxSigmaError", m_ckFitter.params().MaxSigmaError ); - declareProperty( "RichFitMin", m_ckFitter.params().RichFitMin ); - declareProperty( "RichFitMax", m_ckFitter.params().RichFitMax ); - declareProperty( "RichFitTypes", m_ckFitter.params().RichFitTypes ); - - declareProperty( "RefIndexSlope", m_RefIndexSlope = {38.1, 65.25} ); - - declareProperty( "Precision", m_Precision = 8 ); - - declareProperty( "xmlFilePath", m_xmlFilePath = "/group/online/alignment" ); - - declareProperty( "xmlVersionLog", m_xmlVersionLog = "version.txt" ); - declareProperty( "RefIndexSFLog", m_RefIndexSFLog = "refIndexSF.txt" ); - declareProperty( "DIMSummaryFile", m_dimSummaryFile = "DIMUpdateSummary.txt" ); - declareProperty( "CKThetaResLog", m_CKThetaResLog = "CKThetaResolutions.txt" ); - - declareProperty( "DisableDIMPublish", m_disableDIMpublish = false ); - - declareProperty( "CreatePreliminaryCalibration", m_createPrelimCalib = true ); - - declareProperty( "CreatePDFSummary", m_createPDFsummary = true ); - - declareProperty( "MaxCachedCalibsInARow", m_maxCachedCalibs = 5 ); - - declareProperty( "RunNumHistSize", m_runNumHistSize = 100 ); - - declareProperty( "RunTestFit", m_runTestFit = false ); - declareProperty( "TestMaxShiftError", m_testCkFitter.params().MaxShiftError ); - declareProperty( "TestMaxSigmaError", m_testCkFitter.params().MaxSigmaError ); - declareProperty( "TestRichFitMin", m_testCkFitter.params().RichFitMin ); - declareProperty( "TestRichFitMax", m_testCkFitter.params().RichFitMax ); - declareProperty( "TestRichFitTypes", - m_testCkFitter.params().RichFitTypes = {{{"AsymNormal:Hyperbolic", "AsymNormal:FreeNPol"}, - {"AsymNormal:Hyperbolic", "AsymNormal:FreeNPol"}}} ); - - // setProperty( "OutputLevel", MSG::VERBOSE ).ignore(); - - // Partition - const char* partitionName = getenv( "PARTITION" ); - if ( partitionName ) { m_Name += std::string( partitionName ); } -} - -//============================================================================= -// Initialization -//============================================================================= -StatusCode OMARichRefIndex::initialize() { - - // Set the flag to indicate we are in the initalize() call - m_inInit = true; - - // initialise OMALib - auto sc = AnalysisTask::initialize(); - if ( sc.isFailure() ) return sc; - - // Initialise the calibration writer - configureCalib(); - - // turn off the initialize flag - m_inInit = false; - - return sc; -} - -void OMARichRefIndex::configureCalib() { - - // ROOT style for PDFs - if ( m_createPDFsummary ) { setStyle(); } - - // Sometimes its neccessary to perform some file system operations - // Do them here as then they run as Online and have full file permissions... - // Keep lines here just as future examples ... - // copyFile( "/home/jonesc/Rich1GasCKThetaResolutions.txt", - // "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); - - if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg; - - // Can we write to the configured path for condition data - if ( !createDir( m_xmlFilePath ) ) { - const auto curPath = boost::filesystem::current_path().string(); - warning() << "Cannot write to '" << m_xmlFilePath << "' -> Resetting to '" << curPath << "'" << endmsg; - m_xmlFilePath = curPath; - } - info() << "Writing conditions data to " << m_xmlFilePath << endmsg; - - // Fix file permissions ... - // fixFilePermissions(); - - // Initialise DIM state listeners - // initialiseDIMStates(); - - // Publish service - if ( !m_disableDIMpublish ) { - // Is the DIM DNS node defined ? - if ( !getenv( "DIM_DNS_NODE" ) ) { - warning() << "DIM_DNS_NODE not defined. Disabling DIM publishing" << endmsg; - m_disableDIMpublish = true; - } else { - // Initialise scale factors to last known values - m_Rich1RefIndex = getLastRefIndexSF( "Rich1Gas" ); - m_Rich2RefIndex = getLastRefIndexSF( "Rich2Gas" ); - // Initialise the publish service - auto sc = serviceLocator()->service( "LHCb::PublishSvc", m_pPublishSvc, false ); - if ( sc.isSuccess() && m_pPublishSvc ) { - m_pPublishSvc->declarePubItem( m_Rich1TaskName, m_Rich1PubString ); - m_pPublishSvc->declarePubItem( m_Rich2TaskName, m_Rich2PubString ); - m_pPublishSvc->declarePubItem( m_Rich1ScaleTaskName, m_Rich1RefIndex ); - m_pPublishSvc->declarePubItem( m_Rich2ScaleTaskName, m_Rich2RefIndex ); - info() << "PublishSvc initialized" << endmsg; - } - } - } - - // reset the cached histogram stats - m_histStats.clear(); - - // write to summary file - writeToDimSummaryFile( m_Name + " Initialized" ); - - // send a message to camera to say we are ready - cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, "Initialized" ); -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode OMARichRefIndex::execute() { return StatusCode::SUCCESS; } - -//============================================================================= -// Analyze -//============================================================================= -StatusCode OMARichRefIndex::analyze( std::string& SaveSet, std::string Task ) { - if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Analyze" << endmsg; - - // Mandatory: call default analyze method - StatusCode sc = AnalysisTask::analyze( SaveSet, Task ); - if ( sc.isFailure() ) return sc; - // if we are still in initialize... just return - // seems to be needed to prevent a crash when the task is restarted ... - if ( !m_disableDIMpublish && m_inInit ) return sc; - - // // If LHC/LHCb state has changed, send a message to camera - // if ( UNLIKELY( stateChange() ) ) - // { - // setDimStatesAsRead(); - // std::ostringstream mess; - // mess << "State : LHC '" << lhcState() << "' LHCb '" << lhcbState() << "'"; - // m_CamTool->SendAndClearTS( ICameraTool::INFO, m_Name, mess.str() ); - // info() << mess.str() << endmsg; - // } - - // Are we in physics, so send updates - // const bool sendUpdates = inPhysics(); - const bool sendUpdates = true; - - // cache the previous state - static bool lastState = sendUpdates; - - // Flag for first time call - // static bool firstTime = true; - - // // has the state changed ? - // if ( UNLIKELY( firstTime || sendUpdates != lastState ) ) - // { - // std::ostringstream mess; - // mess << "Refractive index calibration now "; - // if ( sendUpdates ) { mess << "ACTIVE"; } else { mess << "INACTIVE"; } - // m_CamTool->SendAndClearTS( ICameraTool::INFO, m_Name, mess.str() ); - // info() << mess.str() << endmsg; - // } - - // return now if not in physics or was previously in physics - if ( lastState || sendUpdates ) { +// from OMALib +#include "OMAlib/AnalysisTask.h" - // Check whether it is the last file of one run - // either with "-EOR" in file name, or run number changed +// Local +#include "RichRefIndexCalibWriter.h" - // Each time we do fit, the last run should be set to 0 - // so that it will be init'ed again - // Fix me!? not do fit for the run withtout "-EOR" just before stopping the calib job... +/** @class OMARichRefIndex OMARichRefIndex.h + * + * Performs Refractive Index calibration from Brunel Savesets. + * + * @author Jibo He + * @author Chris Jones Christopher.Rob.Jones@cern.ch + * @date 2014-04-10 + */ +class OMARichRefIndex final : public AnalysisTask +// public Rich::Mon::CheckLHCState +{ - // Extract the file name from the full path - const auto fileName = boost::filesystem::path( SaveSet ).stem().string(); +public: + /// Standard constructor + OMARichRefIndex( const std::string& name, ISvcLocator* pSvcLocator ) : AnalysisTask( name, pSvcLocator ) {} - // Extract the run number - const auto runNumber = getRunNumber( fileName ); + StatusCode initialize() override { - // Extract the timestamp - m_fileTime = getTimeStamp( fileName ); + // Set the flag to indicate we are in the initalize() call + m_inInit = true; - // start the camera message - std::ostringstream mess1, mess2; - mess1 << "Saveset: '" << SaveSet << "'"; - mess2 << "Extracted file name: " << fileName << ", Run: " << runNumber; - if ( msgLevel( MSG::DEBUG ) ) { - debug() << mess1.str() << endmsg; - debug() << mess2.str() << endmsg; - } - cameraTool()->Append( "TEXT", mess1.str() ); - cameraTool()->Append( "TEXT", mess2.str() ); + // initialise OMALib + auto sc = AnalysisTask::initialize(); + if ( sc.isFailure() ) return sc; - // check the run number is not 0 ... - if ( UNLIKELY( 0 == runNumber ) ) { - const std::string mess = "Run number in Brunel Saveset is '0' !! -> Calibration skipped"; - cameraTool()->SendAndClearTS( ICameraTool::ERROR, m_Name, mess ); - error() << mess << endmsg; - } - // Check run number is not too old... - else if ( UNLIKELY( m_maxSeenRunNum - runNumber > m_runNumHistSize ) ) { - std::ostringstream mess; - mess << "Run " << runNumber << " too old ( Newest seen is " << m_maxSeenRunNum << " ). Calibration Aborted."; - cameraTool()->SendAndClearTS( ICameraTool::ERROR, m_Name, mess.str() ); - error() << mess.str() << endmsg; - } else { - if ( fileName.find( m_EoRSignal ) != std::string::npos ) { - m_mergedRun = RunAndSaveSet( runNumber, SaveSet ); - m_lastRun = RunAndSaveSet( 0, "" ); - runCalibration( "Final EOR", m_mergedRun, true ); - // reset the cached histogram stats - m_histStats.clear(); - } // "-EOR" inside the file name - else { - // if it is the first time to read a file without "-EOR" - // or still the same run - if ( 0 == m_lastRun.run || runNumber == m_lastRun.run ) { - // const bool firstSetForRun = ( 0 == m_lastRun.first ); - m_lastRun = RunAndSaveSet( runNumber, SaveSet ); - // runCalibration( "Periodic", m_lastRun, m_createPrelimCalib && firstSetForRun ); - runCalibration( "Periodic", m_lastRun, m_createPrelimCalib ); - } // wait for new file - else if ( runNumber != m_lastRun.run ) // new Run, use previous file - { - // is last run recent enough to do a calibration for ? - // Because runNumber and m_lastRun.run are unsigned, using abs would just overload it in most recent - // compilers. - const unsigned runDiff = std::max( runNumber, m_lastRun.run ) - std::min( runNumber, m_lastRun.run ); - if ( runDiff < m_runNumHistSize ) { - std::ostringstream mess; - mess << "Refractive index calibration for run " << m_lastRun.run - << " triggered by non-EOR saveset. Check Online Brunel EOR creation..."; - cameraTool()->Append( "TEXT", mess.str() ); - warning() << mess.str() << endmsg; - // Run calibration for the last run - runCalibration( "Final", m_lastRun, true, ICameraTool::WARNING ); - } else { - // warn about an unusual run number - std::ostringstream mess; - mess << "Refractive index calibration for run " << m_lastRun.run << " skipped as run is too old ...."; - cameraTool()->Append( "TEXT", mess.str() ); - warning() << mess.str() << endmsg; - } - // reset the cached histogram stats - m_histStats.clear(); - // Run a first calibration for this run - const auto thisRun = RunAndSaveSet( runNumber, SaveSet ); - runCalibration( "First", thisRun, m_createPrelimCalib ); - // reset for the next call - m_mergedRun = m_lastRun; - m_lastRun = RunAndSaveSet( 0, "" ); - } - } - } - } - - // unset the first time flag - // firstTime = false; - - // update the cached state - lastState = sendUpdates; - - return sc; -} - -//============================================================================= -// Run Calibration from histo pointers -//============================================================================= -void OMARichRefIndex::runCalibration( const std::string& type, // - RadHists& histos, // - const unsigned int runNumber, // - const bool publishCalib, // - ICameraTool::MessageLevel level ) { - - info() << "Starting n-1 calibration for run " << runNumber << " ..." << endmsg; - - // Save the run number - m_runNumber = runNumber; - - if ( m_createPDFsummary ) { printCanvas( "[" ); } - bool keepPDF = false; - - // Is this a final calibration ? - const bool isFinal = ( type == "Final EOR" || type == "Final" ); - - // Loop over radiators - for ( const auto& rad : m_rads ) { - - // the histogram name to fit - cameraTool()->Append( "TEXT", "Fit for " + rad ); - - // try and load the histogram - auto radHist = histos[rad]; - if ( radHist ) { + // turn off the initialize flag + m_inInit = false; - // check the histogram stats. - const auto histStats = radHist->GetEntries(); - const bool betterHistStats = histStats > m_histStats[rad]; - - // Make sure axis titles are set.. - if ( radHist->GetXaxis() ) { radHist->GetXaxis()->SetTitle( "delta(Cherenkov Theta) / rad" ); } - if ( radHist->GetYaxis() ) { radHist->GetYaxis()->SetTitle( "Entries" ); } - - // send the histogram to camera - sendToCamera( radHist, runNumber ); - - // Draw to canvas - draw( radHist ); - - // save fit result; - FitResult savedFitResult; - - double scale = 1.0; - if ( checkCKThetaStats( radHist ) ) { - // Flag PDF should be kept, as at least one fit had enough stats. - keepPDF = true; - // run the fit - const auto fitresult = fitCKThetaHistogram( radHist, rad ); - if ( fitresult.fitOK ) { - savedFitResult = fitresult; - m_cachedCalibCount[rad] = 0; // Normal calibration, so reset count to 0 - scale = nScaleFromShift( fitresult.ckShift, rad ); - std::ostringstream mess; - mess << rad << " n-1 shift = " << fitresult.ckShift << " scale = " << scale; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - level = ICameraTool::WARNING; - ++m_cachedCalibCount[rad]; // Count cached calibrations - scale = getLastRefIndexSF( rad ); - std::ostringstream mess; - mess << "Fit FAILED. Using scale from previous run " << scale; - } - if ( publishCalib || betterHistStats ) { - if ( !updateRefIndexSF( runNumber, rad, scale ) ) { - level = ICameraTool::ERROR; - std::ostringstream mess; - mess << "Failed to update " << rad << " ref index scale"; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - // update the stats for this histogram - m_histStats[rad] = histStats; - } - } - } else // not enough statistics, take the one from previous run - { - level = ICameraTool::WARNING; - ++m_cachedCalibCount[rad]; // Count cached calibrations - scale = getLastRefIndexSF( rad ); - std::ostringstream mess; - mess << "Not enough statistics for " << rad << " -> Using scale from previous run " << scale; - cameraTool()->Append( "TEXT", mess.str() ); - debug() << mess.str() << endmsg; - } - - // if a final OK calibration, write to CK resolution summary - if ( savedFitResult.fitOK && isFinal ) { writeCKThetaLog( rad, savedFitResult, runNumber ); } - - // publish results. Only if histogram did not have 0 entries - if ( 0 != radHist->GetEntries() && ( publishCalib || betterHistStats ) ) { - if ( m_cachedCalibCount[rad] > m_maxCachedCalibs ) { - level = ICameraTool::WARNING; - std::ostringstream mess; - mess << "Too many (" << m_cachedCalibCount[rad] << ") cached calibrations in a row."; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - if ( !xmlWriter( type, runNumber, scale, rad ) ) { - level = ICameraTool::ERROR; - std::ostringstream mess; - mess << "Failed to write xml file for " << rad; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - std::ostringstream mess; - mess << "Successfully wrote and published xml file for " << rad; - cameraTool()->Append( "TEXT", mess.str() ); - } - } else { - const std::string mess = "XML Writing is DISABLED for this saveset"; - info() << mess << endmsg; - cameraTool()->Append( "TEXT", mess ); - } - - if ( msgLevel( MSG::DEBUG ) ) debug() << "Scale factor for " << rad << ": " << scale << endmsg; - - } else { - level = ICameraTool::ERROR; - std::ostringstream mess; - mess << "Failed to load histogram for '" << rad << "'"; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - - } // Loop over radiators - - if ( m_createPDFsummary ) { - // close the PDF - printCanvas( "]" ); - // if not enough stats, remove the file - if ( !keepPDF ) { - const std::string mess = "Not enough statistics for calibration to run. Will remove PDF"; - info() << mess << endmsg; - cameraTool()->Append( "TEXT", mess ); - printCanvas( "DELETE" ); - } + // return + return sc; } - // send camera message and gaudi message - std::ostringstream mess; - mess << type << " Refractive index calibration for Run " << runNumber; - if ( ICameraTool::ERROR != level ) { - mess << " was SUCCESSFUL"; - } else { - mess << " FAILED"; - } - cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); - if ( ICameraTool::ERROR == level ) { - error() << mess.str() << endmsg; - } else if ( ICameraTool::WARNING == level ) { - info() << mess.str() << endmsg; - } else { - info() << mess.str() << endmsg; - } -} + StatusCode execute() override { return StatusCode::SUCCESS; } -//============================================================================= -// Run the calibration from a saveset -//============================================================================= -void OMARichRefIndex::runCalibration( const std::string& type, // - const RunAndSaveSet& data, // - const bool publishCalib, // - ICameraTool::MessageLevel level ) { - - // Save the run number - m_runNumber = data.run; - - // Open Saveset - std::unique_ptr hfile( TFile::Open( data.saveset.c_str(), "READ" ) ); - if ( hfile && !hfile->IsZombie() ) { - - // hist for each radiator - RadHists rHists; - - // load the histos - for ( const auto& rad : m_rads ) { - - // the histogram name to fit - const std::string radHistName = m_HistBase + rad + "/" + m_ResPlot; - cameraTool()->Append( "TEXT", "Fit for " + radHistName ); - - // try and load the histogram - auto radHist = (TH1D*)hfile->Get( radHistName.c_str() ); - // if OK save. - if ( radHist ) { - rHists[rad] = radHist; - } else { - level = ICameraTool::ERROR; - std::ostringstream mess; - mess << "Failed to load histogram '" << radHistName << "'"; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - } - - // run calib - runCalibration( type, rHists, data.run, publishCalib, level ); - - // close the saveset file - hfile->Close(); - - } else { - level = ICameraTool::ERROR; - std::ostringstream info, mess; - info << "Failed to open '" << data.saveset << "'"; - warning() << info.str() << endmsg; - cameraTool()->Append( "TEXT", info.str() ); - mess << type << " Refractive index calibration for Run " << data.run; - cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); - } -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode OMARichRefIndex::finalize() { - // clean up state listeners - // finaliseDIMStates(); - // reset the cached histogram stats - m_histStats.clear(); - // send a message to camera - cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, "Finalized" ); - // write to summary file - writeToDimSummaryFile( m_Name + " Finalized" ); - return AnalysisTask::finalize(); // must be called after all other actions -} - -//============================================================================= -// Fitting histogram -//============================================================================= -OMARichRefIndex::FitResult // -OMARichRefIndex::fitCKThetaHistogram( TH1* hist, // - const std::string& rad, // - const bool testFit ) const { - // Do the fit - const auto irad = ( "Rich1Gas" == rad ? Rich::Rich1Gas : Rich::Rich2Gas ); - auto fitRes = ( !testFit ? m_ckFitter.fit( *hist, irad ) : m_testCkFitter.fit( *hist, irad ) ); - - // shortcuts to the results - const auto& fitOK = fitRes.fitOK; - auto& bestFitF = fitRes.overallFitFunc; - auto& backFunc = fitRes.bkgFitFunc; - - // make the pads for the plots - static unsigned long long iI{0}; - const auto iS = std::to_string(iI++); - auto upPad = std::make_unique( ("U"+iS).c_str(), ("U"+iS).c_str(), 0., 0.25, 1., 1. ); - auto dnPad = std::make_unique( ("L"+iS).c_str(), ("L"+iS).c_str(), 0., 0., 1., 0.25 ); - // upPad->SetTopMargin(0.05); - upPad->SetBottomMargin( 0.1 ); - dnPad->SetTopMargin( 0.05 ); - dnPad->SetBottomMargin( 0.22 ); - canvas()->cd(); - upPad->Draw(); - dnPad->Draw(); + StatusCode analyze( std::string& SaveSet, std::string Task ) override { - // Add fitted functions to camera message and PDFs - if ( fitOK ) { + if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Analyze" << endmsg; - // Print fitted parameters - for ( int i = 0; i < bestFitF.GetNpar(); ++i ) { - const auto param = bestFitF.GetParameter( i ); - const auto err = bestFitF.GetParError( i ); - const auto name = bestFitF.GetParName( i ); - std::ostringstream m; - m << " " << name << " = " << param << " +- " << err; - info() << m.str() << endmsg; - if ( !testFit ) { cameraTool()->Append( "TEXT", m.str() ); } - } + // Mandatory: call default analyze method + StatusCode sc = AnalysisTask::analyze( SaveSet, Task ); + if ( sc.isFailure() ) return sc; - // Full fit - if ( !testFit ) { cameraTool()->Append( &bestFitF ); } + // if we are still in initialize... just return + // seems to be needed to prevent a crash when the task is restarted ... + if ( UNLIKELY( m_inInit ) ) return sc; - // Draw full fit - canvas()->cd(); - upPad->cd(); - bestFitF.SetLineColor( kBlue + 2 ); - hist->Draw(); - bestFitF.Draw( "SAME" ); + // run the calibration + sc = m_refInCalib->runCalibration( SaveSet ); - // Add scale factor - const auto scale = nScaleFromShift( bestFitF.GetParameter( 1 ), rad ); - TText text; - text.SetNDC(); - text.SetTextSize( 0.025 ); - text.DrawText( 0.14, 0.840, ( "Run " + std::to_string( m_runNumber ) ).c_str() ); - text.DrawText( 0.14, 0.814, ( "SF " + std::to_string( scale ) ).c_str() ); - - // background only - if ( !testFit ) { cameraTool()->Append( &backFunc ); } - - // Draw background fit - backFunc.SetLineColor( kRed + 3 ); - backFunc.Draw( "SAME" ); - - // Draw the pull - auto pull = makePullPlot( *hist, bestFitF ); - canvas()->cd(); - dnPad->cd(); - pull->Draw(); - - // print canvas to file - printCanvas(); - - } else { - warning() << rad << " fit FAILED" << endmsg; - // print canvas to file - printCanvas(); + // return + return sc; } - // Final sanity check on the fit results - // limits on fit sigma and mean, to detect complete failures such as when there - // is no Cherenkov signal at all - if ( !testFit && !fitOK ) { cameraTool()->Append( "TEXT", "Fit FAILED final sanity checks" ); } - - // Run a test fit, with different fitter options ? - if ( !testFit && m_runTestFit ) { fitCKThetaHistogram( hist, rad, true ); } - - // return final fit parameter for shift - return fitRes; -} - -//============================================================================= -// Make a pull plot from a histogram and a given function -//============================================================================= -std::unique_ptr OMARichRefIndex::makePullPlot( TH1& hist, TF1& func ) const { - // make the new plot with the same bins and range - std::ostringstream id; - static unsigned long long iI{0}; - id << hist.GetName() << "Pull" << iI++; - auto h = std::make_unique( id.str().c_str(), - "", // no title - hist.GetNbinsX(), hist.GetXaxis()->GetXmin(), hist.GetXaxis()->GetXmax() ); - // h->GetXaxis()->SetTitle( hist.GetXaxis()->GetTitle() ); - h->GetXaxis()->SetTitle( "" ); - h->GetYaxis()->SetTitle( "Pull" ); - h->GetXaxis()->SetTitleSize( 0.08 ); - h->GetYaxis()->SetTitleSize( 0.08 ); - h->GetXaxis()->SetLabelSize( 0.06 ); - h->GetYaxis()->SetLabelSize( 0.06 ); - h->GetYaxis()->SetTitleOffset( 0.3 ); - h->SetStats( false ); - - // set the bins - for ( int i = 0; i < hist.GetNbinsX(); ++i ) { - // bin center - const auto binCen = hist.GetBinCenter( i + 1 ); - // only make pull entries for points in function range - if ( binCen < func.GetXmax() && binCen > func.GetXmin() ) { - // raw bin content - const auto rawCont = hist.GetBinContent( i + 1 ); - // bin error - const auto rawErr = fabs( hist.GetBinError( i + 1 ) ); - // function value - const auto funcVal = func.Eval( binCen ); - // pull - const auto pull = ( rawErr > 0 ? ( rawCont - funcVal ) / rawErr : 0.0 ); - // set the bin content and error in the pull plots - h->SetBinContent( i + 1, pull ); - h->SetBinError( i + 1, 1.0 ); - } - } - - // return - return h; -} - -//============================================================================= - -double OMARichRefIndex::getLastRefIndexSF( const std::string& rad ) { - std::string subDet; - if ( "Rich1Gas" == rad ) { - subDet = m_Rich1TaskName; - } else if ( "Rich2Gas" == rad ) { - subDet = m_Rich2TaskName; - } - - const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); - const boost::filesystem::path filename( m_RefIndexSFLog ); - const boost::filesystem::path full_path = dir / filename; - - unsigned int run = 0; - double scale = 1.0; - - if ( !boost::filesystem::exists( full_path ) ) // meet this for the first run... - { - try { - const auto ok = createDir( dir ); - std::ofstream logging( full_path.string().c_str() ); - if ( ok && logging.is_open() ) { - logging << run << " " << std::setprecision( m_Precision ) << scale << "\n"; - logging.close(); - } else { - std::ostringstream mess; - mess << "Failed to open " << full_path; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - // Exception( mess.str() ); - } - } catch ( const boost::filesystem::filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to create file " << full_path << " " << expt.what(); - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - return scale; - } else { - std::fstream file( full_path.string().c_str(), std::ios::in ); - if ( file.is_open() ) { - file >> run >> scale; - file.close(); - std::ostringstream mess; - mess << "Read from file scale factor " << scale << " for Run " << run; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - std::ostringstream mess; - mess << "Failed to open " << full_path; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - } - - info() << "Read " << rad << " scale factor (" << scale << ") from previous run cache" << endmsg; - - return scale; -} - -//============================================================================= - -bool OMARichRefIndex::updateRefIndexSF( const unsigned int runNumber, // - const std::string& rad, // - const double scale ) { - bool OK = true; - - const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : // - "Rich2Gas" == rad ? m_Rich2TaskName : // - "UNKNOWN" ); - - const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); - const boost::filesystem::path filename( m_RefIndexSFLog ); - const boost::filesystem::path full_path = dir / filename; - - try { - - const auto ok = createDir( dir ); - - std::ofstream ofile( full_path.string().c_str() ); - if ( ok && ofile.is_open() ) { - ofile << runNumber << " " << std::setprecision( m_Precision ) << scale << "\n"; - ofile.close(); - } else { - std::ostringstream mess; - mess << "Failed to open " << full_path; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - OK = false; - } - - } catch ( const boost::filesystem::filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to open file " << full_path << " " << expt.what(); - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - OK = false; - } - - return OK; -} - -//============================================================================= - -bool OMARichRefIndex::xmlWriter( const std::string& type, // - const unsigned int runNumber, // - const double scale, // - const std::string& rad ) { - // Get version - const auto version = setVersion( runNumber, rad ); - bool OK = version.first; - if ( !OK ) { return OK; } - const auto versionS = std::to_string( version.second ); - - const bool isR1 = ( "Rich1Gas" == rad ); - const bool isR2 = ( "Rich2Gas" == rad ); - const bool isFinal = ( type == "Final EOR" || type == "Final" ); - bool scaleIsDifferent = false; - - std::string subDet; - if ( isR1 ) { - subDet = m_Rich1TaskName; - m_Rich1PubString = std::to_string( runNumber ) + " v" + versionS; - scaleIsDifferent = m_Rich1RefIndex != scale; - m_Rich1RefIndex = scale; - } else if ( isR2 ) { - subDet = m_Rich2TaskName; - m_Rich2PubString = std::to_string( runNumber ) + " v" + versionS; - scaleIsDifferent = m_Rich2RefIndex != scale; - m_Rich2RefIndex = scale; - } - - const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); - const boost::filesystem::path file( "v" + versionS + ".xml" ); - const boost::filesystem::path full_path = dir / file; - - if ( msgLevel( MSG::DEBUG ) ) debug() << "Writing to " << full_path << endmsg; - - if ( !boost::filesystem::exists( full_path ) ) { - - try { - const auto ok = createDir( dir ); - - std::ofstream logging( full_path.string().c_str() ); - if ( ok && logging.is_open() ) { - logging << " \n"; - logging << "" << std::setprecision( m_Precision ) << scale - << " \n"; - logging << " \n"; - logging << " \n"; - logging.close(); - std::ostringstream mess; - mess << "Successfully wrote " << rad << " Scale factor to " << full_path; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - std::ostringstream mess; - mess << "Failed to open " << full_path; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - OK = false; - } - } catch ( const boost::filesystem::filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to open file " << full_path << " " << expt.what(); - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - OK = false; - } - - // Publish to DIM - if ( OK ) { - if ( m_pPublishSvc ) { - if ( isR1 ) { - info() << "Publishing to DIM : " << m_Rich1TaskName << " = '" << m_Rich1PubString << "'" << endmsg; - m_pPublishSvc->updateItem( m_Rich1TaskName ); - if ( isFinal && scaleIsDifferent ) { - info() << "Publishing to DIM : " << m_Rich1ScaleTaskName << " = " << m_Rich1RefIndex << endmsg; - m_pPublishSvc->updateItem( m_Rich1ScaleTaskName ); - } - } else if ( isR2 ) { - info() << "Publishing to DIM : " << m_Rich2TaskName << " = '" << m_Rich2PubString << "'" << endmsg; - m_pPublishSvc->updateItem( m_Rich2TaskName ); - if ( isFinal && scaleIsDifferent ) { - info() << "Publishing to DIM : " << m_Rich2ScaleTaskName << " = " << m_Rich2RefIndex << endmsg; - m_pPublishSvc->updateItem( m_Rich2ScaleTaskName ); - } - } - } - std::ostringstream mess; - mess << rad << " XML conditions published for Run " << runNumber; - cameraTool()->Append( "TEXT", mess.str() ); - // update DIM summary file - std::ostringstream dimmess; - dimmess << "Run " << runNumber << " |"; - if ( isR1 ) { dimmess << " " << m_Rich1TaskName << " '" << m_Rich1PubString << "'"; } - if ( isR2 ) { dimmess << " " << m_Rich2TaskName << " '" << m_Rich2PubString << "'"; } - OK = writeToDimSummaryFile( dimmess.str() ); - } else { - std::ostringstream mess; - mess << rad << " XML conditions NOT published for Run " << runNumber; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - - } else // file already there - { - std::ostringstream mess; - mess << "File " << full_path << " already there, something must be wrong"; - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - OK = false; - } - - return OK; -} -//============================================================================= - -bool OMARichRefIndex::writeToDimSummaryFile( const std::string& mess ) const { - bool OK = true; - // Open the summary file in append mode - std::ofstream file( dimSummaryFile().c_str(), std::ios_base::app ); - if ( file.is_open() ) { - file << watermark() << " | " << mess << std::endl; - file.close(); - // setPerms( dimSummaryFile() ); - } else { - std::ostringstream m; - m << "Problem writing DIM summary file " << dimSummaryFile(); - warning() << m.str() << endmsg; - cameraTool()->Append( "TEXT", m.str() ); - OK = false; - } - return OK; -} - -//============================================================================= - -bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, // - const FitResult& fitResult, // - const unsigned int runNumber ) const { - // Path to the summary file - const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" ); - const boost::filesystem::path filename( rad + m_CKThetaResLog ); - const boost::filesystem::path full_path = dir / filename; - bool ok = createDir( dir ); - - // open the file in append mode - std::ofstream file( full_path.string().c_str(), std::ios_base::app ); - if ( ok && file.is_open() ) { - // write out the result for this run - file << runNumber << " " << m_fileTime << " " << fitResult.ckResolution << " " << fitResult.ckResolutionErr - << std::endl; - // close the file - file.close(); - } else { - std::ostringstream m; - m << "Problem writing CK resolution summary file " << full_path; - warning() << m.str() << endmsg; - cameraTool()->Append( "TEXT", m.str() ); - ok = false; - } - - return ok; -} - -//============================================================================= - -std::pair // -OMARichRefIndex::setVersion( const unsigned int runNumber, // - const std::string& rad ) { - bool OK = true; - - unsigned long long version( 0 ); - - // Test the root directory is accessible - if ( !createDir( m_xmlFilePath ) ) { - OK = false; - std::ostringstream mess; - mess << "Cannot access alignment directory " << m_xmlFilePath; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } else { - - std::string subDet; - if ( "Rich1Gas" == rad ) { - subDet = m_Rich1TaskName; - } else if ( "Rich2Gas" == rad ) { - subDet = m_Rich2TaskName; - } - - const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); - const boost::filesystem::path filename( m_xmlVersionLog ); - const boost::filesystem::path full_path = dir / filename; - - unsigned int run( 0 ); - - if ( msgLevel( MSG::DEBUG ) ) debug() << "Version file: " << full_path.string() << endmsg; - - if ( !boost::filesystem::exists( full_path ) ) // the first time - { - try { - version = 0; - const auto ok = createDir( dir ); - std::ofstream logging( full_path.string().c_str() ); - if ( ok && logging.is_open() ) { - logging << runNumber << " " << version << "\n"; - logging.close(); - } else { - OK = false; - std::ostringstream mess; - mess << "Failed to open " << full_path; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - } catch ( const boost::filesystem::filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to open file " << full_path << " " << expt.what(); - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - OK = false; - } - return std::make_pair( OK, version ); - } else { - std::fstream file( full_path.string().c_str(), std::ios::in | std::ios::out ); - if ( file.is_open() ) { - std::istringstream lastLine( getLastLine( file ) ); - - lastLine >> run >> version; - - // increase version number - ++version; - - file << runNumber << " " << version << "\n"; - file.close(); - } else { - OK = false; - std::ostringstream mess; - mess << "Failed to open " << full_path; - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - } - - // setPerms( full_path ); - - std::ostringstream mess; - mess << "Setting version: " << version << " for run: " << runNumber; - if ( msgLevel( MSG::DEBUG ) ) debug() << mess.str() << endmsg; - // cameraTool()->Append("TEXT",mess.str()); - } - - return std::make_pair( OK, version ); -} - -//============================================================================= - -// Get the last line from an input file stream -std::string OMARichRefIndex::getLastLine( std::fstream& in ) { - std::fstream::pos_type pos = in.tellg(); - std::fstream::pos_type lastPos; - while ( in >> std::ws && ignoreline( in, lastPos ) ) { pos = lastPos; } - in.clear(); - in.seekg( pos ); - std::string line; - std::getline( in, line ); - return line; -} - -//============================================================================= - -void OMARichRefIndex::printCanvas( const std::string& tag ) const { - - const std::string imageType = "pdf"; - - // get the PDF file name for this run - auto& pdfFile = m_pdfFile[m_runNumber]; - - // Opening file ? - if ( "[" == tag ) { - - try { - - // If file name is not empty (so repeat fit for a run), delete file - if ( !pdfFile.empty() ) { removeFile( pdfFile ); } - - // Directory to save summaries to - const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" + getDateString() + "/RefIndex/" ); - - // Create directory if it does not exist - if ( !boost::filesystem::exists( dir ) ) { boost::filesystem::create_directories( dir ); } - - // File name - const boost::filesystem::path filename( "Run-" + std::to_string( m_runNumber ) + "." + imageType ); - const boost::filesystem::path full_path = dir / filename; - - // If PDF exists, remove before remaking - removeFile( full_path ); - - // cache image file name for this run - pdfFile = full_path.string(); - - // Make a new canvas - deleteCanvas(); - - // Open new PDF - canvas()->Print( ( pdfFile + tag ).c_str(), imageType.c_str() ); - - // set watermark string - m_watermark = watermark(); - info() << "Watermark = " << m_watermark << endmsg; - - } catch ( const boost::filesystem::filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to create file " << pdfFile << " " << expt.what(); - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - deleteCanvas(); - pdfFile = ""; - } - - } - // Closing the file ? - else if ( "]" == tag ) { - - // Close the file - canvas()->Print( ( pdfFile + tag ).c_str(), imageType.c_str() ); - - // Set group write permissions - // setPerms( pdfFile ); - - // delete canvas - deleteCanvas(); - - // send a message - std::ostringstream mess; - mess << "Created " << pdfFile; - info() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - - // limit the PDF file name map to N entries - while ( m_pdfFile.size() > m_runNumHistSize + 10 ) { m_pdfFile.erase( m_pdfFile.begin() ); } - - } else if ( "" == tag ) { - - // Add time/date watermark - canvas()->cd(); - TText text; - text.SetNDC(); - text.SetTextSize( 0.012 ); - text.SetTextColor( 13 ); - text.DrawText( 0.01, 0.01, m_watermark.c_str() ); - - // Just print - canvas()->Print( pdfFile.c_str(), imageType.c_str() ); - - } else if ( "DELETE" == tag && !pdfFile.empty() ) { - - try { - removeFile( pdfFile ); - } catch ( const boost::filesystem::filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to delete file " << pdfFile << " " << expt.what(); - error() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - } -} - -//============================================================================= - -void OMARichRefIndex::fixFilePermissions() const { - using namespace boost::filesystem; - const path dir( m_xmlFilePath + "/RichCalibSummaries" ); - recursive_directory_iterator end_itr; - for ( recursive_directory_iterator i( dir ); i != end_itr; ++i ) { setPerms( i->path() ); } -} +private: + /// Are we during initialize ? + bool m_inInit{false}; + /// Calibration utility + mutable ToolHandle m_refInCalib{ + this, "CalibWriter", "Rich::Future::Rec::Calib::RefIndexCalibWriter/Writer"}; +}; //============================================================================= diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.h b/Rich/RichOnlineCalib/src/OMARichRefIndex.h deleted file mode 100644 index 642f93b43..000000000 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.h +++ /dev/null @@ -1,486 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, 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. * -\*****************************************************************************/ - -#pragma once - -// Array properties -#include "GaudiKernel/ParsersFactory.h" -#include "GaudiKernel/StdArrayAsProperty.h" - -// from OMALib -#include "OMAlib/AnalysisTask.h" - -// Publish to DIM -#include "GaudiKernel/IPublishSvc.h" -#include "GaudiKernel/ServiceLocatorHelper.h" - -// ROOT includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Boost -#include "boost/algorithm/string.hpp" -#include - -// STL -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// CAMERA -#include "Camera/ICameraTool.h" - -// Dim Objects -#include "RichMonitoringTools/RichDimClasses.h" - -// local -#include "rootstyle.h" - -// CK resolution fitter -#include "RichRecUtils/RichCKResolutionFitter.h" - -/** @class OMARichRefIndex OMARichRefIndex.h - * - * Performs Refractive Index calibration from Brunel Savesets. - * - * @author Jibo He - * @author Chris Jones Christopher.Rob.Jones@cern.ch - * @date 2014-04-10 - */ -class OMARichRefIndex final : public AnalysisTask -// public Rich::Mon::CheckLHCState -{ - -public: - /// Standard constructor - OMARichRefIndex( const std::string& name, ISvcLocator* pSvcLocator ); - - StatusCode initialize() override; ///< Algorithm initialization - StatusCode execute() override; ///< Algorithm execution - StatusCode finalize() override; ///< Algorithm finalization - - StatusCode analyze( std::string& SaveSet, - std::string Task ) override; ///< Algorithm analyze - - void configureCalib(); ///< Configure the calibration output - -private: - /// Fit Result object - using FitResult = Rich::Rec::CKResolutionFitter::FitResult; - - /// Simple class to store a run number and saveset path - class RunAndSaveSet { - public: - RunAndSaveSet() = default; - RunAndSaveSet( const unsigned int r, const std::string& s ) : run( r ), saveset( s ) {} - - public: - unsigned int run{0}; - std::string saveset{""}; - }; - - //============================================================================= - /// Run Calibration from saveset - //============================================================================= - void runCalibration( const std::string& type, // - const RunAndSaveSet& data, // - const bool publishCalib = true, // - ICameraTool::MessageLevel level = ICameraTool::INFO ); - -public: - /// Type for radiator resolution histograms - using RadHists = std::map; - - //============================================================================= - /// Run Calibration from histo pointers - //============================================================================= - void runCalibration( const std::string& type, // - RadHists& histos, // - const unsigned int runNumber, // - const bool publishCalib = true, // - ICameraTool::MessageLevel level = ICameraTool::INFO ); - -private: - //============================================================================= - /// Load camera tool on demand - //============================================================================= - inline ICameraTool* cameraTool() const { - if ( !m_CamTool ) { m_CamTool = tool( "CameraTool" ); } - return m_CamTool; - } - - //============================================================================= - /// Fit the histogram - //============================================================================= - FitResult fitCKThetaHistogram( TH1* hist, // - const std::string& rad, // - const bool testFit = false ) const; - - //============================================================================= - // Make a pull plot from a histogram and a given function - //============================================================================= - std::unique_ptr makePullPlot( TH1& hist, TF1& func ) const; - - //============================================================================= - /// Function to get run number from fileName, rely on the name convention here: - /// https://lbtwiki.cern.ch/bin/view/Online/MonitoringExpertGuide#Savesets - //============================================================================= - inline unsigned int getRunNumber( const std::string& fileName ) { - const auto firstName = fileName.substr( fileName.find_first_of( "-" ) + 1 ); - const auto runString = firstName.substr( 0, firstName.find_first_of( "-" ) ); - const unsigned int runN = atoi( runString.c_str() ); - if ( runN > m_maxSeenRunNum ) { - m_maxSeenRunNum = runN; - info() << "Set latest seen run number to " << runN << endmsg; - } - return runN; - } - - //============================================================================= - // Function to get time stamp from the file name - //============================================================================= - inline std::string getTimeStamp( const std::string& fileName ) { - const std::string tmp1 = fileName.substr( fileName.find_first_of( "-" ) + 1 ); - std::string tmp2 = tmp1.substr( tmp1.find_first_of( "-" ) + 1 ); - boost::erase_all( tmp2, "-EOR" ); - return tmp2; - } - - //============================================================================= - /// Function to check whether enough entries - //============================================================================= - inline bool checkCKThetaStats( const TH1* hist ) { return hist && hist->GetEntries() >= m_minEntries; } - - //============================================================================= - /// Function to calculate scale factor - //============================================================================= - inline double nScaleFromShift( const double& shift, // - const std::string& rad ) const { - // the slope parameter for the given RICH - const double slope = ( "Rich1Gas" == rad ? m_RefIndexSlope[0] : m_RefIndexSlope[1] ); - // Calculate and return the scale factor - return 1.0 + ( shift * slope ); - } - - //============================================================================= - // Function to get ref index scale from previous run - //============================================================================= - double getLastRefIndexSF( const std::string& rad ); - - //============================================================================= - /// Function to update ref index scale - //============================================================================= - bool updateRefIndexSF( const unsigned int runNumber, // - const std::string& rad, // - const double scale ); - - //============================================================================= - /// Function to write out xml file - //============================================================================= - bool xmlWriter( const std::string& type, // - const unsigned int runNumber, // - const double scale, // - const std::string& rad ); - - //============================================================================= - /// Functions to get the last line - //============================================================================= - inline std::istream& ignoreline( std::fstream& in, // - std::fstream::pos_type& pos ) { - pos = in.tellg(); - return in.ignore( std::numeric_limits::max(), '\n' ); - } - - /// Get the last line from an input file stream - std::string getLastLine( std::fstream& in ); - - //============================================================================= - /// Function to set version number - //============================================================================= - std::pair setVersion( const unsigned int runNumber, // - const std::string& rad ); - - //============================================================================= - /// Append a histogram to a camera message with run number added to title - //============================================================================= - template - inline void sendToCamera( HIST* hist, const unsigned int runNumber ) const { - // save title - const std::string title = hist->GetTitle(); - // update title with run number added - std::ostringstream newtitle; - newtitle << title << " | Run " << runNumber; - hist->SetTitle( newtitle.str().c_str() ); - // send to camera - cameraTool()->Append( hist, "E,P" ); - // reset title - hist->SetTitle( title.c_str() ); - } - - /// Draw a histogram - template - inline void draw( HIST* hist, const std::string& opt = "" ) const { - hist->Draw( opt.c_str() ); - } - - /// Print Canvas - void printCanvas( const std::string& tag = "" ) const; - - /// Get year/month/day as a string - inline std::string getDateString() const { - // Get year, month, day - const std::time_t t = std::time( nullptr ); - char mbstr[100]; - return ( std::strftime( mbstr, sizeof( mbstr ), "%Y/%m/%d", std::localtime( &t ) ) ? std::string( mbstr ) : "" ); - } - - /// Get watermark string - inline std::string watermark() const { - const std::time_t t = std::time( nullptr ); - char mbstr[100]; - return ( std::strftime( mbstr, sizeof( mbstr ), "%c", std::localtime( &t ) ) ? std::string( mbstr ) : "" ); - } - - /// Fix file permissions - void fixFilePermissions() const; - - /// Set file permissions on a file - template - inline void setPerms( const FILE& file ) const { - if ( boost::filesystem::exists( file ) ) { - debug() << "Setting permissions for " << file << endmsg; - using namespace boost::filesystem; - try { - permissions( file, add_perms | owner_write | group_write ); - } catch ( const filesystem_error& expt ) { - std::ostringstream mess; - mess << "Failed to set permissions for " << file << " " << expt.what(); - warning() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - } - } - - /// Remove a file - template - inline void removeFile( const FILE& file ) const { - if ( boost::filesystem::exists( file ) ) { - std::ostringstream mess; - mess << "Removing " << file; - info() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - boost::filesystem::remove( file ); - } - } - - /// Copy a file - template - inline void copyFile( const FILEFROM& from, const FILETO& to ) const { - if ( boost::filesystem::exists( from ) ) { - std::ostringstream mess; - mess << "Copying " << from << " ->" << to; - info() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - removeFile( to ); - boost::filesystem::copy_file( from, to ); - } - } - - /// Create directory - template - inline bool createDir( const DIR& dir ) const { - bool OK = true; - if ( !boost::filesystem::exists( dir ) ) { - std::ostringstream mess; - try { - boost::filesystem::create_directories( dir ); - mess << "Created " << dir; - } catch ( const boost::filesystem::filesystem_error& expt ) { - mess << "FAILED to create " << dir << " " << expt.what(); - OK = false; - } - info() << mess.str() << endmsg; - cameraTool()->Append( "TEXT", mess.str() ); - } - return OK; - } - - /// Access and create on demand the current TCanvas - inline TCanvas* canvas() const { - if ( !m_canvas.get() ) { m_canvas = std::make_unique( "RefIndCanvas", "RefIndCanvas", 1200, 1200 ); } - return m_canvas.get(); - } - - /// Delete the current TCanvas - inline void deleteCanvas() const { - //if ( m_canvas.get() ) { m_canvas->Delete(); } - //m_canvas.reset( nullptr ); - } - - /// Get the path to write summaries to - inline std::string summaryPath() const { - const std::string dir( m_xmlFilePath + "/RichCalibSummaries/" + getDateString() + "/RefIndex/" ); - createDir( dir ); - return dir; - } - - /// DIM summary file location - inline std::string dimSummaryFile() const { return summaryPath() + m_dimSummaryFile; } - - /// Write a message to the DIM summary file - bool writeToDimSummaryFile( const std::string& mess ) const; - - /// Write to the CK theta resolution summary log - bool writeCKThetaLog( const std::string& rad, // - const FitResult& fitResult, // - const unsigned int runNumber ) const; - -private: - /// CAMERA reporting tool - mutable ICameraTool* m_CamTool = nullptr; - - /// Algorithm name + partition - std::string m_Name; - - /// RICH1 task name - std::string m_Rich1TaskName; - - /// RICH2 task name - std::string m_Rich2TaskName; - - /// RICH1 name for n-1 scale factor DIM service - std::string m_Rich1ScaleTaskName; - - /// RICH2 name for n-1 scale factor DIM service - std::string m_Rich2ScaleTaskName; - - /// Signal to look for to signify an end of run calibration - std::string m_EoRSignal; - - /// Flag to turn on the creation of a Preliminary calibration for each run - bool m_createPrelimCalib; - - /// Store run number and file path - RunAndSaveSet m_mergedRun; - - /// Store run number and file path of last run - RunAndSaveSet m_lastRun; - - /// run number for run being processed - unsigned int m_runNumber{0}; - - /// The ROOT file directory to use for the calibration (the Gaudi Monitor) - std::string m_HistBase; - - /// The histogram ID to use - std::string m_ResPlot; - - /// The radiators to calibration - std::vector m_rads; - - /// Min entries for a fit - unsigned int m_minEntries; - - /// CK Resolution fitter - Rich::Rec::CKResolutionFitter m_ckFitter; - - /// slope from the shift - std::array m_RefIndexSlope; - - /// Precision for XML file parameters - unsigned int m_Precision; - - /// xml file path - std::string m_xmlFilePath; - - /// log file to list all previous XML versions - std::string m_xmlVersionLog; - - /// log file for previous scale factors - std::string m_RefIndexSFLog; - - /// log file for fitted CK theta resolutions - std::string m_CKThetaResLog; - - /// Cache the timestampe from the saveset name - std::string m_fileTime; - - /// DIM Summary file name - std::string m_dimSummaryFile; - - /// Publishing service - IPublishSvc* m_pPublishSvc = nullptr; - - /// String to publish for new calibrations for RICH1 - std::string m_Rich1PubString{""}; - - /// String to publish for new calibrations for RICH2 - std::string m_Rich2PubString{""}; - - /// The RICH1 scale factor value to publish - double m_Rich1RefIndex{1.0}; - - /// The RICH2 scale factor value to publish - double m_Rich2RefIndex{1.0}; - - /// Flag to turn on/off publishing to DIM - bool m_disableDIMpublish; - - // The stats for the last fits - std::unordered_map m_histStats; - - /// Flag to turn on/off the saving of summary PDF files - bool m_createPDFsummary; - - /// Current TCanvas for printing - mutable std::unique_ptr m_canvas; - - /// PDF file for each run - mutable std::map m_pdfFile; - - /// Watermark string - mutable std::string m_watermark; - - /// Are we during initialize ? - bool m_inInit{false}; - - /** Keep a count of the number of calibrations in a row, per radiator, - * for which a cached value from a previous run is used */ - std::unordered_map m_cachedCalibCount; - - /// maximum cached calibrations to allow in a row - unsigned int m_maxCachedCalibs; - - /// Max run number history - unsigned int m_runNumHistSize; - - /// Max seen run number - unsigned int m_maxSeenRunNum{0}; - - /// Run a 'test' fit with different fitter options - bool m_runTestFit{false}; - - /// Test fitter - Rich::Rec::CKResolutionFitter m_testCkFitter; -}; diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp index 874890376..9082f93e3 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -44,7 +44,7 @@ #include "Camera/ICameraTool.h" // Local -#include "OMARichRefIndex.h" +#include "RichRefIndexCalibWriter.h" // ROOT #include @@ -95,9 +95,6 @@ namespace Rich::Future::Rec::Calib { setProperty( "NBins1DHistos", 150 ).ignore(); // setProperty( "OutputLevel", MSG::VERBOSE ).ignore(); - // make owned insrance of calibration writer - m_refInCalib = std::make_unique( name + ".CondWriter", pSvcLocator ); - // Partition name const char* partition = getenv( "PARTITION" ); if ( partition ) { @@ -119,13 +116,13 @@ namespace Rich::Future::Rec::Calib { const CherenkovAngles::Vector& expTkCKThetas, // const SIMDCherenkovPhoton::Vector& photons ) const override; - /// Initalize - StatusCode initialize() override { - auto sc = Consumer::initialize(); - if ( !sc ) return sc; - m_refInCalib->configureCalib(); - return sc; - } + // /// Initalize + // StatusCode initialize() override { + // auto sc = Consumer::initialize(); + // if ( !sc ) return sc; + // m_refInCalib->configureCalib(); + // return sc; + // } /// Finalize StatusCode finalize() override { @@ -234,8 +231,9 @@ namespace Rich::Future::Rec::Calib { bool m_okToPublish{true}; private: - // Calibration utility - std::unique_ptr m_refInCalib; + /// Calibration utility + mutable ToolHandle m_refInCalib{this, "CalibWriter", + "Rich::Future::Rec::Calib::RefIndexCalibWriter/Writer"}; }; } // namespace Rich::Future::Rec::Calib @@ -459,8 +457,8 @@ void RefIndexCalib::runCalibration( const std::string& type ) const { m_processedRuns[m_runNumber] = m_nEventsThisRun; // run calibration here... - OMARichRefIndex::RadHists hists{{"Rich1Gas", h_ckResAll[Rich::Rich1Gas]}, // - {"Rich2Gas", h_ckResAll[Rich::Rich2Gas]}}; + RefIndexCalibWriter::RadHists hists{{"Rich1Gas", h_ckResAll[Rich::Rich1Gas]}, // + {"Rich2Gas", h_ckResAll[Rich::Rich2Gas]}}; m_refInCalib->runCalibration( type, hists, m_runNumber ); // reset various counters for the next run diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp new file mode 100644 index 000000000..474984ac1 --- /dev/null +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp @@ -0,0 +1,1150 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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 "RichRefIndexCalibWriter.h" + +using namespace Rich::Future::Rec::Calib; + +// Declaration of the Tool Factory +DECLARE_COMPONENT( RefIndexCalibWriter ) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +RefIndexCalibWriter::RefIndexCalibWriter( const std::string& type, // + const std::string& name, // + const IInterface* parent ) + : ToolBase( type, name, parent ) { + + declareProperty( "Rich1TaskName", m_Rich1TaskName = "Rich1/Calib" ); + declareProperty( "Rich2TaskName", m_Rich2TaskName = "Rich2/Calib" ); + declareProperty( "Rich1ScaleTaskName", m_Rich1ScaleTaskName = "Rich1RefIndex" ); + declareProperty( "Rich2ScaleTaskName", m_Rich2ScaleTaskName = "Rich2RefIndex" ); + + declareProperty( "EoRSignal", m_EoRSignal = "-EOR" ); + + declareProperty( "HistBase", m_HistBase = "RICH/RiCKResLongTight/" ); + declareProperty( "ResPlot", m_ResPlot = "ckResAll" ); + + declareProperty( "RichRads", m_rads = {"Rich1Gas", "Rich2Gas"} ); + + declareProperty( "minEntries", m_minEntries = 100000 ); + + declareProperty( "nPolFull", m_ckFitter.params().RichNPol ); + declareProperty( "MaxShiftError", m_ckFitter.params().MaxShiftError ); + declareProperty( "MaxSigmaError", m_ckFitter.params().MaxSigmaError ); + declareProperty( "RichFitMin", m_ckFitter.params().RichFitMin ); + declareProperty( "RichFitMax", m_ckFitter.params().RichFitMax ); + declareProperty( "RichFitTypes", m_ckFitter.params().RichFitTypes ); + + declareProperty( "RefIndexSlope", m_RefIndexSlope = {38.1, 65.25} ); + + declareProperty( "Precision", m_Precision = 8 ); + + declareProperty( "xmlFilePath", m_xmlFilePath = "/group/online/alignment" ); + + declareProperty( "xmlVersionLog", m_xmlVersionLog = "version.txt" ); + declareProperty( "RefIndexSFLog", m_RefIndexSFLog = "refIndexSF.txt" ); + declareProperty( "DIMSummaryFile", m_dimSummaryFile = "DIMUpdateSummary.txt" ); + declareProperty( "CKThetaResLog", m_CKThetaResLog = "CKThetaResolutions.txt" ); + + declareProperty( "DisableDIMPublish", m_disableDIMpublish = false ); + + declareProperty( "CreatePreliminaryCalibration", m_createPrelimCalib = true ); + + declareProperty( "CreatePDFSummary", m_createPDFsummary = true ); + + declareProperty( "MaxCachedCalibsInARow", m_maxCachedCalibs = 5 ); + + declareProperty( "RunNumHistSize", m_runNumHistSize = 100 ); + + declareProperty( "RunTestFit", m_runTestFit = false ); + declareProperty( "TestMaxShiftError", m_testCkFitter.params().MaxShiftError ); + declareProperty( "TestMaxSigmaError", m_testCkFitter.params().MaxSigmaError ); + declareProperty( "TestRichFitMin", m_testCkFitter.params().RichFitMin ); + declareProperty( "TestRichFitMax", m_testCkFitter.params().RichFitMax ); + declareProperty( "TestRichFitTypes", + m_testCkFitter.params().RichFitTypes = {{{"AsymNormal:Hyperbolic", "AsymNormal:FreeNPol"}, + {"AsymNormal:Hyperbolic", "AsymNormal:FreeNPol"}}} ); + + // setProperty( "OutputLevel", MSG::VERBOSE ).ignore(); + + // Partition + const char* partitionName = getenv( "PARTITION" ); + if ( partitionName ) { m_Name += std::string( partitionName ); } +} + +//============================================================================= + +//============================================================================= +// Initialization +//============================================================================= +StatusCode RefIndexCalibWriter::initialize() { + + // initialise OMALib + auto sc = ToolBase::initialize(); + if ( sc.isFailure() ) return sc; + + // Initialise the calibration writer + configureCalib(); + + return sc; +} + +void RefIndexCalibWriter::configureCalib() { + + // ROOT style for PDFs + if ( m_createPDFsummary ) { setStyle(); } + + // Sometimes its neccessary to perform some file system operations + // Do them here as then they run as Online and have full file permissions... + // Keep lines here just as future examples ... + // copyFile( "/home/jonesc/Rich1GasCKThetaResolutions.txt", + // "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); + + if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg; + + // Can we write to the configured path for condition data + if ( !createDir( m_xmlFilePath ) ) { + const auto curPath = boost::filesystem::current_path().string(); + warning() << "Cannot write to '" << m_xmlFilePath << "' -> Resetting to '" << curPath << "'" << endmsg; + m_xmlFilePath = curPath; + } + info() << "Writing conditions data to " << m_xmlFilePath << endmsg; + + // Fix file permissions ... + // fixFilePermissions(); + + // Initialise DIM state listeners + // initialiseDIMStates(); + + // Publish service + if ( !m_disableDIMpublish ) { + // Is the DIM DNS node defined ? + if ( !getenv( "DIM_DNS_NODE" ) ) { + warning() << "DIM_DNS_NODE not defined. Disabling DIM publishing" << endmsg; + m_disableDIMpublish = true; + } else { + // Initialise scale factors to last known values + m_Rich1RefIndex = getLastRefIndexSF( "Rich1Gas" ); + m_Rich2RefIndex = getLastRefIndexSF( "Rich2Gas" ); + // Initialise the publish service + auto sc = serviceLocator()->service( "LHCb::PublishSvc", m_pPublishSvc, false ); + if ( sc.isSuccess() && m_pPublishSvc ) { + m_pPublishSvc->declarePubItem( m_Rich1TaskName, m_Rich1PubString ); + m_pPublishSvc->declarePubItem( m_Rich2TaskName, m_Rich2PubString ); + m_pPublishSvc->declarePubItem( m_Rich1ScaleTaskName, m_Rich1RefIndex ); + m_pPublishSvc->declarePubItem( m_Rich2ScaleTaskName, m_Rich2RefIndex ); + info() << "PublishSvc initialized" << endmsg; + } + } + } + + // reset the cached histogram stats + m_histStats.clear(); + + // write to summary file + writeToDimSummaryFile( m_Name + " Initialized" ); + + // send a message to camera to say we are ready + cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, "Initialized" ); +} + +//============================================================================= +// run from a saveset +//============================================================================= +StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { + + StatusCode sc = StatusCode::SUCCESS; + + // // If LHC/LHCb state has changed, send a message to camera + // if ( UNLIKELY( stateChange() ) ) + // { + // setDimStatesAsRead(); + // std::ostringstream mess; + // mess << "State : LHC '" << lhcState() << "' LHCb '" << lhcbState() << "'"; + // m_CamTool->SendAndClearTS( ICameraTool::INFO, m_Name, mess.str() ); + // info() << mess.str() << endmsg; + // } + + // Are we in physics, so send updates + // const bool sendUpdates = inPhysics(); + const bool sendUpdates = true; + + // cache the previous state + static bool lastState = sendUpdates; + + // Flag for first time call + // static bool firstTime = true; + + // // has the state changed ? + // if ( UNLIKELY( firstTime || sendUpdates != lastState ) ) + // { + // std::ostringstream mess; + // mess << "Refractive index calibration now "; + // if ( sendUpdates ) { mess << "ACTIVE"; } else { mess << "INACTIVE"; } + // m_CamTool->SendAndClearTS( ICameraTool::INFO, m_Name, mess.str() ); + // info() << mess.str() << endmsg; + // } + + // return now if not in physics or was previously in physics + if ( lastState || sendUpdates ) { + + // Check whether it is the last file of one run + // either with "-EOR" in file name, or run number changed + + // Each time we do fit, the last run should be set to 0 + // so that it will be init'ed again + // Fix me!? not do fit for the run withtout "-EOR" just before stopping the calib job... + + // Extract the file name from the full path + const auto fileName = boost::filesystem::path( SaveSet ).stem().string(); + + // Extract the run number + const auto runNumber = getRunNumber( fileName ); + + // Extract the timestamp + m_fileTime = getTimeStamp( fileName ); + + // start the camera message + std::ostringstream mess1, mess2; + mess1 << "Saveset: '" << SaveSet << "'"; + mess2 << "Extracted file name: " << fileName << ", Run: " << runNumber; + if ( msgLevel( MSG::DEBUG ) ) { + debug() << mess1.str() << endmsg; + debug() << mess2.str() << endmsg; + } + cameraTool()->Append( "TEXT", mess1.str() ); + cameraTool()->Append( "TEXT", mess2.str() ); + + // check the run number is not 0 ... + if ( UNLIKELY( 0 == runNumber ) ) { + const std::string mess = "Run number in Brunel Saveset is '0' !! -> Calibration skipped"; + cameraTool()->SendAndClearTS( ICameraTool::ERROR, m_Name, mess ); + error() << mess << endmsg; + } + // Check run number is not too old... + else if ( UNLIKELY( m_maxSeenRunNum - runNumber > m_runNumHistSize ) ) { + std::ostringstream mess; + mess << "Run " << runNumber << " too old ( Newest seen is " << m_maxSeenRunNum << " ). Calibration Aborted."; + cameraTool()->SendAndClearTS( ICameraTool::ERROR, m_Name, mess.str() ); + error() << mess.str() << endmsg; + } else { + if ( fileName.find( m_EoRSignal ) != std::string::npos ) { + m_mergedRun = RunAndSaveSet( runNumber, SaveSet ); + m_lastRun = RunAndSaveSet( 0, "" ); + runCalibration( "Final EOR", m_mergedRun, true ); + // reset the cached histogram stats + m_histStats.clear(); + } // "-EOR" inside the file name + else { + // if it is the first time to read a file without "-EOR" + // or still the same run + if ( 0 == m_lastRun.run || runNumber == m_lastRun.run ) { + // const bool firstSetForRun = ( 0 == m_lastRun.first ); + m_lastRun = RunAndSaveSet( runNumber, SaveSet ); + // runCalibration( "Periodic", m_lastRun, m_createPrelimCalib && firstSetForRun ); + runCalibration( "Periodic", m_lastRun, m_createPrelimCalib ); + } // wait for new file + else if ( runNumber != m_lastRun.run ) // new Run, use previous file + { + // is last run recent enough to do a calibration for ? + // Because runNumber and m_lastRun.run are unsigned, using abs would just overload it in most recent + // compilers. + const unsigned runDiff = std::max( runNumber, m_lastRun.run ) - std::min( runNumber, m_lastRun.run ); + if ( runDiff < m_runNumHistSize ) { + std::ostringstream mess; + mess << "Refractive index calibration for run " << m_lastRun.run + << " triggered by non-EOR saveset. Check Online Brunel EOR creation..."; + cameraTool()->Append( "TEXT", mess.str() ); + warning() << mess.str() << endmsg; + // Run calibration for the last run + runCalibration( "Final", m_lastRun, true, ICameraTool::WARNING ); + } else { + // warn about an unusual run number + std::ostringstream mess; + mess << "Refractive index calibration for run " << m_lastRun.run << " skipped as run is too old ...."; + cameraTool()->Append( "TEXT", mess.str() ); + warning() << mess.str() << endmsg; + } + // reset the cached histogram stats + m_histStats.clear(); + // Run a first calibration for this run + const auto thisRun = RunAndSaveSet( runNumber, SaveSet ); + runCalibration( "First", thisRun, m_createPrelimCalib ); + // reset for the next call + m_mergedRun = m_lastRun; + m_lastRun = RunAndSaveSet( 0, "" ); + } + } + } + } + + // unset the first time flag + // firstTime = false; + + // update the cached state + lastState = sendUpdates; + + return sc; +} + +//============================================================================= +// Run Calibration from histo pointers +//============================================================================= +void RefIndexCalibWriter::runCalibration( const std::string& type, // + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { + + info() << "Starting n-1 calibration for run " << runNumber << " ..." << endmsg; + + // Save the run number + m_runNumber = runNumber; + + if ( m_createPDFsummary ) { printCanvas( "[" ); } + bool keepPDF = false; + + // Is this a final calibration ? + const bool isFinal = ( type == "Final EOR" || type == "Final" ); + + // Loop over radiators + for ( const auto& rad : m_rads ) { + + // the histogram name to fit + cameraTool()->Append( "TEXT", "Fit for " + rad ); + + // try and load the histogram + auto radHist = histos[rad]; + if ( radHist ) { + + // check the histogram stats. + const auto histStats = radHist->GetEntries(); + const bool betterHistStats = histStats > m_histStats[rad]; + + // Make sure axis titles are set.. + if ( radHist->GetXaxis() ) { radHist->GetXaxis()->SetTitle( "delta(Cherenkov Theta) / rad" ); } + if ( radHist->GetYaxis() ) { radHist->GetYaxis()->SetTitle( "Entries" ); } + + // send the histogram to camera + sendToCamera( radHist, runNumber ); + + // Draw to canvas + draw( radHist ); + + // save fit result; + FitResult savedFitResult; + + double scale = 1.0; + if ( checkCKThetaStats( radHist ) ) { + // Flag PDF should be kept, as at least one fit had enough stats. + keepPDF = true; + // run the fit + const auto fitresult = fitCKThetaHistogram( radHist, rad ); + if ( fitresult.fitOK ) { + savedFitResult = fitresult; + m_cachedCalibCount[rad] = 0; // Normal calibration, so reset count to 0 + scale = nScaleFromShift( fitresult.ckShift, rad ); + std::ostringstream mess; + mess << rad << " n-1 shift = " << fitresult.ckShift << " scale = " << scale; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + level = ICameraTool::WARNING; + ++m_cachedCalibCount[rad]; // Count cached calibrations + scale = getLastRefIndexSF( rad ); + std::ostringstream mess; + mess << "Fit FAILED. Using scale from previous run " << scale; + } + if ( publishCalib || betterHistStats ) { + if ( !updateRefIndexSF( runNumber, rad, scale ) ) { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to update " << rad << " ref index scale"; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + // update the stats for this histogram + m_histStats[rad] = histStats; + } + } + } else // not enough statistics, take the one from previous run + { + level = ICameraTool::WARNING; + ++m_cachedCalibCount[rad]; // Count cached calibrations + scale = getLastRefIndexSF( rad ); + std::ostringstream mess; + mess << "Not enough statistics for " << rad << " -> Using scale from previous run " << scale; + cameraTool()->Append( "TEXT", mess.str() ); + debug() << mess.str() << endmsg; + } + + // if a final OK calibration, write to CK resolution summary + if ( savedFitResult.fitOK && isFinal ) { writeCKThetaLog( rad, savedFitResult, runNumber ); } + + // publish results. Only if histogram did not have 0 entries + if ( 0 != radHist->GetEntries() && ( publishCalib || betterHistStats ) ) { + if ( m_cachedCalibCount[rad] > m_maxCachedCalibs ) { + level = ICameraTool::WARNING; + std::ostringstream mess; + mess << "Too many (" << m_cachedCalibCount[rad] << ") cached calibrations in a row."; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + if ( !xmlWriter( type, runNumber, scale, rad ) ) { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to write xml file for " << rad; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + std::ostringstream mess; + mess << "Successfully wrote and published xml file for " << rad; + cameraTool()->Append( "TEXT", mess.str() ); + } + } else { + const std::string mess = "XML Writing is DISABLED for this saveset"; + info() << mess << endmsg; + cameraTool()->Append( "TEXT", mess ); + } + + if ( msgLevel( MSG::DEBUG ) ) debug() << "Scale factor for " << rad << ": " << scale << endmsg; + + } else { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to load histogram for '" << rad << "'"; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + + } // Loop over radiators + + if ( m_createPDFsummary ) { + // close the PDF + printCanvas( "]" ); + // if not enough stats, remove the file + if ( !keepPDF ) { + const std::string mess = "Not enough statistics for calibration to run. Will remove PDF"; + info() << mess << endmsg; + cameraTool()->Append( "TEXT", mess ); + printCanvas( "DELETE" ); + } + } + + // send camera message and gaudi message + std::ostringstream mess; + mess << type << " Refractive index calibration for Run " << runNumber; + if ( ICameraTool::ERROR != level ) { + mess << " was SUCCESSFUL"; + } else { + mess << " FAILED"; + } + cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); + if ( ICameraTool::ERROR == level ) { + error() << mess.str() << endmsg; + } else if ( ICameraTool::WARNING == level ) { + info() << mess.str() << endmsg; + } else { + info() << mess.str() << endmsg; + } +} + +//============================================================================= +// Run the calibration from a saveset +//============================================================================= +void RefIndexCalibWriter::runCalibration( const std::string& type, // + const RunAndSaveSet& data, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { + + // Save the run number + m_runNumber = data.run; + + // Open Saveset + std::unique_ptr hfile( TFile::Open( data.saveset.c_str(), "READ" ) ); + if ( hfile && !hfile->IsZombie() ) { + + // hist for each radiator + RadHists rHists; + + // load the histos + for ( const auto& rad : m_rads ) { + + // the histogram name to fit + const std::string radHistName = m_HistBase + rad + "/" + m_ResPlot; + cameraTool()->Append( "TEXT", "Fit for " + radHistName ); + + // try and load the histogram + auto radHist = (TH1D*)hfile->Get( radHistName.c_str() ); + // if OK save. + if ( radHist ) { + rHists[rad] = radHist; + } else { + level = ICameraTool::ERROR; + std::ostringstream mess; + mess << "Failed to load histogram '" << radHistName << "'"; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } + + // run calib + runCalibration( type, rHists, data.run, publishCalib, level ); + + // close the saveset file + hfile->Close(); + + } else { + level = ICameraTool::ERROR; + std::ostringstream info, mess; + info << "Failed to open '" << data.saveset << "'"; + warning() << info.str() << endmsg; + cameraTool()->Append( "TEXT", info.str() ); + mess << type << " Refractive index calibration for Run " << data.run; + cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); + } +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode RefIndexCalibWriter::finalize() { + // clean up state listeners + // finaliseDIMStates(); + // reset the cached histogram stats + m_histStats.clear(); + // send a message to camera + cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, "Finalized" ); + // write to summary file + writeToDimSummaryFile( m_Name + " Finalized" ); + return ToolBase::finalize(); // must be called after all other actions +} + +//============================================================================= +// Fitting histogram +//============================================================================= +RefIndexCalibWriter::FitResult // +RefIndexCalibWriter::fitCKThetaHistogram( TH1* hist, // + const std::string& rad, // + const bool testFit ) const { + // Do the fit + const auto irad = ( "Rich1Gas" == rad ? Rich::Rich1Gas : Rich::Rich2Gas ); + auto fitRes = ( !testFit ? m_ckFitter.fit( *hist, irad ) : m_testCkFitter.fit( *hist, irad ) ); + + // shortcuts to the results + const auto& fitOK = fitRes.fitOK; + auto& bestFitF = fitRes.overallFitFunc; + auto& backFunc = fitRes.bkgFitFunc; + + // make the pads for the plots + static unsigned long long iI{0}; + const auto iS = std::to_string(iI++); + auto upPad = std::make_unique( ("U"+iS).c_str(), ("U"+iS).c_str(), 0., 0.25, 1., 1. ); + auto dnPad = std::make_unique( ("L"+iS).c_str(), ("L"+iS).c_str(), 0., 0., 1., 0.25 ); + // upPad->SetTopMargin(0.05); + upPad->SetBottomMargin( 0.1 ); + dnPad->SetTopMargin( 0.05 ); + dnPad->SetBottomMargin( 0.22 ); + canvas()->cd(); + upPad->Draw(); + dnPad->Draw(); + + // Add fitted functions to camera message and PDFs + if ( fitOK ) { + + // Print fitted parameters + for ( int i = 0; i < bestFitF.GetNpar(); ++i ) { + const auto param = bestFitF.GetParameter( i ); + const auto err = bestFitF.GetParError( i ); + const auto name = bestFitF.GetParName( i ); + std::ostringstream m; + m << " " << name << " = " << param << " +- " << err; + info() << m.str() << endmsg; + if ( !testFit ) { cameraTool()->Append( "TEXT", m.str() ); } + } + + // Full fit + if ( !testFit ) { cameraTool()->Append( &bestFitF ); } + + // Draw full fit + canvas()->cd(); + upPad->cd(); + bestFitF.SetLineColor( kBlue + 2 ); + hist->Draw(); + bestFitF.Draw( "SAME" ); + + // Add scale factor + const auto scale = nScaleFromShift( bestFitF.GetParameter( 1 ), rad ); + TText text; + text.SetNDC(); + text.SetTextSize( 0.025 ); + text.DrawText( 0.14, 0.840, ( "Run " + std::to_string( m_runNumber ) ).c_str() ); + text.DrawText( 0.14, 0.814, ( "SF " + std::to_string( scale ) ).c_str() ); + + // background only + if ( !testFit ) { cameraTool()->Append( &backFunc ); } + + // Draw background fit + backFunc.SetLineColor( kRed + 3 ); + backFunc.Draw( "SAME" ); + + // Draw the pull + auto pull = makePullPlot( *hist, bestFitF ); + canvas()->cd(); + dnPad->cd(); + pull->Draw(); + + // print canvas to file + printCanvas(); + + } else { + warning() << rad << " fit FAILED" << endmsg; + // print canvas to file + printCanvas(); + } + + // Final sanity check on the fit results + // limits on fit sigma and mean, to detect complete failures such as when there + // is no Cherenkov signal at all + if ( !testFit && !fitOK ) { cameraTool()->Append( "TEXT", "Fit FAILED final sanity checks" ); } + + // Run a test fit, with different fitter options ? + if ( !testFit && m_runTestFit ) { fitCKThetaHistogram( hist, rad, true ); } + + // return final fit parameter for shift + return fitRes; +} + +//============================================================================= +// Make a pull plot from a histogram and a given function +//============================================================================= +std::unique_ptr RefIndexCalibWriter::makePullPlot( TH1& hist, TF1& func ) const { + // make the new plot with the same bins and range + std::ostringstream id; + static unsigned long long iI{0}; + id << hist.GetName() << "Pull" << iI++; + auto h = std::make_unique( id.str().c_str(), + "", // no title + hist.GetNbinsX(), hist.GetXaxis()->GetXmin(), hist.GetXaxis()->GetXmax() ); + // h->GetXaxis()->SetTitle( hist.GetXaxis()->GetTitle() ); + h->GetXaxis()->SetTitle( "" ); + h->GetYaxis()->SetTitle( "Pull" ); + h->GetXaxis()->SetTitleSize( 0.08 ); + h->GetYaxis()->SetTitleSize( 0.08 ); + h->GetXaxis()->SetLabelSize( 0.06 ); + h->GetYaxis()->SetLabelSize( 0.06 ); + h->GetYaxis()->SetTitleOffset( 0.3 ); + h->SetStats( false ); + + // set the bins + for ( int i = 0; i < hist.GetNbinsX(); ++i ) { + // bin center + const auto binCen = hist.GetBinCenter( i + 1 ); + // only make pull entries for points in function range + if ( binCen < func.GetXmax() && binCen > func.GetXmin() ) { + // raw bin content + const auto rawCont = hist.GetBinContent( i + 1 ); + // bin error + const auto rawErr = fabs( hist.GetBinError( i + 1 ) ); + // function value + const auto funcVal = func.Eval( binCen ); + // pull + const auto pull = ( rawErr > 0 ? ( rawCont - funcVal ) / rawErr : 0.0 ); + // set the bin content and error in the pull plots + h->SetBinContent( i + 1, pull ); + h->SetBinError( i + 1, 1.0 ); + } + } + + // return + return h; +} + +//============================================================================= + +double RefIndexCalibWriter::getLastRefIndexSF( const std::string& rad ) { + std::string subDet; + if ( "Rich1Gas" == rad ) { + subDet = m_Rich1TaskName; + } else if ( "Rich2Gas" == rad ) { + subDet = m_Rich2TaskName; + } + + const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); + const boost::filesystem::path filename( m_RefIndexSFLog ); + const boost::filesystem::path full_path = dir / filename; + + unsigned int run = 0; + double scale = 1.0; + + if ( !boost::filesystem::exists( full_path ) ) // meet this for the first run... + { + try { + const auto ok = createDir( dir ); + std::ofstream logging( full_path.string().c_str() ); + if ( ok && logging.is_open() ) { + logging << run << " " << std::setprecision( m_Precision ) << scale << "\n"; + logging.close(); + } else { + std::ostringstream mess; + mess << "Failed to open " << full_path; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + // Exception( mess.str() ); + } + } catch ( const boost::filesystem::filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to create file " << full_path << " " << expt.what(); + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + return scale; + } else { + std::fstream file( full_path.string().c_str(), std::ios::in ); + if ( file.is_open() ) { + file >> run >> scale; + file.close(); + std::ostringstream mess; + mess << "Read from file scale factor " << scale << " for Run " << run; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + std::ostringstream mess; + mess << "Failed to open " << full_path; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } + + info() << "Read " << rad << " scale factor (" << scale << ") from previous run cache" << endmsg; + + return scale; +} + +//============================================================================= + +bool RefIndexCalibWriter::updateRefIndexSF( const unsigned int runNumber, // + const std::string& rad, // + const double scale ) { + bool OK = true; + + const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : // + "Rich2Gas" == rad ? m_Rich2TaskName : // + "UNKNOWN" ); + + const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); + const boost::filesystem::path filename( m_RefIndexSFLog ); + const boost::filesystem::path full_path = dir / filename; + + try { + + const auto ok = createDir( dir ); + + std::ofstream ofile( full_path.string().c_str() ); + if ( ok && ofile.is_open() ) { + ofile << runNumber << " " << std::setprecision( m_Precision ) << scale << "\n"; + ofile.close(); + } else { + std::ostringstream mess; + mess << "Failed to open " << full_path; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + OK = false; + } + + } catch ( const boost::filesystem::filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to open file " << full_path << " " << expt.what(); + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + OK = false; + } + + return OK; +} + +//============================================================================= + +bool RefIndexCalibWriter::xmlWriter( const std::string& type, // + const unsigned int runNumber, // + const double scale, // + const std::string& rad ) { + // Get version + const auto version = setVersion( runNumber, rad ); + bool OK = version.first; + if ( !OK ) { return OK; } + const auto versionS = std::to_string( version.second ); + + const bool isR1 = ( "Rich1Gas" == rad ); + const bool isR2 = ( "Rich2Gas" == rad ); + const bool isFinal = ( type == "Final EOR" || type == "Final" ); + bool scaleIsDifferent = false; + + std::string subDet; + if ( isR1 ) { + subDet = m_Rich1TaskName; + m_Rich1PubString = std::to_string( runNumber ) + " v" + versionS; + scaleIsDifferent = m_Rich1RefIndex != scale; + m_Rich1RefIndex = scale; + } else if ( isR2 ) { + subDet = m_Rich2TaskName; + m_Rich2PubString = std::to_string( runNumber ) + " v" + versionS; + scaleIsDifferent = m_Rich2RefIndex != scale; + m_Rich2RefIndex = scale; + } + + const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); + const boost::filesystem::path file( "v" + versionS + ".xml" ); + const boost::filesystem::path full_path = dir / file; + + if ( msgLevel( MSG::DEBUG ) ) debug() << "Writing to " << full_path << endmsg; + + if ( !boost::filesystem::exists( full_path ) ) { + + try { + const auto ok = createDir( dir ); + + std::ofstream logging( full_path.string().c_str() ); + if ( ok && logging.is_open() ) { + logging << " \n"; + logging << "" << std::setprecision( m_Precision ) << scale + << " \n"; + logging << " \n"; + logging << " \n"; + logging.close(); + std::ostringstream mess; + mess << "Successfully wrote " << rad << " Scale factor to " << full_path; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + std::ostringstream mess; + mess << "Failed to open " << full_path; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + OK = false; + } + } catch ( const boost::filesystem::filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to open file " << full_path << " " << expt.what(); + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + OK = false; + } + + // Publish to DIM + if ( OK ) { + if ( m_pPublishSvc ) { + if ( isR1 ) { + info() << "Publishing to DIM : " << m_Rich1TaskName << " = '" << m_Rich1PubString << "'" << endmsg; + m_pPublishSvc->updateItem( m_Rich1TaskName ); + if ( isFinal && scaleIsDifferent ) { + info() << "Publishing to DIM : " << m_Rich1ScaleTaskName << " = " << m_Rich1RefIndex << endmsg; + m_pPublishSvc->updateItem( m_Rich1ScaleTaskName ); + } + } else if ( isR2 ) { + info() << "Publishing to DIM : " << m_Rich2TaskName << " = '" << m_Rich2PubString << "'" << endmsg; + m_pPublishSvc->updateItem( m_Rich2TaskName ); + if ( isFinal && scaleIsDifferent ) { + info() << "Publishing to DIM : " << m_Rich2ScaleTaskName << " = " << m_Rich2RefIndex << endmsg; + m_pPublishSvc->updateItem( m_Rich2ScaleTaskName ); + } + } + } + std::ostringstream mess; + mess << rad << " XML conditions published for Run " << runNumber; + cameraTool()->Append( "TEXT", mess.str() ); + // update DIM summary file + std::ostringstream dimmess; + dimmess << "Run " << runNumber << " |"; + if ( isR1 ) { dimmess << " " << m_Rich1TaskName << " '" << m_Rich1PubString << "'"; } + if ( isR2 ) { dimmess << " " << m_Rich2TaskName << " '" << m_Rich2PubString << "'"; } + OK = writeToDimSummaryFile( dimmess.str() ); + } else { + std::ostringstream mess; + mess << rad << " XML conditions NOT published for Run " << runNumber; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + + } else // file already there + { + std::ostringstream mess; + mess << "File " << full_path << " already there, something must be wrong"; + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + OK = false; + } + + return OK; +} +//============================================================================= + +bool RefIndexCalibWriter::writeToDimSummaryFile( const std::string& mess ) const { + bool OK = true; + // Open the summary file in append mode + std::ofstream file( dimSummaryFile().c_str(), std::ios_base::app ); + if ( file.is_open() ) { + file << watermark() << " | " << mess << std::endl; + file.close(); + // setPerms( dimSummaryFile() ); + } else { + std::ostringstream m; + m << "Problem writing DIM summary file " << dimSummaryFile(); + warning() << m.str() << endmsg; + cameraTool()->Append( "TEXT", m.str() ); + OK = false; + } + return OK; +} + +//============================================================================= + +bool RefIndexCalibWriter::writeCKThetaLog( const std::string& rad, // + const FitResult& fitResult, // + const unsigned int runNumber ) const { + // Path to the summary file + const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" ); + const boost::filesystem::path filename( rad + m_CKThetaResLog ); + const boost::filesystem::path full_path = dir / filename; + bool ok = createDir( dir ); + + // open the file in append mode + std::ofstream file( full_path.string().c_str(), std::ios_base::app ); + if ( ok && file.is_open() ) { + // write out the result for this run + file << runNumber << " " << m_fileTime << " " << fitResult.ckResolution << " " << fitResult.ckResolutionErr + << std::endl; + // close the file + file.close(); + } else { + std::ostringstream m; + m << "Problem writing CK resolution summary file " << full_path; + warning() << m.str() << endmsg; + cameraTool()->Append( "TEXT", m.str() ); + ok = false; + } + + return ok; +} + +//============================================================================= + +std::pair // +RefIndexCalibWriter::setVersion( const unsigned int runNumber, // + const std::string& rad ) { + bool OK = true; + + unsigned long long version( 0 ); + + // Test the root directory is accessible + if ( !createDir( m_xmlFilePath ) ) { + OK = false; + std::ostringstream mess; + mess << "Cannot access alignment directory " << m_xmlFilePath; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } else { + + std::string subDet; + if ( "Rich1Gas" == rad ) { + subDet = m_Rich1TaskName; + } else if ( "Rich2Gas" == rad ) { + subDet = m_Rich2TaskName; + } + + const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ); + const boost::filesystem::path filename( m_xmlVersionLog ); + const boost::filesystem::path full_path = dir / filename; + + unsigned int run( 0 ); + + if ( msgLevel( MSG::DEBUG ) ) debug() << "Version file: " << full_path.string() << endmsg; + + if ( !boost::filesystem::exists( full_path ) ) // the first time + { + try { + version = 0; + const auto ok = createDir( dir ); + std::ofstream logging( full_path.string().c_str() ); + if ( ok && logging.is_open() ) { + logging << runNumber << " " << version << "\n"; + logging.close(); + } else { + OK = false; + std::ostringstream mess; + mess << "Failed to open " << full_path; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } catch ( const boost::filesystem::filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to open file " << full_path << " " << expt.what(); + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + OK = false; + } + return std::make_pair( OK, version ); + } else { + std::fstream file( full_path.string().c_str(), std::ios::in | std::ios::out ); + if ( file.is_open() ) { + std::istringstream lastLine( getLastLine( file ) ); + + lastLine >> run >> version; + + // increase version number + ++version; + + file << runNumber << " " << version << "\n"; + file.close(); + } else { + OK = false; + std::ostringstream mess; + mess << "Failed to open " << full_path; + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } + + // setPerms( full_path ); + + std::ostringstream mess; + mess << "Setting version: " << version << " for run: " << runNumber; + if ( msgLevel( MSG::DEBUG ) ) debug() << mess.str() << endmsg; + // cameraTool()->Append("TEXT",mess.str()); + } + + return std::make_pair( OK, version ); +} + +//============================================================================= + +// Get the last line from an input file stream +std::string RefIndexCalibWriter::getLastLine( std::fstream& in ) { + std::fstream::pos_type pos = in.tellg(); + std::fstream::pos_type lastPos; + while ( in >> std::ws && ignoreline( in, lastPos ) ) { pos = lastPos; } + in.clear(); + in.seekg( pos ); + std::string line; + std::getline( in, line ); + return line; +} + +//============================================================================= + +void RefIndexCalibWriter::printCanvas( const std::string& tag ) const { + + const std::string imageType = "pdf"; + + // get the PDF file name for this run + auto& pdfFile = m_pdfFile[m_runNumber]; + + // Opening file ? + if ( "[" == tag ) { + + try { + + // If file name is not empty (so repeat fit for a run), delete file + if ( !pdfFile.empty() ) { removeFile( pdfFile ); } + + // Directory to save summaries to + const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" + getDateString() + "/RefIndex/" ); + + // Create directory if it does not exist + if ( !boost::filesystem::exists( dir ) ) { boost::filesystem::create_directories( dir ); } + + // File name + const boost::filesystem::path filename( "Run-" + std::to_string( m_runNumber ) + "." + imageType ); + const boost::filesystem::path full_path = dir / filename; + + // If PDF exists, remove before remaking + removeFile( full_path ); + + // cache image file name for this run + pdfFile = full_path.string(); + + // Make a new canvas + deleteCanvas(); + + // Open new PDF + canvas()->Print( ( pdfFile + tag ).c_str(), imageType.c_str() ); + + // set watermark string + m_watermark = watermark(); + info() << "Watermark = " << m_watermark << endmsg; + + } catch ( const boost::filesystem::filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to create file " << pdfFile << " " << expt.what(); + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + deleteCanvas(); + pdfFile = ""; + } + + } + // Closing the file ? + else if ( "]" == tag ) { + + // Close the file + canvas()->Print( ( pdfFile + tag ).c_str(), imageType.c_str() ); + + // Set group write permissions + // setPerms( pdfFile ); + + // delete canvas + deleteCanvas(); + + // send a message + std::ostringstream mess; + mess << "Created " << pdfFile; + info() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + + // limit the PDF file name map to N entries + while ( m_pdfFile.size() > m_runNumHistSize + 10 ) { m_pdfFile.erase( m_pdfFile.begin() ); } + + } else if ( "" == tag ) { + + // Add time/date watermark + canvas()->cd(); + TText text; + text.SetNDC(); + text.SetTextSize( 0.012 ); + text.SetTextColor( 13 ); + text.DrawText( 0.01, 0.01, m_watermark.c_str() ); + + // Just print + canvas()->Print( pdfFile.c_str(), imageType.c_str() ); + + } else if ( "DELETE" == tag && !pdfFile.empty() ) { + + try { + removeFile( pdfFile ); + } catch ( const boost::filesystem::filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to delete file " << pdfFile << " " << expt.what(); + error() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } +} + +//============================================================================= + +void RefIndexCalibWriter::fixFilePermissions() const { + using namespace boost::filesystem; + const path dir( m_xmlFilePath + "/RichCalibSummaries" ); + recursive_directory_iterator end_itr; + for ( recursive_directory_iterator i( dir ); i != end_itr; ++i ) { setPerms( i->path() ); } +} + +//============================================================================= + diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h new file mode 100644 index 000000000..b74cff971 --- /dev/null +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h @@ -0,0 +1,498 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +#pragma once + +// Gaudi +#include "GaudiKernel/ParsersFactory.h" +#include "GaudiKernel/StdArrayAsProperty.h" + +// base class +#include "RichFutureRecBase/RichRecToolBase.h" + +// Publish to DIM +#include "GaudiKernel/IPublishSvc.h" +#include "GaudiKernel/ServiceLocatorHelper.h" + +// ROOT includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Boost +#include "boost/algorithm/string.hpp" +#include + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// CAMERA +#include "Camera/ICameraTool.h" + +// Dim Objects +#include "RichMonitoringTools/RichDimClasses.h" + +// local +#include "rootstyle.h" + +// CK resolution fitter +#include "RichRecUtils/RichCKResolutionFitter.h" + +/// The interface ID +static const InterfaceID IID_RichRefIndexCalibWriter( "RichRefIndexCalibWriter", 1, 0 ); + +namespace Rich::Future::Rec::Calib { + + /** @class PIDPlots RichPIDPlots.h + * + * Tool which creates standardised PID plots for + * monitoring and calibration purposes. + * + * @author Chris Jones Christopher.Rob.Jones@cern.ch + * @date 2008-04-14 + */ + + class RefIndexCalibWriter final : public ToolBase, virtual public IAlgTool { + + public: + /// Return the interface ID + static const InterfaceID& interfaceID() { return IID_RichRefIndexCalibWriter; } + + public: + /// Standard constructor + RefIndexCalibWriter( const std::string& type, const std::string& name, const IInterface* parent ); + + /// Initialise + StatusCode initialize() override; + + // Finalize + StatusCode finalize() override; + + public: + // 'interface' + + /// Run calibration from a saveset + StatusCode runCalibration( const std::string& SaveSet ); + + /// Type for radiator resolution histograms + using RadHists = std::map; + + //============================================================================= + /// Run Calibration from histo pointers + //============================================================================= + void runCalibration( const std::string& type, // + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib = true, // + ICameraTool::MessageLevel level = ICameraTool::INFO ); + + private: + // implementation details + + void configureCalib(); ///< Configure the calibration output + + /// Fit Result object + using FitResult = Rich::Rec::CKResolutionFitter::FitResult; + + /// Simple class to store a run number and saveset path + class RunAndSaveSet { + public: + RunAndSaveSet() = default; + RunAndSaveSet( const unsigned int r, const std::string& s ) : run( r ), saveset( s ) {} + + public: + unsigned int run{0}; + std::string saveset{""}; + }; + + //============================================================================= + /// Run Calibration from saveset + //============================================================================= + void runCalibration( const std::string& type, // + const RunAndSaveSet& data, // + const bool publishCalib = true, // + ICameraTool::MessageLevel level = ICameraTool::INFO ); + + //============================================================================= + /// Load camera tool on demand + //============================================================================= + inline ICameraTool* cameraTool() const { + if ( !m_CamTool ) { m_CamTool = tool( "CameraTool" ); } + return m_CamTool; + } + + //============================================================================= + /// Fit the histogram + //============================================================================= + FitResult fitCKThetaHistogram( TH1* hist, // + const std::string& rad, // + const bool testFit = false ) const; + + //============================================================================= + // Make a pull plot from a histogram and a given function + //============================================================================= + std::unique_ptr makePullPlot( TH1& hist, TF1& func ) const; + + //============================================================================= + /// Function to get run number from fileName, rely on the name convention here: + /// https://lbtwiki.cern.ch/bin/view/Online/MonitoringExpertGuide#Savesets + //============================================================================= + inline unsigned int getRunNumber( const std::string& fileName ) { + const auto firstName = fileName.substr( fileName.find_first_of( "-" ) + 1 ); + const auto runString = firstName.substr( 0, firstName.find_first_of( "-" ) ); + const unsigned int runN = atoi( runString.c_str() ); + if ( runN > m_maxSeenRunNum ) { + m_maxSeenRunNum = runN; + info() << "Set latest seen run number to " << runN << endmsg; + } + return runN; + } + + //============================================================================= + // Function to get time stamp from the file name + //============================================================================= + inline std::string getTimeStamp( const std::string& fileName ) { + const std::string tmp1 = fileName.substr( fileName.find_first_of( "-" ) + 1 ); + std::string tmp2 = tmp1.substr( tmp1.find_first_of( "-" ) + 1 ); + boost::erase_all( tmp2, "-EOR" ); + return tmp2; + } + + //============================================================================= + /// Function to check whether enough entries + //============================================================================= + inline bool checkCKThetaStats( const TH1* hist ) { return hist && hist->GetEntries() >= m_minEntries; } + + //============================================================================= + /// Function to calculate scale factor + //============================================================================= + inline double nScaleFromShift( const double& shift, // + const std::string& rad ) const { + // the slope parameter for the given RICH + const double slope = ( "Rich1Gas" == rad ? m_RefIndexSlope[0] : m_RefIndexSlope[1] ); + // Calculate and return the scale factor + return 1.0 + ( shift * slope ); + } + + //============================================================================= + // Function to get ref index scale from previous run + //============================================================================= + double getLastRefIndexSF( const std::string& rad ); + + //============================================================================= + /// Function to update ref index scale + //============================================================================= + bool updateRefIndexSF( const unsigned int runNumber, // + const std::string& rad, // + const double scale ); + + //============================================================================= + /// Function to write out xml file + //============================================================================= + bool xmlWriter( const std::string& type, // + const unsigned int runNumber, // + const double scale, // + const std::string& rad ); + + //============================================================================= + /// Functions to get the last line + //============================================================================= + inline std::istream& ignoreline( std::fstream& in, // + std::fstream::pos_type& pos ) { + pos = in.tellg(); + return in.ignore( std::numeric_limits::max(), '\n' ); + } + + /// Get the last line from an input file stream + std::string getLastLine( std::fstream& in ); + + //============================================================================= + /// Function to set version number + //============================================================================= + std::pair setVersion( const unsigned int runNumber, // + const std::string& rad ); + + //============================================================================= + /// Append a histogram to a camera message with run number added to title + //============================================================================= + template + inline void sendToCamera( HIST* hist, const unsigned int runNumber ) const { + // save title + const std::string title = hist->GetTitle(); + // update title with run number added + std::ostringstream newtitle; + newtitle << title << " | Run " << runNumber; + hist->SetTitle( newtitle.str().c_str() ); + // send to camera + cameraTool()->Append( hist, "E,P" ); + // reset title + hist->SetTitle( title.c_str() ); + } + + /// Draw a histogram + template + inline void draw( HIST* hist, const std::string& opt = "" ) const { + hist->Draw( opt.c_str() ); + } + + /// Print Canvas + void printCanvas( const std::string& tag = "" ) const; + + /// Get year/month/day as a string + inline std::string getDateString() const { + // Get year, month, day + const std::time_t t = std::time( nullptr ); + char mbstr[100]; + return ( std::strftime( mbstr, sizeof( mbstr ), "%Y/%m/%d", std::localtime( &t ) ) ? std::string( mbstr ) : "" ); + } + + /// Get watermark string + inline std::string watermark() const { + const std::time_t t = std::time( nullptr ); + char mbstr[100]; + return ( std::strftime( mbstr, sizeof( mbstr ), "%c", std::localtime( &t ) ) ? std::string( mbstr ) : "" ); + } + + /// Fix file permissions + void fixFilePermissions() const; + + /// Set file permissions on a file + template + inline void setPerms( const FILE& file ) const { + if ( boost::filesystem::exists( file ) ) { + debug() << "Setting permissions for " << file << endmsg; + using namespace boost::filesystem; + try { + permissions( file, add_perms | owner_write | group_write ); + } catch ( const filesystem_error& expt ) { + std::ostringstream mess; + mess << "Failed to set permissions for " << file << " " << expt.what(); + warning() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + } + } + + /// Remove a file + template + inline void removeFile( const FILE& file ) const { + if ( boost::filesystem::exists( file ) ) { + std::ostringstream mess; + mess << "Removing " << file; + info() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + boost::filesystem::remove( file ); + } + } + + /// Copy a file + template + inline void copyFile( const FILEFROM& from, const FILETO& to ) const { + if ( boost::filesystem::exists( from ) ) { + std::ostringstream mess; + mess << "Copying " << from << " ->" << to; + info() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + removeFile( to ); + boost::filesystem::copy_file( from, to ); + } + } + + /// Create directory + template + inline bool createDir( const DIR& dir ) const { + bool OK = true; + if ( !boost::filesystem::exists( dir ) ) { + std::ostringstream mess; + try { + boost::filesystem::create_directories( dir ); + mess << "Created " << dir; + } catch ( const boost::filesystem::filesystem_error& expt ) { + mess << "FAILED to create " << dir << " " << expt.what(); + OK = false; + } + info() << mess.str() << endmsg; + cameraTool()->Append( "TEXT", mess.str() ); + } + return OK; + } + + /// Access and create on demand the current TCanvas + inline TCanvas* canvas() const { + if ( !m_canvas.get() ) { m_canvas = std::make_unique( "RefIndCanvas", "RefIndCanvas", 1200, 1200 ); } + return m_canvas.get(); + } + + /// Delete the current TCanvas + inline void deleteCanvas() const { + // if ( m_canvas.get() ) { m_canvas->Delete(); } + // m_canvas.reset( nullptr ); + } + + /// Get the path to write summaries to + inline std::string summaryPath() const { + const std::string dir( m_xmlFilePath + "/RichCalibSummaries/" + getDateString() + "/RefIndex/" ); + createDir( dir ); + return dir; + } + + /// DIM summary file location + inline std::string dimSummaryFile() const { return summaryPath() + m_dimSummaryFile; } + + /// Write a message to the DIM summary file + bool writeToDimSummaryFile( const std::string& mess ) const; + + /// Write to the CK theta resolution summary log + bool writeCKThetaLog( const std::string& rad, // + const FitResult& fitResult, // + const unsigned int runNumber ) const; + + private: + /// CAMERA reporting tool + mutable ICameraTool* m_CamTool = nullptr; + + /// Algorithm name + partition + std::string m_Name; + + /// RICH1 task name + std::string m_Rich1TaskName; + + /// RICH2 task name + std::string m_Rich2TaskName; + + /// RICH1 name for n-1 scale factor DIM service + std::string m_Rich1ScaleTaskName; + + /// RICH2 name for n-1 scale factor DIM service + std::string m_Rich2ScaleTaskName; + + /// Signal to look for to signify an end of run calibration + std::string m_EoRSignal; + + /// Flag to turn on the creation of a Preliminary calibration for each run + bool m_createPrelimCalib; + + /// Store run number and file path + RunAndSaveSet m_mergedRun; + + /// Store run number and file path of last run + RunAndSaveSet m_lastRun; + + /// run number for run being processed + unsigned int m_runNumber{0}; + + /// The ROOT file directory to use for the calibration (the Gaudi Monitor) + std::string m_HistBase; + + /// The histogram ID to use + std::string m_ResPlot; + + /// The radiators to calibration + std::vector m_rads; + + /// Min entries for a fit + unsigned int m_minEntries; + + /// CK Resolution fitter + Rich::Rec::CKResolutionFitter m_ckFitter; + + /// slope from the shift + std::array m_RefIndexSlope; + + /// Precision for XML file parameters + unsigned int m_Precision; + + /// xml file path + std::string m_xmlFilePath; + + /// log file to list all previous XML versions + std::string m_xmlVersionLog; + + /// log file for previous scale factors + std::string m_RefIndexSFLog; + + /// log file for fitted CK theta resolutions + std::string m_CKThetaResLog; + + /// Cache the timestampe from the saveset name + std::string m_fileTime; + + /// DIM Summary file name + std::string m_dimSummaryFile; + + /// Publishing service + IPublishSvc* m_pPublishSvc = nullptr; + + /// String to publish for new calibrations for RICH1 + std::string m_Rich1PubString{""}; + + /// String to publish for new calibrations for RICH2 + std::string m_Rich2PubString{""}; + + /// The RICH1 scale factor value to publish + double m_Rich1RefIndex{1.0}; + + /// The RICH2 scale factor value to publish + double m_Rich2RefIndex{1.0}; + + /// Flag to turn on/off publishing to DIM + bool m_disableDIMpublish; + + // The stats for the last fits + std::unordered_map m_histStats; + + /// Flag to turn on/off the saving of summary PDF files + bool m_createPDFsummary; + + /// Current TCanvas for printing + mutable std::unique_ptr m_canvas; + + /// PDF file for each run + mutable std::map m_pdfFile; + + /// Watermark string + mutable std::string m_watermark; + + /** Keep a count of the number of calibrations in a row, per radiator, + * for which a cached value from a previous run is used */ + std::unordered_map m_cachedCalibCount; + + /// maximum cached calibrations to allow in a row + unsigned int m_maxCachedCalibs; + + /// Max run number history + unsigned int m_runNumHistSize; + + /// Max seen run number + unsigned int m_maxSeenRunNum{0}; + + /// Run a 'test' fit with different fitter options + bool m_runTestFit{false}; + + /// Test fitter + Rich::Rec::CKResolutionFitter m_testCkFitter; + }; + +} // namespace Rich::Future::Rec::Calib -- GitLab From f493d353425be5b00f8e6db68d8cb410fa9cf51a Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 14:21:38 +0000 Subject: [PATCH 08/27] update reference log for refractive index calibration test --- .../tests/refs/rich_ref_index_calib.ref | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref index e69de29bb..3247bcef8 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref @@ -0,0 +1,114 @@ +TrackEventFitter INFO Fitting performance : 100.00 % +TrackEventFitter#1 INFO Fitting performance : 100.00 % +RichRefCalibLong INFO Previous #Events = 2 New #Events = 90 +RichRefCalibLong.Writer INFO Starting n-1 calibration for run 6718803 ... +RichRefCalibLong.Writer INFO Watermark = Wed Feb 17 14:19:13 2021 +RichRefCalibLong.Writer INFO Gaus Const = 2142 +- 22.5153 +RichRefCalibLong.Writer INFO Gaus Mean = 7.82888e-06 +- 9.57439e-06 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000863537 +- 1.05297e-05 +RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 +RichRefCalibLong.Writer INFO Bkg Par 0 = 3018.26 +- 11.7395 +RichRefCalibLong.Writer INFO Bkg Par 1 = 45410.5 +- 3046.9 +RichRefCalibLong.Writer INFO Bkg Par 2 = -5.06111e+06 +- 455665 +RichRefCalibLong.Writer INFO Bkg Par 3 = -5.20548e+07 +- 9.81688e+07 +RichRefCalibLong.Writer INFO Gaus Const = 815.91 +- 12.5565 +RichRefCalibLong.Writer INFO Gaus Mean = 5.63774e-06 +- 8.52861e-06 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000537838 +- 1.06145e-05 +RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 +RichRefCalibLong.Writer INFO Bkg Par 0 = 901.085 +- 7.07634 +RichRefCalibLong.Writer INFO Bkg Par 1 = 30532.1 +- 2951.92 +RichRefCalibLong.Writer INFO Bkg Par 2 = -6.35022e+06 +- 793323 +RichRefCalibLong.Writer INFO Bkg Par 3 = -1.10192e+09 +- 2.84043e+08 +RichRefCalibLong.Writer INFO Created /home/chris/LHCbCMake/Feature/Panoptes/Rich/Panoptes/tests/qmtest/RichCalibSummaries/2021/02/17/RefIndex/Run-6718803.pdf +RichRefCalibLong.Writer INFO Final Refractive index calibration for Run 6718803 was SUCCESSFUL +TransportSvc SUCCESS GEOMETRY ERRORS: 'Skip' map has the size 0 +TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has the size 0 +TransportSvc SUCCESS GEOMETRY ERRORS: 'Codes' map has the size 0 +TransportSvc INFO Reset the static pointer to DetDesc::IGeometyrErrorSvc +ToolSvc INFO Removing all tools created by ToolSvc +ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/1/Finalized +ApplicationMgr INFO Application Manager Finalized successfully +ApplicationMgr INFO Application Manager Terminated successfully +LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of converted Tracks" | 935 | 88914 | 95.095 | +LHCb__MDF__IOAlg INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#banks in raw event" | 1000 | 1025000 | 1025.0 | 0.0000 | 1025.0 | 1025.0 | +PrForwardTrackingVelo INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb output tracks" | 929 | 5319 | 5.7255 | +PrForwardTrackingVelo.PrAddUTHit... INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#UT hits added" | 3485 | 13336 | 3.8267 | + | "#tracks with hits added" | 3485 | +PrGECFilter INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb Events Processed" | 1000 | + | "Nb events removed" | 65 | +PrMatchNN INFO Number of counters : 3 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#MatchingChi2" | 160714 | 862298.1 | 5.3654 | + | "#MatchingTracks" | 928 | 58410 | 62.942 | + | "TracksMLP" | 160714 | 57166.43 | 0.3557 | +PrMatchNN.PrAddUTHitsTool INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#UT hits added" | 51690 | 206086 | 3.9870 | + | "#tracks with hits added" | 51690 | +PrStorePrUTHits INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#banks" | 935 | 168300 | 180.00 | +PrStoreUTHit INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#banks" | 935 | 168300 | 180.00 | +TrackBestTrackCreator INFO Number of counters : 3 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + |*"BadInput" | 5299 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 5299 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 5299 | +TrackBestTrackCreator#1 INFO Number of counters : 3 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + |*"BadInput" | 58222 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 58222 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 58222 | +TrackEventFitter INFO Number of counters : 7 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Long.badChisq" | 5319 | 3172 | 0.59635 | 0.49063 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 5319 | 659.2663 | 0.12395 | 0.23242 | 0.0000 | 0.99911 | + | "Long.flipCharge" | 5319 | 1 | 0.00018801 | 0.01371 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 5319 | 6559 | 1.2331 | 0.85748 | 0.0000 | 2.0000 | + | "nBadInput" | 935 | 0 | 0.0000 | + | "nFitted" | 935 | 5319 | 5.6888 | + | "nTracks" | 935 | 5319 | 5.6888 | +TrackEventFitter#1 INFO Number of counters : 7 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Long.badChisq" | 58410 | 13301 | 0.22772 | 0.41936 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 58410 | 17293.88 | 0.29608 | 0.30068 | 0.0000 | 0.99999 | + | "Long.flipCharge" | 58410 | 1 | 1.7120e-05 | 0.0041376 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 58410 | 39566 | 0.67738 | 0.78438 | 0.0000 | 2.0000 | + | "nBadInput" | 935 | 0 | 0.0000 | + | "nFitted" | 935 | 58410 | 62.471 | + | "nTracks" | 935 | 58410 | 62.471 | +TracksFTConverter#1 INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 5319 | 5.6888 | +TracksMatchConverter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 58410 | 62.471 | +TracksVPConverter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 72320 | 77.348 | +TracksVPMergerConverter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | +VPClus INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Clusters" | 935 | 1617568 | 1730.0 | +VeloClusterTrackingSIMD INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Clusters" | 935 | 1617568 | 1730.0 | + | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | +RichRefCalibLong SUCCESS 1D histograms in directory "RICH/RichRefCalibLong" : 2 + | ID | Title | # | Mean | RMS | Skewness | Kurtosis | + | Rich1Gas/ckResAll | "Rich1Gas Rec-Exp CKTheta - All photons" | 1072818 | 0.00021763 | 0.0037891 | -0.057208 | -0.9884 | + | Rich2Gas/ckResAll | "Rich2Gas Rec-Exp CKTheta - All photons" | 280966 | 0.00010835 | 0.0021191 | -0.054357 | -0.90251 | -- GitLab From 7d5783673efebdfa279c04edab73a5eccb5a6de6 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 14:22:09 +0000 Subject: [PATCH 09/27] use regular track fit by default --- Rich/Panoptes/options/RichRefIndexCalib.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Rich/Panoptes/options/RichRefIndexCalib.py b/Rich/Panoptes/options/RichRefIndexCalib.py index e30ee6b35..f428dea63 100644 --- a/Rich/Panoptes/options/RichRefIndexCalib.py +++ b/Rich/Panoptes/options/RichRefIndexCalib.py @@ -13,12 +13,9 @@ from Panoptes.calibration import standalone_rich_ref_index_calib from PyConf.Tools import TrackMasterFitter from RecoConf.hlt2_tracking import make_hlt2_tracks -#import ROOT -#ROOT.PyConfig.ShutDown = False - options.histo_file = "RichRefIndexCalib.root" with TrackMasterFitter.bind(FastMaterialApproximation=True),\ - make_hlt2_tracks.bind(use_pr_kf=True, light_reco=True, fast_reco=True): + make_hlt2_tracks.bind(use_pr_kf=False, light_reco=True, fast_reco=True): run_reconstruction(options, standalone_rich_ref_index_calib) -- GitLab From ae180e67565a54a63bf3b4df4a6d13f70e68da8f Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 14:23:10 +0000 Subject: [PATCH 10/27] remove dummy QM test, no longer required --- PanoptesSys/CMakeLists.txt | 2 -- PanoptesSys/tests/qmtest/panoptessys.qms/dummy.qmt | 14 -------------- 2 files changed, 16 deletions(-) delete mode 100644 PanoptesSys/tests/qmtest/panoptessys.qms/dummy.qmt diff --git a/PanoptesSys/CMakeLists.txt b/PanoptesSys/CMakeLists.txt index 6b688d3e8..211a68210 100644 --- a/PanoptesSys/CMakeLists.txt +++ b/PanoptesSys/CMakeLists.txt @@ -22,6 +22,4 @@ gaudi_depends_on_subdirs(Rich/Panoptes Rich/RichMirrorAlignmentGanga Rich/RichMirrorAlignmentOnline) -gaudi_add_test(QMTest QMTEST) - diff --git a/PanoptesSys/tests/qmtest/panoptessys.qms/dummy.qmt b/PanoptesSys/tests/qmtest/panoptessys.qms/dummy.qmt deleted file mode 100644 index 5706c646f..000000000 --- a/PanoptesSys/tests/qmtest/panoptessys.qms/dummy.qmt +++ /dev/null @@ -1,14 +0,0 @@ - - - - ls - -- GitLab From e748ecf62ecf2bb425f623eab20e5faa8d3595b5 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 14:39:40 +0000 Subject: [PATCH 11/27] clean up, and move setting of UpdatemanagerSvc overrides to top level task options --- Rich/Panoptes/python/Panoptes/calibration.py | 6 +++++- Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp | 9 +++------ Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Rich/Panoptes/python/Panoptes/calibration.py b/Rich/Panoptes/python/Panoptes/calibration.py index 81e8b5e51..184703f84 100644 --- a/Rich/Panoptes/python/Panoptes/calibration.py +++ b/Rich/Panoptes/python/Panoptes/calibration.py @@ -49,7 +49,11 @@ def standalone_rich_ref_index_calib(): reco_opts["PhotonSelection"] = "Online" # Turn off scale factors so they can be determined. - reco_opts["DisableRefInScaleFactor"] = True + from Configurables import UpdateManagerSvc + UpdateManagerSvc().ConditionsOverride += [ + "Conditions/Environment/Rich1/RefractivityScaleFactor := double CurrentScaleFactor = 1.0;", + "Conditions/Environment/Rich2/RefractivityScaleFactor := double CurrentScaleFactor = 1.0;" + ] # Track selection tkSel = TracksToSelection(InputLocation=tks[track_version]) diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp index 474984ac1..f4ef8785a 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp @@ -546,10 +546,8 @@ RefIndexCalibWriter::fitCKThetaHistogram( TH1* hist, // auto& backFunc = fitRes.bkgFitFunc; // make the pads for the plots - static unsigned long long iI{0}; - const auto iS = std::to_string(iI++); - auto upPad = std::make_unique( ("U"+iS).c_str(), ("U"+iS).c_str(), 0., 0.25, 1., 1. ); - auto dnPad = std::make_unique( ("L"+iS).c_str(), ("L"+iS).c_str(), 0., 0., 1., 0.25 ); + auto upPad = std::make_unique( "U", "U", 0., 0.25, 1., 1. ); + auto dnPad = std::make_unique( "L", "L", 0., 0., 1., 0.25 ); // upPad->SetTopMargin(0.05); upPad->SetBottomMargin( 0.1 ); dnPad->SetTopMargin( 0.05 ); @@ -630,8 +628,7 @@ RefIndexCalibWriter::fitCKThetaHistogram( TH1* hist, // std::unique_ptr RefIndexCalibWriter::makePullPlot( TH1& hist, TF1& func ) const { // make the new plot with the same bins and range std::ostringstream id; - static unsigned long long iI{0}; - id << hist.GetName() << "Pull" << iI++; + id << hist.GetName() << "Pull"; auto h = std::make_unique( id.str().c_str(), "", // no title hist.GetNbinsX(), hist.GetXaxis()->GetXmin(), hist.GetXaxis()->GetXmax() ); diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h index b74cff971..1b7f758c8 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h @@ -347,8 +347,8 @@ namespace Rich::Future::Rec::Calib { /// Delete the current TCanvas inline void deleteCanvas() const { - // if ( m_canvas.get() ) { m_canvas->Delete(); } - // m_canvas.reset( nullptr ); + //if ( m_canvas.get() ) { m_canvas->Delete(); } + m_canvas.reset( nullptr ); } /// Get the path to write summaries to -- GitLab From cab68b7b1137f727a819812ff42f199cf2c2dabb Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 15:55:04 +0000 Subject: [PATCH 12/27] Add RICH Panoptes specific QM test exclusions --- .../python/Panoptes/qmtest/__init__.py | 0 .../python/Panoptes/qmtest/exclusions.py | 29 +++++++++++++++++++ .../tests/qmtest/rich_ref_index_calib.qmt | 4 +-- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 Rich/Panoptes/python/Panoptes/qmtest/__init__.py create mode 100644 Rich/Panoptes/python/Panoptes/qmtest/exclusions.py diff --git a/Rich/Panoptes/python/Panoptes/qmtest/__init__.py b/Rich/Panoptes/python/Panoptes/qmtest/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Rich/Panoptes/python/Panoptes/qmtest/exclusions.py b/Rich/Panoptes/python/Panoptes/qmtest/exclusions.py new file mode 100644 index 000000000..617befbd2 --- /dev/null +++ b/Rich/Panoptes/python/Panoptes/qmtest/exclusions.py @@ -0,0 +1,29 @@ +############################################################################### +# (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, 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. # +############################################################################### +from GaudiTesting.BaseTest import LineSkipper +from Moore.qmtest.exclusions import ref_preprocessor as moore_ref_preprocessor +from Moore.qmtest.exclusions import remove_known_warnings as moore_remove_known_warnings + +remove_known_warnings = moore_remove_known_warnings + LineSkipper(regexps=[ + # Known warnings from calibration writer when not running in ONLINE env. + r"RichRefCalibLong.Writer +WARNING Cannot write to .*", + r"RichRefCalibLong.Writer +WARNING DIM_DNS_NODE not defined. Disabling DIM publishing", + # Warnings when camera server not available (not ONLINE) + r".*CameraTool +WARNING Could not connect to any camera server.*", + r".*CameraTool +WARNING Above message repeated .*", +]) + +ref_preprocessor = moore_ref_preprocessor + LineSkipper(regexps=[ + # Skip lines with variable information (times, file paths etc.) + r"RichRefCalibLong +INFO Previous #Events = .*", + r"RichRefCalibLong.Writer +INFO Watermark = .*", + r"RichRefCalibLong.Writer +INFO Created .*", +]) diff --git a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt index 5a85076c2..9d837334c 100644 --- a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt +++ b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt @@ -25,10 +25,10 @@ Make sure HLT2 configures and runs without errors on raw data. ../refs/empty.ref -from Moore.qmtest.exclusions import ref_preprocessor +from Panoptes.qmtest.exclusions import ref_preprocessor validateWithReference(preproc = ref_preprocessor) -from Moore.qmtest.exclusions import remove_known_warnings +from Panoptes.qmtest.exclusions import remove_known_warnings countErrorLines({"FATAL": 0, "ERROR": 0, "WARNING": 0}, stdout=remove_known_warnings(stdout)) -- GitLab From 97b478ac6b7b17c49606a926b0e3f70e44d1d127 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 19:07:48 +0000 Subject: [PATCH 13/27] Add momentum and beta cuts --- Rich/Panoptes/options/RichRefIndexCalib.py | 10 +++++++--- Rich/Panoptes/python/Panoptes/calibration.py | 3 +++ Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp | 10 +--------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Rich/Panoptes/options/RichRefIndexCalib.py b/Rich/Panoptes/options/RichRefIndexCalib.py index f428dea63..40e793851 100644 --- a/Rich/Panoptes/options/RichRefIndexCalib.py +++ b/Rich/Panoptes/options/RichRefIndexCalib.py @@ -11,11 +11,15 @@ from Moore import options, run_reconstruction from Panoptes.calibration import standalone_rich_ref_index_calib from PyConf.Tools import TrackMasterFitter -from RecoConf.hlt2_tracking import make_hlt2_tracks +from RecoConf.hlt2_tracking import make_hlt2_tracks, make_light_reco_best_tracks options.histo_file = "RichRefIndexCalib.root" -with TrackMasterFitter.bind(FastMaterialApproximation=True),\ + +def track_list_for_light_reco(): + return ["Forward", "Match", "Downstream"] + +with make_light_reco_best_tracks.bind(fit_preselection="(TrP>5000.0) & (TrPT>300.0)", get_tracklist = track_list_for_light_reco ),\ + TrackMasterFitter.bind(FastMaterialApproximation=True),\ make_hlt2_tracks.bind(use_pr_kf=False, light_reco=True, fast_reco=True): run_reconstruction(options, standalone_rich_ref_index_calib) - diff --git a/Rich/Panoptes/python/Panoptes/calibration.py b/Rich/Panoptes/python/Panoptes/calibration.py index 184703f84..e6008e75e 100644 --- a/Rich/Panoptes/python/Panoptes/calibration.py +++ b/Rich/Panoptes/python/Panoptes/calibration.py @@ -48,6 +48,9 @@ def standalone_rich_ref_index_calib(): # Enable online mode for wider CK theta side bands and forcing n-1 scale to 1 reco_opts["PhotonSelection"] = "Online" + # As we aren't running PID, we do not need all hypos + #reco_opts["Particles"] = ["muon","pion","kaon"] + # Turn off scale factors so they can be determined. from Configurables import UpdateManagerSvc UpdateManagerSvc().ConditionsOverride += [ diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp index 9082f93e3..4a7b85fc1 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -159,7 +159,7 @@ namespace Rich::Future::Rec::Calib { // properties and tools /// minimum beta value for tracks - Gaudi::Property> m_minBeta{this, "MinBeta", {0.0f, 0.0f, 0.0f}}; + Gaudi::Property> m_minBeta{this, "MinBeta", {0.9999f, 0.9999f, 0.9999f}}; /// maximum beta value for tracks Gaudi::Property> m_maxBeta{this, "MaxBeta", {999.99f, 999.99f, 999.99f}}; @@ -179,11 +179,6 @@ namespace Rich::Future::Rec::Calib { /// Time interval to send periodic calibration updates Gaudi::Property m_minTimeBetweenCalibs{this, "MinTimeBetweenCalibs", 16 * 60}; // 16 mins - /** Track selector. - * Longer term should get rid of this and pre-filter the input data instead. - */ - ToolHandle m_tkSel{this, "TrackSelector", "TrackSelector"}; - /// Camera messaging mutable ToolHandle m_cameraTool{this, "CameraTool", "CameraTool"}; @@ -353,9 +348,6 @@ void RefIndexCalib::operator()( const LHCb::ODIN& odin, // loop over tracks for ( const auto&& [tk, sumTk] : Ranges::ConstZip( tracks, sumTracks ) ) { - // Is this track selected ? - if ( !m_tkSel.get()->accept( *tk ) ) continue; - // loop over photons for this track for ( const auto photIn : sumTk.photonIndices() ) { // photon data -- GitLab From 42b525a21ccb84dbb3789a2f1a1f6b69f0e5a8af Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 20:28:16 +0000 Subject: [PATCH 14/27] update reference log following momentum and beta cut addition --- .../tests/refs/rich_ref_index_calib.ref | 84 ++++++++++--------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref index 3247bcef8..1473cc8b7 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref @@ -1,25 +1,22 @@ TrackEventFitter INFO Fitting performance : 100.00 % TrackEventFitter#1 INFO Fitting performance : 100.00 % -RichRefCalibLong INFO Previous #Events = 2 New #Events = 90 RichRefCalibLong.Writer INFO Starting n-1 calibration for run 6718803 ... -RichRefCalibLong.Writer INFO Watermark = Wed Feb 17 14:19:13 2021 -RichRefCalibLong.Writer INFO Gaus Const = 2142 +- 22.5153 -RichRefCalibLong.Writer INFO Gaus Mean = 7.82888e-06 +- 9.57439e-06 -RichRefCalibLong.Writer INFO Gaus Sigma = 0.000863537 +- 1.05297e-05 +RichRefCalibLong.Writer INFO Gaus Const = 870.706 +- 14.8007 +RichRefCalibLong.Writer INFO Gaus Mean = 3.65148e-06 +- 1.36801e-05 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000758515 +- 1.42962e-05 RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 -RichRefCalibLong.Writer INFO Bkg Par 0 = 3018.26 +- 11.7395 -RichRefCalibLong.Writer INFO Bkg Par 1 = 45410.5 +- 3046.9 -RichRefCalibLong.Writer INFO Bkg Par 2 = -5.06111e+06 +- 455665 -RichRefCalibLong.Writer INFO Bkg Par 3 = -5.20548e+07 +- 9.81688e+07 -RichRefCalibLong.Writer INFO Gaus Const = 815.91 +- 12.5565 -RichRefCalibLong.Writer INFO Gaus Mean = 5.63774e-06 +- 8.52861e-06 -RichRefCalibLong.Writer INFO Gaus Sigma = 0.000537838 +- 1.06145e-05 +RichRefCalibLong.Writer INFO Bkg Par 0 = 1195.63 +- 6.65966 +RichRefCalibLong.Writer INFO Bkg Par 1 = 10724.3 +- 1872.84 +RichRefCalibLong.Writer INFO Bkg Par 2 = -2.93679e+06 +- 264983 +RichRefCalibLong.Writer INFO Bkg Par 3 = -2.50323e+08 +- 6.03335e+07 +RichRefCalibLong.Writer INFO Gaus Const = 592.322 +- 10.7025 +RichRefCalibLong.Writer INFO Gaus Mean = -5.86809e-06 +- 9.51543e-06 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000512362 +- 1.15357e-05 RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 -RichRefCalibLong.Writer INFO Bkg Par 0 = 901.085 +- 7.07634 -RichRefCalibLong.Writer INFO Bkg Par 1 = 30532.1 +- 2951.92 -RichRefCalibLong.Writer INFO Bkg Par 2 = -6.35022e+06 +- 793323 -RichRefCalibLong.Writer INFO Bkg Par 3 = -1.10192e+09 +- 2.84043e+08 -RichRefCalibLong.Writer INFO Created /home/chris/LHCbCMake/Feature/Panoptes/Rich/Panoptes/tests/qmtest/RichCalibSummaries/2021/02/17/RefIndex/Run-6718803.pdf +RichRefCalibLong.Writer INFO Bkg Par 0 = 628.271 +- 5.59823 +RichRefCalibLong.Writer INFO Bkg Par 1 = 15620.1 +- 2356.76 +RichRefCalibLong.Writer INFO Bkg Par 2 = -5.0528e+06 +- 634991 +RichRefCalibLong.Writer INFO Bkg Par 3 = -5.22683e+08 +- 2.25597e+08 RichRefCalibLong.Writer INFO Final Refractive index calibration for Run 6718803 was SUCCESSFUL TransportSvc SUCCESS GEOMETRY ERRORS: 'Skip' map has the size 0 TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has the size 0 @@ -50,7 +47,7 @@ PrMatchNN INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#MatchingChi2" | 160714 | 862298.1 | 5.3654 | | "#MatchingTracks" | 928 | 58410 | 62.942 | - | "TracksMLP" | 160714 | 57166.43 | 0.3557 | + | "TracksMLP" | 160714 | 57166.44 | 0.3557 | PrMatchNN.PrAddUTHitsTool INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#UT hits added" | 51690 | 206086 | 3.9870 | @@ -61,34 +58,45 @@ PrStorePrUTHits INFO Number of counters : 1 PrStoreUTHit INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#banks" | 935 | 168300 | 180.00 | +ToolSvc.TrackFunctorFactory INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "# loaded from PYTHON" | 2 | TrackBestTrackCreator INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - |*"BadInput" | 5299 | 0 |( 0.000000 +- 0.000000)% | - |*"FitFailed" | 5299 | 0 |( 0.000000 +- 0.000000)% | - | "FittedBefore" | 5299 | + |*"BadInput" | 960 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 960 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 960 | TrackBestTrackCreator#1 INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - |*"BadInput" | 58222 | 0 |( 0.000000 +- 0.000000)% | - |*"FitFailed" | 58222 | 0 |( 0.000000 +- 0.000000)% | - | "FittedBefore" | 58222 | + |*"BadInput" | 25870 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 25870 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 25870 | +TrackContainerSplitter INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#inputs" | 935 | 5319 | 5.6888 | 4.4465 | 0.0000 | 24.000 | + | "#passed" | 935 | 960 | 1.0267 | 1.2566 | 0.0000 | 9.0000 | +TrackContainerSplitter#1 INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#inputs" | 935 | 58410 | 62.471 | 36.330 | 0.0000 | 190.00 | + | "#passed" | 935 | 25939 | 27.742 | 17.018 | 0.0000 | 96.000 | TrackEventFitter INFO Number of counters : 7 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Long.badChisq" | 5319 | 3172 | 0.59635 | 0.49063 | 0.0000 | 1.0000 | - | "Long.chisqprobSum" | 5319 | 659.2663 | 0.12395 | 0.23242 | 0.0000 | 0.99911 | - | "Long.flipCharge" | 5319 | 1 | 0.00018801 | 0.01371 | 0.0000 | 1.0000 | - | "Long.numOutliers" | 5319 | 6559 | 1.2331 | 0.85748 | 0.0000 | 2.0000 | + | "Long.badChisq" | 960 | 475 | 0.49479 | 0.49997 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 960 | 194.3615 | 0.20246 | 0.28831 | 0.0000 | 0.9977 | + | "Long.flipCharge" | 960 | 1 | 0.0010417 | 0.032258 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 960 | 1191 | 1.2406 | 0.87167 | 0.0000 | 2.0000 | | "nBadInput" | 935 | 0 | 0.0000 | - | "nFitted" | 935 | 5319 | 5.6888 | - | "nTracks" | 935 | 5319 | 5.6888 | + | "nFitted" | 935 | 960 | 1.0267 | + | "nTracks" | 935 | 960 | 1.0267 | TrackEventFitter#1 INFO Number of counters : 7 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Long.badChisq" | 58410 | 13301 | 0.22772 | 0.41936 | 0.0000 | 1.0000 | - | "Long.chisqprobSum" | 58410 | 17293.88 | 0.29608 | 0.30068 | 0.0000 | 0.99999 | - | "Long.flipCharge" | 58410 | 1 | 1.7120e-05 | 0.0041376 | 0.0000 | 1.0000 | - | "Long.numOutliers" | 58410 | 39566 | 0.67738 | 0.78438 | 0.0000 | 2.0000 | + | "Long.badChisq" | 25939 | 3977 | 0.15332 | 0.3603 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 25939 | 9009.085 | 0.34732 | 0.30559 | 0.0000 | 0.99999 | + | "Long.flipCharge" | 25939 | 1 | 3.8552e-05 | 0.0062089 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 25939 | 15757 | 0.60746 | 0.75263 | 0.0000 | 2.0000 | | "nBadInput" | 935 | 0 | 0.0000 | - | "nFitted" | 935 | 58410 | 62.471 | - | "nTracks" | 935 | 58410 | 62.471 | + | "nFitted" | 935 | 25939 | 27.742 | + | "nTracks" | 935 | 25939 | 27.742 | TracksFTConverter#1 INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "Nb of Produced Tracks" | 935 | 5319 | 5.6888 | @@ -110,5 +118,5 @@ VeloClusterTrackingSIMD INFO Number of counters : 2 | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | RichRefCalibLong SUCCESS 1D histograms in directory "RICH/RichRefCalibLong" : 2 | ID | Title | # | Mean | RMS | Skewness | Kurtosis | - | Rich1Gas/ckResAll | "Rich1Gas Rec-Exp CKTheta - All photons" | 1072818 | 0.00021763 | 0.0037891 | -0.057208 | -0.9884 | - | Rich2Gas/ckResAll | "Rich2Gas Rec-Exp CKTheta - All photons" | 280966 | 0.00010835 | 0.0021191 | -0.054357 | -0.90251 | + | Rich1Gas/ckResAll | "Rich1Gas Rec-Exp CKTheta - All photons" | 355143 | 4.2555e-05 | 0.003787 | -0.021164 | -0.99682 | + | Rich2Gas/ckResAll | "Rich2Gas Rec-Exp CKTheta - All photons" | 194948 | 8.0991e-05 | 0.0021143 | -0.038702 | -0.89949 | -- GitLab From 820c9df5b065a1f9c2de0cc62f1530020ee6a674 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 20:48:41 +0000 Subject: [PATCH 15/27] Fix comment --- Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt index 9d837334c..40e2b93f5 100644 --- a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt +++ b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt @@ -10,7 +10,7 @@ or submit itself to any jurisdiction. --> gaudirun.py -- GitLab From 53c06ca6547cc91b75ad042f1f0e3bd90b156336 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 17 Feb 2021 20:52:34 +0000 Subject: [PATCH 16/27] remove unneccessary track list method --- Rich/Panoptes/options/RichRefIndexCalib.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Rich/Panoptes/options/RichRefIndexCalib.py b/Rich/Panoptes/options/RichRefIndexCalib.py index 40e793851..2da7d4e34 100644 --- a/Rich/Panoptes/options/RichRefIndexCalib.py +++ b/Rich/Panoptes/options/RichRefIndexCalib.py @@ -15,11 +15,10 @@ from RecoConf.hlt2_tracking import make_hlt2_tracks, make_light_reco_best_tracks options.histo_file = "RichRefIndexCalib.root" - -def track_list_for_light_reco(): - return ["Forward", "Match", "Downstream"] - -with make_light_reco_best_tracks.bind(fit_preselection="(TrP>5000.0) & (TrPT>300.0)", get_tracklist = track_list_for_light_reco ),\ +with make_light_reco_best_tracks.bind(fit_preselection="(TrP>5000.0) & (TrPT>300.0)"),\ TrackMasterFitter.bind(FastMaterialApproximation=True),\ make_hlt2_tracks.bind(use_pr_kf=False, light_reco=True, fast_reco=True): run_reconstruction(options, standalone_rich_ref_index_calib) + +#with make_hlt2_tracks.bind(use_pr_kf=True, light_reco=True, fast_reco=True): +# run_reconstruction(options, standalone_rich_ref_index_calib) -- GitLab From 32289e7ab74d08f8c3c6ccaff284ac00228e4991 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 18 Feb 2021 10:01:37 +0000 Subject: [PATCH 17/27] Update test refs, add avx2+fma specific version --- .../tests/refs/rich_ref_index_calib.ref | 104 +++++++-------- ...ch_ref_index_calib.ref.x86_64+avx2+fma-opt | 122 ++++++++++++++++++ 2 files changed, 174 insertions(+), 52 deletions(-) create mode 100644 Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref index 1473cc8b7..e9583f760 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref @@ -1,22 +1,22 @@ TrackEventFitter INFO Fitting performance : 100.00 % TrackEventFitter#1 INFO Fitting performance : 100.00 % RichRefCalibLong.Writer INFO Starting n-1 calibration for run 6718803 ... -RichRefCalibLong.Writer INFO Gaus Const = 870.706 +- 14.8007 -RichRefCalibLong.Writer INFO Gaus Mean = 3.65148e-06 +- 1.36801e-05 -RichRefCalibLong.Writer INFO Gaus Sigma = 0.000758515 +- 1.42962e-05 +RichRefCalibLong.Writer INFO Gaus Const = 845.964 +- 14.9816 +RichRefCalibLong.Writer INFO Gaus Mean = -2.58644e-06 +- 1.38093e-05 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000729754 +- 1.39184e-05 RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 -RichRefCalibLong.Writer INFO Bkg Par 0 = 1195.63 +- 6.65966 -RichRefCalibLong.Writer INFO Bkg Par 1 = 10724.3 +- 1872.84 -RichRefCalibLong.Writer INFO Bkg Par 2 = -2.93679e+06 +- 264983 -RichRefCalibLong.Writer INFO Bkg Par 3 = -2.50323e+08 +- 6.03335e+07 -RichRefCalibLong.Writer INFO Gaus Const = 592.322 +- 10.7025 -RichRefCalibLong.Writer INFO Gaus Mean = -5.86809e-06 +- 9.51543e-06 -RichRefCalibLong.Writer INFO Gaus Sigma = 0.000512362 +- 1.15357e-05 +RichRefCalibLong.Writer INFO Bkg Par 0 = 1223.96 +- 6.42398 +RichRefCalibLong.Writer INFO Bkg Par 1 = 13916.5 +- 1839.86 +RichRefCalibLong.Writer INFO Bkg Par 2 = -5.33299e+06 +- 254102 +RichRefCalibLong.Writer INFO Bkg Par 3 = -4.52594e+08 +- 5.85483e+07 +RichRefCalibLong.Writer INFO Gaus Const = 591.74 +- 10.7162 +RichRefCalibLong.Writer INFO Gaus Mean = -6.28009e-06 +- 9.69663e-06 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000511297 +- 1.15065e-05 RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 -RichRefCalibLong.Writer INFO Bkg Par 0 = 628.271 +- 5.59823 -RichRefCalibLong.Writer INFO Bkg Par 1 = 15620.1 +- 2356.76 -RichRefCalibLong.Writer INFO Bkg Par 2 = -5.0528e+06 +- 634991 -RichRefCalibLong.Writer INFO Bkg Par 3 = -5.22683e+08 +- 2.25597e+08 +RichRefCalibLong.Writer INFO Bkg Par 0 = 630.685 +- 5.58705 +RichRefCalibLong.Writer INFO Bkg Par 1 = 15833.4 +- 2748.42 +RichRefCalibLong.Writer INFO Bkg Par 2 = -5.28415e+06 +- 633732 +RichRefCalibLong.Writer INFO Bkg Par 3 = -5.66088e+08 +- 2.68456e+08 RichRefCalibLong.Writer INFO Final Refractive index calibration for Run 6718803 was SUCCESSFUL TransportSvc SUCCESS GEOMETRY ERRORS: 'Skip' map has the size 0 TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has the size 0 @@ -28,30 +28,30 @@ ApplicationMgr INFO Application Manager Finalized succes ApplicationMgr INFO Application Manager Terminated successfully LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Nb of converted Tracks" | 935 | 88914 | 95.095 | + | "Nb of converted Tracks" | 935 | 88915 | 95.096 | LHCb__MDF__IOAlg INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#banks in raw event" | 1000 | 1025000 | 1025.0 | 0.0000 | 1025.0 | 1025.0 | PrForwardTrackingVelo INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Nb output tracks" | 929 | 5319 | 5.7255 | + | "Nb output tracks" | 929 | 5308 | 5.7137 | PrForwardTrackingVelo.PrAddUTHit... INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "#UT hits added" | 3485 | 13336 | 3.8267 | - | "#tracks with hits added" | 3485 | + | "#UT hits added" | 3468 | 13272 | 3.8270 | + | "#tracks with hits added" | 3468 | PrGECFilter INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "Nb Events Processed" | 1000 | | "Nb events removed" | 65 | PrMatchNN INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "#MatchingChi2" | 160714 | 862298.1 | 5.3654 | - | "#MatchingTracks" | 928 | 58410 | 62.942 | - | "TracksMLP" | 160714 | 57166.44 | 0.3557 | + | "#MatchingChi2" | 160419 | 860731.9 | 5.3655 | + | "#MatchingTracks" | 928 | 58318 | 62.843 | + | "TracksMLP" | 160419 | 57076.32 | 0.3558 | PrMatchNN.PrAddUTHitsTool INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "#UT hits added" | 51690 | 206086 | 3.9870 | - | "#tracks with hits added" | 51690 | + | "#UT hits added" | 51616 | 205788 | 3.9869 | + | "#tracks with hits added" | 51616 | PrStorePrUTHits INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#banks" | 935 | 168300 | 180.00 | @@ -63,60 +63,60 @@ ToolSvc.TrackFunctorFactory INFO Number of counters : 1 | "# loaded from PYTHON" | 2 | TrackBestTrackCreator INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - |*"BadInput" | 960 | 0 |( 0.000000 +- 0.000000)% | - |*"FitFailed" | 960 | 0 |( 0.000000 +- 0.000000)% | - | "FittedBefore" | 960 | + |*"BadInput" | 958 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 958 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 958 | TrackBestTrackCreator#1 INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - |*"BadInput" | 25870 | 0 |( 0.000000 +- 0.000000)% | - |*"FitFailed" | 25870 | 0 |( 0.000000 +- 0.000000)% | - | "FittedBefore" | 25870 | + |*"BadInput" | 25869 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 25869 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 25869 | TrackContainerSplitter INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "#inputs" | 935 | 5319 | 5.6888 | 4.4465 | 0.0000 | 24.000 | - | "#passed" | 935 | 960 | 1.0267 | 1.2566 | 0.0000 | 9.0000 | + | "#inputs" | 935 | 5308 | 5.6770 | 4.4422 | 0.0000 | 23.000 | + | "#passed" | 935 | 958 | 1.0246 | 1.2506 | 0.0000 | 9.0000 | TrackContainerSplitter#1 INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "#inputs" | 935 | 58410 | 62.471 | 36.330 | 0.0000 | 190.00 | - | "#passed" | 935 | 25939 | 27.742 | 17.018 | 0.0000 | 96.000 | + | "#inputs" | 935 | 58318 | 62.372 | 36.320 | 0.0000 | 191.00 | + | "#passed" | 935 | 25903 | 27.704 | 17.027 | 0.0000 | 97.000 | TrackEventFitter INFO Number of counters : 7 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Long.badChisq" | 960 | 475 | 0.49479 | 0.49997 | 0.0000 | 1.0000 | - | "Long.chisqprobSum" | 960 | 194.3615 | 0.20246 | 0.28831 | 0.0000 | 0.9977 | - | "Long.flipCharge" | 960 | 1 | 0.0010417 | 0.032258 | 0.0000 | 1.0000 | - | "Long.numOutliers" | 960 | 1191 | 1.2406 | 0.87167 | 0.0000 | 2.0000 | + | "Long.badChisq" | 958 | 473 | 0.49374 | 0.49996 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 958 | 194.3273 | 0.20285 | 0.28845 | 0.0000 | 0.9977 | + | "Long.flipCharge" | 958 | 1 | 0.0010438 | 0.032292 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 958 | 1187 | 1.2390 | 0.87189 | 0.0000 | 2.0000 | | "nBadInput" | 935 | 0 | 0.0000 | - | "nFitted" | 935 | 960 | 1.0267 | - | "nTracks" | 935 | 960 | 1.0267 | + | "nFitted" | 935 | 958 | 1.0246 | + | "nTracks" | 935 | 958 | 1.0246 | TrackEventFitter#1 INFO Number of counters : 7 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Long.badChisq" | 25939 | 3977 | 0.15332 | 0.3603 | 0.0000 | 1.0000 | - | "Long.chisqprobSum" | 25939 | 9009.085 | 0.34732 | 0.30559 | 0.0000 | 0.99999 | - | "Long.flipCharge" | 25939 | 1 | 3.8552e-05 | 0.0062089 | 0.0000 | 1.0000 | - | "Long.numOutliers" | 25939 | 15757 | 0.60746 | 0.75263 | 0.0000 | 2.0000 | + | "Long.badChisq" | 25903 | 3958 | 0.1528 | 0.3598 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 25903 | 9003.377 | 0.34758 | 0.30558 | 0.0000 | 0.99999 | + | "Long.flipCharge" | 25903 | 1 | 3.8606e-05 | 0.0062132 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 25903 | 15713 | 0.60661 | 0.75234 | 0.0000 | 2.0000 | | "nBadInput" | 935 | 0 | 0.0000 | - | "nFitted" | 935 | 25939 | 27.742 | - | "nTracks" | 935 | 25939 | 27.742 | + | "nFitted" | 935 | 25903 | 27.704 | + | "nTracks" | 935 | 25903 | 27.704 | TracksFTConverter#1 INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Nb of Produced Tracks" | 935 | 5319 | 5.6888 | + | "Nb of Produced Tracks" | 935 | 5308 | 5.6770 | TracksMatchConverter INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Nb of Produced Tracks" | 935 | 58410 | 62.471 | + | "Nb of Produced Tracks" | 935 | 58318 | 62.372 | TracksVPConverter INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Nb of Produced Tracks" | 935 | 72320 | 77.348 | + | "Nb of Produced Tracks" | 935 | 72102 | 77.114 | TracksVPMergerConverter INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | + | "Nb of Produced Tracks" | 935 | 208195 | 222.67 | VPClus INFO Number of counters : 1 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "Nb of Produced Clusters" | 935 | 1617568 | 1730.0 | VeloClusterTrackingSIMD INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "Nb of Produced Clusters" | 935 | 1617568 | 1730.0 | - | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | + | "Nb of Produced Tracks" | 935 | 208195 | 222.67 | RichRefCalibLong SUCCESS 1D histograms in directory "RICH/RichRefCalibLong" : 2 | ID | Title | # | Mean | RMS | Skewness | Kurtosis | - | Rich1Gas/ckResAll | "Rich1Gas Rec-Exp CKTheta - All photons" | 355143 | 4.2555e-05 | 0.003787 | -0.021164 | -0.99682 | - | Rich2Gas/ckResAll | "Rich2Gas Rec-Exp CKTheta - All photons" | 194948 | 8.0991e-05 | 0.0021143 | -0.038702 | -0.89949 | + | Rich1Gas/ckResAll | "Rich1Gas Rec-Exp CKTheta - All photons" | 339090 | 8.1983e-06 | 0.0037416 | -0.020709 | -0.98145 | + | Rich2Gas/ckResAll | "Rich2Gas Rec-Exp CKTheta - All photons" | 187965 | 7.8954e-05 | 0.0021132 | -0.038584 | -0.89918 | diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt new file mode 100644 index 000000000..1473cc8b7 --- /dev/null +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt @@ -0,0 +1,122 @@ +TrackEventFitter INFO Fitting performance : 100.00 % +TrackEventFitter#1 INFO Fitting performance : 100.00 % +RichRefCalibLong.Writer INFO Starting n-1 calibration for run 6718803 ... +RichRefCalibLong.Writer INFO Gaus Const = 870.706 +- 14.8007 +RichRefCalibLong.Writer INFO Gaus Mean = 3.65148e-06 +- 1.36801e-05 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000758515 +- 1.42962e-05 +RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 +RichRefCalibLong.Writer INFO Bkg Par 0 = 1195.63 +- 6.65966 +RichRefCalibLong.Writer INFO Bkg Par 1 = 10724.3 +- 1872.84 +RichRefCalibLong.Writer INFO Bkg Par 2 = -2.93679e+06 +- 264983 +RichRefCalibLong.Writer INFO Bkg Par 3 = -2.50323e+08 +- 6.03335e+07 +RichRefCalibLong.Writer INFO Gaus Const = 592.322 +- 10.7025 +RichRefCalibLong.Writer INFO Gaus Mean = -5.86809e-06 +- 9.51543e-06 +RichRefCalibLong.Writer INFO Gaus Sigma = 0.000512362 +- 1.15357e-05 +RichRefCalibLong.Writer INFO Gaus Asym = 0 +- 0 +RichRefCalibLong.Writer INFO Bkg Par 0 = 628.271 +- 5.59823 +RichRefCalibLong.Writer INFO Bkg Par 1 = 15620.1 +- 2356.76 +RichRefCalibLong.Writer INFO Bkg Par 2 = -5.0528e+06 +- 634991 +RichRefCalibLong.Writer INFO Bkg Par 3 = -5.22683e+08 +- 2.25597e+08 +RichRefCalibLong.Writer INFO Final Refractive index calibration for Run 6718803 was SUCCESSFUL +TransportSvc SUCCESS GEOMETRY ERRORS: 'Skip' map has the size 0 +TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has the size 0 +TransportSvc SUCCESS GEOMETRY ERRORS: 'Codes' map has the size 0 +TransportSvc INFO Reset the static pointer to DetDesc::IGeometyrErrorSvc +ToolSvc INFO Removing all tools created by ToolSvc +ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/1/Finalized +ApplicationMgr INFO Application Manager Finalized successfully +ApplicationMgr INFO Application Manager Terminated successfully +LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of converted Tracks" | 935 | 88914 | 95.095 | +LHCb__MDF__IOAlg INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#banks in raw event" | 1000 | 1025000 | 1025.0 | 0.0000 | 1025.0 | 1025.0 | +PrForwardTrackingVelo INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb output tracks" | 929 | 5319 | 5.7255 | +PrForwardTrackingVelo.PrAddUTHit... INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#UT hits added" | 3485 | 13336 | 3.8267 | + | "#tracks with hits added" | 3485 | +PrGECFilter INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb Events Processed" | 1000 | + | "Nb events removed" | 65 | +PrMatchNN INFO Number of counters : 3 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#MatchingChi2" | 160714 | 862298.1 | 5.3654 | + | "#MatchingTracks" | 928 | 58410 | 62.942 | + | "TracksMLP" | 160714 | 57166.44 | 0.3557 | +PrMatchNN.PrAddUTHitsTool INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#UT hits added" | 51690 | 206086 | 3.9870 | + | "#tracks with hits added" | 51690 | +PrStorePrUTHits INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#banks" | 935 | 168300 | 180.00 | +PrStoreUTHit INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#banks" | 935 | 168300 | 180.00 | +ToolSvc.TrackFunctorFactory INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "# loaded from PYTHON" | 2 | +TrackBestTrackCreator INFO Number of counters : 3 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + |*"BadInput" | 960 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 960 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 960 | +TrackBestTrackCreator#1 INFO Number of counters : 3 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + |*"BadInput" | 25870 | 0 |( 0.000000 +- 0.000000)% | + |*"FitFailed" | 25870 | 0 |( 0.000000 +- 0.000000)% | + | "FittedBefore" | 25870 | +TrackContainerSplitter INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#inputs" | 935 | 5319 | 5.6888 | 4.4465 | 0.0000 | 24.000 | + | "#passed" | 935 | 960 | 1.0267 | 1.2566 | 0.0000 | 9.0000 | +TrackContainerSplitter#1 INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "#inputs" | 935 | 58410 | 62.471 | 36.330 | 0.0000 | 190.00 | + | "#passed" | 935 | 25939 | 27.742 | 17.018 | 0.0000 | 96.000 | +TrackEventFitter INFO Number of counters : 7 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Long.badChisq" | 960 | 475 | 0.49479 | 0.49997 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 960 | 194.3615 | 0.20246 | 0.28831 | 0.0000 | 0.9977 | + | "Long.flipCharge" | 960 | 1 | 0.0010417 | 0.032258 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 960 | 1191 | 1.2406 | 0.87167 | 0.0000 | 2.0000 | + | "nBadInput" | 935 | 0 | 0.0000 | + | "nFitted" | 935 | 960 | 1.0267 | + | "nTracks" | 935 | 960 | 1.0267 | +TrackEventFitter#1 INFO Number of counters : 7 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Long.badChisq" | 25939 | 3977 | 0.15332 | 0.3603 | 0.0000 | 1.0000 | + | "Long.chisqprobSum" | 25939 | 9009.085 | 0.34732 | 0.30559 | 0.0000 | 0.99999 | + | "Long.flipCharge" | 25939 | 1 | 3.8552e-05 | 0.0062089 | 0.0000 | 1.0000 | + | "Long.numOutliers" | 25939 | 15757 | 0.60746 | 0.75263 | 0.0000 | 2.0000 | + | "nBadInput" | 935 | 0 | 0.0000 | + | "nFitted" | 935 | 25939 | 27.742 | + | "nTracks" | 935 | 25939 | 27.742 | +TracksFTConverter#1 INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 5319 | 5.6888 | +TracksMatchConverter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 58410 | 62.471 | +TracksVPConverter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 72320 | 77.348 | +TracksVPMergerConverter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | +VPClus INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Clusters" | 935 | 1617568 | 1730.0 | +VeloClusterTrackingSIMD INFO Number of counters : 2 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Nb of Produced Clusters" | 935 | 1617568 | 1730.0 | + | "Nb of Produced Tracks" | 935 | 208704 | 223.21 | +RichRefCalibLong SUCCESS 1D histograms in directory "RICH/RichRefCalibLong" : 2 + | ID | Title | # | Mean | RMS | Skewness | Kurtosis | + | Rich1Gas/ckResAll | "Rich1Gas Rec-Exp CKTheta - All photons" | 355143 | 4.2555e-05 | 0.003787 | -0.021164 | -0.99682 | + | Rich2Gas/ckResAll | "Rich2Gas Rec-Exp CKTheta - All photons" | 194948 | 8.0991e-05 | 0.0021143 | -0.038702 | -0.89949 | -- GitLab From effc7349a2774a027385a225c3e483114a274227 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 18 Feb 2021 10:06:20 +0000 Subject: [PATCH 18/27] update some print statements for python 3 --- .../RichMirrorAlignmentOnline/Configuration.py | 16 ++++++++-------- .../RichMonitoringSys/RichHitMapMonitor.py | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Rich/RichMirrorAlignmentOnline/python/RichMirrorAlignmentOnline/Configuration.py b/Rich/RichMirrorAlignmentOnline/python/RichMirrorAlignmentOnline/Configuration.py index 2e936a46c..476451f4f 100644 --- a/Rich/RichMirrorAlignmentOnline/python/RichMirrorAlignmentOnline/Configuration.py +++ b/Rich/RichMirrorAlignmentOnline/python/RichMirrorAlignmentOnline/Configuration.py @@ -257,19 +257,19 @@ class Rich1MirrAlignOnConf(LHCbConfigurableUser): if self.getProp("MinItStart") < 9: if not self.getProp("MajItStart") == 0: self.setProp("MajItStart", 0) - print "Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration." + print("Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration.") else: majstartit = (self.getProp("MinItStart") - ( self.getProp("MinItStart") % self.getProp("MajItStart")) ) / self.getProp("MajItStart") if not self.getProp("MajItStart") == majstartit: self.setProp('MajItStart', majstartit) - print "Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration." + print("Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration.") if (self.getProp("magnFactorsMode") == 0 and self.getProp("magnifDir") == ""): self.setProp("magnifDir", '/group/rich/AlignmentFiles/MagnifFactors/Rich1/') - print "Warning: Mode for calculating magnification coefficients was chosen to be 0 but no directory with pre-determined coefficients provided. Directory set to default." + print("Warning: Mode for calculating magnification coefficients was chosen to be 0 but no directory with pre-determined coefficients provided. Directory set to default.") if self.getProp("magnFactorsMode") == 0: self.setProp("MinItStart", self.getProp("MajItStart") * 9) @@ -281,7 +281,7 @@ class Rich1MirrAlignOnConf(LHCbConfigurableUser): self.setProp('WorkDir', os.path.join(self.getProp('WorkDir'), '')) self.setProp('SaveDir', os.path.join(self.getProp('SaveDir'), '')) self.setProp('magnifDir', os.path.join(self.getProp('magnifDir'), '')) - print "INFO: Rich1MirrAlignOnConf applied" + print("INFO: Rich1MirrAlignOnConf applied") class Rich2MirrAlignOnConf(LHCbConfigurableUser): @@ -506,19 +506,19 @@ class Rich2MirrAlignOnConf(LHCbConfigurableUser): if self.getProp("MinItStart") < 9: if not self.getProp("MajItStart") == 0: self.setProp("MajItStart", 0) - print "Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration." + print("Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration.") else: majstartit = (self.getProp("MinItStart") - ( self.getProp("MinItStart") % self.getProp("MajItStart")) ) / self.getProp("MajItStart") if not self.getProp("MajItStart") == majstartit: self.setProp('MajItStart', majstartit) - print "Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration." + print("Warning: Major Iteration did not match minor itertion. Major iteration was set to match minor iteration.") if (self.getProp("magnFactorsMode") == 0 and self.getProp("magnifDir") == ""): self.setProp("magnifDir", '/group/rich/AlignmentFiles/MagnifFactors/Rich2/') - print "Warning: Mode for calculating magnification coefficients was chosen to be 0 but no directory with pre-determined coefficients provided. Directory set to default." + print("Warning: Mode for calculating magnification coefficients was chosen to be 0 but no directory with pre-determined coefficients provided. Directory set to default.") if self.getProp("magnFactorsMode") == 0: self.setProp("MinItStart", self.getProp("MajItStart") * 9) @@ -530,7 +530,7 @@ class Rich2MirrAlignOnConf(LHCbConfigurableUser): self.setProp('WorkDir', os.path.join(self.getProp('WorkDir'), '')) self.setProp('SaveDir', os.path.join(self.getProp('SaveDir'), '')) self.setProp('magnifDir', os.path.join(self.getProp('magnifDir'), '')) - print "INFO: Rich2MirrAlignOnConf applied" + print("INFO: Rich2MirrAlignOnConf applied") #=============================================================================== diff --git a/Rich/RichMonitoringSys/python/RichMonitoringSys/RichHitMapMonitor.py b/Rich/RichMonitoringSys/python/RichMonitoringSys/RichHitMapMonitor.py index 89e573a7c..2d90700b3 100755 --- a/Rich/RichMonitoringSys/python/RichMonitoringSys/RichHitMapMonitor.py +++ b/Rich/RichMonitoringSys/python/RichMonitoringSys/RichHitMapMonitor.py @@ -58,9 +58,9 @@ class RichHitMapMonitorConf(RichConfigurableUser): sequence = self.getProp("HitMapMonSequencer") if sequence.name() == "HitMapMonDefaultSequencer": - print "=================>>>>> WARNING <<<<<<<<<<========================" - print "No sequence defined for RichHitMapMonitorConf" - print "HitMapMonSequencer %s" % sequence.name() + print("=================>>>>> WARNING <<<<<<<<<<========================") + print("No sequence defined for RichHitMapMonitorConf") + print("HitMapMonSequencer ",sequence.name()) from Configurables import Rich__Mon__HitMapsMonitor HitMapMon = Rich__Mon__HitMapsMonitor("HitMapMon") -- GitLab From d414467ec99b0e270d54bcca41fd9d20e89ec79f Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 18 Feb 2021 10:13:02 +0000 Subject: [PATCH 19/27] Add skylake ref sym link --- .../tests/refs/rich_ref_index_calib.ref.skylake_avx512-opt | 1 + 1 file changed, 1 insertion(+) create mode 120000 Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.skylake_avx512-opt diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.skylake_avx512-opt b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.skylake_avx512-opt new file mode 120000 index 000000000..40d1d489c --- /dev/null +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.skylake_avx512-opt @@ -0,0 +1 @@ +rich_ref_index_calib.ref.x86_64+avx2+fma-opt \ No newline at end of file -- GitLab From ce5830fd6dbb6c996401684ea11ea24daab439ad Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 18 Feb 2021 18:19:40 +0000 Subject: [PATCH 20/27] update qmt test and refs to use temp directory --- Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt | 1 + Rich/Panoptes/tests/refs/rich_ref_index_calib.ref | 2 +- .../tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt index 40e2b93f5..f7e4f4aad 100644 --- a/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt +++ b/Rich/Panoptes/tests/qmtest/rich_ref_index_calib.qmt @@ -14,6 +14,7 @@ Run RICH refractive index calibration task --> gaudirun.py +true 1200 $MOOREROOT/tests/options/mdf_input_and_conds.py diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref index e9583f760..bda58cabf 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref @@ -23,7 +23,7 @@ TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has TransportSvc SUCCESS GEOMETRY ERRORS: 'Codes' map has the size 0 TransportSvc INFO Reset the static pointer to DetDesc::IGeometyrErrorSvc ToolSvc INFO Removing all tools created by ToolSvc -ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/1/Finalized +ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/Finalized' ApplicationMgr INFO Application Manager Finalized successfully ApplicationMgr INFO Application Manager Terminated successfully LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt index 1473cc8b7..c10a19a83 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt @@ -23,7 +23,7 @@ TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has TransportSvc SUCCESS GEOMETRY ERRORS: 'Codes' map has the size 0 TransportSvc INFO Reset the static pointer to DetDesc::IGeometyrErrorSvc ToolSvc INFO Removing all tools created by ToolSvc -ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/1/Finalized +ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/Finalized' ApplicationMgr INFO Application Manager Finalized successfully ApplicationMgr INFO Application Manager Terminated successfully LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 -- GitLab From d289d72f8a9aefe3c0ea4a7785fee5970da9e4f8 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 19 Feb 2021 22:02:00 +0000 Subject: [PATCH 21/27] RichRefIndexCalib - use public instance of camera tool --- Rich/Panoptes/tests/refs/rich_ref_index_calib.ref | 3 +-- .../tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt | 3 +-- Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref index bda58cabf..a195101c9 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref @@ -23,7 +23,6 @@ TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has TransportSvc SUCCESS GEOMETRY ERRORS: 'Codes' map has the size 0 TransportSvc INFO Reset the static pointer to DetDesc::IGeometyrErrorSvc ToolSvc INFO Removing all tools created by ToolSvc -ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/Finalized' ApplicationMgr INFO Application Manager Finalized successfully ApplicationMgr INFO Application Manager Terminated successfully LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 @@ -47,7 +46,7 @@ PrMatchNN INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#MatchingChi2" | 160419 | 860731.9 | 5.3655 | | "#MatchingTracks" | 928 | 58318 | 62.843 | - | "TracksMLP" | 160419 | 57076.32 | 0.3558 | + | "TracksMLP" | 160419 | 57076.31 | 0.3558 | PrMatchNN.PrAddUTHitsTool INFO Number of counters : 2 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "#UT hits added" | 51616 | 205788 | 3.9869 | diff --git a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt index c10a19a83..dcadafc5b 100644 --- a/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt +++ b/Rich/Panoptes/tests/refs/rich_ref_index_calib.ref.x86_64+avx2+fma-opt @@ -23,7 +23,6 @@ TransportSvc SUCCESS GEOMETRY ERRORS: 'Recover' map has TransportSvc SUCCESS GEOMETRY ERRORS: 'Codes' map has the size 0 TransportSvc INFO Reset the static pointer to DetDesc::IGeometyrErrorSvc ToolSvc INFO Removing all tools created by ToolSvc -ToolSvc.CameraTool WARNING Could not connect to any camera server! -> Aborting message '/Finalized' ApplicationMgr INFO Application Manager Finalized successfully ApplicationMgr INFO Application Manager Terminated successfully LHCb__Converters__Track__PrSeedi... INFO Number of counters : 1 @@ -45,7 +44,7 @@ PrGECFilter INFO Number of counters : 2 | "Nb events removed" | 65 | PrMatchNN INFO Number of counters : 3 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "#MatchingChi2" | 160714 | 862298.1 | 5.3654 | + | "#MatchingChi2" | 160714 | 862298 | 5.3654 | | "#MatchingTracks" | 928 | 58410 | 62.942 | | "TracksMLP" | 160714 | 57166.44 | 0.3557 | PrMatchNN.PrAddUTHitsTool INFO Number of counters : 2 diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp index 4a7b85fc1..8278e644d 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -180,7 +180,7 @@ namespace Rich::Future::Rec::Calib { Gaudi::Property m_minTimeBetweenCalibs{this, "MinTimeBetweenCalibs", 16 * 60}; // 16 mins /// Camera messaging - mutable ToolHandle m_cameraTool{this, "CameraTool", "CameraTool"}; + mutable ToolHandle m_cameraTool{this, "CameraTool", "CameraTool/CameraTool:PUBLIC"}; private: // cached data -- GitLab From 8c9c2ed158f4a2745c40196105d51da77e20d417 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 19 Feb 2021 22:42:13 +0000 Subject: [PATCH 22/27] RichRefIndexCalibWriter - clean up --- .../src/RichRefIndexCalibWriter.cpp | 37 +++++++++---------- .../src/RichRefIndexCalibWriter.h | 5 +-- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp index f4ef8785a..f67b268f3 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp @@ -301,10 +301,10 @@ StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { // Run Calibration from histo pointers //============================================================================= void RefIndexCalibWriter::runCalibration( const std::string& type, // - RadHists& histos, // - const unsigned int runNumber, // - const bool publishCalib, // - ICameraTool::MessageLevel level ) { + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { info() << "Starting n-1 calibration for run " << runNumber << " ..." << endmsg; @@ -462,9 +462,9 @@ void RefIndexCalibWriter::runCalibration( const std::string& type, // Run the calibration from a saveset //============================================================================= void RefIndexCalibWriter::runCalibration( const std::string& type, // - const RunAndSaveSet& data, // - const bool publishCalib, // - ICameraTool::MessageLevel level ) { + const RunAndSaveSet& data, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { // Save the run number m_runNumber = data.run; @@ -534,8 +534,8 @@ StatusCode RefIndexCalibWriter::finalize() { //============================================================================= RefIndexCalibWriter::FitResult // RefIndexCalibWriter::fitCKThetaHistogram( TH1* hist, // - const std::string& rad, // - const bool testFit ) const { + const std::string& rad, // + const bool testFit ) const { // Do the fit const auto irad = ( "Rich1Gas" == rad ? Rich::Rich1Gas : Rich::Rich2Gas ); auto fitRes = ( !testFit ? m_ckFitter.fit( *hist, irad ) : m_testCkFitter.fit( *hist, irad ) ); @@ -729,8 +729,8 @@ double RefIndexCalibWriter::getLastRefIndexSF( const std::string& rad ) { //============================================================================= bool RefIndexCalibWriter::updateRefIndexSF( const unsigned int runNumber, // - const std::string& rad, // - const double scale ) { + const std::string& rad, // + const double scale ) { bool OK = true; const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : // @@ -771,9 +771,9 @@ bool RefIndexCalibWriter::updateRefIndexSF( const unsigned int runNumber, // //============================================================================= bool RefIndexCalibWriter::xmlWriter( const std::string& type, // - const unsigned int runNumber, // - const double scale, // - const std::string& rad ) { + const unsigned int runNumber, // + const double scale, // + const std::string& rad ) { // Get version const auto version = setVersion( runNumber, rad ); bool OK = version.first; @@ -904,8 +904,8 @@ bool RefIndexCalibWriter::writeToDimSummaryFile( const std::string& mess ) const //============================================================================= bool RefIndexCalibWriter::writeCKThetaLog( const std::string& rad, // - const FitResult& fitResult, // - const unsigned int runNumber ) const { + const FitResult& fitResult, // + const unsigned int runNumber ) const { // Path to the summary file const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" ); const boost::filesystem::path filename( rad + m_CKThetaResLog ); @@ -933,9 +933,9 @@ bool RefIndexCalibWriter::writeCKThetaLog( const std::string& rad, // //============================================================================= -std::pair // +std::pair // RefIndexCalibWriter::setVersion( const unsigned int runNumber, // - const std::string& rad ) { + const std::string& rad ) { bool OK = true; unsigned long long version( 0 ); @@ -1144,4 +1144,3 @@ void RefIndexCalibWriter::fixFilePermissions() const { } //============================================================================= - diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h index 1b7f758c8..54db7dd0f 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h @@ -346,10 +346,7 @@ namespace Rich::Future::Rec::Calib { } /// Delete the current TCanvas - inline void deleteCanvas() const { - //if ( m_canvas.get() ) { m_canvas->Delete(); } - m_canvas.reset( nullptr ); - } + inline void deleteCanvas() const { m_canvas.reset( nullptr ); } /// Get the path to write summaries to inline std::string summaryPath() const { -- GitLab From 4ba5b617a2f1d8fa17da9508705300f65b931fcb Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 19 Feb 2021 22:42:45 +0000 Subject: [PATCH 23/27] RichRefIndexCalib - apply beta cut before scalar loop --- Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp index 8278e644d..11a05e19e 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -116,14 +116,6 @@ namespace Rich::Future::Rec::Calib { const CherenkovAngles::Vector& expTkCKThetas, // const SIMDCherenkovPhoton::Vector& photons ) const override; - // /// Initalize - // StatusCode initialize() override { - // auto sc = Consumer::initialize(); - // if ( !sc ) return sc; - // m_refInCalib->configureCalib(); - // return sc; - // } - /// Finalize StatusCode finalize() override { runCalibration(); @@ -373,7 +365,7 @@ void RefIndexCalib::operator()( const LHCb::ODIN& odin, const auto beta = richPartProps()->beta( pTot, pid ); // selection cuts - const auto betaC = ( beta >= m_minBeta[rad] && beta <= m_maxBeta[rad] ); + if ( beta < m_minBeta[rad] || beta > m_maxBeta[rad] ) { continue; } // expected CK theta const auto thetaExp = expCKangles[pid]; @@ -389,7 +381,7 @@ void RefIndexCalib::operator()( const LHCb::ODIN& odin, const auto deltaTheta = thetaRec - thetaExp; // fill resolution histos - if ( betaC ) { h_ckResAll[rad]->Fill( deltaTheta ); } + h_ckResAll[rad]->Fill( deltaTheta ); } // valid scalars } // SIMD loop -- GitLab From 5695165ddf190f7f7af41b59728f7eb8953555b3 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Sat, 20 Feb 2021 12:34:43 +0000 Subject: [PATCH 24/27] Make some more python print statements v3 happy --- .../Panoptes/python/Panoptes/Configuration.py | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/Rich/Panoptes/python/Panoptes/Configuration.py b/Rich/Panoptes/python/Panoptes/Configuration.py index 746237546..bafda4f52 100755 --- a/Rich/Panoptes/python/Panoptes/Configuration.py +++ b/Rich/Panoptes/python/Panoptes/Configuration.py @@ -150,8 +150,8 @@ class Panoptes(LHCbConfigurableUser): partition = os.getenv('PARTITION', '') self.setProp("Partition", partition) - #print "Mode = ", self.getProp("Mode") - #print "Partition = ", self.getProp("Partition") + #print("Mode = ", self.getProp("Mode")) + #print("Partition = ", self.getProp("Partition")) #sanity checks self.checkConfiguration() @@ -219,8 +219,8 @@ class Panoptes(LHCbConfigurableUser): except ImportError: - print self.getProp( - "MonName"), "ERROR : Cannot import MonitoringEnv" + print(self.getProp("MonName"), + "ERROR : Cannot import MonitoringEnv") else: @@ -360,8 +360,8 @@ class Panoptes(LHCbConfigurableUser): except ImportError: - print self.getProp( - "MonName"), "ERROR : Cannot import MonitoringEnv" + print(self.getProp("MonName"), + "ERROR : Cannot import MonitoringEnv") # Additional services ApplicationMgr().ExtSvc += ["ToolSvc", "AuditorSvc"] @@ -398,8 +398,8 @@ class Panoptes(LHCbConfigurableUser): else: servers = ["hist01.lbdaq.cern.ch:45121"] Camera().setProp("CameraServers", servers) - print self.getProp( - "MonName"), "INFO : Camera Server(s)", Camera().CameraServers + print(self.getProp("MonName"), "INFO : Camera Server(s)", + Camera().CameraServers) # Monitoring Svc if self.getProp("UseMonitorSvc"): @@ -414,8 +414,8 @@ class Panoptes(LHCbConfigurableUser): MonitorSvc().ExpandNameInfix = DimName MonitorSvc().PartitionName = MonitoringEnv.PartitionName except ImportError: - print self.getProp( - "MonName"), "ERROR : Cannot import MonitoringEnv" + print(self.getProp("MonName"), + "ERROR : Cannot import MonitoringEnv") # Incident Svc if self.getProp("UseIncidentSvc"): @@ -536,14 +536,11 @@ class Panoptes(LHCbConfigurableUser): "ERROR : Unkonwn Panoptes Partition '%s'" % partition) if (monitorRaw or monitorExpress) and monitorReco: - print self.getProp( - "MonName" - ), "INFO : monitor raw events %s " % monitorRaw - print self.getProp( - "MonName" - ), "INFO : monitor express events %s " % monitorExpress - print self.getProp( - "MonName" - ), "INFO : monitor reconstructed events %s " % monitorReco + print(self.getProp("MonName"), + "INFO : monitor raw events %s " % monitorRaw) + print(self.getProp("MonName"), + "INFO : monitor express events %s " % monitorExpress) + print(self.getProp("MonName"), + "INFO : monitor reconstructed events %s " % monitorReco) raise RuntimeError( "ERROR: can't subscribe to both RAW and RECONSTRUCTED streams") -- GitLab From d4182714beb0e8ad271ab1933bdc6e6b3648a441 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Sun, 21 Feb 2021 10:50:43 +0000 Subject: [PATCH 25/27] Simplify the calibrations options a little --- Rich/Panoptes/python/Panoptes/calibration.py | 40 +++++++------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/Rich/Panoptes/python/Panoptes/calibration.py b/Rich/Panoptes/python/Panoptes/calibration.py index e6008e75e..c60f64183 100644 --- a/Rich/Panoptes/python/Panoptes/calibration.py +++ b/Rich/Panoptes/python/Panoptes/calibration.py @@ -17,7 +17,7 @@ from PyConf.Algorithms import ( from RecoConf.hlt2_tracking import make_hlt2_tracks from RecoConf.rich_reconstruction import ( - default_rich_reco_options, make_rich_photons, get_radiator_bool_opts, + default_rich_reco_options, make_rich_pids, get_radiator_bool_opts, get_detector_bool_opts) from RecoConf.standalone import reco_prefilters @@ -33,14 +33,14 @@ def standalone_rich_ref_index_calib(): # Make the tracks hlt2_tracks = make_hlt2_tracks() - track_version = "v1" #print("Available Track Types", hlt2_tracks.keys()) - # The output data nodes - data = [] + # The track type we use + track_version = "v1" + tkType = "Long" # Get the fitted long tracks to use - tks = hlt2_tracks["BestLong"] + tks = hlt2_tracks["Best" + tkType] # Default RICH reco options reco_opts = default_rich_reco_options() @@ -61,32 +61,19 @@ def standalone_rich_ref_index_calib(): # Track selection tkSel = TracksToSelection(InputLocation=tks[track_version]) - # RICH photon reco (PID not needed here) - conf = make_rich_photons( - track_name="Long", + # RICH photon reco + conf = make_rich_pids( + track_name=tkType, input_tracks=tkSel.OutputLocation, options=reco_opts) # The detector and radiator options - rad_opts = get_radiator_bool_opts(reco_opts, "Long") - det_opts = get_detector_bool_opts(reco_opts, "Long") - - # Create working event summary of reco info - recSum = RecSummary( - name="RichRecSummaryLong", - Detectors=det_opts, - Radiators=rad_opts, - TrackSegmentsLocation=conf["TrackSegments"], - TrackToSegmentsLocation=conf["SelectedTrackToSegments"], - PhotonToParentsLocation=conf["PhotonToParents"], - DetectablePhotonYieldLocation=conf["DetectableYields"], - SignalPhotonYieldLocation=conf["SignalYields"], - PhotonSignalsLocation=conf["PhotonSignals"], - RichSIMDPixelSummariesLocation=conf["RichSIMDPixels"]) + rad_opts = get_radiator_bool_opts(reco_opts, tkType) + det_opts = get_detector_bool_opts(reco_opts, tkType) # Calibration algorithm calib = RefIndexCalib( - name="RichRefCalibLong", + name="RichRefCalib" + tkType, Detectors=det_opts, Radiators=rad_opts, ODINLocation=make_odin(), @@ -94,8 +81,7 @@ def standalone_rich_ref_index_calib(): TrackSegmentsLocation=conf["TrackSegments"], CherenkovPhotonLocation=conf["CherenkovPhotons"], CherenkovAnglesLocation=conf["SignalCKAngles"], - SummaryTracksLocation=recSum.SummaryTracksLocation, + SummaryTracksLocation=conf["SummaryTracks"], PhotonToParentsLocation=conf["PhotonToParents"]) - data += [calib] - return Reconstruction('rich_ref_index_calib', data, reco_prefilters()) + return Reconstruction('rich_ref_index_calib', [calib], reco_prefilters()) -- GitLab From d4f06d36358d916c6e4111feefa9c522a1ab3c86 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 23 Feb 2021 10:31:41 +0000 Subject: [PATCH 26/27] Return StatusCode from calibration methods --- .../RichOnlineCalib/src/RichRefIndexCalib.cpp | 12 +++--- .../src/RichRefIndexCalibWriter.cpp | 39 ++++++++++++------- .../src/RichRefIndexCalibWriter.h | 18 ++++----- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp index 11a05e19e..44013c458 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -437,13 +437,15 @@ void RefIndexCalib::runCalibration( const std::string& type ) const { m_cameraTool->Append( "TEXT", m.str() ); } - // save this run in the processed list with number of events used. - m_processedRuns[m_runNumber] = m_nEventsThisRun; - - // run calibration here... + // histos to fit RefIndexCalibWriter::RadHists hists{{"Rich1Gas", h_ckResAll[Rich::Rich1Gas]}, // {"Rich2Gas", h_ckResAll[Rich::Rich2Gas]}}; - m_refInCalib->runCalibration( type, hists, m_runNumber ); + // run the calib + const auto sc = m_refInCalib->runCalibration( type, hists, m_runNumber ); + if ( sc ) { + // save this run in the processed list with number of events used. + m_processedRuns[m_runNumber] = m_nEventsThisRun; + } // reset various counters for the next run resetCalibCounters(); diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp index f67b268f3..fca97acd4 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.cpp @@ -241,7 +241,7 @@ StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { if ( fileName.find( m_EoRSignal ) != std::string::npos ) { m_mergedRun = RunAndSaveSet( runNumber, SaveSet ); m_lastRun = RunAndSaveSet( 0, "" ); - runCalibration( "Final EOR", m_mergedRun, true ); + sc = runCalibration( "Final EOR", m_mergedRun, true ); // reset the cached histogram stats m_histStats.clear(); } // "-EOR" inside the file name @@ -252,7 +252,7 @@ StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { // const bool firstSetForRun = ( 0 == m_lastRun.first ); m_lastRun = RunAndSaveSet( runNumber, SaveSet ); // runCalibration( "Periodic", m_lastRun, m_createPrelimCalib && firstSetForRun ); - runCalibration( "Periodic", m_lastRun, m_createPrelimCalib ); + sc = runCalibration( "Periodic", m_lastRun, m_createPrelimCalib ); } // wait for new file else if ( runNumber != m_lastRun.run ) // new Run, use previous file { @@ -267,7 +267,7 @@ StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { cameraTool()->Append( "TEXT", mess.str() ); warning() << mess.str() << endmsg; // Run calibration for the last run - runCalibration( "Final", m_lastRun, true, ICameraTool::WARNING ); + sc = runCalibration( "Final", m_lastRun, true, ICameraTool::WARNING ); } else { // warn about an unusual run number std::ostringstream mess; @@ -279,7 +279,7 @@ StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { m_histStats.clear(); // Run a first calibration for this run const auto thisRun = RunAndSaveSet( runNumber, SaveSet ); - runCalibration( "First", thisRun, m_createPrelimCalib ); + sc = runCalibration( "First", thisRun, m_createPrelimCalib ); // reset for the next call m_mergedRun = m_lastRun; m_lastRun = RunAndSaveSet( 0, "" ); @@ -300,11 +300,13 @@ StatusCode RefIndexCalibWriter::runCalibration( const std::string& SaveSet ) { //============================================================================= // Run Calibration from histo pointers //============================================================================= -void RefIndexCalibWriter::runCalibration( const std::string& type, // - RadHists& histos, // - const unsigned int runNumber, // - const bool publishCalib, // - ICameraTool::MessageLevel level ) { +StatusCode RefIndexCalibWriter::runCalibration( const std::string& type, // + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { + + StatusCode sc = StatusCode::SUCCESS; info() << "Starting n-1 calibration for run " << runNumber << " ..." << endmsg; @@ -447,6 +449,7 @@ void RefIndexCalibWriter::runCalibration( const std::string& type, mess << " was SUCCESSFUL"; } else { mess << " FAILED"; + sc = StatusCode::FAILURE; } cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); if ( ICameraTool::ERROR == level ) { @@ -456,15 +459,19 @@ void RefIndexCalibWriter::runCalibration( const std::string& type, } else { info() << mess.str() << endmsg; } + + return sc; } //============================================================================= // Run the calibration from a saveset //============================================================================= -void RefIndexCalibWriter::runCalibration( const std::string& type, // - const RunAndSaveSet& data, // - const bool publishCalib, // - ICameraTool::MessageLevel level ) { +StatusCode RefIndexCalibWriter::runCalibration( const std::string& type, // + const RunAndSaveSet& data, // + const bool publishCalib, // + ICameraTool::MessageLevel level ) { + + StatusCode sc = StatusCode::SUCCESS; // Save the run number m_runNumber = data.run; @@ -494,11 +501,12 @@ void RefIndexCalibWriter::runCalibration( const std::string& type, mess << "Failed to load histogram '" << radHistName << "'"; warning() << mess.str() << endmsg; cameraTool()->Append( "TEXT", mess.str() ); + sc = StatusCode::FAILURE; } } // run calib - runCalibration( type, rHists, data.run, publishCalib, level ); + sc = runCalibration( type, rHists, data.run, publishCalib, level ); // close the saveset file hfile->Close(); @@ -511,7 +519,10 @@ void RefIndexCalibWriter::runCalibration( const std::string& type, cameraTool()->Append( "TEXT", info.str() ); mess << type << " Refractive index calibration for Run " << data.run; cameraTool()->SendAndClearTS( level, m_Name, mess.str() ); + sc = StatusCode::FAILURE; } + + return sc; } //============================================================================= diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h index 54db7dd0f..98d1d9696 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalibWriter.h @@ -102,11 +102,11 @@ namespace Rich::Future::Rec::Calib { //============================================================================= /// Run Calibration from histo pointers //============================================================================= - void runCalibration( const std::string& type, // - RadHists& histos, // - const unsigned int runNumber, // - const bool publishCalib = true, // - ICameraTool::MessageLevel level = ICameraTool::INFO ); + StatusCode runCalibration( const std::string& type, // + RadHists& histos, // + const unsigned int runNumber, // + const bool publishCalib = true, // + ICameraTool::MessageLevel level = ICameraTool::INFO ); private: // implementation details @@ -130,10 +130,10 @@ namespace Rich::Future::Rec::Calib { //============================================================================= /// Run Calibration from saveset //============================================================================= - void runCalibration( const std::string& type, // - const RunAndSaveSet& data, // - const bool publishCalib = true, // - ICameraTool::MessageLevel level = ICameraTool::INFO ); + StatusCode runCalibration( const std::string& type, // + const RunAndSaveSet& data, // + const bool publishCalib = true, // + ICameraTool::MessageLevel level = ICameraTool::INFO ); //============================================================================= /// Load camera tool on demand -- GitLab From 9ada1dc08c760864c76cde9884c6b05392bf35b4 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 23 Feb 2021 10:32:14 +0000 Subject: [PATCH 27/27] Add overrides (comments) to calibration options --- Rich/Panoptes/options/RichRefIndexCalib.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Rich/Panoptes/options/RichRefIndexCalib.py b/Rich/Panoptes/options/RichRefIndexCalib.py index 2da7d4e34..454c6ee74 100644 --- a/Rich/Panoptes/options/RichRefIndexCalib.py +++ b/Rich/Panoptes/options/RichRefIndexCalib.py @@ -15,6 +15,10 @@ from RecoConf.hlt2_tracking import make_hlt2_tracks, make_light_reco_best_tracks options.histo_file = "RichRefIndexCalib.root" +# Override previously set defaults +#options.evt_max = 100000 +#options.n_threads = 4 + with make_light_reco_best_tracks.bind(fit_preselection="(TrP>5000.0) & (TrPT>300.0)"),\ TrackMasterFitter.bind(FastMaterialApproximation=True),\ make_hlt2_tracks.bind(use_pr_kf=False, light_reco=True, fast_reco=True): -- GitLab