From f1409ee0533a5ae8795e717493112d4ebea28046 Mon Sep 17 00:00:00 2001 From: Siarhei Harkusha Date: Fri, 13 May 2022 20:20:32 +0200 Subject: [PATCH 1/2] TileMonitoring+TileRecEx: Add post-processing for Tile raw channel monitoring Tile raw channel monitoring post-processing has been added for calibration runs. Script to run Tile reconstruction and monitoring for calibration runs has been updated to include raw channel post-processing and add interactive mode. --- .../TileRecEx/python/RunTileCalibRec.py | 21 +- .../data/TileRawChanCisPostProc.yaml | 88 +++ .../data/TileRawChanDspPostProc.yaml | 85 +++ .../data/TileRawChanLasPostProc.yaml | 29 + .../data/TileRawChanPostProc.yaml | 69 +++ .../python/TilePostProcessing.py | 585 ++++++++++++++++-- 6 files changed, 821 insertions(+), 56 deletions(-) create mode 100644 TileCalorimeter/TileMonitoring/data/TileRawChanCisPostProc.yaml create mode 100644 TileCalorimeter/TileMonitoring/data/TileRawChanDspPostProc.yaml create mode 100644 TileCalorimeter/TileMonitoring/data/TileRawChanLasPostProc.yaml create mode 100644 TileCalorimeter/TileMonitoring/data/TileRawChanPostProc.yaml diff --git a/TileCalorimeter/TileExample/TileRecEx/python/RunTileCalibRec.py b/TileCalorimeter/TileExample/TileRecEx/python/RunTileCalibRec.py index 6b3e6a8b302..30cb760fb2f 100755 --- a/TileCalorimeter/TileExample/TileRecEx/python/RunTileCalibRec.py +++ b/TileCalorimeter/TileExample/TileRecEx/python/RunTileCalibRec.py @@ -44,6 +44,7 @@ def getArgumentParser(): import argparse parser= argparse.ArgumentParser(parents=parserParents, add_help=False, fromfile_prefix_chars='@', epilog=epiLog, formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('-i', '--interactive', action='store_true', help='Interactive mode') parser.add_argument('--preExec', help='Code to execute before locking configs') parser.add_argument('--postExec', help='Code to execute after setup') parser.add_argument('--printDetailedConfig', action='store_true', help='Print detailed Athena configuration') @@ -247,6 +248,9 @@ if __name__=='__main__': log.info('Executing preExec: %s', args.preExec) exec(args.preExec) + if args.interactive: + os.environ['PYTHONINSPECT'] = '1' + ConfigFlags.lock() log.info('=====>>> FINAL CONFIG FLAGS SETTINGS FOLLOW:') @@ -336,7 +340,7 @@ if __name__=='__main__': setOnlineEnvironment(cfg.getEventAlgo('TileDigitsMonAlg')) if args.channel_mon: - from TileRawChannelMonitorAlgorithm import TileRawChannelMonitoringConfig + from TileMonitoring.TileRawChannelMonitorAlgorithm import TileRawChannelMonitoringConfig cfg.merge(TileRawChannelMonitoringConfig(ConfigFlags)) setOnlineEnvironment(cfg.getEventAlgo('TileRawChannelMonAlg')) @@ -366,9 +370,17 @@ if __name__=='__main__': dataPath = find_datafile('TileMonitoring') if any([args.tmdb_digits_mon, args.tmdb_mon]): configurations += [os.path.join(dataPath, 'TileTMDBPostProc.yaml')] - if args.digits_mon: configurations += [os.path.join(dataPath, 'TileDigitsPostProc.yaml')] + if args.channel_mon: + if 'CIS' in ConfigFlags.Tile.RunType: + configurations += [os.path.join(dataPath, 'TileRawChanCisPostProc.yaml')] + else: + configurations += [os.path.join(dataPath, 'TileRawChanPostProc.yaml')] + if ConfigFlags.Tile.RunType == 'LAS': + configurations += [os.path.join(dataPath, 'TileRawChanLasPostProc.yaml')] + if not biGainRun: + configurations += [os.path.join(dataPath, 'TileRawChanDspPostProc.yaml')] from DataQualityUtils.DQPostProcessingAlg import DQPostProcessingAlg class TileMonPostProcessingAlg(DQPostProcessingAlg): @@ -436,5 +448,6 @@ if __name__=='__main__': cfg.printConfig(withDetails=args.printDetailedConfig) - sc = cfg.run() - sys.exit(0 if sc.isSuccess() else 1) + if not args.interactive: + sc = cfg.run() + sys.exit(0 if sc.isSuccess() else 1) diff --git a/TileCalorimeter/TileMonitoring/data/TileRawChanCisPostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileRawChanCisPostProc.yaml new file mode 100644 index 00000000000..3747d8d4936 --- /dev/null +++ b/TileCalorimeter/TileMonitoring/data/TileRawChanCisPostProc.yaml @@ -0,0 +1,88 @@ +# +# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +# +# Post-processing of histograms from Tile raw channel monitoring for CIS calibration runs +## Separate blocks with --- +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_5', 'Tile/RawChannel/Summary/{module}_{gain}_tails_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per LBA module with amplitude over charge ratio of all channels in the module for 5 pF +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_5', 'Tile/RawChannel/Summary/{module}_{gain}_tails_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per LBC module with amplitude over charge ratio of all channels in the module for 5 pF +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_5', 'Tile/RawChannel/Summary/{module}_{gain}_tails_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per EBA module with amplitude over charge ratio of all channels in the module for 5 pF +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_5', 'Tile/RawChannel/Summary/{module}_{gain}_tails_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per EBC module with amplitude over charge ratio of all channels in the module for 5 pF + +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_5', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per LBA module with time slope and offset of all channels in the module for 5 pF +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_5', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per LBC module with time slope and offset of all channels in the module for 5 pF +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_5', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per EBA module with time slope and offset of all channels in the module for 5 pF +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_5$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_5', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_5' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per EBC module with time slope and offset of all channels in the module for 5 pF + +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_100', 'Tile/RawChannel/Summary/{module}_{gain}_tails_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per LBA module with amplitude over charge ratio of all channels in the module for 100 pF +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_100', 'Tile/RawChannel/Summary/{module}_{gain}_tails_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per LBC module with amplitude over charge ratio of all channels in the module for 100 pF +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_100', 'Tile/RawChannel/Summary/{module}_{gain}_tails_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per EBA module with amplitude over charge ratio of all channels in the module for 100 pF +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp_ratio_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_qratio_100', 'Tile/RawChannel/Summary/{module}_{gain}_tails_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeOverChargeRatio +Description: Produce Tile 1D summary histograms and graphs per EBC module with amplitude over charge ratio of all channels in the module for 100 pF + +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_100', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per LBA module with time slope and offset of all channels in the module for 100 pF +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_100', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per LBC module with time slope and offset of all channels in the module for 100 pF +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_100', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per EBA module with time slope and offset of all channels in the module for 100 pF +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_vs_time_100$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_tslope_100', 'Tile/RawChannel/Summary/{module}_{gain}_toffset_100' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeSlopeAndOffset +Description: Produce Tile 1D summary histograms per EBC module with time slope and offset of all channels in the module for 100 pF diff --git a/TileCalorimeter/TileMonitoring/data/TileRawChanDspPostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileRawChanDspPostProc.yaml new file mode 100644 index 00000000000..e43a370d461 --- /dev/null +++ b/TileCalorimeter/TileMonitoring/data/TileRawChanDspPostProc.yaml @@ -0,0 +1,85 @@ +# +# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +# +# Post-processing of histograms from Tile DSP raw channel monitoring +## Separate blocks with --- +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_chi2_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_summary_chi2_amp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleChi2VsAmplitude +Description: Produce Tile 2D summary histograms per LBA module with Chi2 vs amplitude of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_chi2_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_summary_chi2_amp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleChi2VsAmplitude +Description: Produce Tile 2D summary histograms per LBC module with Chi2 vs amplitude of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_chi2_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_summary_chi2_amp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleChi2VsAmplitude +Description: Produce Tile 2D summary histograms per EBA module with Chi2 vs amplitude of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_chi2_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_summary_chi2_amp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleChi2VsAmplitude +Description: Produce Tile 2D summary histograms per EBC module with Chi2 vs amplitude of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspamp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDSP +Description: Produce Tile 1D summary histograms per LBA module with DSP amplitudes of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspamp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDSP +Description: Produce Tile 1D summary histograms per LBC module with DSP amplitudes of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspamp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDSP +Description: Produce Tile 1D summary histograms per EBA module with DSP amplitudes of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspamp' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDSP +Description: Produce Tile 1D summary histograms per EBC module with DSP amplitudes of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_amp_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_ampdiff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_amphbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per LBA module with amplitude difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_amp_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_ampdiff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_amphbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per LBC module with amplitude difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_amp_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_ampdiff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_amphbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per EBA module with amplitude difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_amp_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_ampdiff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_amphbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per EBC module with amplitude difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_time_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timediff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timehbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per LBA module with time difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_time_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timediff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timehbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per LBC module with time difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_time_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timediff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timehbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per EBA module with time difference between offline and DSP of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_dsp-fit_time_diff$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timediff', 'Tile/RawChannel/Summary/{module}_{gain}_dspfit_timehbar' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeDiffBetweenOfflineAndDSP +Description: Produce Tile 1D summary histograms per EBC module with time difference between offline and DSP of all channels in the module diff --git a/TileCalorimeter/TileMonitoring/data/TileRawChanLasPostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileRawChanLasPostProc.yaml new file mode 100644 index 00000000000..e87e9a50931 --- /dev/null +++ b/TileCalorimeter/TileMonitoring/data/TileRawChanLasPostProc.yaml @@ -0,0 +1,29 @@ +# +# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +# +# Post-processing of histograms from Tile raw channel monitoring +## Separate blocks with --- +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_even', + 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_odd', 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_empty' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeVarianceOverMean +Description: Produce Tile 1D summary histograms per LBA module with amplitude variance over mean of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_even', + 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_odd', 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_empty' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeVarianceOverMean +Description: Produce Tile 1D summary histograms per LBC module with amplitude variance over mean of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_even', + 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_odd', 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_empty' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeVarianceOverMean +Description: Produce Tile 1D summary histograms per EBA module with amplitude variance over mean of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_even', + 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_odd', 'Tile/RawChannel/Summary/{module}_{gain}_pmtGain_empty' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeVarianceOverMean +Description: Produce Tile 1D summary histograms per EBC module with amplitude variance over mean of all channels in the module diff --git a/TileCalorimeter/TileMonitoring/data/TileRawChanPostProc.yaml b/TileCalorimeter/TileMonitoring/data/TileRawChanPostProc.yaml new file mode 100644 index 00000000000..3d22be3ff63 --- /dev/null +++ b/TileCalorimeter/TileMonitoring/data/TileRawChanPostProc.yaml @@ -0,0 +1,69 @@ +# +# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +# +# Post-processing of histograms from Tile raw channel monitoring +## Separate blocks with --- +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_amp', + 'Tile/RawChannel/Summary/{module}_{gain}_sigma', 'Tile/RawChannel/Summary/{module}_{gain}_rms' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeAndSigmaWithRMS +Description: Produce Tile 1D summary histograms per LBA module with amplitude, sigma, and RMS of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_amp', + 'Tile/RawChannel/Summary/{module}_{gain}_sigma', 'Tile/RawChannel/Summary/{module}_{gain}_rms' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeAndSigmaWithRMS +Description: Produce Tile 1D summary histograms per LBC module with amplitude, sigma, and RMS of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_amp', + 'Tile/RawChannel/Summary/{module}_{gain}_sigma', 'Tile/RawChannel/Summary/{module}_{gain}_rms' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeAndSigmaWithRMS +Description: Produce Tile 1D summary histograms per EBA module with amplitude, sigma, and RMS of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_amp$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_amp', + 'Tile/RawChannel/Summary/{module}_{gain}_sigma', 'Tile/RawChannel/Summary/{module}_{gain}_rms' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleAmplitudeAndSigmaWithRMS +Description: Produce Tile 1D summary histograms per EBC module with amplitude, sigma, and RMS of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTime +Description: Produce Tile 1D summary histograms per LBA module with time of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTime +Description: Produce Tile 1D summary histograms per LBC module with time of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTime +Description: Produce Tile 1D summary histograms per EBA module with time of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTime +Description: Produce Tile 1D summary histograms per EBC module with time of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_corr$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time_corr' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeCorrected +Description: Produce Tile 1D summary histograms per LBA module with time corrected of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PLBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_corr$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time_corr' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeCorrected +Description: Produce Tile 1D summary histograms per LBC module with time corrected of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBA[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_corr$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time_corr' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeCorrected +Description: Produce Tile 1D summary histograms per EBA module with time corrected of all channels in the module +--- +Input: [ 'Tile/RawChannel/(?PEBC[0-6]\d{1})/(?P=module)_ch_(?P\d{2})_(?P[h|l][i|o])_time_corr$' ] +Output: [ 'Tile/RawChannel/Summary/{module}_{gain}_time_corr' ] +Function: TileMonitoring.TilePostProcessing.getTileModuleTimeCorrected +Description: Produce Tile 1D summary histograms per EBC module with time corrected of all channels in the module diff --git a/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py b/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py index 753e4a258ce..3300061600b 100644 --- a/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py +++ b/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py @@ -11,6 +11,47 @@ import os, sys, signal, subprocess from AthenaCommon.Utils.unixtools import find_datafile + +def getTileModuleHistogram(inputs, name, title): + """ This function returns 1D histogram for Tile module """ + + import ROOT + # Force batch mode + ROOT.gROOT.SetBatch(True) + + from TileCalibBlobObjs.Classes import TileCalibUtils as Tile + + gain = inputs[0][0]['gain'] + gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) + module = inputs[0][0]['module'] + run = str(inputs[0][1][0].GetTitle()).split(' ')[1] + + fullName = f'{module}_{gain}_{name}' + fullTitle = f'Run {run} {module} {gainName} gain: {title}' + histogram = ROOT.TH1F(fullName, fullTitle, Tile.MAX_CHAN, 0.0, Tile.MAX_CHAN) + + return histogram + + +def setTileModuleHistogramStyle(histogram, markerStyle=None, markerSize=None, markerColor=None, + labelSize=None, ymin=None, ymax=None, delta=0.1): + """ This function set up stype of Tile module monitoring histogram """ + + if ymin and (histogram.GetMinimum() > ymin + delta * abs(ymin)): + histogram.SetMinimum(ymin) + if ymax and (histogram.GetMaximum() < (1.0 - delta) * ymax): + histogram.SetMaximum(ymax) + if markerStyle: + histogram.SetMarkerStyle(markerStyle) + if markerColor: + histogram.SetMarkerColor(markerColor) + if markerSize: + histogram.SetMarkerSize(markerSize) + if labelSize: + histogram.SetLabelSize(labelSize, "X") + histogram.SetLabelSize(labelSize, "Y") + + def getProfile2D_RMS(inputs, title, name): """ This function produces 2D histogram with RMS from Profile2D per Tile partition """ @@ -120,24 +161,8 @@ def getTilePartitionRawChannelNoise(inputs): def getTileModulePedestalsAndLFN(inputs): """ This function produces 1D summary histogram per Tile module with pedestals and LFN of all channels in the module """ - import ROOT - # Force batch mode - ROOT.gROOT.SetBatch(True) - - from TileCalibBlobObjs.Classes import TileCalibUtils as Tile - - gain = inputs[0][0]['gain'] - gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) - module = inputs[0][0]['module'] - run = str(inputs[0][1][0].GetTitle()).split(' ')[1] - - pedestalName = f'{module}_{gain}_ped' - pedestalTitle = f'Run {run} {module} {gainName} gain: Pedestal[0]' - pedestalHistogram = ROOT.TH1F(pedestalName, pedestalTitle, Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5) - - lfnName = f'{module}_{gain}_rms_lfr' - lfnTitle = f'Run {run} {module} {gainName} gain: RMS noise low frequency' - lfnHistogram = ROOT.TH1F(lfnName, lfnTitle, Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5) + pedestalHistogram = getTileModuleHistogram(inputs, 'ped', 'Pedestal[0]') + lfnHistogram = getTileModuleHistogram(inputs, 'rms_lfr', 'RMS noise low frequency') for input in inputs: @@ -158,20 +183,7 @@ def getTileModulePedestalsAndLFN(inputs): def getTileModuleHFN(inputs): """ This function produces 1D summary histogram per Tile module with HFN of all channels in the module """ - import ROOT - # Force batch mode - ROOT.gROOT.SetBatch(True) - - from TileCalibBlobObjs.Classes import TileCalibUtils as Tile - - gain = inputs[0][0]['gain'] - gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) - module = inputs[0][0]['module'] - run = str(inputs[0][1][0].GetTitle()).split(' ')[1] - - hfnName = f'{module}_{gain}_rms_hfr' - hfnTitle = f'Run {run} {module} {gainName} gain: RMS noise high frequency' - hfnHistogram = ROOT.TH1F(hfnName, hfnTitle, Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5) + hfnHistogram = getTileModuleHistogram(inputs, 'rms_hfr', 'RMS noise high frequency') for input in inputs: @@ -197,7 +209,7 @@ def getTileModuleCRC(inputs): crcName = f'{module}_crc' crcTitle = f'Run {run} {module}: CRC errors' - crcHistogram = ROOT.TH1F(crcName, crcTitle, 16, -0.5, 15.5) + crcHistogram = ROOT.TH1F(crcName, crcTitle, 16, 0.0, 16.0) for input in inputs: @@ -252,7 +264,7 @@ def getTileModuleBCID(inputs): bcidName = f'{module}_{gain}_bcid' bcidTitle = f'Run {run} {module} {gainName} gain: BCID errors' - bcidHistogram = ROOT.TH1F(bcidName, bcidTitle, 16, -0.5, 15.5) + bcidHistogram = ROOT.TH1F(bcidName, bcidTitle, 16, 0.0, 16.0) for input in inputs: @@ -414,20 +426,7 @@ def getTileStuckBitsNumber(inputHistogram): def getTileModuleStuckBits(inputs): """ Produce Tile 1D summary histograms per module with stuck bits and zeros for all channels in the module """ - import ROOT - # Force batch mode - ROOT.gROOT.SetBatch(True) - - from TileCalibBlobObjs.Classes import TileCalibUtils as Tile - - gain = inputs[0][0]['gain'] - gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) - module = inputs[0][0]['module'] - run = str(inputs[0][1][0].GetTitle()).split(' ')[1] - - bitsName = f'{module}_{gain}_bits' - bitsTitle = f'Run {run} {module} {gainName} gain: Stuck bits and zero amplitudes' - bitsHistogram = ROOT.TH1F(bitsName, bitsTitle, Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5) + bitsHistogram = getTileModuleHistogram(inputs, 'bits', 'Stuck bits and zero amplitudes') for input in inputs: @@ -473,14 +472,14 @@ def getTileModuleCovariance(inputs): covarianceName = f'{module}_{gain}_covar' covarianceTitle = f'Run {run} {module} {gainName} gain: Covariance' covarianceHistogram = ROOT.TH2F(covarianceName, covarianceTitle, - Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5, - Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5) + Tile.MAX_CHAN, 0.0, Tile.MAX_CHAN, + Tile.MAX_CHAN, 0.0, Tile.MAX_CHAN) correlationName = f'{module}_{gain}_corr' correlationTitle = f'Run {run} {module} {gainName} gain: Correlation' correlationHistogram = ROOT.TH2F(correlationName, correlationTitle, - Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5, - Tile.MAX_CHAN, -0.5, Tile.MAX_CHAN - 0.5) + Tile.MAX_CHAN, 0.0, Tile.MAX_CHAN, + Tile.MAX_CHAN, 0.0, Tile.MAX_CHAN) meanSampleHistogram = inputs[0][1][0] meanSample12Histogram = inputs[0][1][1] @@ -513,6 +512,488 @@ def getTileModuleCovariance(inputs): return [covarianceHistogram, correlationHistogram] +def getTileModuleChi2VsAmplitude(inputs): + """ This function produces 2D summary histogram per Tile module with Chi2 vs amplitude of all channels in the module """ + + gain = inputs[0][0]['gain'] + gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) + module = inputs[0][0]['module'] + run = str(inputs[0][1][0].GetTitle()).split(' ')[1] + + chi2AmpName = f'{module}_{gain}_summary_chi2_amp' + chi2AmpTitle = f'Run {run} {module} {gainName} gain: Summary DSP #chi^{2} vs Amplitude' + inputHistogram = inputs[0][1][0] + chi2AmpHistogram = inputHistogram.Clone() + chi2AmpHistogram.Reset() + chi2AmpHistogram.SetTitle(chi2AmpTitle) + chi2AmpHistogram.SetName(chi2AmpName) + + for input in inputs: + inputHistogram = input[1][0] + if inputHistogram.GetEntries() > 0: + chi2AmpHistogram.Add(inputHistogram) + + setTileModuleHistogramStyle(chi2AmpHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=-0.05, ymax=10.0) + + return [chi2AmpHistogram] + +def getTileModuleAmplitudeAndSigmaWithRMS(inputs): + """ This function produces 1D summary histogram per Tile module with amplitude, sigma, and RMS of all channels in the module """ + + import math + import ROOT + # Force batch mode + ROOT.gROOT.SetBatch(True) + + gain = inputs[0][0]['gain'] + + amplitudeHistogram = getTileModuleHistogram(inputs, 'amp', 'Average Amplitude and RMS') + rmsHistogram = getTileModuleHistogram(inputs, 'rms', 'RMS of Amplitude') + sigmaHistogram = getTileModuleHistogram(inputs, 'sigma', 'Sigma of Amplitude from Gaussian fit') + + fitFunction = ROOT.TF1("g", 'gaus') + inputHistogram = inputs[0][1][0] + overlapHistogram = inputHistogram.GetBinWidth(1) == inputHistogram.GetBinWidth(100) + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + rms = inputHistogram.GetRMS() + amplitude = inputHistogram.GetMean() + amplitudeHistogram.SetBinContent(bin, amplitude) + amplitudeHistogram.SetBinError(bin, rms / math.sqrt(nEntries)) + + rmsHistogram.SetBinContent(bin, rms) + rmsHistogram.SetBinError(bin, rms / math.sqrt(2.0 * nEntries)) + + if nEntries > 90: + if overlapHistogram: + inputHistogram.Scale(1, 'width') + inputHistogram.Fit(fitFunction, 'Q') + sigma = fitFunction.GetParameter(2) + sigmaError = fitFunction.GetParError(2) + sigmaHistogram.SetBinContent(bin, sigma) + sigmaHistogram.SetBinError(bin, sigmaError) + + setTileModuleHistogramStyle(amplitudeHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, + ymin={'hi' : -0.05, 'lo' : -1.0}.get(gain), + ymax={'hi' : 0.05, 'lo' : 1.0}.get(gain)) + + yMin = min(0.0, rmsHistogram.GetMinimum(), sigmaHistogram.GetMinimum()) + yMax = max({'hi' : 0.05, 'lo' : 1.0}.get(gain), rmsHistogram.GetMaximum(), sigmaHistogram.GetMaximum()) + + setTileModuleHistogramStyle(rmsHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=yMin, ymax=yMax) + setTileModuleHistogramStyle(sigmaHistogram, markerStyle=25, markerSize=0.75, labelSize=0.08,ymin=yMin, ymax=yMax) + + return [amplitudeHistogram, sigmaHistogram, rmsHistogram] + + +def getTileModuleTime(inputs): + """ This function produces 1D summary histogram per Tile module with time of all channels in the module """ + + import ROOT + # Force batch mode + ROOT.gROOT.SetBatch(True) + + timeHistogram = getTileModuleHistogram(inputs, 'time', 'Average Time and RMS') + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + rms = inputHistogram.GetRMS() + time = inputHistogram.GetMean() + timeHistogram.SetBinContent(bin, time) + timeHistogram.SetBinError(bin, rms) + + setTileModuleHistogramStyle(timeHistogram, markerStyle=21, markerSize=0.75, ymin=-25.0, ymax=25.0, labelSize=0.08) + + return [timeHistogram] + + +def getTileModuleTimeCorrected(inputs): + """ This function produces 1D summary histogram per Tile module with time corrected of all channels in the module """ + + timeHistogram = getTileModuleHistogram(inputs, 'time_corr', 'Average Time corrected and RMS') + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + rms = inputHistogram.GetRMS() + time = inputHistogram.GetMean() + timeHistogram.SetBinContent(bin, time) + timeHistogram.SetBinError(bin, rms) + + setTileModuleHistogramStyle(timeHistogram, markerStyle=21, markerSize=0.75, ymin=-25.0, ymax=25.0, labelSize=0.08) + + return [timeHistogram] + + +def getTileModuleAmplitudeDiffBetweenOfflineAndDSP(inputs): + """ This function produces 1D summary histogram per Tile module with amplitude difference between offline and DSP of all channels in the module """ + + gain = inputs[0][0]['gain'] + gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) + module = inputs[0][0]['module'] + run = str(inputs[0][1][0].GetTitle()).split(' ')[1] + + ampDiffHistogram = getTileModuleHistogram(inputs, 'dspfit_ampdiff', '(DSP-OFFLINE)/OFFLINE Amplitude and RMS') + + sumAmpDiffName = f'{module}_{gain}_dspfit_amphbar' + sumAmpDiffTitle = f'Run {run} {module} {gainName} gain: (DSP-OFFLINE)/OFFLINE Amplitude for all channels' + inputHistogram = inputs[0][1][0] + sumAmpDiffHistogram = inputHistogram.Clone() + sumAmpDiffHistogram.Reset() + sumAmpDiffHistogram.SetTitle(sumAmpDiffTitle) + sumAmpDiffHistogram.SetName(sumAmpDiffName) + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + rms = inputHistogram.GetRMS() + ampDiff = inputHistogram.GetMean() + ampDiffHistogram.SetBinContent(bin, ampDiff) + ampDiffHistogram.SetBinError(bin, rms) + + sumAmpDiffHistogram.Add(inputHistogram) + + setTileModuleHistogramStyle(ampDiffHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=-0.05, ymax=0.05) + + return [ampDiffHistogram, sumAmpDiffHistogram] + + +def getTileModuleAmplitudeDSP(inputs): + """ This function produces 1D summary histogram per Tile module with DSP amplitudes of all channels in the module """ + + amplitudeHistogram = getTileModuleHistogram(inputs, 'dspamp', 'Average DSP Amplitude and RMS') + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + rms = inputHistogram.GetRMS() + amplitude = inputHistogram.GetMean() + amplitudeHistogram.SetBinContent(bin, amplitude) + amplitudeHistogram.SetBinError(bin, rms) + + return [amplitudeHistogram] + + +def getTileModuleTimeDiffBetweenOfflineAndDSP(inputs): + """ This function produces 1D summary histogram per Tile module with time difference between offline and DSP of all channels in the module """ + + gain = inputs[0][0]['gain'] + gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) + module = inputs[0][0]['module'] + run = str(inputs[0][1][0].GetTitle()).split(' ')[1] + + timeDiffHistogram = getTileModuleHistogram(inputs, 'dspfit_timediff', 'DSP-OFFLINE Time and RMS') + + sumTimeDiffName = f'{module}_{gain}_dspfit_amphbar' + sumTimeDiffTitle = f'Run {run} {module} {gainName} gain: DSP-OFFLINE Time for all channels' + inputHistogram = inputs[0][1][0] + sumTimeDiffHistogram = inputHistogram.Clone() + sumTimeDiffHistogram.Reset() + sumTimeDiffHistogram.SetTitle(sumTimeDiffTitle) + sumTimeDiffHistogram.SetName(sumTimeDiffName) + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + rms = inputHistogram.GetRMS() + timeDiff = inputHistogram.GetMean() + timeDiffHistogram.SetBinContent(bin, timeDiff) + timeDiffHistogram.SetBinError(bin, rms) + + sumTimeDiffHistogram.Add(inputHistogram) + + setTileModuleHistogramStyle(timeDiffHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=-0.5, ymax=0.5) + + return [timeDiffHistogram, sumTimeDiffHistogram] + + +def channelToPMT(module, channel): + """ + This function converts Tile channel number to PMT number (hole/position in drawer) + + Negative number means that PMT is not connected! + """ + + position = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34, + 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46, + + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24, + -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34, + 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ] + + if module.startswith('EB'): + channel += 48 # Extended barrel + pmt = position[channel] + # One need to do something for special modules EBA15 and EBC18 where + # the first 4 channels are not connected, but E3 and E4 gap scintilators + # are connected to channels 18 and 19 correspondingly + if module in ['EBA15', 'EBC18'] and (channel < 4 or channel in [18, 19]): + pmt = -pmt + + return pmt + + +def getTileModuleAmplitudeVarianceOverMean(inputs): + """ This function produces 1D summary histogram per Tile module with amplitude variance over mean of all channels in the module """ + + import math + module = inputs[0][0]['module'] + + emptyPMTHistogram = getTileModuleHistogram(inputs, 'pmtGain_empty', 'Variance/Mean') + setTileModuleHistogramStyle(emptyPMTHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=-0.2, ymax=2.2) + + evenPMTHistogram = getTileModuleHistogram(inputs, 'pmtGain_even', 'Variance/Mean') + setTileModuleHistogramStyle(evenPMTHistogram, markerStyle=22, markerSize=0.75, labelSize=0.08, markerColor=2, ymin=-0.2, ymax=2.2) + + oddPMTHistogram = getTileModuleHistogram(inputs, 'pmtGain_odd', 'Variance/Mean') + setTileModuleHistogramStyle(oddPMTHistogram, markerStyle=23, markerSize=0.75, markerColor=4, labelSize=0.08, ymin=-0.2, ymax=2.2) + + kapa = 1.30e-3 + + for input in inputs: + + inputHistogram = input[1][0] + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + channel = int(input[0]['channel']) + bin = int(channel) + 1 + pmt = channelToPMT(module, channel) + if pmt < 0: # PMT is not connected + emptyPMTHistogram.SetBinContent(bin, 0.01) + emptyPMTHistogram.SetBinError(bin, 0.01) + else: + mean = inputHistogram.GetMean() + rms = inputHistogram.GetRMS() + + meanError = rms / math.sqrt(nEntries) + rmsError = rms / math.sqrt(2 * nEntries) + + if mean > 10e-3 and rms > 0.: + varianceOverMean = rms * rms / mean - kapa * mean + varianceOverMeanError = (rms * rms / mean) * math.sqrt(4 * (rmsError / rms) * (rmsError / rms) + + (meanError / mean) * (meanError / mean)) + else: + varianceOverMean = -0.5 + varianceOverMeanError = 0.001 + + if pmt % 2 == 0: + evenPMTHistogram.SetBinContent(bin, varianceOverMean) + evenPMTHistogram.SetBinError(bin, varianceOverMeanError) + else: + oddPMTHistogram.SetBinContent(bin, varianceOverMean) + oddPMTHistogram.SetBinError(bin, varianceOverMeanError) + + + maxY = max(1.05 * oddPMTHistogram.GetMaximum(), 1.05 * evenPMTHistogram.GetMaximum(), 0.20) + minY = min(oddPMTHistogram.GetMinimum() - 0.05 * abs(oddPMTHistogram.GetMinimum()), + evenPMTHistogram.GetMinimum() - 0.05 * abs(evenPMTHistogram.GetMinimum()), -0.10) + + emptyPMTHistogram.GetYaxis().SetRangeUser(minY, maxY) + + return [evenPMTHistogram, oddPMTHistogram, emptyPMTHistogram] + + +def getTileModuleAmplitudeOverChargeRatio(inputs): + """ This function produces 1D summary histogram graph per Tile module with amplitude over charge ratio of all channels in the module """ + + import ROOT + # Force batch mode + ROOT.gROOT.SetBatch(True) + + from TileCalibBlobObjs.Classes import TileCalibUtils as Tile + + capactior = str(inputs[0][1][0].GetName()).split('_').pop() + amplitudeOverQHistogram = getTileModuleHistogram(inputs, f'qratio_{capactior}', f'Amplitude/Q Ratio for {capactior} pF') + + gain = inputs[0][0]['gain'] + gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) + module = inputs[0][0]['module'] + run = str(inputs[0][1][0].GetTitle()).split(' ')[1] + + amplitudeOverQGraphName = f'{module}_{gain}_tails_{capactior}' + amplitudeOverQGraphTitle = f'Run {run} {module} {gainName} gain: Mean Amplitude/Q and up/down tails for {capactior} pF' + amplitudeOverQGraph = ROOT.TGraphAsymmErrors(Tile.MAX_CHAN) + amplitudeOverQGraph.SetName(amplitudeOverQGraphName) + amplitudeOverQGraph.SetTitle(amplitudeOverQGraphTitle) + + downLimit = 0.7 + upLimit = 1.3 + + lowIntegralLimit = 0.005 + mediumIntegralLimit = 0.010 + highIntegralLimit = 0.015 + + for input in inputs: + + inputHistogram = input[1][0] + channel = int(input[0]['channel']) + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + bin = int(channel) + 1 + + mean = inputHistogram.GetMean() + amplitudeOverQHistogram.SetBinContent(bin, mean) + + # The following code calculates the error bars of amplitude over Q summary plots. + # The error bar depends on the percentage of events outside a certain limit. + # If the percentage of events outside a certain limit is below the threshold, + # then the error bar length is set to 0. + # There are 3 different thresholds and a lower and an upper limit. + minBin = inputHistogram.FindFirstBinAbove(0) + maxBin = inputHistogram.FindLastBinAbove(0) + xMin = inputHistogram.GetBinCenter(minBin) + xMax = inputHistogram.GetBinCenter(maxBin) + if downLimit < mean < upLimit: + if xMin > downLimit: + xMin = mean + else: + downLimitBin = inputHistogram.FindBin(downLimit) + # We also want underflow, in case... Integral() is calculated including the contents of both limiting bins. + # As 0.7 falls in the middle of a bin, we are calculating the integral by excess + integral = inputHistogram.Integral(0, downLimitBin) + ratio = integral / nEntries + if ratio > highIntegralLimit: + # Larger error bar + xMin = mean - 1.05 + elif ratio > mediumIntegralLimit: + # Intermediate error bar + xMin = mean - 0.7 + elif ratio > lowIntegralLimit: + # Small error bar + xMin = mean - 0.35 + else: + xMin = mean + + if xMax < upLimit: + xMax = mean + else: + upLimitBin = inputHistogram.FindBin(upLimit) + # We also want overflow, in case... Integral() is calculated including the contents of both limiting bins. + # As 1.3 falls in the middle of a bin, we are calculating the integral by excess. + integral = inputHistogram.Integral(upLimitBin, (inputHistogram.GetNbinsX() + 1)) + ratio = integral / nEntries + if ratio > highIntegralLimit: + # Larger error bar + xMax = mean + 1.05 + elif ratio > mediumIntegralLimit: + # Intermediate error bar + xMax = mean + 0.7 + elif ratio > lowIntegralLimit: + # Small error bar + xMax = mean + 0.35 + else: + xMax = mean + + amplitudeOverQGraph.SetPoint(channel, channel + 0.5, mean) + amplitudeOverQGraph.SetPointError(channel, 0.0, 0.0, max(0.0, mean - xMin), max(0.0, xMax - mean)) + else: + amplitudeOverQGraph.SetPoint(channel, channel + 0.5, 0.0) + + amplitudeOverQHistogram.SetStats(ROOT.kFALSE) + setTileModuleHistogramStyle(amplitudeOverQHistogram, markerStyle=21, markerSize=0.75, ymin=-0.2, ymax=2.2, labelSize=0.06) + + amplitudeOverQGraph.GetXaxis().SetRangeUser(0, 48) + setTileModuleHistogramStyle(amplitudeOverQGraph, markerStyle=21, markerSize=0.75, ymin=-0.2, ymax=2.2) + + + return [amplitudeOverQHistogram, amplitudeOverQGraph] + + +def getTileModuleTimeSlopeAndOffset(inputs): + """ This function produces 1D summary histogram per Tile module with amplitude over charge ratio of all channels in the module """ + + import ROOT + # Force batch mode + ROOT.gROOT.SetBatch(True) + + capactior = str(inputs[0][1][0].GetName()).split('_').pop() + timeSlopeHistogram = getTileModuleHistogram(inputs, f'tslope_{capactior}', f'Time slope for {capactior} pF') + timeOffsetHistogram = getTileModuleHistogram(inputs, f'toffset_{capactior}', f'Time offset for {capactior} pF') + + fitFunction = ROOT.TF1("polfun", "pol1", 0., 25.) + + for input in inputs: + + inputHistogram = input[1][0] + + nEntries = inputHistogram.GetEntries() + if nEntries > 0: + profile = inputHistogram.ProfileX() + nBins = profile.GetNbinsX() + histogram = ROOT.TH1S("histogram", "TMP Histogram", nBins, profile.GetBinLowEdge(1), profile.GetBinLowEdge(nBins + 1)) + + timeShift = 0 + lastBin = 0 + lastBinContent = -99.0 + for xBin in range(1, nBins + 1): + if profile.GetBinError(xBin) > 1e-7: + binContent = profile.GetBinContent(xBin) + # Allow only 1 shift and only of negative sign + if (timeShift < 1) and (binContent - (lastBinContent + (xBin - lastBin))) < -15.0: + timeShift = 25. + lastBin = xBin + lastBinContent = binContent + histogram.SetBinContent(xBin, binContent + timeShift) + histogram.SetBinError(xBin, profile.GetBinError(xBin)) + + if histogram.GetEntries() > 1: + histogram.Fit(fitFunction, "NQ") + + channel = int(input[0]['channel']) + bin = int(channel) + 1 + + # Shift by -25 ns to be consistent with previous definition + timeOffset = fitFunction.GetParameter(0) - 25.0 + timeOffsetError = min(5.0, fitFunction.GetParError(0)) + timeOffsetHistogram.SetBinContent(bin, timeOffset) + timeOffsetHistogram.SetBinError(bin, timeOffsetError) + + timeSlope = fitFunction.GetParameter(1) + timeSlopeError = min(5.0, fitFunction.GetParError(1)) + timeSlopeHistogram.SetBinContent(bin, timeSlope) + timeSlopeHistogram.SetBinError(bin, timeSlopeError) + + setTileModuleHistogramStyle(timeSlopeHistogram, markerStyle=21, markerSize=0.75, ymin=-0.1, ymax=1.4, labelSize=0.1) + setTileModuleHistogramStyle(timeOffsetHistogram, markerStyle=21, markerSize=0.75, ymin=-15, ymax=15, labelSize=0.1) + + return [timeSlopeHistogram, timeOffsetHistogram] + if __name__== '__main__': -- GitLab From 2ba7efe7eda999edb22301e393b15effac742bc7 Mon Sep 17 00:00:00 2001 From: Siarhei Harkusha Date: Mon, 16 May 2022 16:06:25 +0200 Subject: [PATCH 2/2] TileMonitoring: Refactor Tile post-processing python code to avoid duplication --- .../python/TilePostProcessing.py | 136 ++++++------------ 1 file changed, 42 insertions(+), 94 deletions(-) diff --git a/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py b/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py index 3300061600b..b1a87b5423e 100644 --- a/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py +++ b/TileCalorimeter/TileMonitoring/python/TilePostProcessing.py @@ -593,14 +593,8 @@ def getTileModuleAmplitudeAndSigmaWithRMS(inputs): return [amplitudeHistogram, sigmaHistogram, rmsHistogram] -def getTileModuleTime(inputs): - """ This function produces 1D summary histogram per Tile module with time of all channels in the module """ - - import ROOT - # Force batch mode - ROOT.gROOT.SetBatch(True) - - timeHistogram = getTileModuleHistogram(inputs, 'time', 'Average Time and RMS') +def fillTileModuleMeanAndRMS(histogram, inputs): + """ This function fills 1D summary histogram per Tile module with mean value and RMS of all channels in the module """ for input in inputs: @@ -611,73 +605,65 @@ def getTileModuleTime(inputs): bin = int(channel) + 1 rms = inputHistogram.GetRMS() - time = inputHistogram.GetMean() - timeHistogram.SetBinContent(bin, time) - timeHistogram.SetBinError(bin, rms) - - setTileModuleHistogramStyle(timeHistogram, markerStyle=21, markerSize=0.75, ymin=-25.0, ymax=25.0, labelSize=0.08) + mean = inputHistogram.GetMean() + histogram.SetBinContent(bin, mean) + histogram.SetBinError(bin, rms) - return [timeHistogram] +def getTileModuleSumHistogram(inputs, name, title): + """ This function produces 1D summary histogram per Tile module adding all histograms per channel in the module """ -def getTileModuleTimeCorrected(inputs): - """ This function produces 1D summary histogram per Tile module with time corrected of all channels in the module """ + gain = inputs[0][0]['gain'] + gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) + module = inputs[0][0]['module'] + run = str(inputs[0][1][0].GetTitle()).split(' ')[1] - timeHistogram = getTileModuleHistogram(inputs, 'time_corr', 'Average Time corrected and RMS') + fullName = f'{module}_{gain}_{name}' + fullTitle = f'Run {run} {module} {gainName} gain: {title}' + inputHistogram = inputs[0][1][0] + sumHistogram = inputHistogram.Clone() + sumHistogram.Reset() + sumHistogram.SetTitle(fullTitle) + sumHistogram.SetName(fullName) for input in inputs: - inputHistogram = input[1][0] nEntries = inputHistogram.GetEntries() if nEntries > 0: - channel = int(input[0]['channel']) - bin = int(channel) + 1 - - rms = inputHistogram.GetRMS() - time = inputHistogram.GetMean() - timeHistogram.SetBinContent(bin, time) - timeHistogram.SetBinError(bin, rms) + sumHistogram.Add(inputHistogram) - setTileModuleHistogramStyle(timeHistogram, markerStyle=21, markerSize=0.75, ymin=-25.0, ymax=25.0, labelSize=0.08) + return sumHistogram - return [timeHistogram] +def getTileModuleTime(inputs): + """ This function produces 1D summary histogram per Tile module with time of all channels in the module """ -def getTileModuleAmplitudeDiffBetweenOfflineAndDSP(inputs): - """ This function produces 1D summary histogram per Tile module with amplitude difference between offline and DSP of all channels in the module """ + timeHistogram = getTileModuleHistogram(inputs, 'time', 'Average Time and RMS') + fillTileModuleMeanAndRMS(timeHistogram, inputs) + setTileModuleHistogramStyle(timeHistogram, markerStyle=21, markerSize=0.75, ymin=-25.0, ymax=25.0, labelSize=0.08) - gain = inputs[0][0]['gain'] - gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) - module = inputs[0][0]['module'] - run = str(inputs[0][1][0].GetTitle()).split(' ')[1] + return [timeHistogram] - ampDiffHistogram = getTileModuleHistogram(inputs, 'dspfit_ampdiff', '(DSP-OFFLINE)/OFFLINE Amplitude and RMS') - sumAmpDiffName = f'{module}_{gain}_dspfit_amphbar' - sumAmpDiffTitle = f'Run {run} {module} {gainName} gain: (DSP-OFFLINE)/OFFLINE Amplitude for all channels' - inputHistogram = inputs[0][1][0] - sumAmpDiffHistogram = inputHistogram.Clone() - sumAmpDiffHistogram.Reset() - sumAmpDiffHistogram.SetTitle(sumAmpDiffTitle) - sumAmpDiffHistogram.SetName(sumAmpDiffName) +def getTileModuleTimeCorrected(inputs): + """ This function produces 1D summary histogram per Tile module with time corrected of all channels in the module """ - for input in inputs: + timeHistogram = getTileModuleHistogram(inputs, 'time_corr', 'Average Time corrected and RMS') + fillTileModuleMeanAndRMS(timeHistogram, inputs) + setTileModuleHistogramStyle(timeHistogram, markerStyle=21, markerSize=0.75, ymin=-25.0, ymax=25.0, labelSize=0.08) - inputHistogram = input[1][0] - nEntries = inputHistogram.GetEntries() - if nEntries > 0: - channel = int(input[0]['channel']) - bin = int(channel) + 1 + return [timeHistogram] - rms = inputHistogram.GetRMS() - ampDiff = inputHistogram.GetMean() - ampDiffHistogram.SetBinContent(bin, ampDiff) - ampDiffHistogram.SetBinError(bin, rms) - sumAmpDiffHistogram.Add(inputHistogram) +def getTileModuleAmplitudeDiffBetweenOfflineAndDSP(inputs): + """ This function produces 1D summary histogram per Tile module with amplitude difference between offline and DSP of all channels in the module """ + ampDiffHistogram = getTileModuleHistogram(inputs, 'dspfit_ampdiff', '(DSP-OFFLINE)/OFFLINE Amplitude and RMS') + fillTileModuleMeanAndRMS(ampDiffHistogram, inputs) setTileModuleHistogramStyle(ampDiffHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=-0.05, ymax=0.05) + sumAmpDiffHistogram = getTileModuleSumHistogram(inputs, 'dspfit_amphbar', '(DSP-OFFLINE)/OFFLINE Amplitude for all channels') + return [ampDiffHistogram, sumAmpDiffHistogram] @@ -685,19 +671,7 @@ def getTileModuleAmplitudeDSP(inputs): """ This function produces 1D summary histogram per Tile module with DSP amplitudes of all channels in the module """ amplitudeHistogram = getTileModuleHistogram(inputs, 'dspamp', 'Average DSP Amplitude and RMS') - - for input in inputs: - - inputHistogram = input[1][0] - nEntries = inputHistogram.GetEntries() - if nEntries > 0: - channel = int(input[0]['channel']) - bin = int(channel) + 1 - - rms = inputHistogram.GetRMS() - amplitude = inputHistogram.GetMean() - amplitudeHistogram.SetBinContent(bin, amplitude) - amplitudeHistogram.SetBinError(bin, rms) + fillTileModuleMeanAndRMS(amplitudeHistogram, inputs) return [amplitudeHistogram] @@ -705,38 +679,12 @@ def getTileModuleAmplitudeDSP(inputs): def getTileModuleTimeDiffBetweenOfflineAndDSP(inputs): """ This function produces 1D summary histogram per Tile module with time difference between offline and DSP of all channels in the module """ - gain = inputs[0][0]['gain'] - gainName = {'hi' : 'high', 'lo' : 'low'}.get(gain) - module = inputs[0][0]['module'] - run = str(inputs[0][1][0].GetTitle()).split(' ')[1] - timeDiffHistogram = getTileModuleHistogram(inputs, 'dspfit_timediff', 'DSP-OFFLINE Time and RMS') - - sumTimeDiffName = f'{module}_{gain}_dspfit_amphbar' - sumTimeDiffTitle = f'Run {run} {module} {gainName} gain: DSP-OFFLINE Time for all channels' - inputHistogram = inputs[0][1][0] - sumTimeDiffHistogram = inputHistogram.Clone() - sumTimeDiffHistogram.Reset() - sumTimeDiffHistogram.SetTitle(sumTimeDiffTitle) - sumTimeDiffHistogram.SetName(sumTimeDiffName) - - for input in inputs: - - inputHistogram = input[1][0] - nEntries = inputHistogram.GetEntries() - if nEntries > 0: - channel = int(input[0]['channel']) - bin = int(channel) + 1 - - rms = inputHistogram.GetRMS() - timeDiff = inputHistogram.GetMean() - timeDiffHistogram.SetBinContent(bin, timeDiff) - timeDiffHistogram.SetBinError(bin, rms) - - sumTimeDiffHistogram.Add(inputHistogram) - + fillTileModuleMeanAndRMS(timeDiffHistogram, inputs) setTileModuleHistogramStyle(timeDiffHistogram, markerStyle=21, markerSize=0.75, labelSize=0.08, ymin=-0.5, ymax=0.5) + sumTimeDiffHistogram = getTileModuleSumHistogram(inputs, 'dspfit_amphbar', 'DSP-OFFLINE Time for all channels') + return [timeDiffHistogram, sumTimeDiffHistogram] -- GitLab