diff --git a/Rich/RichOnlineCalib/src/RichCalibUtils.h b/Rich/RichOnlineCalib/src/RichCalibUtils.h index 532956c42f5b10ab01a73e1d4c16d040719db505..41b3984285f8c27de5cc633e7a80931779d38800 100644 --- a/Rich/RichOnlineCalib/src/RichCalibUtils.h +++ b/Rich/RichOnlineCalib/src/RichCalibUtils.h @@ -36,22 +36,29 @@ // STL #include #include +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include namespace Rich::Calib::Utils { + template + using RunByRunHists = std::deque; + /// Type for value+-error template struct ValueWithError { @@ -115,6 +122,9 @@ namespace Rich::Calib::Utils { * with the number of events used for that calibration */ mutable std::map m_processedRuns; + /// Last run number for 'extra histograms' + mutable std::optional m_lastRunExtraHists{}; + protected: // properties @@ -365,6 +375,16 @@ namespace Rich::Calib::Utils { // Make a pull plot from a histogram and a given function //============================================================================= std::unique_ptr makePullPlot( TH1& hist, TF1& func ) const; + + /// Fill the 'last' run by run histogram + template + inline void fillRunByRunHist( RunByRunHists& hists, Args&&... args ) const { + assert( !hists.empty() ); + if ( !hists.empty() ) { + // Always fill the last histogram added to the container + ++hists.back()[{std::forward( args )...}]; + } + } }; }; // namespace Rich::Calib::Utils diff --git a/Rich/RichOnlineCalib/src/RichPhotonCounting.cpp b/Rich/RichOnlineCalib/src/RichPhotonCounting.cpp index 6fd9249675566e02984b4782699ddf51b0ad0dad..04e2e8ea5d7f64fde3103073df03e574c6124ad5 100644 --- a/Rich/RichOnlineCalib/src/RichPhotonCounting.cpp +++ b/Rich/RichOnlineCalib/src/RichPhotonCounting.cpp @@ -48,7 +48,9 @@ namespace Rich::Future::Rec::Counting { namespace { using PhotonYield = ValueWithError; - } + template + using QuadArray = std::array; + } // namespace /** @class PhotonCounting RichPhotonCounting.h * @@ -199,6 +201,81 @@ namespace Rich::Future::Rec::Counting { } } + /// Initialise extra histos + bool initExtraHists( const unsigned int RunNumber = 0 ) const { + bool ok = true; + if ( !m_lastRunExtraHists.has_value() || RunNumber != m_lastRunExtraHists.value() ) { + m_lastRunExtraHists = RunNumber; + calib_message( MSG::DEBUG, "Resetting run-by-run histograms for run ", RunNumber ); + const auto runT = ( RunNumber > 0 ? " | Run " + std::to_string( RunNumber ) : "" ); + const auto runID = ( RunNumber > 0 ? "Runs/" + std::to_string( RunNumber ) + "/" : "" ); + const auto quadS = std::array{" | Quadrant x>0 y>0", " | Quadrant x<0 y>0", // + " | Quadrant x>0 y<0", " | Quadrant x<0 y<0"}; + for ( const auto rad : activeRadiators() ) { + ok &= initHist( h_ckThetaRec_run[rad].emplace_back(), HID( runID + "ckThetaRec", rad ), "Rec CKTheta" + runT, + m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), "Cherenkov theta / rad" ); + ok &= initHist( h_ckThetaExp_run[rad].emplace_back(), HID( runID + "ckThetaExp", rad ), "Exp CKTheta" + runT, + m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), "Cherenkov theta / rad" ); + ok &= initHist( h_ckThetaRes_run[rad].emplace_back(), HID( runID + "ckThetaRes", rad ), // + "Rec-Exp CKTheta" + runT, // + -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // + "delta(Cherenkov theta) / rad" ); + ok &= initHist( h_tkPtot_run[rad].emplace_back(), HID( runID + "tkPtot", rad ), "Track Momentum" + runT, + m_minP[rad], std::min( m_maxP[rad], 120 * Gaudi::Units::GeV ), nBins1D(), + "Track Momentum / MeV" ); + for ( unsigned int q = 0; q < quadS.size(); ++q ) { + ok &= initHist( h_ckThetaRes_quadrants_run[rad].at( q ).emplace_back(), + HID( runID + "ckThetaResQuad" + std::to_string( q ), rad ), + "Rec-Exp CKTheta" + runT + quadS.at( q ), -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), + "delta(Cherenkov theta) / rad" ); + } + // track (x,y) plots + const double xSize = ( Rich::Rich1Gas == rad ? 500 : 2000 ); + const double ySize = ( Rich::Rich1Gas == rad ? 500 : 2000 ); + ok &= initHist( h_tkEntryXY_run[rad].emplace_back(), HID( runID + "trackEntryXY", rad ), // + "Track Radiator Entry (x,y)" + runT, // + -xSize, xSize, nBins2D(), // + -ySize, ySize, nBins2D(), // + "Track Entry X / mm", "TrackEntry Y / mm" ); + ok &= initHist( h_tkSegMomVSPhotonYield_run[rad].emplace_back(), + HID( runID + "trackSegMomVSPhotonYield", rad ), "Track Seg Momentum Photon Yield" + runT, + -100, 200, 40, 5000, 50000, 40, "Detected Cherenkov Photons", "Segment Momentum / MeV" ); + ok &= initHist( h_tkpathLengthVSPhotonYield_run[rad].emplace_back(), + HID( runID + "trackpathLengthVSPhotonYield", rad ), "Track Path Length Photon Yield" + runT, + -100, 200, 40, 1000, 1250, 40, "Detected Cherenkov Photons", "Track Path Length / mm" ); + + ok &= initHist( h_ckPhotonSig_run[rad].emplace_back(), HID( runID + "ckPhotonSigYield", rad ), + "Detected CKPhoton Yield" + runT, -100, 200, 40, "Detected Cherenkov Photons" ); + ok &= initHist( h_ckPhotonSigNoSub_run[rad].emplace_back(), HID( runID + "ckPhotonSigNoSub", rad ), + "Detected CKPhoton SigNoSub" + runT, -100, 400, 40, "Detected Cherenkov Photons" ); + ok &= initHist( h_ckPhotonBckLow_run[rad].emplace_back(), HID( runID + "ckPhotonBckLow", rad ), + "Detected CKPhoton BckLow" + runT, -100, 200, 40, "Detected Cherenkov Photons" ); + ok &= initHist( h_ckPhotonBckHigh_run[rad].emplace_back(), HID( runID + "ckPhotonBckHigh", rad ), + "Detected CKPhoton BckHigh" + runT, -100, 200, 40, "Detected Cherenkov Photons" ); + + for ( unsigned int q = 0; q < quadS.size(); ++q ) { + ok &= initHist( h_ckPhotonSig_quadrants_run[rad].at( q ).emplace_back(), + HID( runID + "ckPhotonSigYieldQuad" + std::to_string( q ), rad ), + "Detected CKPhoton Yield" + runT + quadS.at( q ), // + -100, 200, 40, "Detected Cherenkov Photons" ); + ok &= initHist( h_ckPhotonSigNoSub_quadrants_run[rad].at( q ).emplace_back(), + HID( runID + "ckPhotonSigNoSubQuad" + std::to_string( q ), rad ), + "Detected CKPhoton SigNoSub" + runT + quadS.at( q ), // + -100, 400, 40, "Detected Cherenkov Photons" ); + ok &= initHist( h_ckPhotonBckLow_quadrants_run[rad].at( q ).emplace_back(), + HID( runID + "ckPhotonBckLowQuad" + std::to_string( q ), rad ), + "Detected CKPhoton BckLow" + runT + quadS.at( q ), // + -100, 200, 40, "Detected Cherenkov Photons" ); + ok &= initHist( h_ckPhotonBckHigh_quadrants_run[rad].at( q ).emplace_back(), + HID( runID + "ckPhotonBckHighQuad" + std::to_string( q ), rad ), + "Detected CKPhoton BckHigh" + runT + quadS.at( q ), // + -100, 200, 40, "Detected Cherenkov Photons" ); + } + } + } + return ok; + } + /// Run the photon counting ... void runPhotonCounting( const std::string& type = "Final" ) const; @@ -249,26 +326,22 @@ namespace Rich::Future::Rec::Counting { RadiatorArray> h_ckPhotonYield = {{}}; // Current active run-by-run histograms - mutable RadiatorArray h_ckThetaRec_run = {{}}; - mutable RadiatorArray h_ckThetaExp_run = {{}}; - mutable RadiatorArray h_ckThetaRes_run = {{}}; - mutable RadiatorArray h_tkPtot_run = {{}}; - mutable RadiatorArray> h_ckThetaRes_quadrants_run = {{{}}}; - mutable RadiatorArray h_tkEntryXY_run = {{}}; - - mutable RadiatorArray h_ckPhotonSig_run = {{}}; - mutable RadiatorArray> h_ckPhotonSig_quadrants_run = {{{}}}; - - mutable RadiatorArray h_ckPhotonSigNoSub_run = {{}}; - mutable RadiatorArray> h_ckPhotonSigNoSub_quadrants_run = {{{}}}; - - mutable RadiatorArray h_ckPhotonBckLow_run = {{}}; - mutable RadiatorArray> h_ckPhotonBckLow_quadrants_run = {{{}}}; - mutable RadiatorArray h_ckPhotonBckHigh_run = {{}}; - mutable RadiatorArray> h_ckPhotonBckHigh_quadrants_run = {{{}}}; - - mutable RadiatorArray h_tkSegMomVSPhotonYield_run = {{}}; - mutable RadiatorArray h_tkpathLengthVSPhotonYield_run = {{}}; + mutable RadiatorArray>> h_ckThetaRec_run = {{}}; + mutable RadiatorArray>> h_ckThetaExp_run = {{}}; + mutable RadiatorArray>> h_ckThetaRes_run = {{}}; + mutable RadiatorArray>> h_tkPtot_run = {{}}; + mutable RadiatorArray>>> h_ckThetaRes_quadrants_run = {{{}}}; + mutable RadiatorArray>> h_tkEntryXY_run = {{}}; + mutable RadiatorArray>> h_ckPhotonSig_run = {{}}; + mutable RadiatorArray>>> h_ckPhotonSig_quadrants_run = {{{}}}; + mutable RadiatorArray>> h_ckPhotonSigNoSub_run = {{}}; + mutable RadiatorArray>>> h_ckPhotonSigNoSub_quadrants_run = {{{}}}; + mutable RadiatorArray>> h_ckPhotonBckLow_run = {{}}; + mutable RadiatorArray>>> h_ckPhotonBckLow_quadrants_run = {{{}}}; + mutable RadiatorArray>> h_ckPhotonBckHigh_run = {{}}; + mutable RadiatorArray>>> h_ckPhotonBckHigh_quadrants_run = {{{}}}; + mutable RadiatorArray>> h_tkSegMomVSPhotonYield_run = {{}}; + mutable RadiatorArray>> h_tkpathLengthVSPhotonYield_run = {{}}; }; } // namespace Rich::Future::Rec::Counting @@ -315,146 +388,12 @@ void PhotonCounting::operator()( const LHCb::ODIN& odin, } } // before updating cached run number, check if new run-by-run histograms are required - if ( m_enableRunByRunHists ) { - calib_message( MSG::DEBUG, "Resetting run-by-run histograms for run ", RunNumber ); - const auto runS = std::to_string( RunNumber ); - for ( const auto rad : activeRadiators() ) { - // reset pointers to new histos for this run - h_ckThetaRec_run[rad] = richHisto1D( HID( "Runs/" + runS + "/ckThetaRec", rad ), "Rec CKTheta | Run " + runS, // - m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), "Cherenkov theta / rad" ); - h_ckThetaExp_run[rad] = richHisto1D( HID( "Runs/" + runS + "/ckThetaExp", rad ), "Exp CKTheta | Run " + runS, // - m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), "Cherenkov theta / rad" ); - h_ckThetaRes_run[rad] = richHisto1D( HID( "Runs/" + runS + "/ckThetaRes", rad ), // - "Rec-Exp CKTheta | Run " + runS, // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad" ); - h_tkPtot_run[rad] = richHisto1D( HID( "Runs/" + runS + "/tkPtot", rad ), "Track Momentum | Run " + runS, // - m_minP[rad], std::min( m_maxP[rad], 120 * Gaudi::Units::GeV ), nBins1D(), - "Track Momentum / MeV" ); - h_ckThetaRes_quadrants_run[rad][0] = richHisto1D( HID( "Runs/" + runS + "/ckThetaResQuad0", rad ), // - "Rec-Exp CKTheta | Run " + runS + " | Quadrant x>0 y>0", // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad" ); - h_ckThetaRes_quadrants_run[rad][1] = richHisto1D( HID( "Runs/" + runS + "/ckThetaResQuad1", rad ), // - "Rec-Exp CKTheta | Run " + runS + " | Quadrant x<0 y>0", // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad" ); - h_ckThetaRes_quadrants_run[rad][2] = richHisto1D( HID( "Runs/" + runS + "/ckThetaResQuad2", rad ), // - "Rec-Exp CKTheta | Run " + runS + " | Quadrant x>0 y<0", // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad" ); - h_ckThetaRes_quadrants_run[rad][3] = richHisto1D( HID( "Runs/" + runS + "/ckThetaResQuad3", rad ), // - "Rec-Exp CKTheta | Run " + runS + " | Quadrant x<0 y<0", // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad" ); - // track (x,y) plots - const double xSize = ( Rich::Rich1Gas == rad ? 500 : 2000 ); - const double ySize = ( Rich::Rich1Gas == rad ? 500 : 2000 ); - h_tkEntryXY_run[rad] = richHisto2D( HID( "Runs/" + runS + "/trackEntryXY", rad ), // - "Track Radiator Entry (x,y) | Run " + runS, // - -xSize, xSize, nBins2D(), // - -ySize, ySize, nBins2D(), // - "Track Entry X / mm", "TrackEntry Y / mm" ); - - h_tkSegMomVSPhotonYield_run[rad] = richHisto2D( HID( "Runs/" + runS + "/trackSegMomVSPhotonYield", rad ), // - "Track Seg Momentum Photon Yield | Run " + runS, // - -100, 200, 40, // - 5000, 50000, 40, // - "Detected Cherenkov Photon", "Seg Momentum / MeV" ); - h_tkpathLengthVSPhotonYield_run[rad] = - richHisto2D( HID( "Runs/" + runS + "/trackpathLengthVSPhotonYield", rad ), // - "Track Path Length Photon Yield | Run " + runS, // - -100, 200, 40, // - 1000, 1250, 40, // - "Detected Cherenkov Photon", "Track Path Length / mm" ); - - h_ckPhotonSig_run[rad] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigYield", rad ), "Detected CKPhoton Yield | Run " + runS, // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSig_quadrants_run[rad][0] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigYieldQuad0", rad ), - "Detected CKPhoton Yield | Run " + runS + " | Quadrant x>0 y>0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSig_quadrants_run[rad][1] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigYieldQuad1", rad ), - "Detected CKPhoton Yield | Run " + runS + " | Quadrant x<0 y>0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSig_quadrants_run[rad][2] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigYieldQuad2", rad ), - "Detected CKPhoton Yield | Run " + runS + " | Quadrant x>0 y<0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSig_quadrants_run[rad][3] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigYieldQuad3", rad ), - "Detected CKPhoton Yield | Run " + runS + " | Quadrant x<0 y<0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - - h_ckPhotonSigNoSub_run[rad] = richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigNoSub", rad ), - "Detected CKPhoton SigNoSub | Run " + runS, // - -100, 400, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSigNoSub_quadrants_run[rad][0] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigNoSubQuad0", rad ), - "Detected CKPhoton SigNoSub | Run " + runS + " | Quadrant x>0 y>0", // - -100, 400, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSigNoSub_quadrants_run[rad][1] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigNoSubQuad1", rad ), - "Detected CKPhoton SigNoSub | Run " + runS + " | Quadrant x<0 y>0", // - -100, 400, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSigNoSub_quadrants_run[rad][2] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigNoSubQuad2", rad ), - "Detected CKPhoton SigNoSub | Run " + runS + " | Quadrant x>0 y<0", // - -100, 400, 40, "Detected Cherenkov Photon" ); - h_ckPhotonSigNoSub_quadrants_run[rad][3] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonSigNoSubQuad3", rad ), - "Detected CKPhoton SigNoSub | Run " + runS + " | Quadrant x<0 y<0", // - -100, 400, 40, "Detected Cherenkov Photon" ); - - h_ckPhotonBckLow_run[rad] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckLow", rad ), "Detected CKPhoton BckLow | Run " + runS, // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckLow_quadrants_run[rad][0] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckLowQuad0", rad ), - "Detected CKPhoton BckLow | Run " + runS + " | Quadrant x>0 y>0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckLow_quadrants_run[rad][1] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckLowQuad1", rad ), - "Detected CKPhoton BckLow | Run " + runS + " | Quadrant x<0 y>0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckLow_quadrants_run[rad][2] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckLowQuad2", rad ), - "Detected CKPhoton BckLow | Run " + runS + " | Quadrant x>0 y<0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckLow_quadrants_run[rad][3] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckLowQuad3", rad ), - "Detected CKPhoton BckLow | Run " + runS + " | Quadrant x<0 y<0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - - h_ckPhotonBckHigh_run[rad] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckHigh", rad ), "Detected CKPhoton BckHigh | Run " + runS, // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckHigh_quadrants_run[rad][0] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckHighQuad0", rad ), - "Detected CKPhoton BckHigh | Run " + runS + " | Quadrant x>0 y>0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckHigh_quadrants_run[rad][1] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckHighQuad1", rad ), - "Detected CKPhoton BckHigh | Run " + runS + " | Quadrant x<0 y>0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckHigh_quadrants_run[rad][2] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckHighQuad2", rad ), - "Detected CKPhoton BckHigh | Run " + runS + " | Quadrant x>0 y<0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - h_ckPhotonBckHigh_quadrants_run[rad][3] = - richHisto1D( HID( "Runs/" + runS + "/ckPhotonBckHighQuad3", rad ), - "Detected CKPhoton BckHigh | Run " + runS + " | Quadrant x<0 y<0", // - -100, 200, 40, "Detected Cherenkov Photon" ); - } - } + if ( m_enableRunByRunHists && RunNumber != runNumber() ) { initExtraHists( RunNumber ); } } // Check to see if a counting should be run due to a new run being detected - if ( runNumber() != 0 ) { - if ( runNumber() != RunNumber ) { runPhotonCounting(); } - } + if ( runNumber() != 0 && runNumber() != RunNumber ) { runPhotonCounting(); } + // update cached run number m_runNumber = RunNumber; // count events @@ -555,16 +494,16 @@ void PhotonCounting::operator()( const LHCb::ODIN& odin, // Segment (x,y) entry point to radiator const auto seg_x = seg.entryPoint().x(); const auto seg_y = seg.entryPoint().y(); - fillHisto( h_tkEntryXY_run[rad], seg_x, seg_y ); + fillRunByRunHist( h_tkEntryXY_run[rad], seg_x, seg_y ); // Loop over scalar entries in SIMD photon for ( std::size_t i = 0; i < SIMDCherenkovPhoton::SIMDFP::Size; ++i ) { // Select valid entries and fill if ( phot.validityMask()[i] ) { - fillHisto( h_ckThetaRec_run[rad], phot.CherenkovTheta()[i] ); - fillHisto( h_ckThetaExp_run[rad], thetaExp[i] ); - fillHisto( h_ckThetaRes_run[rad], deltaTheta[i] ); + fillRunByRunHist( h_ckThetaRec_run[rad], phot.CherenkovTheta()[i] ); + fillRunByRunHist( h_ckThetaExp_run[rad], thetaExp[i] ); + fillRunByRunHist( h_ckThetaRes_run[rad], deltaTheta[i] ); const auto q = ( seg_x > 0 ? ( seg_y > 0 ? 0 : 2 ) : ( seg_y > 0 ? 1 : 3 ) ); - fillHisto( h_ckThetaRes_quadrants_run[rad][q], deltaTheta[i] ); + fillRunByRunHist( h_ckThetaRes_quadrants_run[rad].at( q ), deltaTheta[i] ); } } } @@ -599,9 +538,8 @@ void PhotonCounting::operator()( const LHCb::ODIN& odin, const auto bkgSubN = bkgNLinSig[rich] - ( bkgNLinB1[rich] * cBl + bkgNLinB2[rich] * cBh ); // Calculations for quadratic background subtractions - const auto bkgSubN_Q = GetQuadraticYield( rich, // - bkgNQuadB1[rich], bkgNQuadB2[rich], bkgNQuadB3[rich], // - bkgNQuadSig[rich] ); + const auto bkgSubN_Q = + GetQuadraticYield( rich, bkgNQuadB1[rich], bkgNQuadB2[rich], bkgNQuadB3[rich], bkgNQuadSig[rich] ); // Fill photon yield according to used background model if ( m_enableQuadraticBckModel ) { @@ -611,18 +549,18 @@ void PhotonCounting::operator()( const LHCb::ODIN& odin, } if ( m_enableRunByRunHists ) { - fillHisto( h_ckPhotonSig_run[rad], bkgSubN ); - fillHisto( h_ckPhotonSigNoSub_run[rad], bkgNLinSig[rich] ); - fillHisto( h_ckPhotonBckLow_run[rad], bkgNLinB1[rich] ); - fillHisto( h_ckPhotonBckHigh_run[rad], bkgNLinB2[rich] ); - fillHisto( h_tkSegMomVSPhotonYield_run[rad], bkgSubN, pTot ); - fillHisto( h_tkpathLengthVSPhotonYield_run[rad], bkgSubN, pathLen ); + fillRunByRunHist( h_ckPhotonSig_run[rad], bkgSubN ); + fillRunByRunHist( h_ckPhotonSigNoSub_run[rad], bkgNLinSig[rich] ); + fillRunByRunHist( h_ckPhotonBckLow_run[rad], bkgNLinB1[rich] ); + fillRunByRunHist( h_ckPhotonBckHigh_run[rad], bkgNLinB2[rich] ); + fillRunByRunHist( h_tkSegMomVSPhotonYield_run[rad], bkgSubN, pTot ); + fillRunByRunHist( h_tkpathLengthVSPhotonYield_run[rad], bkgSubN, pathLen ); // Quad 1-4 const auto q = ( seg_x > 0 ? ( seg_y > 0 ? 0 : 2 ) : ( seg_y > 0 ? 1 : 3 ) ); - fillHisto( h_ckPhotonSig_quadrants_run[rad][q], bkgSubN ); - fillHisto( h_ckPhotonSigNoSub_quadrants_run[rad][q], bkgNLinSig[rich] ); - fillHisto( h_ckPhotonBckLow_quadrants_run[rad][q], bkgNLinB1[rich] ); - fillHisto( h_ckPhotonBckHigh_quadrants_run[rad][q], bkgNLinB2[rich] ); + fillRunByRunHist( h_ckPhotonSig_quadrants_run[rad].at( q ), bkgSubN ); + fillRunByRunHist( h_ckPhotonSigNoSub_quadrants_run[rad].at( q ), bkgNLinSig[rich] ); + fillRunByRunHist( h_ckPhotonBckLow_quadrants_run[rad].at( q ), bkgNLinB1[rich] ); + fillRunByRunHist( h_ckPhotonBckHigh_quadrants_run[rad].at( q ), bkgNLinB2[rich] ); } } } @@ -639,7 +577,7 @@ void PhotonCounting::operator()( const LHCb::ODIN& odin, // beta const auto beta = richPartProps()->beta( pTot, pid ); if ( beta < m_minBeta[rad] || beta > m_maxBeta[rad] ) { continue; } - fillHisto( h_tkPtot_run[rad], pTot ); + fillRunByRunHist( h_tkPtot_run[rad], pTot ); } } } diff --git a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp index 7bbba89feec8478acbb0fe70b476457e419c4a50..19fcbb86f93f45dddf8c6b07b302cf53c7050d18 100644 --- a/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp +++ b/Rich/RichOnlineCalib/src/RichRefIndexCalib.cpp @@ -13,7 +13,6 @@ #include "Gaudi/Parsers/Factory.h" #include "GaudiKernel/PhysicalConstants.h" #include "GaudiKernel/StdArrayAsProperty.h" -#include "GaudiUtils/Aida2ROOT.h" // Local #include "RichCalibUtils.h" @@ -269,8 +268,8 @@ namespace Rich::Future::Rec::Calib { protected: /// Pre-Book all histograms StatusCode prebookHistograms() override { - bool ok = true; - auto initHist = [&]( auto* h ) { + bool ok = true; + auto initTHist = [&]( auto* h ) { bool ok = false; if ( h ) { ok = true; @@ -293,13 +292,13 @@ namespace Rich::Future::Rec::Calib { h_ckResAll[rad] = std::make_unique( ( "ckResAll" + Rich::text( rad ) ).c_str(), // ( Rich::text( rad ) + " Rec-Exp CK Theta Resolution" ).c_str(), // nBins1D(), -m_ckResRange[rad], m_ckResRange[rad] ); - ok &= initHist( h_ckResAll[rad].get() ); + ok &= initTHist( h_ckResAll[rad].get() ); for ( unsigned int q = 0; q < 4; ++q ) { h_ckResAllQuads[rad][q] = std::make_unique( ( "ckResAll" + Rich::text( rad ) + "Q" + std::to_string( q ) ).c_str(), // ( Rich::text( rad ) + " Rec-Exp CK Theta Resolution | Quadrant " + quadString( q ) ).c_str(), // nBins1D(), -m_ckResRange[rad], m_ckResRange[rad] ); - ok &= initHist( h_ckResAllQuads[rad][q].get() ); + ok &= initTHist( h_ckResAllQuads[rad][q].get() ); } } // active rad loop if ( !m_enableRunByRunHists ) { initExtraHists(); } @@ -341,40 +340,43 @@ namespace Rich::Future::Rec::Calib { /// Initialise extra histos bool initExtraHists( const unsigned int RunNumber = 0 ) const { bool ok = true; - calib_message( MSG::DEBUG, "Resetting run-by-run histograms for run ", RunNumber ); - const auto runT = ( RunNumber > 0 ? " | Run " + std::to_string( RunNumber ) : "" ); - const auto runID = ( RunNumber > 0 ? "Runs/" + std::to_string( RunNumber ) + "/" : "" ); - for ( const auto rad : activeRadiators() ) { - // reset pointers to new histos for this run - ok &= saveAndCheck( h_ckThetaRec_run[rad], // - richHisto1D( HID( runID + "ckThetaRec", rad ), "Rec CKTheta" + runT, // - m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), // - "Cherenkov theta / rad", "Entries" ) ); - ok &= saveAndCheck( h_ckThetaExp_run[rad], // - richHisto1D( HID( runID + "ckThetaExp", rad ), "Exp CKTheta" + runT, // - m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), // - "Cherenkov theta / rad", "Entries" ) ); - ok &= saveAndCheck( h_ckThetaRes_run[rad], // - richHisto1D( HID( runID + "ckThetaRes", rad ), // - "Rec-Exp CKTheta" + runT, // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad", "Entries" ) ); - for ( unsigned int q = 0; q < 4; ++q ) { - ok &= saveAndCheck( h_ckThetaRes_quads_run[rad][q], // - richHisto1D( HID( runID + "ckThetaResQuad" + std::to_string( q ), rad ), // - "Rec-Exp CKTheta | Quadrant " + quadString( q ) + runT, // - -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // - "delta(Cherenkov theta) / rad", "Entries" ) ); + if ( !m_lastRunExtraHists.has_value() || RunNumber != m_lastRunExtraHists.value() ) { + m_lastRunExtraHists = RunNumber; + calib_message( MSG::DEBUG, "Resetting run-by-run histograms for run ", RunNumber ); + const auto runT = ( RunNumber > 0 ? " | Run " + std::to_string( RunNumber ) : "" ); + const auto runID = ( RunNumber > 0 ? "Runs/" + std::to_string( RunNumber ) + "/" : "" ); + for ( const auto rad : activeRadiators() ) { + // reset pointers to new histos for this run + ok &= initHist( h_ckThetaRec_run[rad].emplace_back(), // + HID( runID + "ckThetaRec", rad ), "Rec CKTheta" + runT, // + m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), // + "Cherenkov theta / rad", "Entries" ); + ok &= initHist( h_ckThetaExp_run[rad].emplace_back(), // + HID( runID + "ckThetaExp", rad ), "Exp CKTheta" + runT, // + m_ckThetaMin[rad], m_ckThetaMax[rad], nBins1D(), // + "Cherenkov theta / rad", "Entries" ); + ok &= initHist( h_ckThetaRes_run[rad].emplace_back(), // + HID( runID + "ckThetaRes", rad ), // + "Rec-Exp CKTheta" + runT, // + -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // + "delta(Cherenkov theta) / rad", "Entries" ); + for ( unsigned int q = 0; q < 4; ++q ) { + ok &= initHist( h_ckThetaRes_quads_run[rad][q].emplace_back(), // + HID( runID + "ckThetaResQuad" + std::to_string( q ), rad ), // + "Rec-Exp CKTheta | Quadrant " + quadString( q ) + runT, // + -m_ckResRange[rad], m_ckResRange[rad], nBins1D(), // + "delta(Cherenkov theta) / rad", "Entries" ); + } + // track (x,y) plots + const double xSize = ( Rich::Rich1Gas == rad ? 500.0 : 2000.0 ); + const double ySize = ( Rich::Rich1Gas == rad ? 500.0 : 2000.0 ); + ok &= initHist( h_tkEntryXY_run[rad].emplace_back(), // + HID( runID + "trackEntryXY", rad ), // + "Track Radiator Entry (x,y)" + runT, // + -xSize, xSize, nBins2D(), // + -ySize, ySize, nBins2D(), // + "Track Entry X / mm", "TrackEntry Y / mm", "Entries" ); } - // track (x,y) plots - const double xSize = ( Rich::Rich1Gas == rad ? 500.0 : 2000.0 ); - const double ySize = ( Rich::Rich1Gas == rad ? 500.0 : 2000.0 ); - ok &= saveAndCheck( h_tkEntryXY_run[rad], // - richHisto2D( HID( runID + "trackEntryXY", rad ), // - "Track Radiator Entry (x,y)" + runT, // - -xSize, xSize, nBins2D(), // - -ySize, ySize, nBins2D(), // - "Track Entry X / mm", "TrackEntry Y / mm", "Entries" ) ); } return ok; } @@ -462,7 +464,7 @@ namespace Rich::Future::Rec::Calib { Gaudi::Property m_forcedRunNumber{this, "ForcedRunNumber", 0}; private: - // cached data + // cached datax /// Lock for main event processing mutable std::mutex m_mutex; @@ -472,11 +474,11 @@ namespace Rich::Future::Rec::Calib { RadiatorArray>> h_ckResAllQuads = {{{}}}; // Monitoring histos - mutable RadiatorArray h_ckThetaRec_run = {{}}; - mutable RadiatorArray h_ckThetaExp_run = {{}}; - mutable RadiatorArray h_ckThetaRes_run = {{}}; - mutable RadiatorArray> h_ckThetaRes_quads_run = {{{}}}; - mutable RadiatorArray h_tkEntryXY_run = {{}}; + mutable Hist::RadArray>> h_ckThetaRec_run = {{}}; + mutable Hist::RadArray>> h_ckThetaExp_run = {{}}; + mutable Hist::RadArray>> h_ckThetaRes_run = {{}}; + mutable Hist::RadArray>>> h_ckThetaRes_quads_run = {{{}}}; + mutable Hist::RadArray>> h_tkEntryXY_run = {{}}; /// Publishing service IPublishSvc* m_pPublishSvc = nullptr; @@ -798,7 +800,7 @@ void RefIndexCalib::operator()( const LHCb::ODIN& odin, const auto seg_x = seg.entryPoint().x(); const auto seg_y = seg.entryPoint().y(); const auto q = ( seg_x > 0 ? ( seg_y > 0 ? 0 : 2 ) : ( seg_y > 0 ? 1 : 3 ) ); - fillHisto( h_tkEntryXY_run[rad], seg_x, seg_y ); + fillRunByRunHist( h_tkEntryXY_run[rad], seg_x, seg_y ); // Loop over scalar entries in SIMD photon for ( std::size_t i = 0; i < SIMDCherenkovPhoton::SIMDFP::Size; ++i ) { @@ -808,10 +810,10 @@ void RefIndexCalib::operator()( const LHCb::ODIN& odin, h_ckResAll[rad]->Fill( deltaTheta[i] ); h_ckResAllQuads[rad][q]->Fill( deltaTheta[i] ); // these are for monitoring (Monet) - fillHisto( h_ckThetaRec_run[rad], phot.CherenkovTheta()[i] ); - fillHisto( h_ckThetaExp_run[rad], thetaExp[i] ); - fillHisto( h_ckThetaRes_run[rad], deltaTheta[i] ); - fillHisto( h_ckThetaRes_quads_run[rad][q], deltaTheta[i] ); + fillRunByRunHist( h_ckThetaRec_run[rad], phot.CherenkovTheta()[i] ); + fillRunByRunHist( h_ckThetaExp_run[rad], thetaExp[i] ); + fillRunByRunHist( h_ckThetaRes_run[rad], deltaTheta[i] ); + fillRunByRunHist( h_ckThetaRes_quads_run[rad][q], deltaTheta[i] ); } } diff --git a/Rich/RichOnlineMonitors/src/RichBXTypeMonitor.cpp b/Rich/RichOnlineMonitors/src/RichBXTypeMonitor.cpp index 7d42ef9f60f0ed9e48904ae05109a2c32c497c19..869f9ff4f76228e4dfe195b060a8b58675fb3cb3 100644 --- a/Rich/RichOnlineMonitors/src/RichBXTypeMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichBXTypeMonitor.cpp @@ -1,6 +1,5 @@ /*****************************************************************************\ - -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* (c) Copyright 2000-2026 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". * @@ -22,9 +21,6 @@ #include "RichRecUtils/RichDetParams.h" #include "RichUtils/RichDAQDefinitions.h" -// ROOT -#include "TString.h" - // Rich DAQ #include "RichFutureDAQ/RichPDMDBEncodeMapping.h" #include "RichFutureDAQ/RichTel40CableMapping.h" @@ -32,6 +28,9 @@ // event #include "Event/ODIN.h" +// ROOT +#include "TString.h" + // STD #include #include @@ -55,34 +54,28 @@ namespace Rich::Future::Mon { {KeyValue{"ODINLocation", LHCb::ODINLocation::Default}, KeyValue{"DecodedDataLocation", DAQ::DecodedDataLocation::Default}} ) {} - /// Initialize - StatusCode initialize() override { - return Consumer::initialize().andThen( [&] {} ); - } - private: // histograms /// Pixel based hit map - DetectorArray h_pixelMapBeamCrossing = {{}}; - DetectorArray h_pixelMap2BeamCrossing = {{}}; - DetectorArray h_pixelMapBeamGas = {{}}; - DetectorArray h_pixelMap2BeamGas = {{}}; - DetectorArray h_pixelMapEmptyEmpty = {{}}; - DetectorArray h_pixelMap2EmptyEmpty = {{}}; - /// nHits - DetectorArray h_nHitsBXIDBeamCrossing = {{}}; // jj - DetectorArray> h_nHitsBXIDBeamCrossing_side = {{}}; // jj - DetectorArray h_nHitsBXIDBeamGas = {{}}; // jj - DetectorArray h_nHitsBXIDEmptyEmpty = {{}}; // jj - /// MaPmts hits (for occupancy) - DetectorArray h_Occupancy_bb = {{}}; // jj - DetectorArray h_Occupancy_ee = {{}}; // jj - DetectorArray h_Occupancy_ebbe = {{}}; // jj + mutable Hist::DetArray> h_pixelMapBeamCrossing = {{}}; + mutable Hist::DetArray> h_pixelMap2BeamCrossing = {{}}; + mutable Hist::DetArray> h_pixelMapBeamGas = {{}}; + mutable Hist::DetArray> h_pixelMap2BeamGas = {{}}; + mutable Hist::DetArray> h_pixelMapEmptyEmpty = {{}}; + mutable Hist::DetArray> h_pixelMap2EmptyEmpty = {{}}; + // nHits + mutable Hist::DetArray> h_nHitsBXIDBeamCrossing = {{}}; + mutable Hist::DetArray>> h_nHitsBXIDBeamCrossing_side = {{}}; + mutable Hist::DetArray> h_nHitsBXIDBeamGas = {{}}; + mutable Hist::DetArray> h_nHitsBXIDEmptyEmpty = {{}}; + // MaPmts hits (for occupancy) + mutable Hist::DetArray> h_Occupancy_bb = {{}}; + mutable Hist::DetArray> h_Occupancy_ee = {{}}; + mutable Hist::DetArray> h_Occupancy_ebbe = {{}}; + private: - /// mutex lock - mutable std::mutex m_updateLock; - float weight_PMThit = 1.0 / 64.0; + static constexpr float weight_PMThit = 1.0 / 64.0; protected: /// Pre-Book all histograms @@ -92,84 +85,83 @@ namespace Rich::Future::Mon { // Loop over RICHes for ( const auto rich : Rich::detectors() ) { - const auto xRange = LHCb::RichSmartID::MaPMT::PDGlobalViewRangeX[rich] + 20; - const auto xBins = ( 2 * xRange ) + 1; - const auto yRange = LHCb::RichSmartID::MaPMT::PDGlobalViewRangeY[rich] + 20; - const auto yBins = ( 2 * yRange ) + 1; - const float xMax = xRange + 0.5; - const float yMax = yRange + 0.5; - ok &= saveAndCheck( h_pixelMapBeamCrossing[rich], // - richHisto2D( Rich::HistogramID( "PixelMapBeamCrossing", rich ), // - "Global Pixel Map Beam Crossing", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_pixelMapBeamGas[rich], // - richHisto2D( Rich::HistogramID( "PixelMapBeamGas", rich ), // - "Global Pixel Map Beam Gas", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_pixelMapEmptyEmpty[rich], // - richHisto2D( Rich::HistogramID( "PixelMapEmptyEmpty", rich ), // - "Global Pixel Map Empty Empty", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_nHitsBXIDBeamCrossing[rich], // jjj - richHisto1D( Rich::HistogramID( "nHitsBXIDBeamCrossing", rich ), // - "Number of hits from ID trigger (Beam Crossing)", // - 0, 35000, 3500, // - "nHitsBXIDBeamCrossing" ) ); // jjjj - ok &= saveAndCheck( h_nHitsBXIDBeamGas[rich], // jjj - richHisto1D( Rich::HistogramID( "nHitsBXIDBeamGas", rich ), // - "Number of hits from ID trigger (Beam Gas)", // - 0, 35000, 3500, // - "nHitsBXIDBeamGas" ) ); // jjjj - ok &= saveAndCheck( h_nHitsBXIDEmptyEmpty[rich], // jjj - richHisto1D( Rich::HistogramID( "nHitsBXIDEmptyEmpty", rich ), // - "Number of hits from ID trigger (Empty Empty)", // - 0, 35000, 3500, // - "nHitsBXIDEmptyEmpty" ) ); // jjjj - ok &= saveAndCheck( h_pixelMap2BeamCrossing[rich], // - richHisto2D( Rich::HistogramID( "PixelMap2BeamCrossing", rich ), // - "Global Pixel Map 2 Beam Crossing", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_pixelMap2BeamGas[rich], // - richHisto2D( Rich::HistogramID( "PixelMap2BeamGas", rich ), // - "Global Pixel Map 2 Beam Gas", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_pixelMap2EmptyEmpty[rich], // - richHisto2D( Rich::HistogramID( "PixelMap2EmptyEmpty", rich ), // - "Global Pixel Map 2 Empty Empty", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_Occupancy_bb[rich], // jjj - richHisto1D( Rich::HistogramID( "Occupancy_bb", rich ), // - "MaPMT nHits", // - 0, 2600, 2600, // - "PMT index" ) ); // jjjj - ok &= saveAndCheck( h_Occupancy_ee[rich], // jjj - richHisto1D( Rich::HistogramID( "Occupancy_ee", rich ), // - "MaPMT nHits", // - 0, 2600, 2600, // - "PMT index" ) ); // jjjj - ok &= saveAndCheck( h_Occupancy_ebbe[rich], // jjj - richHisto1D( Rich::HistogramID( "Occupancy_ebbe", rich ), // - "MaPMT nHits", // - 0, 2600, 2600, // - "PMT index" ) ); // jjjj + const auto xRange = LHCb::RichSmartID::MaPMT::PDGlobalViewRangeX[rich] + 20; + const auto xBins = ( 2 * xRange ) + 1; + const auto yRange = LHCb::RichSmartID::MaPMT::PDGlobalViewRangeY[rich] + 20; + const auto yBins = ( 2 * yRange ) + 1; + const auto xMax = xRange + 0.5; + const auto yMax = yRange + 0.5; + ok &= initHist( h_pixelMapBeamCrossing[rich], // + Rich::HistogramID( "PixelMapBeamCrossing", rich ), // + "Global Pixel Map Beam Crossing", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_pixelMapBeamGas[rich], // + Rich::HistogramID( "PixelMapBeamGas", rich ), // + "Global Pixel Map Beam Gas", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_pixelMapEmptyEmpty[rich], // + Rich::HistogramID( "PixelMapEmptyEmpty", rich ), // + "Global Pixel Map Empty Empty", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_nHitsBXIDBeamCrossing[rich], // + Rich::HistogramID( "nHitsBXIDBeamCrossing", rich ), // + "Number of hits from ID trigger (Beam Crossing)", // + 0, 35000, 3500, // + "nHitsBXIDBeamCrossing" ); // + ok &= initHist( h_nHitsBXIDBeamGas[rich], // + Rich::HistogramID( "nHitsBXIDBeamGas", rich ), // + "Number of hits from ID trigger (Beam Gas)", // + 0, 35000, 3500, // + "nHitsBXIDBeamGas" ); // + ok &= initHist( h_nHitsBXIDEmptyEmpty[rich], // + Rich::HistogramID( "nHitsBXIDEmptyEmpty", rich ), // + "Number of hits from ID trigger (Empty Empty)", // + 0, 35000, 3500, // + "nHitsBXIDEmptyEmpty" ); // + ok &= initHist( h_pixelMap2BeamCrossing[rich], // + Rich::HistogramID( "PixelMap2BeamCrossing", rich ), // + "Global Pixel Map 2 Beam Crossing", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_pixelMap2BeamGas[rich], // + Rich::HistogramID( "PixelMap2BeamGas", rich ), // + "Global Pixel Map 2 Beam Gas", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_pixelMap2EmptyEmpty[rich], // + Rich::HistogramID( "PixelMap2EmptyEmpty", rich ), // + "Global Pixel Map 2 Empty Empty", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_Occupancy_bb[rich], // + Rich::HistogramID( "Occupancy_bb", rich ), // + "MaPMT nHits", // + 0, 2600, 2600, // + "PMT index" ); // + ok &= initHist( h_Occupancy_ee[rich], // + Rich::HistogramID( "Occupancy_ee", rich ), // + "MaPMT nHits", // + 0, 2600, 2600, // + "PMT index" ); // + ok &= initHist( h_Occupancy_ebbe[rich], // + Rich::HistogramID( "Occupancy_ebbe", rich ), // + "MaPMT nHits", // + 0, 2600, 2600, // + "PMT index" ); // for ( const auto side : Rich::sides() ) { - ok &= saveAndCheck( - h_nHitsBXIDBeamCrossing_side[rich][side], - richHisto1D( Rich::HistogramID( Form( "nHitsBXIDBeamCrossing_RICH%d_Side%d", rich, side ), rich, side ), - "Number of hits from ID triggers per side (Beam Crossing)", 0, 35000, 3500, - "nHitsBXIDBeamCrossing_side" ) ); + ok &= initHist( h_nHitsBXIDBeamCrossing_side[rich][side], + Rich::HistogramID( Form( "nHitsBXIDBeamCrossing_RICH%d_Side%d", rich, side ), rich, side ), + "Number of hits from ID triggers per side (Beam Crossing)", 0, 35000, 3500, + "nHitsBXIDBeamCrossing_side" ); } } return StatusCode{ok}; @@ -177,11 +169,18 @@ namespace Rich::Future::Mon { public: /// Functional operator - void operator()( const LHCb::ODIN& odin, // - const DAQ::DecodedData& data // - ) const override { - - std::lock_guard lock( m_updateLock ); + void operator()( const LHCb::ODIN& odin, const DAQ::DecodedData& data ) const override { + + // local buffers + auto hb_Occupancy_bb = h_Occupancy_bb.buffer(); + auto hb_Occupancy_ebbe = h_Occupancy_ebbe.buffer(); + auto hb_Occupancy_ee = h_Occupancy_ee.buffer(); + auto hb_pixelMapBeamCrossing = h_pixelMapBeamCrossing.buffer(); + auto hb_pixelMap2BeamCrossing = h_pixelMap2BeamCrossing.buffer(); + auto hb_pixelMapBeamGas = h_pixelMapBeamGas.buffer(); + auto hb_pixelMap2BeamGas = h_pixelMap2BeamGas.buffer(); + auto hb_pixelMapEmptyEmpty = h_pixelMapEmptyEmpty.buffer(); + auto hb_pixelMap2EmptyEmpty = h_pixelMap2EmptyEmpty.buffer(); // Loop over RICHes for ( const auto rich : Rich::detectors() ) { @@ -218,12 +217,12 @@ namespace Rich::Future::Mon { ( 13 * 6 * 4 * 4 * ( id.panel() ) + 6 * 4 * 4 * ( id.panelLocalModuleColumn() ) + 4 * 4 * id.columnLocalModuleNum() + 4 * id.elementaryCell() + id.pdNumInEC() ); if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { - fillHisto( h_Occupancy_bb[rich], pmtbin, weight_PMThit ); + hb_Occupancy_bb[rich][pmtbin] += weight_PMThit; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam1 || odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) { - fillHisto( h_Occupancy_ebbe[rich], pmtbin, weight_PMThit ); + hb_Occupancy_ebbe[rich][pmtbin] += weight_PMThit; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) { - fillHisto( h_Occupancy_ee[rich], pmtbin, weight_PMThit ); + hb_Occupancy_ee[rich][pmtbin] += weight_PMThit; } const auto iGlobalX = id.ecGlobalPMTFrameX() - id.panel() * 220; @@ -234,66 +233,72 @@ namespace Rich::Future::Mon { for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { - fillHisto( h_pixelMapBeamCrossing[rich], iGlobalX + i, iGlobalY + j ); - fillHisto( h_pixelMap2BeamCrossing[rich], iGlobalX2 + i, iGlobalY + j ); + ++hb_pixelMapBeamCrossing[rich][{iGlobalX + i, iGlobalY + j}]; + ++hb_pixelMap2BeamCrossing[rich][{iGlobalX2 + i, iGlobalY + j}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam1 || odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) { - fillHisto( h_pixelMapBeamGas[rich], iGlobalX + i, iGlobalY + j ); - fillHisto( h_pixelMap2BeamGas[rich], iGlobalX2 + i, iGlobalY + j ); + ++hb_pixelMapBeamGas[rich][{iGlobalX + i, iGlobalY + j}]; + ++hb_pixelMap2BeamGas[rich][{iGlobalX2 + i, iGlobalY + j}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) { - fillHisto( h_pixelMapEmptyEmpty[rich], iGlobalX + i, iGlobalY + j ); - fillHisto( h_pixelMap2EmptyEmpty[rich], iGlobalX2 + i, iGlobalY + j ); + ++hb_pixelMapEmptyEmpty[rich][{iGlobalX + i, iGlobalY + j}]; + ++hb_pixelMap2EmptyEmpty[rich][{iGlobalX2 + i, iGlobalY + j}]; } } } } else { if ( Rich::Rich1 == rich ) { if ( 0 == side ) { + // FixMe : This lambda should be properly defined as a method someone and all + // the magic numbers explained obvious its just a meaningless horrid conversion + // no one in the future will understand. + auto convertX = []( const auto x ) { return ( -1 * ( x + 3 - 89 - 21 ) ) + 89 + 21; }; + auto convertY = []( const auto y ) { return -( y + 1 ); }; if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { - fillHisto( h_pixelMapBeamCrossing[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX + 3 - 89 - 21 ) ) + 89 + 21 ); - fillHisto( h_pixelMap2BeamCrossing[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX2 + 3 - 89 - 21 ) ) + 89 + 21 ); + ++hb_pixelMapBeamCrossing[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2BeamCrossing[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam1 || odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) { - fillHisto( h_pixelMapBeamGas[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX + 3 - 89 - 21 ) ) + 89 + 21 ); - fillHisto( h_pixelMap2BeamGas[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX2 + 3 - 89 - 21 ) ) + 89 + 21 ); + ++hb_pixelMapBeamGas[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2BeamGas[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) { - fillHisto( h_pixelMapEmptyEmpty[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX + 3 - 89 - 21 ) ) + 89 + 21 ); - fillHisto( h_pixelMap2EmptyEmpty[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX2 + 3 - 89 - 21 ) ) + 89 + 21 ); + ++hb_pixelMapEmptyEmpty[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2EmptyEmpty[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } } else { + // FixMe : These lambdas should be properly defined as a method someone and all + // the magic numbers explained obvious its just a meaningless horrid conversion + // no one in the future will understand. + auto convertX = []( const auto x ) { return x + 3; }; + auto convertY = []( const auto y ) { return y + 1; }; if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { - fillHisto( h_pixelMapBeamCrossing[rich], iGlobalY + 1, iGlobalX + 3 ); - fillHisto( h_pixelMap2BeamCrossing[rich], iGlobalY + 1, iGlobalX2 + 3 ); + ++hb_pixelMapBeamCrossing[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2BeamCrossing[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam1 || odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) { - fillHisto( h_pixelMapBeamGas[rich], iGlobalY + 1, iGlobalX + 3 ); - fillHisto( h_pixelMap2BeamGas[rich], iGlobalY + 1, iGlobalX2 + 3 ); + ++hb_pixelMapBeamGas[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2BeamGas[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) { - fillHisto( h_pixelMapEmptyEmpty[rich], iGlobalY + 1, iGlobalX + 3 ); - fillHisto( h_pixelMap2EmptyEmpty[rich], iGlobalY + 1, iGlobalX2 + 3 ); + ++hb_pixelMapEmptyEmpty[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2EmptyEmpty[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } } } else { + auto convertX = []( const auto x ) { return x + 1; }; + auto convertY = []( const auto y ) { return y; }; if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { - fillHisto( h_pixelMapBeamCrossing[rich], iGlobalX + 1, iGlobalY ); - fillHisto( h_pixelMap2BeamCrossing[rich], iGlobalX2 + 1, iGlobalY ); + ++hb_pixelMapBeamCrossing[rich][{convertX( iGlobalX ), convertY( iGlobalY )}]; + ++hb_pixelMap2BeamCrossing[rich][{convertX( iGlobalX2 ), convertY( iGlobalY )}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam1 || odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) { - fillHisto( h_pixelMapBeamGas[rich], iGlobalX + 1, iGlobalY ); - fillHisto( h_pixelMap2BeamGas[rich], iGlobalX2 + 1, iGlobalY ); + ++hb_pixelMapBeamGas[rich][{convertX( iGlobalX ), convertY( iGlobalY )}]; + ++hb_pixelMap2BeamGas[rich][{convertX( iGlobalX2 ), convertY( iGlobalY )}]; } else if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) { - fillHisto( h_pixelMapEmptyEmpty[rich], iGlobalX + 1, iGlobalY ); - fillHisto( h_pixelMap2EmptyEmpty[rich], iGlobalX2 + 1, iGlobalY ); + ++hb_pixelMapEmptyEmpty[rich][{convertX( iGlobalX ), convertY( iGlobalY )}]; + ++hb_pixelMap2EmptyEmpty[rich][{convertX( iGlobalX2 ), convertY( iGlobalY )}]; } } } @@ -306,18 +311,25 @@ namespace Rich::Future::Mon { } // PDs } // modules - if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) - fillHisto( h_nHitsBXIDBeamCrossing_side[rich][side], nHitsSide ); // jj - } // panels - if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) - fillHisto( h_nHitsBXIDBeamCrossing[rich], nHits ); // jj + if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { + ++h_nHitsBXIDBeamCrossing_side[rich][side][nHitsSide]; + } + + } // panels + + if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) { + ++h_nHitsBXIDBeamCrossing[rich][nHits]; + } if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam1 || - odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) - fillHisto( h_nHitsBXIDBeamGas[rich], nHits ); // jj - if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) - fillHisto( h_nHitsBXIDEmptyEmpty[rich], nHits ); // jj - } // RICHes + odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::Beam2 ) { + ++h_nHitsBXIDBeamGas[rich][nHits]; + } + if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::NoBeam ) { + ++h_nHitsBXIDEmptyEmpty[rich][nHits]; + } + + } // RICHes } }; diff --git a/Rich/RichOnlineMonitors/src/RichBankSizesMonitor.cpp b/Rich/RichOnlineMonitors/src/RichBankSizesMonitor.cpp index de58959c13463aa3a1964fae31c5bc3efa37d217..f808c45649bfa88b168f563231f60719b4c0e7a0 100644 --- a/Rich/RichOnlineMonitors/src/RichBankSizesMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichBankSizesMonitor.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include namespace Rich::Future::Mon { @@ -60,14 +59,8 @@ namespace Rich::Future::Mon { } private: - // mutex lock; - mutable std::mutex m_updateLock; - /// Bank size vs sourceID histogram - DetectorArray> h_BankSizes = {{}}; - - private: - // messaging + mutable Hist::DetArray>> h_BankSizes = {{}}; /// Invalid SourceID mutable ErrorCounter m_invalidSourceID{this, "Invalid Tel40 SourceID"}; @@ -91,12 +84,12 @@ namespace Rich::Future::Mon { xMin = ( side == Rich::aside ? 18432. : 19456. ); xMax = ( side == Rich::aside ? 19455. : 20479. ); } - ok &= saveAndCheck( h_BankSizes[rich][side], // - richHisto2D( Rich::HistogramID( "BankSizeVsSourceID", rich, side ), // - "Bank size vs SourceID", // - xMin - 0.5, xMax + 0.5, xMax - xMin + 1, // - -0.5, 300.5, 301, // - "Source ID", "Bank size [B]" ) ); // + ok &= initHist( h_BankSizes[rich][side], // + Rich::HistogramID( "BankSizeVsSourceID", rich, side ), // + "Bank size vs SourceID", // + xMin - 0.5, xMax + 0.5, xMax - xMin + 1, // + -0.5, 300.5, 301, // + "Source ID", "Bank size [B]" ); // } } @@ -107,7 +100,7 @@ namespace Rich::Future::Mon { /// Functional operator void operator()( const LHCb::RawBank::View& richBanks ) const override { - std::lock_guard lock( m_updateLock ); + auto hb_BankSizes = h_BankSizes.buffer(); for ( const auto* const bank : richBanks ) { if ( bank ) { @@ -119,13 +112,10 @@ namespace Rich::Future::Mon { mess << "Invalid Source ID " << tel40ID; throw Rich::Exception( mess.str() ); } - const std::size_t bankSize = bank->size(); const auto rich = tel40ID.rich(); const auto side = tel40ID.side(); - // const float idTell40 = find_id->second.first; - // const float idBlock = find_id->second.second; - fillHisto( h_BankSizes[rich][side], source_id, bankSize ); + ++hb_BankSizes[rich][side][{source_id, bankSize}]; } } } diff --git a/Rich/RichOnlineMonitors/src/RichHitMapsMonitor.cpp b/Rich/RichOnlineMonitors/src/RichHitMapsMonitor.cpp index 206e8ee00f96a83e4d73a13bbe5cab99dddb3fd3..9101fea625ae2bff45e3bec01bdc7cef471d3bee 100644 --- a/Rich/RichOnlineMonitors/src/RichHitMapsMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichHitMapsMonitor.cpp @@ -1,6 +1,5 @@ /*****************************************************************************\ - -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* (c) Copyright 2000-2026 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". * @@ -22,9 +21,6 @@ #include "RichRecUtils/RichDetParams.h" #include "RichUtils/RichDAQDefinitions.h" -// ROOT -#include "TString.h" - // Rich DAQ #include "RichFutureDAQ/RichPDMDBEncodeMapping.h" #include "RichFutureDAQ/RichTel40CableMapping.h" @@ -32,11 +28,13 @@ // event #include "Event/ODIN.h" +// ROOT +#include "TString.h" + // STD #include #include #include -#include #include namespace Rich::Future::Mon { @@ -96,37 +94,35 @@ namespace Rich::Future::Mon { private: // histograms - using PMTPlotsPerEC = std::array; - using PMTPlotsPerPDM = std::array; - using PMTPlotsPerMod = std::array; - using PMTPlotsPerCol = std::array; - using PMTPlotsPerPanel = PanelArray; - using PMTPlots = DetectorArray; + using PMTPlotsPerEC = Hist::Array, LHCb::RichSmartID::MaPMT::RTypePMTsPerEC>; + using PMTPlotsPerPDM = Hist::Array; + using PMTPlotsPerMod = Hist::Array; + using PMTPlotsPerCol = Hist::Array; + using PMTPlotsPerPanel = Hist::PanelArray; + using PMTPlots = Hist::DetArray; /// Hit map for RICH, local coordinates - DetectorArray h_hitMaps = {{}}; + mutable Hist::DetArray> h_hitMaps = {{}}; /// Pixel based hit map - DetectorArray h_pixelMap = {{}}; - DetectorArray h_pixelMap2 = {{}}; + mutable Hist::DetArray> h_pixelMap = {{}}; + mutable Hist::DetArray> h_pixelMap2 = {{}}; /// Occupancy vs slotID - DetectorArray h_NHitsVsSlotID = {{}}; + mutable Hist::DetArray> h_NHitsVsSlotID = {{}}; /// Occupancy vs bunchID - DetectorArray h_NHitsVsBunchID = {{}}; + mutable Hist::DetArray> h_NHitsVsBunchID = {{}}; /// slotID vs tell40 bit - DetectorArray h_SlotIDVsBitID = {{}}; + mutable Hist::DetArray> h_SlotIDVsBitID = {{}}; /// bunchID vs tell40 link (i.e. 100 bits) - DetectorArray h_BunchIDVsBitID = {{}}; + mutable Hist::DetArray> h_BunchIDVsBitID = {{}}; /// Individual maps for each PMT - std::unique_ptr h_pixelMapsCol; + mutable std::unique_ptr h_pixelMapsCol; /// Individual hits for each PMT - std::unique_ptr h_pixelCol; + mutable std::unique_ptr h_pixelCol; /// nHits - DetectorArray h_nHits = {{}}; // jj - DetectorArray> h_nHits_side = {{}}; // jj + mutable Hist::DetArray> h_nHits = {{}}; + mutable Hist::DetArray>> h_nHits_side = {{}}; private: - /// mutex lock - mutable std::mutex m_updateLock; // Gaudi::Property m_start_scan{this, "scanStart", 0}; // Gaudi::Property m_stop_scan{this, "scanStop", 0}; unsigned int m_start_scan{0}; @@ -153,12 +149,12 @@ namespace Rich::Future::Mon { // Loop over RICHes for ( const auto rich : Rich::detectors() ) { if ( m_fillSpacePlots ) { - ok &= saveAndCheck( h_hitMaps[rich], // - richHisto2D( Rich::HistogramID( "localHitMap", rich ), // - "Local PD Panel Space Point Hit Map", // - xMinPDLoc[rich], xMaxPDLoc[rich], nBins2D(), // - yMinPDLoc[rich], yMaxPDLoc[rich], nBins2D(), // - "Local Panel X", "Local Panel Y" ) ); + ok &= initHist( h_hitMaps[rich], // + Rich::HistogramID( "localHitMap", rich ), // + "Local PD Panel Space Point Hit Map", // + xMinPDLoc[rich], xMaxPDLoc[rich], nBins2D(), // + yMinPDLoc[rich], yMaxPDLoc[rich], nBins2D(), // + "Local Panel X", "Local Panel Y" ); } const auto xRange = LHCb::RichSmartID::MaPMT::PDGlobalViewRangeX[rich] + 20; const auto xBins = ( 2 * xRange ) + 1; @@ -166,66 +162,59 @@ namespace Rich::Future::Mon { const auto yBins = ( 2 * yRange ) + 1; const float xMax = xRange + 0.5; const float yMax = yRange + 0.5; - ok &= saveAndCheck( h_pixelMap[rich], // - richHisto2D( Rich::HistogramID( "PixelMap", rich ), // - "Global Pixel Map 1", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_nHits[rich], // jjj - richHisto1D( Rich::HistogramID( "nHits", rich ), // - "Number of hits", // - 0, 35000, 35000, // - "nHits" ) ); // jjjj - ok &= saveAndCheck( h_pixelMap2[rich], // - richHisto2D( Rich::HistogramID( "PixelMap2", rich ), // - "Global Pixel Map 2", // - -xMax, xMax, xBins, // - -yMax, yMax, yBins, // - "Global Pixel X", "Global Pixel Y" ) ); - ok &= saveAndCheck( h_NHitsVsSlotID[rich], // - richHisto2D( Rich::HistogramID( "NHitsVsSlotID", rich ), // - "# of hits Vs slot ID", // - -0.5, 31.5, 32, // - -0.5, 1.25e5 - 0.5, 1.25e5, // - "Slot ID=abs(bxid-1024)%23", "# of hits" ) ); - ok &= saveAndCheck( h_NHitsVsBunchID[rich], // - richHisto2D( Rich::HistogramID( "NHitsVsBunchID", rich ), // - "# of hits Vs bunch ID", // - -0.5, 3600 - 0.5, 3600, // jj - -0.5, 1.25e5 - 0.5, 1.25e3, // - "Bunch ID", "# of hits" ) ); + ok &= initHist( h_pixelMap[rich], Rich::HistogramID( "PixelMap", rich ), // + "Global Pixel Map 1", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_nHits[rich], Rich::HistogramID( "nHits", rich ), // + "Number of hits", // + 0, 35000, 35000, // + "nHits" ); // + ok &= initHist( h_pixelMap2[rich], // + Rich::HistogramID( "PixelMap2", rich ), // + "Global Pixel Map 2", // + -xMax, xMax, xBins, // + -yMax, yMax, yBins, // + "Global Pixel X", "Global Pixel Y" ); + ok &= initHist( h_NHitsVsSlotID[rich], Rich::HistogramID( "NHitsVsSlotID", rich ), // + "# of hits Vs slot ID", // + -0.5, 31.5, 32, // + -0.5, 1.25e5 - 0.5, 1.25e5, // + "Slot ID=abs(bxid-1024)%23", "# of hits" ); + ok &= initHist( h_NHitsVsBunchID[rich], Rich::HistogramID( "NHitsVsBunchID", rich ), // + "# of hits Vs bunch ID", // + -0.5, 3600 - 0.5, 3600, // + -0.5, 1.25e5 - 0.5, 1.25e3, // + "Bunch ID", "# of hits" ); if ( m_enableOfflinePlots ) { - /*ok &= saveAndCheck( h_NHitsVsBunchID[rich], // - richHisto2D( Rich::HistogramID( "NHitsVsBunchID", rich ), // + /*ok &= initHist( h_NHitsVsBunchID[rich], // + Rich::HistogramID( "NHitsVsBunchID", rich ), // "# of hits Vs bunch ID", // - -0.5, 3600 - 0.5, 3600, // jj + -0.5, 3600 - 0.5, 3600, // -0.5, 1.25e5 - 0.5, 1.25e4, // - "Bunch ID", "# of hits" ) );*/ - ok &= saveAndCheck( h_SlotIDVsBitID[rich], // - richHisto2D( Rich::HistogramID( "SlotIDVsBitID", rich ), // - "Slot ID Vs global bit ID", // - -0.5, 2e5 - 0.5, 2e5, // - -0.5, 32 - 0.5, 32, // - "bit ID", "Slot ID=abs(bxid-1024)%23" ) ); - ok &= saveAndCheck( h_BunchIDVsBitID[rich], // - richHisto2D( Rich::HistogramID( "BunchIDVsBitID", rich ), // - "Bunch ID Vs global bit ID", // - -0.5, 2e5 - 0.5, 2e3, // - -0.5, 3564 - 0.5, 3564, // - "bit ID", "Bunch ID" ) ); + "Bunch ID", "# of hits" );*/ + ok &= initHist( h_SlotIDVsBitID[rich], Rich::HistogramID( "SlotIDVsBitID", rich ), // + "Slot ID Vs global bit ID", // + -0.5, 2e5 - 0.5, 2e5, // + -0.5, 32 - 0.5, 32, // + "bit ID", "Slot ID=abs(bxid-1024)%23" ); + ok &= initHist( h_BunchIDVsBitID[rich], Rich::HistogramID( "BunchIDVsBitID", rich ), // + "Bunch ID Vs global bit ID", // + -0.5, 2e5 - 0.5, 2e3, // + -0.5, 3564 - 0.5, 3564, // + "bit ID", "Bunch ID" ); } if ( m_fillVerbosePMTPlots ) { if ( !h_pixelMapsCol.get() ) { h_pixelMapsCol = std::make_unique(); } if ( !h_pixelCol.get() ) { h_pixelCol = std::make_unique(); } for ( const auto side : Rich::sides() ) { - ok &= saveAndCheck( - h_nHits_side[rich][side], // jjj - richHisto1D( Rich::HistogramID( Form( "nHits_RICH%d_Side%d", rich, side ), rich, side ), // - "Number of hits", // - 0, 3500, 3500, // - "nHits" ) ); // jjjj + ok &= initHist( h_nHits_side[rich][side], + Rich::HistogramID( Form( "nHits_RICH%d_Side%d", rich, side ), rich, side ), // + "Number of hits", // + 0, 3500, 3500, // + "nHits" ); // for ( std::size_t iCol = 0; iCol < LHCb::RichSmartID::MaPMT::ModuleColumnsPerPanel[rich]; ++iCol ) { for ( std::size_t iPDM = 0; iPDM < LHCb::RichSmartID::MaPMT::ModulesPerColumn; ++iPDM ) { for ( std::size_t iEC = 0; iEC < LHCb::RichSmartID::MaPMT::ECsPerModule; ++iEC ) { @@ -238,22 +227,20 @@ namespace Rich::Future::Mon { const auto iColCorr = ( rich == Rich::Rich2 ? 1 : 0 ); #endif const auto pmt = ( 1000 * ( iCol + iColCorr ) ) + ( 100 * iPDM ) + ( 10 * iEC ) + iPMT; - ok &= saveAndCheck( ( *h_pixelMapsCol )[rich][side][iCol][iPDM][iEC][iPMT], // - richHisto2D( Rich::HistogramID( Form( "PMTHitMap%05zu", pmt ), rich, side ), // - Form( "COL%02zu_PDM%zu_EC%zu_PMT%zu Hit Map", iCol + iColCorr, - iPDM, iEC, iPMT ), // - -0.5, LHCb::RichSmartID::MaPMT::PixelsPerRow - 0.5, - LHCb::RichSmartID::MaPMT::PixelsPerRow, // - -0.5, LHCb::RichSmartID::MaPMT::PixelsPerCol - 0.5, - LHCb::RichSmartID::MaPMT::PixelsPerCol, // - "Pixel Row", "Pixel Column" ) ); - ok &= saveAndCheck( - ( *h_pixelCol )[rich][side][iCol][iPDM][iEC][iPMT], // - richHisto2D( Rich::HistogramID( Form( "PMTHits%05zu", pmt ), rich, side ), // - Form( "COL%02zu_PDM%zu_EC%zu_PMT%zu Hits", iCol + iColCorr, iPDM, iEC, iPMT ), // - 0, 256, 256, // - 0, 64, 64, // - "StepID", "Anode Index" ) ); + ok &= initHist( ( *h_pixelMapsCol )[rich][side][iCol][iPDM][iEC][iPMT], // + Rich::HistogramID( Form( "PMTHitMap%05zu", pmt ), rich, side ), // + Form( "COL%02zu_PDM%zu_EC%zu_PMT%zu Hit Map", iCol + iColCorr, iPDM, iEC, iPMT ), // + -0.5, LHCb::RichSmartID::MaPMT::PixelsPerRow - 0.5, + LHCb::RichSmartID::MaPMT::PixelsPerRow, // + -0.5, LHCb::RichSmartID::MaPMT::PixelsPerCol - 0.5, + LHCb::RichSmartID::MaPMT::PixelsPerCol, // + "Pixel Row", "Pixel Column" ); + ok &= initHist( ( *h_pixelCol )[rich][side][iCol][iPDM][iEC][iPMT], // + Rich::HistogramID( Form( "PMTHits%05zu", pmt ), rich, side ), // + Form( "COL%02zu_PDM%zu_EC%zu_PMT%zu Hits", iCol + iColCorr, iPDM, iEC, iPMT ), // + 0, 256, 256, // + 0, 64, 64, // + "StepID", "Anode Index" ); } } } @@ -267,7 +254,7 @@ namespace Rich::Future::Mon { private: /// Get the plot for a specific PMT - inline auto getPMTPlot( const LHCb::RichSmartID id ) const { + inline auto& getPMTPlot( const LHCb::RichSmartID id ) const { // extract some parameters const auto rich = id.rich(); const auto side = id.panel(); @@ -277,18 +264,12 @@ namespace Rich::Future::Mon { const auto iPMT = id.pdNumInEC(); // sanity check before using as array indices assert( h_pixelMapsCol.get() ); - const auto& plts = ( *h_pixelMapsCol ); - assert( (std::size_t)rich < plts.size() ); - assert( (std::size_t)side < plts[rich].size() ); - assert( iCol < plts[rich][side].size() ); - assert( iPDM < plts[rich][side][iCol].size() ); - assert( iEC < plts[rich][side][iCol][iPDM].size() ); - assert( iPMT < plts[rich][side][iCol][iPDM][iEC].size() ); - // return plot pointer - return plts[rich][side][iCol][iPDM][iEC][iPMT]; + auto& plts = ( *h_pixelMapsCol ); + // return plot reference + return plts.at( rich ).at( side ).at( iCol ).at( iPDM ).at( iEC ).at( iPMT ); } - inline auto getPMTHitsPlot( const LHCb::RichSmartID id ) const { + inline auto& getPMTHitsPlot( const LHCb::RichSmartID id ) const { // extract some parameters const auto rich = id.rich(); const auto side = id.panel(); @@ -298,15 +279,9 @@ namespace Rich::Future::Mon { const auto iPMT = id.pdNumInEC(); // sanity check before using as array indices assert( h_pixelCol.get() ); - const auto& plts = ( *h_pixelCol ); - assert( (std::size_t)rich < plts.size() ); - assert( (std::size_t)side < plts[rich].size() ); - assert( iCol < plts[rich][side].size() ); - assert( iPDM < plts[rich][side][iCol].size() ); - assert( iEC < plts[rich][side][iCol][iPDM].size() ); - assert( iPMT < plts[rich][side][iCol][iPDM][iEC].size() ); - // return plot pointer - return plts[rich][side][iCol][iPDM][iEC][iPMT]; + auto& plts = ( *h_pixelCol ); + // return plot reference + return plts.at( rich ).at( side ).at( iCol ).at( iPDM ).at( iEC ).at( iPMT ); } public: @@ -317,7 +292,12 @@ namespace Rich::Future::Mon { const DAQ::Tel40CableMapping& tel40Maps, // const DAQ::PDMDBEncodeMapping& pdmdbMaps ) const override { - std::lock_guard lock( m_updateLock ); + // local buffers + auto hb_SlotIDVsBitID = h_SlotIDVsBitID.buffer(); + auto hb_BunchIDVsBitID = h_BunchIDVsBitID.buffer(); + auto hb_pixelMap = h_pixelMap.buffer(); + auto hb_pixelMap2 = h_pixelMap2.buffer(); + auto hb_hitMaps = h_hitMaps.buffer(); //// Get bxID const auto bunchID = odin.bunchId(); @@ -368,25 +348,18 @@ namespace Rich::Future::Mon { const auto& tel40Data = tel40Maps.tel40Data( id, anodeData.pdmdb, anodeData.frame ); if ( m_enableOfflinePlots ) { - // get the DB anode data for this hit - // info() << "PDMDB " << anodeData << endmsg; - // get the DB tel40 data - // info() << "Tel40 " << tel40Data << endmsg; - fillHisto( h_SlotIDVsBitID[rich], - 1e5 * static_cast( id.panel() ) + - 100 * ( 24 * ( tel40Data.sourceID.data() & 0x3F ) + tel40Data.connector.data() ) + - anodeData.bit.data(), - slotID ); - fillHisto( h_BunchIDVsBitID[rich], - 1e5 * static_cast( id.panel() ) + - 100 * ( 24 * ( tel40Data.sourceID.data() & 0x3F ) + tel40Data.connector.data() ) + - anodeData.bit.data(), - bunchID ); + // FixMe : Another horrid set of magic numbers that require documentation + const auto bitID = + 1e5 * static_cast( id.panel() ) + + 100 * ( 24 * ( tel40Data.sourceID.data() & 0x3F ) + tel40Data.connector.data() ) + + anodeData.bit.data(); + ++hb_SlotIDVsBitID[rich][{bitID, slotID}]; + ++hb_BunchIDVsBitID[rich][{bitID, bunchID}]; } if ( m_fillVerbosePMTPlots ) { - fillHisto( getPMTHitsPlot( id ), thDAC_ID, id.anodeIndex() ); - fillHisto( getPMTPlot( id ), id.ecLocalPMTFrameX(), id.ecLocalPMTFrameY() ); + ++( getPMTHitsPlot( id )[{thDAC_ID, id.anodeIndex()}] ); + ++( getPMTPlot( id )[{id.ecLocalPMTFrameX(), id.ecLocalPMTFrameY()}] ); } const auto iGlobalX = id.ecGlobalPMTFrameX() - id.panel() * 220; @@ -396,24 +369,29 @@ namespace Rich::Future::Mon { // For large H type PMTs fill a group of 4 corresponding to the effective smaller pixels for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { - fillHisto( h_pixelMap[rich], iGlobalX + i, iGlobalY + j ); - fillHisto( h_pixelMap2[rich], iGlobalX2 + i, iGlobalY + j ); + ++hb_pixelMap[rich][{iGlobalX + i, iGlobalY + j}]; + ++hb_pixelMap2[rich][{iGlobalX2 + i, iGlobalY + j}]; } } } else { if ( Rich::Rich1 == rich ) { + // FixMe : These horrid conversions again (also in BX type monitor) if ( 0 == side ) { - fillHisto( h_pixelMap[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX + 3 - 89 - 21 ) ) + 89 + 21 ); - fillHisto( h_pixelMap2[rich], -( iGlobalY + 1 ), - ( -1 * ( iGlobalX2 + 3 - 89 - 21 ) ) + 89 + 21 ); + auto convertX = []( const auto x ) { return ( -1 * ( x + 3 - 89 - 21 ) ) + 89 + 21; }; + auto convertY = []( const auto y ) { return -( y + 1 ); }; + ++hb_pixelMap[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } else { - fillHisto( h_pixelMap[rich], iGlobalY + 1, iGlobalX + 3 ); - fillHisto( h_pixelMap2[rich], iGlobalY + 1, iGlobalX2 + 3 ); + auto convertX = []( const auto x ) { return x + 3; }; + auto convertY = []( const auto y ) { return y + 1; }; + ++hb_pixelMap[rich][{convertY( iGlobalY ), convertX( iGlobalX )}]; + ++hb_pixelMap2[rich][{convertY( iGlobalY ), convertX( iGlobalX2 )}]; } } else { - fillHisto( h_pixelMap[rich], iGlobalX + 1, iGlobalY ); - fillHisto( h_pixelMap2[rich], iGlobalX2 + 1, iGlobalY ); + auto convertX = []( const auto x ) { return x + 1; }; + auto convertY = []( const auto y ) { return y; }; + ++hb_pixelMap[rich][{convertX( iGlobalX ), convertY( iGlobalY )}]; + ++hb_pixelMap2[rich][{convertX( iGlobalX2 ), convertY( iGlobalY )}]; } } @@ -424,7 +402,7 @@ namespace Rich::Future::Mon { // info() << "gPos " << gPos << endmsg; const auto lPos = smartIDsHelper.globalToPDPanel( gPos ); // info() << "lPos " << lPos << endmsg; - fillHisto( h_hitMaps[rich], lPos.x(), lPos.y() ); + ++hb_hitMaps[rich][{lPos.x(), lPos.y()}]; } } // hit loop @@ -435,13 +413,13 @@ namespace Rich::Future::Mon { } // PDs } // modules - if ( m_fillVerbosePMTPlots ) { fillHisto( h_nHits_side[rich][side], nHitsSide ); } + if ( m_fillVerbosePMTPlots ) { ++h_nHits_side[rich][side][nHitsSide]; } } // panels - fillHisto( h_NHitsVsSlotID[rich], slotID, nHits ); - fillHisto( h_NHitsVsBunchID[rich], bunchID, nHits ); - // if ( m_enableOfflinePlots ) { fillHisto( h_NHitsVsBunchID[rich], bunchID, nHits ); } - fillHisto( h_nHits[rich], nHits ); // jj - } // RICHes + ++h_NHitsVsSlotID[rich][{slotID, nHits}]; + ++h_NHitsVsBunchID[rich][{bunchID, nHits}]; + // if ( m_enableOfflinePlots ) { ++h_NHitsVsBunchID[rich][{ bunchID, nHits }]; } + ++h_nHits[rich][nHits]; + } // RICHes } }; diff --git a/Rich/RichOnlineMonitors/src/RichTAEMonitor.cpp b/Rich/RichOnlineMonitors/src/RichTAEMonitor.cpp index c9c4a58ecdacc04157d9e9353f938060210610c7..2c04e5665313afff359a2b1d7b44f91eb036e1ca 100644 --- a/Rich/RichOnlineMonitors/src/RichTAEMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichTAEMonitor.cpp @@ -22,9 +22,6 @@ #include "RichRecUtils/RichDetParams.h" #include "RichUtils/RichDAQDefinitions.h" -// ROOT -#include "TString.h" - // Rich DAQ #include "RichFutureDAQ/RichPDMDBEncodeMapping.h" #include "RichFutureDAQ/RichTel40CableMapping.h" @@ -43,14 +40,10 @@ #include #include #include -#include #include namespace Rich::Future::Mon { - // Use the functional framework - // using namespace Gaudi::Functional; - /** @class TAEMonitor TAEMonitor.h * * Produces RICH hit maps. @@ -67,23 +60,19 @@ namespace Rich::Future::Mon { void( ODINVector const&, DecodedDataVector const& ), Gaudi::Functional::Traits::BaseClass_t>> { - using base_class = LHCb::Algorithm::MergingConsumer< - void( ODINVector const&, DecodedDataVector const& ), - Gaudi::Functional::Traits::BaseClass_t>>; - public: /// Standard constructor TAEMonitor( const std::string& name, ISvcLocator* pSvcLocator ) - : base_class( name, pSvcLocator, - // input data - {KeyValues{"ODINsLocation", {}}, KeyValues{"DecodedDatasLocation", {}}} ) { + : MergingConsumer( name, pSvcLocator, + // input data + {KeyValues{"ODINsLocation", {}}, KeyValues{"DecodedDatasLocation", {}}} ) { // setProperty( "HistoPrint", true ).ignore(); setProperty( "NBins2DHistos", 500 ).ignore(); } /// Initialize StatusCode initialize() override { - return base_class::initialize().andThen( [&] { + return MergingConsumer::initialize().andThen( [&] { // create the RICH smartID helper instance DAQ::Tel40CableMapping::addConditionDerivation( this, m_tel40CableMapping.key() ); DAQ::PDMDBEncodeMapping::addConditionDerivation( this, m_pdmdbEncodeMapping.key() ); @@ -95,13 +84,9 @@ namespace Rich::Future::Mon { // histograms /// Occupancy vs taeID - DetectorArray h_NHitsVsTaeID = {{}}; + mutable Hist::DetArray> h_NHitsVsTaeID = {{}}; /// taeID vs tell40 link (i.e. 100 bits) - DetectorArray h_TaeIDVsBitID = {{}}; - - private: - /// mutex lock - mutable std::mutex m_updateLock; + mutable Hist::DetArray> h_TaeIDVsBitID = {{}}; ConditionAccessor m_tel40CableMapping{this, DAQ::Tel40CableMapping::DefaultConditionKey + "-" + name()}; @@ -118,18 +103,18 @@ namespace Rich::Future::Mon { // Loop over RICHes for ( const auto rich : Rich::detectors() ) { - ok &= saveAndCheck( h_NHitsVsTaeID[rich], richHisto2D( Rich::HistogramID( "NHitsVsTaeID", rich ), // - "# of hits Vs Tae ID", // - -4.5, 4.5, 9, // - -0.5, 1.25e5 - 0.5, 1.25e3, // - "TAE ID", "# of hits", "", // - TAEaxisLabels ) ); - ok &= saveAndCheck( h_TaeIDVsBitID[rich], richHisto2D( Rich::HistogramID( "TaeIDVsBitID", rich ), // - "Tae ID Vs global bit ID", // - -0.5, 2e5 - 0.5, 2e3, // - -4.5, 4.5, 9, // - "bit ID", "TAE ID", "", // - BinLabels(), TAEaxisLabels ) ); + ok &= initHist( h_NHitsVsTaeID[rich], Rich::HistogramID( "NHitsVsTaeID", rich ), // + "# of hits Vs Tae ID", // + -4.5, 4.5, 9, // + -0.5, 1.25e5 - 0.5, 1.25e3, // + "TAE ID", "# of hits", "", // + TAEaxisLabels ); + ok &= initHist( h_TaeIDVsBitID[rich], Rich::HistogramID( "TaeIDVsBitID", rich ), // + "Tae ID Vs global bit ID", // + -0.5, 2e5 - 0.5, 2e3, // + -4.5, 4.5, 9, // + "bit ID", "TAE ID", "", // + BinLabels(), TAEaxisLabels ); } return StatusCode{ok}; @@ -142,12 +127,13 @@ namespace Rich::Future::Mon { auto const& tel40Maps = m_tel40CableMapping.get(); auto const& pdmdbMaps = m_pdmdbEncodeMapping.get(); - std::lock_guard lock( m_updateLock ); - auto taeEvents = m_taeHandler.arrangeTAE( odinVector, decodedDataVector, -1 ); - if ( taeEvents.empty() ) { // In case something went wrong - return; - } + // In case something went wrong + if ( taeEvents.empty() ) { return; } + + // local buffers + auto hb_TaeIDVsBitID = h_TaeIDVsBitID.buffer(); + auto hb_NHitsVsTaeID = h_NHitsVsTaeID.buffer(); // Loop over taeEvents for ( auto const& element : taeEvents ) { @@ -180,18 +166,15 @@ namespace Rich::Future::Mon { // loop over hits for ( const auto id : rawIDs ) { - ++nHits; - const auto& anodeData = pdmdbMaps.anodeData( id ); const auto& tel40Data = tel40Maps.tel40Data( id, anodeData.pdmdb, anodeData.frame ); if ( offset == 0 || odin.bunchCrossingType() == LHCb::ODIN::BXTypes::NoBeam ) { - fillHisto( h_TaeIDVsBitID[rich], - 1e5 * static_cast( id.panel() ) + - 100 * - ( 24 * ( tel40Data.sourceID.data() & 0x3F ) + tel40Data.connector.data() ) + - anodeData.bit.data(), - offset ); + ++hb_TaeIDVsBitID[rich][{ + 1e5 * static_cast( id.panel() ) + + 100 * ( 24 * ( tel40Data.sourceID.data() & 0x3F ) + tel40Data.connector.data() ) + + anodeData.bit.data(), + offset}]; } } // hit loop @@ -203,7 +186,7 @@ namespace Rich::Future::Mon { } // modules } // panels if ( ( offset == 0 || odin.bunchCrossingType() == LHCb::ODIN::BXTypes::NoBeam ) && ( nHits > 0 ) ) { - fillHisto( h_NHitsVsTaeID[rich], offset, nHits ); + ++hb_NHitsVsTaeID[rich][{offset, nHits}]; } } // RICHes }