Skip to content
Snippets Groups Projects

New merge to master for VELO monitoring (rebased from velomon_rhel9, TAEmonitor only now)

Merged Lanxing Li requested to merge lali_velomon_rebase_TAE_only into master
Compare and
4 files
+ 1301
206
Compare changes
  • Side-by-side
  • Inline
Files
4
+ 284
0
/*****************************************************************************\
* (c) Copyright 2020 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 "Event/ODIN.h"
#include "Event/VPFullCluster.h"
//#include "VPRetinaFullCluster.h"
#include "Kernel/VPConstants.h"
#include "VPDet/DeVP.h"
#include "DetDesc/GenericConditionAccessorHolder.h"
#include "VPDet/DeVPSensor.h"
#include "GaudiAlg/Consumer.h"
#include "GaudiAlg/GaudiTupleAlg.h"
#include <GaudiAlg/GaudiHistoAlg.h>
#include <GaudiKernel/IHistogramSvc.h>
#include <GaudiUtils/HistoLabels.h>
#include "Gaudi/Accumulators/Histogram.h"
#include <algorithm>
#include <cmath>
#include <string>
#include <utility>
#include <vector>
/* @class VPBunchMonitors VPBunchMonitors.cpp
*
* * Class for plotting
* - Number of clusters per bunch ID for each module
*
* @author T.H.McGrath
* @date 2022-05-19
*/
namespace {
constexpr auto NAsicsTotal = VP::NSensorsPerModule * VP::NChipsPerSensor * VP::NModules;
// Get asic in range [0, 623]
constexpr uint get_asic( uint sensor, uint chipNr ) { return 3 * sensor + chipNr; }
} // namespace
using namespace Gaudi::Functional; // Consumer
using namespace Gaudi::Utils; // Aida2ROOT::aida2root
class VPBunchMonitors : public Consumer<void( const LHCb::ODIN&, const std::vector<LHCb::VPFullCluster>& ),
LHCb::DetDesc::usesBaseAndConditions<GaudiHistoAlg>> {
public:
// Constructor
VPBunchMonitors( const std::string& name, ISvcLocator* pSvcLocator );
// Initialize
StatusCode initialize() override;
// Functional operator
void operator()( const LHCb::ODIN&, const std::vector<LHCb::VPFullCluster>& ) const override;
private:
// Input variables
Gaudi::Property<bool> applyCut{this, "ClearNoise", false, "Whether to remove noisy pixels to clean data"};
Gaudi::Property<bool> printInfo{this, "PrintInfo", true, "Whether to print BxID info for each event"};
Gaudi::Property<bool> debug{this, "DebugMode", true, "Whether to produce extra plots for debugging"};
// Histogram objects
struct Histograms {
mutable Gaudi::Accumulators::Histogram<1> m_ncl; // Clusters / event frequency
mutable Gaudi::Accumulators::Histogram<1> m_bxid; // BxID frequency
mutable Gaudi::Accumulators::Histogram<2> m_bxidpe; // Clusters / event frequency vs BxID
mutable Gaudi::Accumulators::Histogram<2> m_allmods; // Number of clusters per bunch ID per module
mutable Gaudi::Accumulators::Histogram<2> m_allasics; // Number of clusters per bunch ID per ASIC
mutable std::array<Gaudi::Accumulators::Histogram<1>, VP::NModules> m_nclpm; // Clusters / event frequency for each
// module
mutable std::array<Gaudi::Accumulators::Histogram<2>, VP::NModules> m_bxidpepm; // Clusters / event frequency vs
// BxID for each module
mutable std::array<Gaudi::Accumulators::Histogram<1>, VP::NModules> m_listmods; // Number of clusters per bunch ID
// for each module
mutable std::array<Gaudi::Accumulators::Histogram<2>, VP::NModules> m_pixmaps; // Pixels hit maps for each hot
// module
// mutable std::array<Gaudi::Accumulators::Histogram<2>, NAsicsTotal> m_bxidpepc; // Clusters / event
// frequency vs BxID for each chip
mutable Gaudi::Accumulators::Histogram<1> m_csize; // Number of pixels per cluster (cluster size)
// Builder for array of 1D histos with same range and same titles!
template <std::size_t... IDXs>
static std::array<Gaudi::Accumulators::Histogram<1>, sizeof...( IDXs )>
histoArrayBuilderST( const VPBunchMonitors* owner, const std::string& name, const std::string& title,
const std::string& title_suffix, std::tuple<unsigned, double, double> bins,
std::index_sequence<IDXs...> ) {
return {{{owner,
name + std::to_string( IDXs ),
title + std::to_string( IDXs ) + title_suffix,
{std::get<0>( bins ), std::get<1>( bins ), std::get<2>( bins )}}...}};
}
// Builder for array of 2D histos with fixed ranges and labels (General)
template <std::size_t... IDXs>
static std::array<Gaudi::Accumulators::Histogram<2>, sizeof...( IDXs )>
histoArrayBuilder2D( const VPBunchMonitors* owner, const std::string& name, const std::string& title,
const std::string& title_suffix, std::tuple<unsigned, double, double> xbins,
std::tuple<unsigned, double, double> ybins, std::index_sequence<IDXs...> ) {
return {{{owner,
name + std::to_string( IDXs ),
title + std::to_string( IDXs ) + title_suffix,
{std::get<0>( xbins ), std::get<1>( xbins ), std::get<2>( xbins )},
{std::get<0>( ybins ), std::get<1>( ybins ), std::get<2>( ybins )}}...}};
}
// Builder for array of 2D histos with fixed ranges and different title (m_bxidpepc)
template <std::size_t... IDXs>
static std::array<Gaudi::Accumulators::Histogram<2>, sizeof...( IDXs )>
histoArrayBuilder2D_pepc( const VPBunchMonitors* owner, const std::string& name, const std::string& name_suffix,
const std::string& title, const std::string& title_suffix,
const std::string& title_suffix2, std::tuple<unsigned, double, double> xbins,
std::tuple<unsigned, double, double> ybins, std::index_sequence<IDXs...> ) {
return {{{owner,
name + std::to_string( ( IDXs % 12 ) / 3 ) + std::to_string( IDXs / 3 ) + name_suffix +
std::to_string( IDXs / 12 ),
title + std::to_string( ( IDXs % 12 ) / 3 ) + std::to_string( IDXs / 3 ) + title_suffix +
std::to_string( IDXs / 12 ) + title_suffix2,
{std::get<0>( xbins ), std::get<1>( xbins ), std::get<2>( xbins )},
{std::get<0>( ybins ), std::get<1>( ybins ), std::get<2>( ybins )}}...}};
}
// Book all plots
Histograms( const VPBunchMonitors* owner )
: m_ncl{owner,
"VPClustersPerEvent",
"Frequency of # of VP clusters per event (Frequency vs Clusters/event); Clusters/event;",
{25, 0., 25.}}
, m_bxid{owner, "BxIDFrequency", "# of VP clusters per BxID (Frequency vs BxID); BxID;", {3564, 0.5, 3564.5}}
, m_bxidpe{owner,
"VPClustersPerEventVSBxID",
"# of VP clusters per event per BxID (Clusters/event vs BxID); BxID; Clusters/event",
{3564, 0.5, 3564.5},
{5001, -1, 10001}}
, m_allmods{owner,
"VPClustersPerModulePerBxID",
"Cluster frequency per module per BxID (BxID vs Modules); Module; BxId",
{VP::NModules, -0.5, VP::NModules - 0.5},
{3564, 0.5, 3564.5}}
, m_allasics{owner,
"VPClustersPerASICPerBxID",
"Cluster frequency per ASIC per BxID (BxID vs ASIC); ASIC; BxId",
{NAsicsTotal, -0.5, NAsicsTotal - 0.5},
{3564, 0.5, 3564.5}}
,
// Only book per module plots if in debug mode (currently add all debug plots)
m_bxidpepm{histoArrayBuilder2D( owner, "VPClustersPerEventVSBxIDForModule",
"# of VP clusters per event per BxID for Module ",
" (Clusters/event vs BxID); BxID; Clusters/event", {3564, 0.5, 3564.5},
{25, 0., 25.}, std::make_index_sequence<VP::NModules>() )}
, m_nclpm{histoArrayBuilderST( owner, "VPClustersPerEventForModule",
"Frequency of # of VP clusters per event for Module ",
" (Frequency vs Clusters/event); Clusters/event;", {25, 0., 25.},
std::make_index_sequence<VP::NModules>() )}
, m_listmods{histoArrayBuilderST( owner, "VPClustersPerBxIDForModule", "Cluster frequency per BxID for Module ",
" (Clusters vs BxID); BxID; Clusters", {3564, 0.5, 3564.5},
std::make_index_sequence<VP::NModules>() )}
, m_pixmaps{histoArrayBuilder2D( owner, "VPClusterssMapModule", "VP cluster map on module ",
" (Row vs Column); Column; Row", {VP::NColumns, 0, VP::NColumns},
{VP::NRows, 0, VP::NRows}, std::make_index_sequence<VP::NModules>() )}
,
// Only book per chip plots if in debug mode (currently add all debug plots)
// m_bxidpepc{histoArrayBuilder2D_pepc(owner, "VPClustersPerEventVSBxIDOnVP", "Mod",
// "# of VP clusters per event per BxID for VP", " on Module "," (Clusters/event vs
// BxID); BxID; Clusters/event", {3564, 0.5, 3564.5}, {25, 0., 25.},
// std::make_index_sequence< NAsicsTotal >() )},
m_csize{owner,
"VPClusterSize",
"Number of pixels per VP cluster (Frequency vs Cluster Size); Cluster Size;",
{49, 1, 50}} {}
};
std::unique_ptr<Histograms> m_histos;
}; // End of class
// Declaration of the Algorithm Factory
DECLARE_COMPONENT( VPBunchMonitors )
// ===============================================================
// Constructor
// ===============================================================
VPBunchMonitors::VPBunchMonitors( const std::string& name, ISvcLocator* pSvcLocator )
: Consumer( name, pSvcLocator,
{KeyValue{"ODINLocation", LHCb::ODINLocation::Default},
KeyValue{"ClusterLocation", LHCb::VPFullClusterLocation::Default}} ) {}
// ===============================================================
// Initialize
// ===============================================================
StatusCode VPBunchMonitors::initialize() {
StatusCode sc = Consumer::initialize();
if ( sc.isFailure() ) return sc;
return sc.andThen( [&]() { m_histos = std::make_unique<Histograms>( this ); } );
}
// ===============================================================
// Main
// ===============================================================
void VPBunchMonitors::operator()( const LHCb::ODIN& odin, const std::vector<LHCb::VPFullCluster>& vpClusters ) const {
// Get event information from ODIN
const auto bxid = odin.bunchId();
const auto runNr = odin.runNumber();
const auto evtNr = odin.eventNumber();
if ( printInfo ) {
info() << "BxID: " << bxid << " run #: " << runNr << " event #: " << evtNr << endmsg;
info() << "Number of clusters: " << vpClusters.size() << endmsg;
}
std::vector<uint> nClusPerMod( VP::NModules, 0 );
std::vector<uint> nClusPerChip( NAsicsTotal, 0 );
uint nClusPerEvent( 0 );
// Loop over clusters vector
for ( const auto& vpCluster : vpClusters ) {
// Get VP Channel IDs of pixels in cluster
const auto vpID = vpCluster.channelID();
const auto pixels = vpCluster.pixels();
// Get module where cluster is
const auto mod = vpID.module();
const auto asic = get_asic( to_unsigned( vpID.sensor() ), to_unsigned( vpID.chip() ) );
// info() << "Module: " << mod << endmsg;
// Get pixel
const auto row = to_unsigned( vpID.row() );
const auto col = to_unsigned( vpID.col() );
// Fill histograms
++( *m_histos ).m_bxid[bxid];
++( *m_histos ).m_allmods[{mod, bxid}];
++( *m_histos ).m_allasics[{asic, bxid}];
++( *m_histos ).m_csize[{pixels.size()}];
// Add each cluster from asic
++nClusPerChip[asic];
++nClusPerEvent;
if ( debug ) {
++( *m_histos ).m_listmods[mod][bxid];
++( *m_histos ).m_pixmaps[mod][{col, row}];
++nClusPerMod[mod];
}
} // Loop over clusters per event
++( *m_histos ).m_bxidpe[{bxid, nClusPerEvent}];
++( *m_histos ).m_ncl[{nClusPerEvent}];
if ( debug ) {
for ( uint modNr = 0; modNr < VP::NModules; ++modNr ) {
++( *m_histos ).m_nclpm[modNr][nClusPerMod[modNr]];
++( *m_histos ).m_bxidpepm[modNr][{bxid, nClusPerMod[modNr]}];
// info() << "Clusters in this event for module " << modNr << ": " << nClusPerMod[modNr] << endmsg;
}
// for ( uint asic = 0; asic < NAsicsTotal; ++asic ) { ++( *m_histos ).m_bxidpepc[asic][ {bxid,
// nClusPerChip[asic]} ]; }
}
// clear vector before next event
nClusPerMod.clear();
}
Loading