Skip to content
Snippets Groups Projects
Commit 62534af2 authored by Duc Ta's avatar Duc Ta
Browse files

Merge branch '24.0-tile-tb-cell-mon-run3-add' into '24.0'

TileMonitoring: Migrate Tile TB cell monitoring tool for Run3

See merge request !70757
parents 10ee3e45 4560a8b9
No related branches found
No related tags found
2 merge requests!708052024-04-23: merge of 24.0 into main,!70757TileMonitoring: Migrate Tile TB cell monitoring tool for Run3
......@@ -133,3 +133,8 @@ atlas_add_test( TileJiveXMLConfig_test
SCRIPT python -m TileMonitoring.TileJiveXMLConfig
PROPERTIES TIMEOUT 600
POST_EXEC_SCRIPT nopost.sh)
atlas_add_test( TileTBCellMonitorAlgorithm_test
SCRIPT python -m TileMonitoring.TileTBCellMonitorAlgorithm
PROPERTIES TIMEOUT 600
POST_EXEC_SCRIPT nopost.sh)
#
# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
#
'''
@file TileMonitoringHelper.py
......@@ -198,6 +198,26 @@ def getCellChannelTMDB_Labels(partition):
return _cellNameTMDB_LB if partition.startswith('L') else _cellNameTMDB_EB
def getLegacyChannelForDemonstrator(useDemoCabling, partition, drawer, channel):
''' Function to get legacy channel number from Tile Demonatrator '''
legacyChannel = channel
if (useDemoCabling == 2015 and partition == 'EBC' and drawer == 1):
demo2legacy = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
26, 25, 24, 29, 31, 32, 27, 28, 30, 35, 34, 33, 38, 37, 43, 44, 41, 40, 39, 36, 42, 47, 46, 45]
legacyChannel = demo2legacy[channel]
elif useDemoCabling >= 2016 and useDemoCabling <= 2019 and partition == 'LBC' and (drawer == 1 or drawer > 2):
demo2legacy = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
26, 25, 24, 29, 28, 27, 32, 31, 30, 35, 34, 33, 38, 37, 36, 41, 40, 39, 44, 43, 42, 47, 46, 45]
legacyChannel = demo2legacy[channel]
elif useDemoCabling >= 2018 and partition == 'EBC' and drawer >= 2:
demo2legacyEB = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
31, 32, 30, 35, 33, 34, 38, 37, 41, 40, 39, 36, 26, 25, 24, 29, 28, 27, 44, 43, 42, 47, 46, 45]
legacyChannel = demo2legacyEB[channel]
return legacyChannel
def addValueVsModuleAndChannelMaps(group, name, title, path, subDirectory = False, type = 'TH2D', value = '', trigger = '', run = ''):
'''
This function configures 2D histograms (maps) with Tile monitored value vs module and channel per partion.
......
#
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
#
'''
@file TileTBCellMonitorAlgorithm.py
@brief Python configuration of TileTBCellMonitorAlgorithm algorithm for the Run III
'''
def TileTBCellMonitoringConfig(flags, timeRange=[-100, 100], fragIDs=[0x100, 0x101, 0x200, 0x201, 0x402], useDemoCabling=2018, **kwargs):
''' Function to configure TileTBCellMonitorAlgorithm algorithm in the monitoring system.'''
from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
result = ComponentAccumulator()
from TileGeoModel.TileGMConfig import TileGMCfg
result.merge(TileGMCfg(flags))
from LArGeoAlgsNV.LArGMConfig import LArGMCfg
result.merge(LArGMCfg(flags))
from TileConditions.TileCablingSvcConfig import TileCablingSvcCfg
result.merge(TileCablingSvcCfg(flags))
from TileConditions.TileInfoLoaderConfig import TileInfoLoaderCfg
result.merge(TileInfoLoaderCfg(flags))
from AthenaMonitoring import AthMonitorCfgHelper
helper = AthMonitorCfgHelper(flags, 'TileTBCellMonitoring')
from AthenaConfiguration.ComponentFactory import CompFactory
tileTBCellMonAlg = helper.addAlgorithm(CompFactory.TileTBCellMonitorAlgorithm, 'TileTBCellMonAlg')
tileTBCellMonAlg.TriggerChain = ''
demoCabling = kwargs.pop('useDemoCabling', 2018)
from TileCalibBlobObjs.Classes import TileCalibUtils as Tile
modules = []
if fragIDs:
for fragID in fragIDs:
ros = fragID >> 8
drawer = fragID & 0x3F
modules += [Tile.getDrawerString(ros, drawer)]
else:
for ros in range(1, Tile.MAX_ROS):
for drawer in range(0, Tile.MAX_DRAWER):
fragIDs += [(ros << 8) | drawer]
modules += [Tile.getDrawerString(ros, drawer)]
tileTBCellMonAlg.TileFragIDs = fragIDs
for k, v in kwargs.items():
setattr(tileTBCellMonAlg, k, v)
towersLB = [[tower for tower in range(0, 10)], # Sample A
[tower for tower in range(0, 9)], # Sample BC/B
[tower*2 for tower in range(0, 4)]] # Sample D
towersEB = [[tower for tower in range(11, 15)], # Sample A
[tower for tower in range(9, 14)], # Sample B/C
[tower*2 for tower in range(4, 7)]] # Sample D
def getCellNameFromSampleAndTower(sample, tower):
''' The function to get Tile cell name from sample and tower'''
sampleName = {0: 'A', 1: 'B', 2: 'D'}[sample]
if sample == 1:
if tower < 8:
sampleName += 'C' # BC1 ... BC8 in LB
elif tower == 9:
sampleName = 'C' # C10 in EB
cellName = f'{sampleName}{tower + 1}' if sample < 2 else f'{sampleName}{int(tower / 2)}'
return cellName
def addCellHistogramsArray(helper, modules, algorithm, name, title, path='', type='TH1D',
xbins=100, xmin=-100, xmax=100, ybins=None, ymin=None, ymax=None,
run='', xvalue='', yvalue=None, aliasPrefix='', xtitle='', ytitle=''):
''' This function configures 1D or 2D histograms with monitored value per Tile module and cell '''
cellArray = helper.addArray([modules], algorithm, name, topPath=path)
for postfix, tool in cellArray.Tools.items():
moduleName = postfix[1:]
partition = moduleName[:3]
towers = towersLB if moduleName.startswith('L') else towersEB
for sample in range(0, 3):
for tower in towers[sample]:
cellName = getCellNameFromSampleAndTower(sample, tower)
fullPath = f'{partition}/{moduleName}'
name = f'{xvalue}_{sample}_{tower}'
if yvalue:
name += f',{yvalue}_{sample}_{tower}'
name += f';{aliasPrefix}{cellName}_{moduleName}'
fullTitle = f'Run {run} {moduleName} {cellName}: {title};{xtitle};{ytitle}'
tool.defineHistogram(name, title=fullTitle, path=fullPath, type=type,
xbins=xbins, xmin=xmin, xmax=xmax,
ybins=ybins, ymin=ymin, ymax=ymax)
return cellArray
from TileMonitoring.TileMonitoringCfgHelper import getCellName
from TileMonitoring.TileMonitoringCfgHelper import getLegacyChannelForDemonstrator
def addChannelHistogramsArray(helper, modules, algorithm, name, title, path='', type='TH1D',
xbins=100, xmin=-100, xmax=100, xvalue='', xtitle='', ytitle='',
run='', aliasPrefix='', useDemoCabling=demoCabling):
''' This function configures 1D histograms with Tile monitored value per module and channel '''
channelArray = helper.addArray([modules], algorithm, name, topPath=path)
for postfix, tool in channelArray.Tools.items():
moduleName = postfix[1:]
partition = moduleName[:3]
module = int(moduleName[3:]) - 1
for channel in range(0, Tile.MAX_CHAN):
legacyChannel = getLegacyChannelForDemonstrator(useDemoCabling, partition, module, channel)
cell = getCellName(partition, legacyChannel)
if cell:
cellName = cell.replace('B', 'BC') if (partition in ['LBA','LBC'] and cell and cell[0] == 'B' and cell != 'B9') else cell
fullPath = f'{partition}/{moduleName}'
name = f'{xvalue}_{channel};{aliasPrefix}_{moduleName}_{cellName}_ch_{channel}'
fullTitle = f'Run {run} {moduleName} {cellName} Channel {channel}: {title};{xtitle};{ytitle}'
tool.defineHistogram(name, title=fullTitle, path=fullPath, type=type,
xbins=xbins, xmin=xmin, xmax=xmax)
return channelArray
totalEnergy = min(flags.Beam.Energy, 300)
nEnergyBins = int(totalEnergy * 2)
run = str(flags.Input.RunNumbers[0])
nTimeBins = timeRange[1] - timeRange[0]
# Configure histogram with TileTBCellMonAlg algorithm execution time
executeTimeGroup = helper.addGroup(tileTBCellMonAlg, 'TileTBCellMonExecuteTime', 'TestBeam')
executeTimeGroup.defineHistogram('TIME_execute', path='PulseShape', type='TH1F',
title='Time for execute TileTBCellMonAlg algorithm;time [#mus]',
xbins=100, xmin=0, xmax=1000)
sampleEnergyArray = helper.addArray([modules], tileTBCellMonAlg, 'TileSampleEnergy', topPath='TestBeam')
for postfix, tool in sampleEnergyArray.Tools.items():
moduleName = postfix[1:]
partition = moduleName[:3]
fullPath = f'{partition}/{moduleName}'
titlePrefix = f'Run {run} {moduleName}:'
tool.defineHistogram(f'energy;EnergyTotal{moduleName}', path=fullPath, type='TH1D',
title=f'{titlePrefix} Total energy;Energy [pC];Entries',
xbins=nEnergyBins, xmin=0.0, xmax=totalEnergy)
tool.defineHistogram('energyA,energyBC;EnergyTotalSampleBCVsA', path=fullPath, type='TH2D',
title=f'{titlePrefix} Total energy in sample BC vs sample A;Sample A Energy [pC];Sample B Energy [pC]',
xbins=nEnergyBins, xmin=0.0, xmax=totalEnergy, ybins=nEnergyBins, ymin=0.0, ymax=totalEnergy)
tool.defineHistogram('energyD;EnergyTotalSampleD', path=fullPath, type='TH1D',
title=f'{titlePrefix} Total energy in sample D;Sample D Energy [pC];Entries',
xbins=nEnergyBins, xmin=0.0, xmax=totalEnergy)
addCellHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileCellEnergy', path='TestBeam', xvalue='energy',
title='Tile Cell Energy', xbins=nEnergyBins, xmin=0, xmax=totalEnergy,
run=run, aliasPrefix='CellEnergy', xtitle='Energy [pC]', ytitle='Entries')
addCellHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileCellEnergyDiff', path='TestBeam', xvalue='energyDiff',
title='Tile Cell Energy difference between PMTs', xbins=nEnergyBins, xmin=0, xmax=totalEnergy,
run=run, aliasPrefix='CellEnergy', xtitle='Energy [pC]', ytitle='Entries')
addCellHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileCellTime', path='TestBeam', xvalue='time',
title='Tile Cell Time', xbins=nTimeBins, xmin=timeRange[0], xmax=timeRange[1],
run=run, aliasPrefix='CellTime', xtitle='Time [ns]', ytitle='Entries')
addCellHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileCellTimeDiff', path='TestBeam',
xvalue='timeDiff', title='Tile Cell Time difference between PMTs',
xbins=nTimeBins, xmin=timeRange[0], xmax=timeRange[1],
run=run, aliasPrefix='CellTime', xtitle='Time [ns]', ytitle='Entries')
addCellHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileCellEnergyLeftVsRightPMT', path='TestBeam', type='TH2D',
xvalue='energy1', yvalue='energy2', title='Tile Cell PMT2 vs PMT1 Energy',
xbins=nEnergyBins, xmin=0, xmax=totalEnergy, ybins=nEnergyBins, ymin=0, ymax=totalEnergy,
run=run, aliasPrefix='CellEnergyLeftVsRightPMT',
xtitle='Energy [pC]', ytitle='Energy [pC]')
addCellHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileCellTimeLeftVsRightPMT', path='TestBeam', type='TH2D',
xvalue='time1', yvalue='time2', title='Tile Cell PMT2 vs PMT1 Time',
xbins=nTimeBins, xmin=timeRange[0], xmax=timeRange[1], ybins=nTimeBins, ymin=timeRange[0], ymax=timeRange[1],
run=run, aliasPrefix='CellTimeLeftVsRightPMT', xtitle='Time [ns]', ytitle='Time [ns]')
addChannelHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileChannelEnergy', path='TestBeam/ChannelEnergy', type='TH1D',
xvalue='energy', title='Tile channel energy', xbins=nEnergyBins, xmin=0, xmax=totalEnergy,
run=run, aliasPrefix='ChannelEnergy', xtitle='Energy [pC]', ytitle='Entries')
addChannelHistogramsArray(helper, modules, tileTBCellMonAlg, name='TileChannelTime', path='TestBeam/ChannelTime', type='TH1D',
xvalue='time', title='Tile channel time', xbins=nTimeBins, xmin=timeRange[0], xmax=timeRange[1],
run=run, aliasPrefix='ChannelTime', xtitle='Time [ns]', ytitle='Entries')
accumalator = helper.result()
result.merge(accumalator)
return result
if __name__=='__main__':
# Setup logs
from AthenaCommon.Logging import log
from AthenaCommon.Constants import INFO
log.setLevel(INFO)
# Set the Athena configuration flags
from AthenaConfiguration.AllConfigFlags import initConfigFlags
from AthenaConfiguration.TestDefaults import defaultTestFiles
flags = initConfigFlags()
parser = flags.getArgumentParser()
parser.add_argument('--postExec', help='Code to execute after setup')
parser.add_argument('--time-range', dest='timeRange', nargs=2, default=[-200, 200], help='Time range for pulse shape histograms')
parser.add_argument('--frag-ids', dest='fragIDs', nargs="*", default=['0x100', '0x101', '0x200', '0x201', '0x402'],
help='Tile Frag IDs of modules to be monitored. Empty=ALL')
parser.add_argument('--demo-cabling', dest='demoCabling', type=int, default=2018, help='Time Demonatrator cabling to be used')
args, _ = parser.parse_known_args()
fragIDs = [int(fragID, base=16) for fragID in args.fragIDs]
timeRange = [int(time) for time in args.timeRange]
flags.Input.Files = defaultTestFiles.ESD
flags.Output.HISTFileName = 'TileTBCellMonitorOutput.root'
flags.DQ.useTrigger = False
flags.DQ.enableLumiAccess = False
flags.Exec.MaxEvents = 3
flags.Common.isOnline = True
flags.fillFromArgs(parser=parser)
flags.lock()
# Initialize configuration object, add accumulator, merge, and run.
from AthenaConfiguration.MainServicesConfig import MainServicesCfg
cfg = MainServicesCfg(flags)
from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
cfg.merge(PoolReadCfg(flags))
cfg.merge(TileTBCellMonitoringConfig(flags,
fragIDs=fragIDs,
timeRange=timeRange,
useDemoCabling=args.demoCabling))
# Any last things to do?
if args.postExec:
log.info('Executing postExec: %s', args.postExec)
exec(args.postExec)
cfg.printConfig(withDetails=True, summariseProps=True)
cfg.store(open('TileTBCellMonitorAlgorithm.pkl', 'wb'))
sc = cfg.run()
import sys
# Success should be 0
sys.exit(not sc.isSuccess())
......@@ -7,6 +7,7 @@
'''
from AthenaConfiguration.Enums import Format
from TileMonitoring.TileMonitoringCfgHelper import getLegacyChannelForDemonstrator
def getPMT(partition, channel):
......@@ -38,26 +39,6 @@ def getPMT(partition, channel):
return pmt
def getLegacyChannelForDemonstrator(useDemoCabling, partition, drawer, channel):
''' Function to get legacy channel number from Tile Demonatrator '''
legacyChannel = channel
if (useDemoCabling == 2015 and partition == 'EBC' and drawer == 1):
demo2legacy = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
26, 25, 24, 29, 31, 32, 27, 28, 30, 35, 34, 33, 38, 37, 43, 44, 41, 40, 39, 36, 42, 47, 46, 45]
legacyChannel = demo2legacy[channel]
elif useDemoCabling >= 2016 and useDemoCabling <= 2019 and partition == 'LBC' and (drawer == 1 or drawer > 2):
demo2legacy = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
26, 25, 24, 29, 28, 27, 32, 31, 30, 35, 34, 33, 38, 37, 36, 41, 40, 39, 44, 43, 42, 47, 46, 45]
legacyChannel = demo2legacy[channel]
elif useDemoCabling >= 2018 and partition == 'EBC' and drawer >= 2:
demo2legacyEB = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
31, 32, 30, 35, 33, 34, 38, 37, 41, 40, 39, 36, 26, 25, 24, 29, 28, 27, 44, 43, 42, 47, 46, 45]
legacyChannel = demo2legacyEB[channel]
return legacyChannel
def TileTBPulseMonitoringConfig(flags, timeRange=[-100, 100], fragIDs=[0x100, 0x101, 0x200, 0x201, 0x402], useDemoCabling=2018, **kwargs):
''' Function to configure TileTBPulseMonitorAlgorithm algorithm in the monitoring system.'''
......
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "TileTBCellMonitorAlgorithm.h"
#include "AthenaKernel/Units.h"
#include "AthenaMonitoringKernel/MonitoredScalar.h"
#include "TileCalibBlobObjs/TileCalibUtils.h"
#include "TileConditions/TileInfo.h"
#include "TileIdentifier/TileHWID.h"
#include "TileEvent/TileCell.h"
#include "CaloIdentifier/TileID.h"
#include "StoreGate/ReadHandle.h"
#include <algorithm>
#include <string>
StatusCode TileTBCellMonitorAlgorithm::initialize() {
ATH_MSG_INFO("in initialize()");
ATH_CHECK( AthMonitorAlgorithm::initialize() );
ATH_CHECK( m_caloCellContainerKey.initialize() );
ATH_CHECK( m_cablingSvc.retrieve() );
m_cabling = m_cablingSvc->cablingService();
ATH_CHECK( detStore()->retrieve(m_tileID) );
ATH_CHECK( detStore()->retrieve(m_tileHWID) );
std::vector<std::string> modules;
for (int fragID : m_fragIDs) {
int ros = fragID >> 8;
int drawer = fragID & 0x3F;
modules.push_back(TileCalibUtils::getDrawerString(ros, drawer));
m_monitoredDrawerIdx[TileCalibUtils::getDrawerIdx(ros, drawer)] = true;
}
std::ostringstream os;
if ( m_fragIDs.size() != 0) {
std::sort(m_fragIDs.begin(), m_fragIDs.end());
for (int fragID : m_fragIDs) {
unsigned int ros = fragID >> 8;
unsigned int drawer = fragID & 0xFF;
std::string module = TileCalibUtils::getDrawerString(ros, drawer);
os << " " << module << "/0x" << std::hex << fragID << std::dec;
}
} else {
os << "NONE";
}
ATH_MSG_INFO("Monitored modules/frag ID:" << os.str());
std::map<std::string, unsigned int> roses = { {"AUX", 0}, {"LBA", 1}, {"LBC", 2}, {"EBA", 3}, {"EBC", 4} };
for (std::string maskedModuleChannels : m_masked) {
std::string module = maskedModuleChannels.substr(0, 5);
std::string partition = module.substr(0, 3);
if (roses.count(partition) != 1) {
ATH_MSG_WARNING("There no such partition: " << partition << " in module: " << module
<< " => skip because of bad format: " << maskedModuleChannels);
continue;
}
unsigned int drawer = std::stoi(module.substr(3, 2)) - 1;
if (drawer >= TileCalibUtils::MAX_DRAWER) {
ATH_MSG_WARNING("There no such drawer: " << drawer + 1 << " in module: " << module
<< " => skip because of bad format: " << maskedModuleChannels);
continue;
}
unsigned int ros = roses.at(partition);
unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
std::string gain = maskedModuleChannels.substr(5,7);
unsigned int adc = std::stoi(gain);
if (adc >= TileCalibUtils::MAX_GAIN) {
ATH_MSG_WARNING("There no such gain: " << gain << " => skip because of bad format: " << maskedModuleChannels);
continue;
}
std::stringstream channels(maskedModuleChannels.substr(7));
std::string channel;
while (std::getline(channels, channel, ',')) {
if (!channel.empty()) {
unsigned int chan = std::stoi(channel);
if (chan >= TileCalibUtils::MAX_CHAN) {
ATH_MSG_WARNING("There no such channel: " << chan << " in channels: " << channels.str()
<< " => skip because of bad format: " << maskedModuleChannels);
continue;
}
m_maskedChannels[drawerIdx][chan] |= (1U << adc);
ATH_MSG_INFO(TileCalibUtils::getDrawerString(ros, drawer) << " ch" << chan << (adc ? " HG" : " LG") << ": masked!");
}
}
}
for (unsigned int ros = 0; ros < TileCalibUtils::MAX_ROS; ++ros) {
for (unsigned int drawer = 0; drawer < TileCalibUtils::getMaxDrawer(ros); ++drawer) {
unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
m_drawerIdxToROS[drawerIdx] = ros;
m_drawerIdxToDrawer[drawerIdx] = drawer;
}
}
using namespace Monitored;
m_sampleEnergyGroups = buildToolMap<int>(m_tools, "TileSampleEnergy", modules);
m_energyGroups = buildToolMap<int>(m_tools, "TileCellEnergy", modules);
m_energyDiffGroups = buildToolMap<int>(m_tools, "TileCellEnergyDiff", modules);
m_energy2VsEnergy1Groups = buildToolMap<int>(m_tools, "TileCellEnergyLeftVsRightPMT", modules);
m_timeGroups = buildToolMap<int>(m_tools, "TileCellTime", modules);
m_timeDiffGroups = buildToolMap<int>(m_tools, "TileCellTimeDiff", modules);
m_time2VsTime1Groups = buildToolMap<int>(m_tools, "TileCellTimeLeftVsRightPMT", modules);
if (m_fillHistogramsPerChannel) {
m_channelEnergyGroups = buildToolMap<int>(m_tools, "TileChannelEnergy", modules);
m_channelTimeGroups = buildToolMap<int>(m_tools, "TileChannelTime", modules);
}
return StatusCode::SUCCESS;
}
StatusCode TileTBCellMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
// In case you want to measure the execution time
auto timer = Monitored::Timer("TIME_execute");
using Athena::Units::GeV;
constexpr int allSamples = TileID::SAMP_E; // To be used to keep total energy from all samples
constexpr int nSamples = allSamples + 1;
double sampleEnergy[TileCalibUtils::MAX_DRAWERIDX][nSamples] = {{0}};
SG::ReadHandle<CaloCellContainer> caloCellContainer(m_caloCellContainerKey, ctx);
ATH_CHECK( caloCellContainer.isValid() );
if (!caloCellContainer->empty()) {
for (const CaloCell* cell : *caloCellContainer) {
Identifier id = cell->ID();
if (m_tileID->is_tile(id)) {
const TileCell* tile_cell = dynamic_cast<const TileCell*>(cell);
if (!tile_cell) continue;
int drawer = 0; // The same for both channels
int channel1 = -1;
int channel2 = -1;
int ros1 = -1;
int ros2 = -1;
int drawerIdx1 = -1;
int drawerIdx2 = -1;
int gain1 = tile_cell->gain1(); // Gain of first PMT
int gain2 = tile_cell->gain2(); // Gain of second PMT
const CaloDetDescrElement* caloDDE = tile_cell->caloDDE();
IdentifierHash hash1 = caloDDE->onl1();
if (hash1 != TileHWID::NOT_VALID_HASH) {
HWIdentifier channel1_id = m_tileHWID->channel_id(hash1);
channel1 = m_tileHWID->channel(channel1_id);
drawer = m_tileHWID->drawer(channel1_id);
ros1 = m_tileHWID->ros(channel1_id);
drawerIdx1 = TileCalibUtils::getDrawerIdx(ros1, drawer);
}
IdentifierHash hash2 = caloDDE->onl2();
if (hash2 != TileHWID::NOT_VALID_HASH) {
HWIdentifier channel2_id = m_tileHWID->channel_id(hash2);
channel2 = m_tileHWID->channel(channel2_id);
drawer = m_tileHWID->drawer(channel2_id);
ros2 = m_tileHWID->ros(channel2_id);
drawerIdx2 = TileCalibUtils::getDrawerIdx(ros2, drawer);
}
if (!((drawerIdx1 >= 0 && m_monitoredDrawerIdx[drawerIdx1])
|| (drawerIdx2 >= 0 && m_monitoredDrawerIdx[drawerIdx2]))) continue;
bool isOkChannel1 = (channel1 > -1 && gain1 != CaloGain::INVALIDGAIN);
bool isOkChannel2 = (channel2 > -1 && gain2 != CaloGain::INVALIDGAIN);
bool isMaskedChannel1 = isOkChannel1 && ((m_maskedChannels[drawerIdx1][channel1] >> gain1) & 1U);
bool isMaskedChannel2 = isOkChannel2 && ((m_maskedChannels[drawerIdx2][channel2] >> gain2) & 1U);
int sample = m_tileID->sample(id);
int tower = m_tileID->tower(id);
bool single_PMT_scin = (sample == TileID::SAMP_E);
std::string moduleName = TileCalibUtils::getDrawerString(ros1, drawer);
std::string sampleTowerSuffix = "_" + std::to_string(sample) + "_" + std::to_string(tower);
// Keep energy in GeV;
double energy = cell->energy() * (1.0 / GeV);
double energy1 = tile_cell->ene1() * (1.0 / GeV);
double energy2 = tile_cell->ene2() * (1.0 / GeV);
double energyDiff = (single_PMT_scin) ? 0.0 : tile_cell->eneDiff() * (1.0 / GeV);
double time = cell->time();
double time1 = tile_cell->time1();
double time2 = tile_cell->time2();
double timeDiff = (single_PMT_scin) ? 0.0 : 2. * tile_cell->timeDiff(); // Attention! factor of 2 is needed here
if (m_fillHistogramsPerChannel) {
if (isOkChannel1) {
auto monChannel1Energy = Monitored::Scalar<double>("energy_" + std::to_string(channel1), energy1);
fill(m_tools[m_channelEnergyGroups.at(moduleName)], monChannel1Energy);
}
if (isOkChannel2) {
auto monChannel2Energy = Monitored::Scalar<double>("energy_" + std::to_string(channel2), energy2);
fill(m_tools[m_channelEnergyGroups.at(moduleName)], monChannel2Energy);
}
if (tile_cell->energy() > m_energyThresholdForTime) {
if (isOkChannel1) {
auto monChannel1Time = Monitored::Scalar<double>("time_" + std::to_string(channel1), time1);
fill(m_tools[m_channelTimeGroups.at(moduleName)], monChannel1Time);
}
if (isOkChannel2) {
auto monChannel2Time = Monitored::Scalar<double>("time_" + std::to_string(channel2), time2);
fill(m_tools[m_channelTimeGroups.at(moduleName)], monChannel2Time);
}
}
}
if (sample < TileID::SAMP_E) { // Normal Tile cells with two channels (in TB setup)
auto monEnergy = Monitored::Scalar<double>("energy" + sampleTowerSuffix, energy);
fill(m_tools[m_energyGroups.at(moduleName)], monEnergy);
auto monEnergyDiff = Monitored::Scalar<double>("energyDiff" + sampleTowerSuffix, energyDiff);
fill(m_tools[m_energyDiffGroups.at(moduleName)], monEnergyDiff);
auto monEnergy1 = Monitored::Scalar<double>("energy1" + sampleTowerSuffix, energy1);
auto monEnergy2 = Monitored::Scalar<double>("energy2" + sampleTowerSuffix, energy2);
fill(m_tools[m_energy2VsEnergy1Groups.at(moduleName)], monEnergy1, monEnergy2);
if (tile_cell->energy() > m_energyThresholdForTime) {
auto monTime = Monitored::Scalar<double>("time" + sampleTowerSuffix, time);
fill(m_tools[m_timeGroups.at(moduleName)], monTime);
auto monTimeDiff = Monitored::Scalar<double>("timeDiff" + sampleTowerSuffix, timeDiff);
fill(m_tools[m_timeDiffGroups.at(moduleName)], monTimeDiff);
auto monTime1 = Monitored::Scalar<double>("time1" + sampleTowerSuffix, time1);
auto monTime2 = Monitored::Scalar<double>("time2" + sampleTowerSuffix, time2);
fill(m_tools[m_time2VsTime1Groups.at(moduleName)], monTime1, monTime2);
}
if (isMaskedChannel1 && !isMaskedChannel2) {
energy = energy2 * 2.0;
} else if (isMaskedChannel2 && !isMaskedChannel1) {
energy = energy1 * 2.0;
} else if (isMaskedChannel1 && isMaskedChannel2) {
energy = 0.0;
}
sampleEnergy[drawerIdx1][sample] += energy;
sampleEnergy[drawerIdx1][allSamples] += energy;
}
}
}
for (unsigned int drawerIdx = 0; drawerIdx < TileCalibUtils::MAX_DRAWERIDX; ++drawerIdx) {
if (m_monitoredDrawerIdx[drawerIdx]) {
unsigned int ros = m_drawerIdxToROS[drawerIdx];
unsigned int drawer = m_drawerIdxToDrawer[drawerIdx];
std::string moduleName = TileCalibUtils::getDrawerString(ros, drawer);
auto monEnergy = Monitored::Scalar<double>("energy", sampleEnergy[drawerIdx][allSamples]);
auto monEnergyA = Monitored::Scalar<double>("energyA", sampleEnergy[drawerIdx][TileID::SAMP_A]);
auto monEnergyBC = Monitored::Scalar<double>("energyBC", sampleEnergy[drawerIdx][TileID::SAMP_BC]);
auto monEnergyD = Monitored::Scalar<double>("energyD", sampleEnergy[drawerIdx][TileID::SAMP_D]);
fill(m_tools[m_sampleEnergyGroups.at(moduleName)], monEnergy);
fill(m_tools[m_sampleEnergyGroups.at(moduleName)], monEnergyA, monEnergyBC);
fill(m_tools[m_sampleEnergyGroups.at(moduleName)], monEnergyD);
}
}
}
fill("TileTBCellMonExecuteTime", timer);
return StatusCode::SUCCESS;
}
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef TILEMONITORING_TILETBCELLMONITORALGORITHM_H
#define TILEMONITORING_TILETBCELLMONITORALGORITHM_H
#include "TileConditions/TileCablingSvc.h"
#include "TileCalibBlobObjs/TileCalibUtils.h"
#include "CaloEvent/CaloCellContainer.h"
#include "AthenaMonitoring/AthMonitorAlgorithm.h"
#include "StoreGate/ReadHandleKey.h"
#include <array>
class TileInfo;
class TileID;
class TileHWID;
/** @class TileTBCellMonitorAlgorithm
* @brief Class for Tile TB Cell based monitoring
*/
class TileTBCellMonitorAlgorithm : public AthMonitorAlgorithm {
public:
using AthMonitorAlgorithm::AthMonitorAlgorithm;
virtual ~TileTBCellMonitorAlgorithm() = default;
virtual StatusCode initialize() override;
virtual StatusCode fillHistograms(const EventContext& ctx) const override;
private:
/**
* @brief Name of Tile cabling service
*/
ServiceHandle<TileCablingSvc> m_cablingSvc{ this,
"TileCablingSvc", "TileCablingSvc", "The Tile cabling service"};
SG::ReadHandleKey<CaloCellContainer> m_caloCellContainerKey{this,
"CaloCellContainer", "AllCalo", "Calo cell container name"};
Gaudi::Property<std::vector<int>> m_fragIDs{this,
"TileFragIDs", {0x100, 0x101, 0x200, 0x201, 0x402}, "Tile Frag IDs of modules to process."};
Gaudi::Property<int> m_TBperiod{this,
"TBperiod", 2016, "Tile TB period."};
Gaudi::Property<std::vector<std::string>> m_masked{this,
"Masked", {}, "Masked channels: 'module gain channel,channel' (channels are separated by comma)"};
Gaudi::Property<float> m_energyThresholdForTime{this,
"EnergyThresholdForTime", 100.0F, "Energy threshold for timing in MeV"};
Gaudi::Property<bool> m_fillHistogramsPerChannel{this,
"fillHistogramsPerChannel", true, "Fill time and energy histograms per channel"};
std::map<std::string, int> m_sampleEnergyGroups;
std::map<std::string, int> m_energyGroups;
std::map<std::string, int> m_energyDiffGroups;
std::map<std::string, int> m_energy2VsEnergy1Groups;
std::map<std::string, int> m_timeGroups;
std::map<std::string, int> m_timeDiffGroups;
std::map<std::string, int> m_time2VsTime1Groups;
std::map<std::string, int> m_channelEnergyGroups;
std::map<std::string, int> m_channelTimeGroups;
const TileID* m_tileID{nullptr};
const TileHWID* m_tileHWID{nullptr};
const TileCablingService* m_cabling{nullptr};
std::array<unsigned int, TileCalibUtils::MAX_DRAWERIDX> m_drawerIdxToROS{};
std::array<unsigned int, TileCalibUtils::MAX_DRAWERIDX> m_drawerIdxToDrawer{};
std::array<bool, TileCalibUtils::MAX_DRAWERIDX> m_monitoredDrawerIdx{};
std::array<std::array<unsigned char, TileCalibUtils::MAX_CHAN>, TileCalibUtils::MAX_DRAWERIDX> m_maskedChannels{{}};
};
#endif // TILEMONITORING_TILETBCELLMONITORALGORITHM_H
......@@ -30,6 +30,7 @@
#include "../TileTBPulseMonitorAlgorithm.h"
#include "../TileTBMonitorAlgorithm.h"
#include "../TileTBBeamMonitorAlgorithm.h"
#include "../TileTBCellMonitorAlgorithm.h"
DECLARE_COMPONENT( TileFatherMonTool )
DECLARE_COMPONENT( TilePaterMonTool )
......@@ -59,3 +60,4 @@ DECLARE_COMPONENT( TileRawChannelMonitorAlgorithm )
DECLARE_COMPONENT( TileTBPulseMonitorAlgorithm )
DECLARE_COMPONENT( TileTBMonitorAlgorithm )
DECLARE_COMPONENT( TileTBBeamMonitorAlgorithm )
DECLARE_COMPONENT( TileTBCellMonitorAlgorithm )
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment