ATLAS Offline Software
Loading...
Searching...
No Matches
TileCellBuilder Class Reference

This class creates Cells from RawChannels and stores them in a container. More...

#include <TileCellBuilder.h>

Inheritance diagram for TileCellBuilder:

Classes

class  DoubleVectorIterator
struct  VecParams

Public Member Functions

 TileCellBuilder (const std::string &type, const std::string &name, const IInterface *parent)
 Contructor.
virtual ~TileCellBuilder ()
 Destructor.
virtual StatusCode initialize () override
 Initializer.
virtual StatusCode finalize () override
virtual StatusCode process (CaloCellContainer *theCellContainer, const EventContext &ctx) const override
 method to process all raw channels and store them in container
void reset (bool fullSizeCont, bool printReset=true)
 Method to reset the options of the TileCellContainer.

Static Public Member Functions

static const InterfaceID & interfaceID ()

Private Types

enum  CELL_CHANNEL { E1_CHANNEL = 12 }
enum  CELL_TOWER { E1_TOWER = 10 , E1_TOWER_UPGRADE_ABC = 42 }
typedef TileDrawerEvtStatus TileDrawerEvtStatusArray[5][64]
 status of every drawer

Private Member Functions

template<class ITERATOR, class COLLECTION>
void build (const EventContext &ctx, TileDrawerEvtStatusArray &drawerEvtStatus, VecParams &params, const ITERATOR &begin, const ITERATOR &end, COLLECTION *coll, TileCellContainer *MBTSCells, TileCellContainer *E4prCells) const
 < method to process raw channels from a given vector and store them in collection
bool maskBadChannel (TileDrawerEvtStatusArray &drawerEvtStatus, const TileDQstatus *DQstatus, const TileDCSState *dcsState, const TileBadChannels *badChannels, TileCell *pCell, HWIdentifier hwid) const
 method to check if channels are good or bad.
bool maskBadChannels (TileDrawerEvtStatusArray &drawerEvtStatus, const TileDQstatus *DQstatus, const TileDCSState *dcsState, const TileBadChannels *badChannels, TileCell *pCell) const
void correctCell (TileCell *pCell, int correction, int pmt, int gain, float ener, float time, unsigned char iqual, unsigned char qbit, int ch_type) const
 Compute calibrated energy, time, etc.
unsigned char iquality (float qual) const
unsigned char qbits (TileDrawerEvtStatusArray &drawerEvtStatus, TileFragHash::TYPE RChType, int ros, int drawer, bool count_over, bool good_time, bool good_ener, bool overflow, bool underflow, bool good_overflowfit) const
 method to compute the cell quality bits

Private Attributes

SG::ReadHandleKey< TileRawChannelContainerm_rawChannelContainerKey
SG::ReadHandleKey< TileRawChannelContainerm_dspRawChannelContainerKey
SG::ReadHandleKey< xAOD::EventInfom_eventInfoKey
SG::ReadHandleKey< TileDQstatusm_DQstatusKey
SG::WriteHandleKey< TileCellContainerm_MBTSContainerKey
SG::WriteHandleKey< TileCellContainerm_E4prContainerKey
SG::WriteDecorHandleKey< xAOD::EventInfom_EventInfoTileStatusKey
std::string m_dspRawChannelContainer
float m_eneForTimeCut
 keep time for channels with energy above cut
float m_eneForTimeCutMBTS
 similar cut for MBTS in pC
float m_zeroEnergy
 energy to store in every PMT if both PMT are bad
int m_qualityCut
 cut on channel quality (set energy to m_zeroEnergy for them)
bool m_correctTime
 should time be corrected (deltat added from CondDB)
bool m_correctAmplitude
 If true, amplitude is corrected by parabolic function (needed for OF without iterations)
bool m_of2
 If true, assume OF2 method for amplitude correction, otherwise - OF1.
bool m_mergeChannels
 If true, missing raw channels are taken from DSP container.
float m_ampMinThresh
 correct amplitude if it's above amplitude threshold (in ADC counts)
float m_timeMinThresh
 correct amplitude is time is above time min threshold
float m_timeMaxThresh
 correct amplitude is time is below time max threshold
float m_minEneChan [3]
 channel energy thresholds for masking (normal,gap,mbts)
float m_eThreshold
 cell energy threshold to consider the cell
float m_maxTimeDiff
 maximum time difference between the PMTs in the cell
float m_maxTime
 maximum time for the PMTs in the cels
float m_minTime
 minimum time for the PMTs in the cels
float m_maxChi2
 maximum chi2 for the PMTs in the cels
float m_minChi2
 minimum chi2 for the PMTs in the cels
bool m_thresholdNotSet
 bool variable to check whether some threshold have been set
bool m_fullSizeCont
bool m_maskBadChannels
 if true=> bad channels are masked
bool m_fakeCrackCells
 if true=> fake E3/E4 cells added
int m_skipGain
 for two-gain calib runs skip one of two gains
int m_useDemoCabling
bool m_checkDCS
const TileIDm_tileID
 Pointer to TileID.
const TileTBIDm_tileTBID
 Pointer to TileTBID.
const TileHWIDm_tileHWID
 Pointer to TileHWID.
const TileCablingServicem_cabling
 TileCabling instance.
SG::ReadCondHandleKey< TileBadChannelsm_badChannelsKey
 Name of TileBadChannels in condition store.
SG::ReadCondHandleKey< TileEMScalem_emScaleKey
 Name of TileEMScale in condition store.
ToolHandle< TileCondToolTimingm_tileToolTiming
ToolHandleArray< ITileRawChannelToolm_noiseFilterTools
SG::ReadCondHandleKey< TileDCSStatem_DCSStateKey
 Name of TileDCSState object in condition store.
ServiceHandle< TileCablingSvcm_cablingSvc
 Name of Tile cabling service.
const TileDetDescrManagerm_tileMgr
 Pointer to TileDetDescrManager.
const MbtsDetDescrManagerm_mbtsMgr
 Pointer to MbtsDetDescrManager.
std::vector< CaloAffectedRegionInfom_affectedRegionInfo_global
std::vector< CaloAffectedRegionInfom_affectedRegionInfo_current_run
int m_towerE1 = E1_TOWER
bool m_notUpgradeCabling
bool m_run2
std::string m_infoName
const TileInfom_tileInfo
float m_ADCmaskValueMinusEps
float m_ADCmaskValuePlusEps
bool m_run2plus

Friends

class TileHid2RESrcID

Detailed Description

This class creates Cells from RawChannels and stores them in a container.

Definition at line 107 of file TileCellBuilder.h.

Member Typedef Documentation

◆ TileDrawerEvtStatusArray

typedef TileDrawerEvtStatus TileCellBuilder::TileDrawerEvtStatusArray[5][64]
private

status of every drawer

Definition at line 133 of file TileCellBuilder.h.

Member Enumeration Documentation

◆ CELL_CHANNEL

Enumerator
E1_CHANNEL 

Definition at line 387 of file TileCellBuilder.h.

◆ CELL_TOWER

Enumerator
E1_TOWER 
E1_TOWER_UPGRADE_ABC 

Definition at line 388 of file TileCellBuilder.h.

Constructor & Destructor Documentation

◆ TileCellBuilder()

TileCellBuilder::TileCellBuilder ( const std::string & type,
const std::string & name,
const IInterface * parent )

Contructor.

< normal channel energy threshold for masking

< gap channel energy threshold for masking

< MBTS channel energy threshold for masking (not used currently(

Definition at line 48 of file TileCellBuilder.cxx.

50 : base_class(type, name, parent)
51 , m_eneForTimeCut(35. * MeV) // keep time only for cells above 70 MeV (more than 35 MeV in at least one PMT to be precise)
52 , m_eneForTimeCutMBTS(0.03675) // the same cut for MBTS, but in pC, corresponds to 3 ADC counts or 35 MeV
53 , m_qualityCut(254) // cut on overflow in quality (if quality is 255 - assume that channel is bad)
54 , m_eThreshold(-100000.)
55 , m_maxTimeDiff(100000.)
56 , m_maxTime (100000.)
57 , m_minTime(-100000.)
58 , m_maxChi2(100000.)
59 , m_minChi2(-100000.)
60 , m_thresholdNotSet(true)
61 , m_fullSizeCont(true)
62 , m_maskBadChannels(true)
63 , m_fakeCrackCells(false)
64 , m_tileID(nullptr)
65 , m_tileTBID(nullptr)
66 , m_tileHWID(nullptr)
67 , m_cabling(nullptr)
68 , m_tileMgr(nullptr)
69 , m_mbtsMgr(nullptr)
71 , m_run2(false)
72 , m_tileInfo(0)
73 , m_run2plus(false)
74{
75 declareInterface<TileCellBuilder>( this );
76
77 //memset(m_drawerRunStatus, 0, sizeof(m_drawerRunStatus));
78 //memset(m_eventErrorCounter, 0, sizeof(m_eventErrorCounter));
79
80 // never set energy to zero, but set it to some small number
81 // this will help TopoCluster to assign proper weight to the cell if needed
82 m_zeroEnergy = 0.5 * MeV; // half a MeV in both PMTs i.e. one MeV in a cell
83
85 m_minEneChan[0] = -5000. * MeV;
87 m_minEneChan[1] = -10000. * MeV;
89 m_minEneChan[2] = -999999. * MeV;
90
91 declareProperty( "MinEnergyChan", m_minEneChan[0]);
92 declareProperty( "MinEnergyGap", m_minEneChan[1]);
93 declareProperty( "MinEnergyMBTS", m_minEneChan[2]);
94
95 // Energy threshold in MeV that the Cell must exceed to be considered:
96 declareProperty("EThreshold",m_eThreshold);
97
98 // Maximum difference between times of two PMTs in cell:
99 declareProperty("MaxTimeDiff", m_maxTimeDiff);
100
101 // Maximum and minimum time for a cell to be included:
102 declareProperty("MaxTime", m_maxTime);
103 declareProperty("MinTime", m_minTime);
104
105 // Maximum and Minimum fit quality for cell to be considered:
106 declareProperty("MaxChi2", m_maxChi2);
107 declareProperty("MinChi2", m_minChi2);
108
109 declareProperty("fullSizeCont", m_fullSizeCont);
110
111 // put zero energy in bad channels and recover from single-channel failure using second PMT is a cell
112 declareProperty("maskBadChannels", m_maskBadChannels);
113
114 // create fake E3/E4 crack scintillators with zero energy when they do not exist
115 declareProperty("fakeCrackCells", m_fakeCrackCells);
116
117 // PMT energy will be set to this value if channel is bad
118 declareProperty("BadChannelZeroEnergy", m_zeroEnergy);
119 // PMT with energy above cut will preserve time info in ESD
120 declareProperty("EneForTimeCut", m_eneForTimeCut);
121 declareProperty("EneForTimeCutMBTS", m_eneForTimeCutMBTS);
122 // PMT with quality greater than this cut will be masked
123 declareProperty("QualityCut", m_qualityCut);
124
125 // apply time correction taking numbers from CondDB (if not yet done in OF)
126 declareProperty("correctTime", m_correctTime = false);
127
128 // apply parabolic amplitude correction (if not yet done in OF without iterations)
129 declareProperty("correctAmplitude", m_correctAmplitude = false);
130
131 // use parabolic amplitude correction for OF2 or OF1 method
132 declareProperty("OF2", m_of2 = true);
133
134 // merge DSP results with offline reco results
135 declareProperty("mergeChannels", m_mergeChannels = true);
136
137 // thresholds for parabolic amplitude correction
138 declareProperty("AmpMinForAmpCorrection", m_ampMinThresh = 15.0);
139 declareProperty("TimeMinForAmpCorrection", m_timeMinThresh = -12.5);
140 declareProperty("TimeMaxForAmpCorrection", m_timeMaxThresh = 12.5);
141
142 declareProperty("SkipGain", m_skipGain = -1); // never skip any gain by default
143
144 declareProperty("UseDemoCabling", m_useDemoCabling = 0); // if set to 2015 - assume TB 2015 cabling
145
146 declareProperty("TileInfoName", m_infoName = "TileInfo");
147
148 declareProperty("CheckDCS", m_checkDCS = false);
149}
const TileDetDescrManager * m_tileMgr
Pointer to TileDetDescrManager.
int m_qualityCut
cut on channel quality (set energy to m_zeroEnergy for them)
float m_timeMaxThresh
correct amplitude is time is below time max threshold
const TileTBID * m_tileTBID
Pointer to TileTBID.
float m_timeMinThresh
correct amplitude is time is above time min threshold
bool m_mergeChannels
If true, missing raw channels are taken from DSP container.
const MbtsDetDescrManager * m_mbtsMgr
Pointer to MbtsDetDescrManager.
const TileInfo * m_tileInfo
bool m_fakeCrackCells
if true=> fake E3/E4 cells added
bool m_thresholdNotSet
bool variable to check whether some threshold have been set
bool m_of2
If true, assume OF2 method for amplitude correction, otherwise - OF1.
const TileCablingService * m_cabling
TileCabling instance.
int m_skipGain
for two-gain calib runs skip one of two gains
float m_eneForTimeCut
keep time for channels with energy above cut
const TileHWID * m_tileHWID
Pointer to TileHWID.
float m_minEneChan[3]
channel energy thresholds for masking (normal,gap,mbts)
float m_zeroEnergy
energy to store in every PMT if both PMT are bad
float m_maxChi2
maximum chi2 for the PMTs in the cels
bool m_correctTime
should time be corrected (deltat added from CondDB)
float m_eneForTimeCutMBTS
similar cut for MBTS in pC
bool m_correctAmplitude
If true, amplitude is corrected by parabolic function (needed for OF without iterations)
float m_minTime
minimum time for the PMTs in the cels
float m_ampMinThresh
correct amplitude if it's above amplitude threshold (in ADC counts)
std::string m_infoName
bool m_maskBadChannels
if true=> bad channels are masked
float m_maxTimeDiff
maximum time difference between the PMTs in the cell
float m_maxTime
maximum time for the PMTs in the cels
const TileID * m_tileID
Pointer to TileID.
float m_minChi2
minimum chi2 for the PMTs in the cels
float m_eThreshold
cell energy threshold to consider the cell

◆ ~TileCellBuilder()

TileCellBuilder::~TileCellBuilder ( )
virtual

Destructor.

Definition at line 154 of file TileCellBuilder.cxx.

154 {
155}

Member Function Documentation

◆ build()

template<class ITERATOR, class COLLECTION>
void TileCellBuilder::build ( const EventContext & ctx,
TileDrawerEvtStatusArray & drawerEvtStatus,
VecParams & params,
const ITERATOR & begin,
const ITERATOR & end,
COLLECTION * coll,
TileCellContainer * MBTSCells,
TileCellContainer * E4prCells ) const
private

< method to process raw channels from a given vector and store them in collection

Definition at line 1029 of file TileCellBuilder.cxx.

1037{
1038 // Now retrieve the TileDQstatus
1039 const TileDQstatus* DQstatus = nullptr;
1041 DQstatus = SG::makeHandle (m_DQstatusKey, ctx).get();
1042 }
1043
1044 const TileDCSState* dcsState = m_checkDCS ? SG::ReadCondHandle(m_DCSStateKey, ctx).cptr() : nullptr;
1045 SG::ReadCondHandle<TileEMScale> emScale(m_emScaleKey, ctx);
1046 SG::ReadCondHandle<TileBadChannels> badChannels(m_badChannelsKey, ctx);
1047
1048 /* zero all counters and sums */
1049 int nTwo = 0;
1050 int nCell = 0;
1051 int nFake = 0;
1052 int nMBTS = 0;
1053 int nE4pr = 0;
1054 int nChan = 0;
1055 float eCh = 0.0;
1056 float eCellTot = 0.0;
1057 float eMBTSTot = 0.0;
1058 float eE4prTot = 0.0;
1059 bool EBdrawerPresent[128];
1060 memset(EBdrawerPresent, 0, sizeof(EBdrawerPresent));
1061 DataPool<TileCell> tileCellsP(5217);
1062 //**
1063 //* Iterate over raw channels, creating new TileCells (or incrementing
1064 //* existing ones). Add each new TileCell to the output collection
1065 //**
1066
1067 std::vector<TileCell*> allCells (m_tileID->cell_hash_max(), nullptr);
1068
1069 for (ITERATOR rawItr = begin; rawItr != end; ++rawItr) {
1070
1071 const TileRawChannel* pChannel = (*rawItr);
1072 HWIdentifier adc_id = pChannel->adc_HWID();
1073 int ros = m_tileHWID->ros(adc_id);
1074 int drawer = m_tileHWID->drawer(adc_id);
1075 int channel = m_tileHWID->channel(adc_id);
1076 int gain = m_tileHWID->adc(adc_id);
1077 if (gain == m_skipGain) {
1078 ATH_MSG_VERBOSE (" skipping adc_id=" << m_tileHWID->to_string(adc_id));
1079 continue; // select only one of two gains in calib runs
1080 }
1081 int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
1082 if (channel == 0 && ros > 2) EBdrawerPresent[(ros - 3) * 64 + drawer] = true; // EB drawer appeared in the data
1083
1084 float time = pChannel->uncorrTime(); // take uncorrected time (if available)
1085 float amp = pChannel->amplitude();
1086
1087 TileRawChannelUnit::UNIT oldUnit = params.m_RChUnit;
1088 if (params.m_correctAmplitude && time > m_timeMinThresh && time < m_timeMaxThresh) { // parabolic correction
1089 if (params.m_RChUnit > TileRawChannelUnit::OnlineADCcounts) { // convert from online units to ADC counts
1091 amp = emScale->undoOnlineChannelCalibration(drawerIdx, channel, gain, amp, params.m_RChUnit);
1092
1093 if (amp > m_ampMinThresh) // amp cut in ADC counts
1094 amp *= TileRawChannelBuilder::correctAmp(time,params.m_of2);
1095 } else if (params.m_RChUnit == TileRawChannelUnit::ADCcounts
1097 if (amp > m_ampMinThresh)
1098 amp *= TileRawChannelBuilder::correctAmp(time,params.m_of2);
1099 } else {
1100 ATH_MSG_ERROR( "Units in raw channel container is " << params.m_RChUnit );
1101 ATH_MSG_ERROR( "But amplitude correction works only with ADC counts " );
1102 ATH_MSG_ERROR( "Please, disable CIS calibration in optimal filter " );
1103 }
1104 }
1105
1106 float qual = pChannel->quality();
1107
1108 // check that time was really reconstructed
1109 bool good_time = (fabs(time) < params.m_maxTimeCorr);
1110 bool non_zero_time = (params.m_RChType == TileFragHash::OptFilterDspCompressed)
1111 ? ((qual > 2.99 && qual < 4.01))
1112 : ((qual > 0.0 || params.m_RChType == TileFragHash::OptFilterDsp));
1113
1114 // new feature in rel 17.2.7 - pedestal keeps information about overflow and underflow
1115 // if there is an underflow, 10000 is added to pedestal value
1116 // if there is an overflow, 20000 is added to pedestal value
1117 // if there is an underflow in all samples, 80000 is added to pedestal value
1118 // if there is an overflow in all samples, 90000 is added to pedestal value
1119 // if there is bad pattern nunber N 100000+N*10000 is added to pedestal value
1120 bool overflow = false;
1121 bool underflow = false;
1122 bool overfit = false;
1123 float ped = pChannel->pedestal();
1124 if (ped > 59500.) { // one of bad patterns
1125 qual = 9999; // mask all bad patterns
1126 } else if (ped > 39500.) { // 40000 for constant value or 50000 for all zeros in disconnexted channel
1127 // nothing to do
1128 } else if (ped > m_ADCmaskValuePlusEps) { // 10000 for underflow or 20000 for overflow or 10000+20000
1129 // NOTE: opt filter can yield values between (-500, 4600) and overlay magic number is 4800 in case of 12-bit ADCs
1130 underflow = ((ped < 10000. + m_ADCmaskValuePlusEps) || (ped > 29500.));
1131 overflow = (ped > 10000. + m_ADCmaskValuePlusEps);
1132 // special flag indicating that fit method was applied for overflow channels
1133 overfit = ( (ped > 20000. + m_ADCmaskValueMinusEps && ped < 29500) || (ped > 30000. + m_ADCmaskValueMinusEps && ped < 39500) );
1134
1135 if (overflow
1136 && gain == TileID::LOWGAIN
1137 && amp > 0
1138 && time > m_timeMinThresh
1139 && time < m_timeMaxThresh) {
1140
1141 qual = fabs(qual);
1142 if (qual > m_qualityCut && qual < 9999.) {
1143 qual = m_qualityCut; // to avoid masking of overflow in low gain
1144 }
1145 }
1146 }
1147
1148 // apply time correction if needed
1149 if (params.m_correctTime && good_time && non_zero_time)
1150 time -= m_tileToolTiming->getSignalPhase(drawerIdx, channel, gain);
1151 else
1152 time = pChannel->time();
1153
1154 ++nChan;
1155 eCh += amp;
1156
1157 int index, pmt;
1158 int channel1 = channel;
1159
1160 if (m_useDemoCabling == 2015 && ros == 4 && drawer == 1) {
1161 int pmt2channel[48] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
1162 26,25,24,29,31,32,27,28,30,35,34,33,38,37,43,44,41,40,39,36,42,47,46,45};
1163 channel1 = pmt2channel[channel];
1164
1165 } else if ( (m_useDemoCabling >= 2016 && m_useDemoCabling <= 2019)
1166 && (ros == 2 && (drawer == 1 || drawer>2)) ) {
1167 int pmt2channel[48] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
1168 26,25,24,29,28,27,32,31,30,35,34,33,38,37,36,41,40,39,44,43,42,47,46,45};
1169 channel1 = pmt2channel[channel];
1170 } else if ( (m_useDemoCabling >= 2018)
1171 && (ros == 4 && drawer>=2) ) {
1172 int pmt2channelEB[48] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
1173 31,32,30,35, 33,34, 38,37,41,40,39,36, 26,25,24,29,28,27, 44,43,42,47,46,45};
1174 channel1 = pmt2channelEB[channel];
1175 }
1176
1177 Identifier cell_id = m_cabling->h2s_cell_id_index (ros, drawer, channel1, index, pmt);
1178
1179 if (index == -3) { // E4' cells
1180
1181 if (E4prCells) { // do something with them only if the container exists
1182 ++nE4pr;
1183
1184 // convert ADC counts to MeV. like for normal cells
1185 float ener = emScale->calibrateChannel(drawerIdx, channel, gain, amp, oldUnit
1187
1188 eE4prTot += ener;
1189 unsigned char iqual = iquality(qual);
1190 // for E4' cell qbit use only non_zero_time flag and check that energy is above standatd energy threshold in MeV
1191 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1192 ros, drawer, true, non_zero_time, (fabs(ener) > m_eneForTimeCut)
1193 , overflow, underflow, overfit);
1197
1198 TileCell* pCell = tileCellsP.nextElementPtr();
1199 // no CaloDDE
1200 // Cell ID is set explicitly
1201 pCell->set(NULL, cell_id);
1202 pCell->setEnergy_nonvirt(ener, 0, cgain, 3);
1203 pCell->setTime_nonvirt(time);
1204 pCell->setQual1(iqual);
1205 pCell->setQual2(0);
1206 pCell->setQbit1(qbit);
1207 pCell->setQbit2(0);
1208
1209 if (msgLvl(MSG::VERBOSE)) {
1210 msg(MSG::VERBOSE) << " E4' cell_id=" << m_tileTBID->to_string(cell_id)
1211 << " adc_id=" << m_tileHWID->to_string(adc_id)
1212 << " ene= " << ener
1213 << " amp= " << amp
1214 << " time= " << time
1215 << " qual= " << pChannel->quality()
1216 << " iqual= " << (int) iqual
1217 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1218
1219 if (ped > m_ADCmaskValuePlusEps)
1220 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1221 else
1222 msg(MSG::VERBOSE) << endmsg;
1223 }
1224
1225 if (m_maskBadChannels && maskBadChannel(drawerEvtStatus, DQstatus, dcsState,
1226 *badChannels, pCell, adc_id))
1227 ATH_MSG_VERBOSE ( "cell with id=" << m_tileTBID->to_string(cell_id)
1228 << " bad channel masked, new energy=" << pCell->energy() );
1229
1230 E4prCells->push_back(pCell); // store cell in container
1231
1232 }
1233
1234 } else if (index == -2) { // MBTS cells
1235
1236 if (MBTSCells) { // do something with them only if contaier existst
1237 ++nMBTS;
1238
1239 // convert ADC counts to pCb and not to MeV
1240 float ener = emScale->calibrateChannel(drawerIdx, channel, gain, amp , oldUnit
1242
1243 eMBTSTot += ener;
1244 unsigned char iqual = iquality(qual);
1245 // for MBTS qbit use AND of good_time and non_zero_time and check that energy is above MBTS energy threshold in pC
1246 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1247 ros, drawer, false, (good_time && non_zero_time),
1248 (fabs(ener) > m_eneForTimeCutMBTS), overflow, underflow, overfit);
1249
1253
1254 TileCell* pCell = tileCellsP.nextElementPtr();
1255 // MBTS CaloDDE
1256 // Cell ID is set explicitly
1257 pCell->set((m_mbtsMgr) ? m_mbtsMgr->get_element(cell_id) : NULL, cell_id);
1258 pCell->setEnergy_nonvirt(ener, 0, cgain, 3);
1259 pCell->setTime_nonvirt(time);
1260 pCell->setQual1(iqual);
1261 pCell->setQual2(0);
1262 pCell->setQbit1(qbit);
1263 pCell->setQbit2(0);
1264
1265 if (msgLvl(MSG::VERBOSE)) {
1266 msg(MSG::VERBOSE) << " MBTS cell_id=" << m_tileTBID->to_string(cell_id)
1267 << " adc_id=" << m_tileHWID->to_string(adc_id)
1268 << " ene= " << ener
1269 << " amp= " << amp
1270 << " time= " << time
1271 << " qual= " << pChannel->quality()
1272 << " iqual= " << (int) iqual
1273 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1274
1275 if (ped > m_ADCmaskValuePlusEps)
1276 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1277 else
1278 msg(MSG::VERBOSE) << endmsg;
1279 }
1280
1281 if (m_maskBadChannels && maskBadChannel(drawerEvtStatus, DQstatus, dcsState,
1282 *badChannels, pCell, adc_id))
1283 ATH_MSG_VERBOSE ( "cell with id=" << m_tileTBID->to_string(cell_id)
1284 << " bad channel masked, new energy=" << pCell->energy() );
1285
1286 MBTSCells->push_back(pCell); // store cell in container
1287
1288 }
1289 } else if (index != -1) { // connected channel
1290
1291 float ener = emScale->calibrateChannel(drawerIdx, channel, gain, amp
1293
1294 eCellTot += ener;
1295
1296 unsigned char iqual = iquality(qual);
1297 // for normal cell qbit use only non_zero_time flag and check that energy is above standatd energy threshold in MeV
1298 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1299 ros, drawer, true, non_zero_time, (fabs(ener) > m_eneForTimeCut)
1300 , overflow, underflow, overfit);
1301
1302
1303 if (m_run2plus && channel == E1_CHANNEL && ros > 2) { // Raw channel -> E1 cell.
1304
1305 int drawer2 = m_cabling->E1_merged_with_run2plus(ros,drawer);
1306 if (drawer2 != 0) { // Raw channel splitted into two E1 cells for Run 2.
1307 int side = (ros == 3) ? 1 : -1;
1308 Identifier cell_id2 = m_tileID->cell_id(TileID::GAPDET, side, drawer2, m_towerE1, TileID::SAMP_E);
1309 int index2 = m_tileID->cell_hash(cell_id2);
1310 TileCell* pCell2 = tileCellsP.nextElementPtr();
1311 ++nCell;
1312 allCells[index2] = pCell2;
1313 const CaloDetDescrElement* dde2 = m_tileMgr->get_cell_element(index2);
1314 pCell2->set(dde2, cell_id2);
1316 int pmt2(0);
1317 ener /= 2.0F;
1318 correctCell(pCell2, 1, pmt2, gain, ener, time, iqual, qbit, 1);
1319
1320 ATH_MSG_DEBUG("E1 cell Id => " << m_tileID->to_string(cell_id)
1321 << " splitted into " << m_tileID->to_string(cell_id2));
1322
1323
1324 }
1325
1326 }
1327
1328 TileCell* pCell = allCells[index];
1329 if (pCell) {
1330 ++nTwo;
1331 correctCell(pCell, 2, pmt, gain, ener, time, iqual, qbit, 0); // correct & merge 2 PMTs in one cell
1332 } else {
1333 ++nCell;
1334 allCells[index] = pCell = tileCellsP.nextElementPtr();
1335 const CaloDetDescrElement* dde = m_tileMgr->get_cell_element(index);
1336 pCell->set(dde, cell_id);
1338 int ch_type = (dde->onl2() == TileHWID::NOT_VALID_HASH) ? 1 : 0;
1339 correctCell(pCell, 1, pmt, gain, ener, time, iqual, qbit, ch_type); // correct & save e,t,q in new cell
1340 }
1341
1342 if (msgLvl(MSG::VERBOSE)) {
1343 float calib1 = (amp != 0) ? ener / amp : 0.0;
1344 msg(MSG::VERBOSE) << " cell_id=" << m_tileID->to_string(cell_id, -2)
1345 << " adc_id=" << m_tileHWID->to_string(adc_id)
1346 << " calib=" << calib1
1347 << " nCell=" << nCell
1348 << " energy=" << ener << " (" << pCell->energy() << ", " << pCell->eneDiff() << ")" << endmsg;
1349
1350 msg(MSG::VERBOSE) << " amp= " << amp
1351 << " time= " << time
1352 << " qual= " << pChannel->quality()
1353 << " iqual= " << (int) iqual
1354 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1355
1356 if (ped > m_ADCmaskValuePlusEps)
1357 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1358 else
1359 msg(MSG::VERBOSE) << endmsg;
1360 }
1361
1362 } else {
1363
1364 if (msgLvl(MSG::VERBOSE)) {
1365
1366 unsigned char iqual = iquality(qual);
1367 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1368 0, drawer, false, non_zero_time, false, overflow, underflow, overfit); //fake ros number here
1369
1370 msg(MSG::VERBOSE) << " channel with adc_id=" << m_tileHWID->to_string(adc_id)
1371 << " is not connected" << endmsg;
1372
1373 msg(MSG::VERBOSE) << " amp= " << amp
1374 << " time= " << time
1375 << " qual= " << pChannel->quality()
1376 << " iqual= " << (int) iqual
1377 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1378
1379 if (ped > m_ADCmaskValuePlusEps)
1380 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1381 else
1382 msg(MSG::VERBOSE) << endmsg;
1383 }
1384 }
1385 if (msgLvl(MSG::VERBOSE)) {
1386 if ((params.m_correctTime && good_time && non_zero_time) || pChannel->sizeTime() > 1) {
1387 msg(MSG::VERBOSE) << " OF_time = " << pChannel->uncorrTime()
1388 << " corr_time = " << time << endmsg;
1389 }
1390 }
1391 }
1392
1393 //**
1394 // Now store all TileCells
1395 //**
1396 for (unsigned int index = 0; index < allCells.size(); ++index) {
1397
1398 TileCell * pCell = allCells[index];
1399
1400 if (pCell) { // cell exists
1401
1403 if (maskBadChannels (drawerEvtStatus, DQstatus, dcsState, *badChannels, pCell))
1404 ATH_MSG_VERBOSE ( "cell with id=" << m_tileID->to_string(pCell->ID(), -2)
1405 << " bad channels masked, new energy=" << pCell->energy() );
1406
1408 || (pCell->energy() > m_eThreshold
1409 && fabs(pCell->timeDiff()) < m_maxTimeDiff
1410 && pCell->time1() < m_maxTime && pCell->time1() > m_minTime
1411 && pCell->time2() < m_maxTime && pCell->time2() > m_minTime
1412 && pCell->qual1() > m_minChi2 && pCell->qual1() < m_maxChi2
1413 && pCell->qual2() > m_minChi2 && pCell->qual2() < m_maxChi2)) {
1414
1415 coll->push_back(pCell); // store cell in container
1416
1417 } else {
1418
1419 //delete pCell; it's dangerous to delete cell, if it's in DataPool
1420
1421 }
1422
1423 allCells[index] = 0; // clear pointer for next event
1424 } else if (m_fakeCrackCells) { // can be true only for full-size container
1425
1426 pCell = tileCellsP.nextElementPtr();
1427 const CaloDetDescrElement* dde = m_tileMgr->get_cell_element(index);
1428 pCell->set(dde, dde->identify());
1429
1430 if (m_tileID->section(pCell->ID()) == TileID::GAPDET) { // missing D4/E3/E4 cell
1431
1432 int ind = m_tileID->module(pCell->ID()) + ((m_tileID->side(pCell->ID()) > 0) ? 0 : 64);
1433 if (EBdrawerPresent[ind]) {
1434 ++nFake;
1435 if (m_tileID->sample(pCell->ID()) == TileID::SAMP_E) {
1436 pCell->setEnergy(0.0, 0.0, TileID::LOWGAIN, CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
1437 pCell->setQuality(0, TileCell::MASK_BADCH, 0); // reset quality flag for first pmt
1438 pCell->setQuality(0, TileCell::MASK_BADCH, 1); // reset quality flag for second pmt
1439 } else {
1440 pCell->setEnergy(0.0, 0.0, TileID::LOWGAIN, TileID::LOWGAIN); // reset energy completely, indicate problem putting low gain
1441 pCell->setQuality(0, 0, 0); // reset quality flag for first pmt
1442 pCell->setQuality(0, 0, 1); // reset quality flag for second pmt
1443 }
1444 pCell->setTime(0.0); // reset time completely
1445
1446 ATH_MSG_VERBOSE ( "adding fake cell with id=" << m_tileID->to_string(pCell->ID(), -2)
1447 << " ene=" << pCell->energy()
1448 << " status=" << (pCell->badcell() ? "bad" : "good") );
1449
1450 coll->push_back(pCell); // store cell in container
1451 }
1452 }
1453 }
1454 }
1455
1456 if (msgLvl(MSG::DEBUG)) {
1457 msg(MSG::DEBUG) << " nChan=" << nChan
1458 << " RawChSum=" << eCh
1459 << " nCell=" << nCell
1460 << " n2=" << nTwo
1461 << " nFake=" << nFake
1462 << " eneTot=" << eCellTot;
1463
1464 if (MBTSCells)
1465 msg(MSG::DEBUG) << " nMBTS=" << nMBTS
1466 << " eMBTS=" << eMBTSTot;
1467 if (E4prCells)
1468 msg(MSG::DEBUG) << " nE4pr=" << nE4pr
1469 << " eE4pr=" << eE4prTot;
1470
1471 msg(MSG::DEBUG) << endmsg;
1472 }
1473}
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
double energy() const
get energy (data member)
Definition CaloCell.h:327
void set(const CaloDetDescrElement *caloDDE, const Identifier &ID)
Fast method to change the identity of a cell.
Definition CaloCell.h:511
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition CaloCell.h:295
Identifier identify() const override final
cell identifier
IdentifierHash onl2() const
cell online identifier 2
value_type push_back(value_type pElem)
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
ToolHandle< TileCondToolTiming > m_tileToolTiming
SG::ReadHandleKey< TileDQstatus > m_DQstatusKey
bool maskBadChannel(TileDrawerEvtStatusArray &drawerEvtStatus, const TileDQstatus *DQstatus, const TileDCSState *dcsState, const TileBadChannels *badChannels, TileCell *pCell, HWIdentifier hwid) const
method to check if channels are good or bad.
bool maskBadChannels(TileDrawerEvtStatusArray &drawerEvtStatus, const TileDQstatus *DQstatus, const TileDCSState *dcsState, const TileBadChannels *badChannels, TileCell *pCell) const
unsigned char iquality(float qual) const
SG::ReadCondHandleKey< TileDCSState > m_DCSStateKey
Name of TileDCSState object in condition store.
unsigned char qbits(TileDrawerEvtStatusArray &drawerEvtStatus, TileFragHash::TYPE RChType, int ros, int drawer, bool count_over, bool good_time, bool good_ener, bool overflow, bool underflow, bool good_overflowfit) const
method to compute the cell quality bits
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
void correctCell(TileCell *pCell, int correction, int pmt, int gain, float ener, float time, unsigned char iqual, unsigned char qbit, int ch_type) const
Compute calibrated energy, time, etc.
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
uint8_t qual1(void) const
get quality of first PMT (data member)
Definition TileCell.h:197
float time1(void) const
get time of first PMT
Definition TileCell.h:192
void setEnergy_nonvirt(float e1, float e2, int gain1, int gain2)
Definition TileCell.h:257
void setQual2(unsigned char qual)
set quality of second PMT
Definition TileCell.h:165
virtual bool badcell(void) const override final
check if whole cell is bad (i.e.
Definition TileCell.h:214
void setTime_nonvirt(float t)
Definition TileCell.h:244
float eneDiff(void) const
all get methods
Definition TileCell.h:182
virtual void setEnergy(float ene) override final
set total energy, reset eneDiff to zero (final override of CaloCell method)
Definition TileCell.cxx:123
uint8_t qual2(void) const
get quality of second PMT (data member)
Definition TileCell.h:200
void setQbit1(unsigned char qbit)
set quality bits of first PMT
Definition TileCell.h:168
void setQbit2(unsigned char qbit)
set quality bits of second PMT
Definition TileCell.h:171
void setQuality(unsigned char qual, unsigned char qbit, int pmt)
set quality value and quality bits for one PMT (TileCell specific overloads)
Definition TileCell.h:280
void setQual1(unsigned char qual)
set quality of first PMT
Definition TileCell.h:162
virtual void setTime(float t) override final
set cell time, reset timeDiff
Definition TileCell.h:251
float timeDiff(void) const
get time diff for two PMTs (data member)
Definition TileCell.h:184
float time2(void) const
get time of second PMT
Definition TileCell.h:194
@ MASK_BADCH
Definition TileCell.h:63
@ NOT_VALID_HASH
Definition TileHWID.h:314
static const char * BadPatternName(float ped)
static double correctAmp(double phase, bool of2=true)
Amplitude correction factor according to the time when using weights for tau=0 without iterations.
float pedestal(void) const
float time(int ind=0) const
float quality(int ind=0) const
int sizeTime() const
float uncorrTime() const
float amplitude(int ind=0) const
HWIdentifier adc_HWID(void) const
Definition TileRawData.h:53
@ INVALIDGAIN
Definition CaloGain.h:18
@ TILEONEHIGH
Definition CaloGain.h:17
@ TILEONELOW
Definition CaloGain.h:16
time(flags, cells_name, *args, **kw)
str index
Definition DeMoScan.py:362
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
MsgStream & msg
Definition testRead.cxx:32

◆ correctCell()

void TileCellBuilder::correctCell ( TileCell * pCell,
int correction,
int pmt,
int gain,
float ener,
float time,
unsigned char iqual,
unsigned char qbit,
int ch_type ) const
private

Compute calibrated energy, time, etc.

for TileCell and adjust it.

Definition at line 667 of file TileCellBuilder.cxx.

668 {
669//************************************************************************
670
671// Merge two pmts in one cell if needed
672// and apply corrections
673
674 // do not trust to energies below certain threshold
675 if (ener < m_minEneChan[ch_type]) {
676#ifdef ALLOW_DEBUG_COUT
677 std::cout << "channel with negative energy " << ener << " => setting quality to 255" << std::endl;
678#endif
679 iqual = 255;
680 }
681
682 switch (correction) {
683 case 1: // first pmt for this cell
684 pCell->addEnergy(ener, pmt, gain);
685 pCell->setTime(time); // overwrite time completely
686 pCell->setQuality(iqual, qbit, pmt);
687 pCell->setQuality(0, 0, 1 - pmt);
688 break;
689 case 2: // second pmt for this cell
690 pCell->addEnergy(ener, pmt, gain);
691 pCell->setTime(time, pmt); // calculate average time and timeDiff
692 pCell->setQuality(iqual, qbit, pmt);
693 break;
694 }
695}
void addEnergy(float e, int pmt, int gain)
set energy and gain for one PMT
Definition TileCell.cxx:145

◆ finalize()

StatusCode TileCellBuilder::finalize ( )
overridevirtual

Definition at line 265 of file TileCellBuilder.cxx.

265 {
266
267 ATH_MSG_INFO( "Finalizing" );
268
269 return StatusCode::SUCCESS;
270}
#define ATH_MSG_INFO(x)

◆ initialize()

StatusCode TileCellBuilder::initialize ( )
overridevirtual

Initializer.

Definition at line 160 of file TileCellBuilder.cxx.

160 {
161
162 // retrieve MBTS and Tile detector manager, TileID helper and TileIfno from det store
163 if (m_MBTSContainerKey.key().empty()) {
164 m_mbtsMgr = nullptr;
165 } else {
166
167 ATH_CHECK( m_MBTSContainerKey.initialize() );
168 ATH_MSG_INFO( "Storing MBTS cells in " << m_MBTSContainerKey.key() );
169
170 if (detStore()->retrieve(m_mbtsMgr).isFailure()) {
171 ATH_MSG_WARNING( "Unable to retrieve MbtsDetDescrManager from DetectorStore" );
172 m_mbtsMgr = nullptr;
173 }
174 }
175
176 ATH_CHECK( m_eventInfoKey.initialize() );
177 ATH_CHECK( m_DQstatusKey.initialize() );
178 ATH_CHECK( m_EventInfoTileStatusKey.initialize() );
179 ATH_CHECK( m_emScaleKey.initialize() );
180
185
186 ATH_CHECK( m_badChannelsKey.initialize() );
187
188 // access tools and store them
189 ATH_CHECK( m_noiseFilterTools.retrieve() );
190
191 //=== get TileCondToolTiming
192 ATH_CHECK( m_tileToolTiming.retrieve() );
193
194 ATH_CHECK( m_DCSStateKey.initialize(m_checkDCS) );
195
196 ATH_CHECK( m_cablingSvc.retrieve() );
197 m_cabling = m_cablingSvc->cablingService();
198
199 reset(true, false);
200
201 m_run2 = m_cabling->isRun2Cabling();
202 m_run2plus = m_cabling->isRun2PlusCabling();
203
204 if (m_run2 && !m_E4prContainerKey.key().empty()) {
205 ATH_CHECK( m_E4prContainerKey.initialize() );
206 ATH_MSG_INFO( "Storing E4' cells in " << m_E4prContainerKey.key() );
207 } else {
208 m_E4prContainerKey = ""; // no E4' container for RUN1
209 }
210
211 if (m_cabling->getCablingType() == TileCablingService::UpgradeABC) {
213 m_notUpgradeCabling = false;
214 }
215
216 ATH_CHECK( m_rawChannelContainerKey.initialize() );
217
219 || m_dspRawChannelContainerKey.key().empty())) {
220 m_mergeChannels = false;
221 }
222
224 ATH_CHECK( m_eventInfoKey.initialize() );
225
226 ATH_MSG_INFO( "TileCellBuilder initialization completed" );
227
228 //=== get TileInfo
230 m_ADCmaskValueMinusEps = m_tileInfo->ADCmaskValue() - 0.01; // indicates channels which were masked in background dataset
231 m_ADCmaskValuePlusEps = m_tileInfo->ADCmaskValue() + 0.01; // indicates channels which were masked in background dataset
232
233 return StatusCode::SUCCESS;
234}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
SG::ReadHandleKey< TileRawChannelContainer > m_dspRawChannelContainerKey
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
void reset(bool fullSizeCont, bool printReset=true)
Method to reset the options of the TileCellContainer.
SG::WriteDecorHandleKey< xAOD::EventInfo > m_EventInfoTileStatusKey
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
SG::WriteHandleKey< TileCellContainer > m_E4prContainerKey
SG::WriteHandleKey< TileCellContainer > m_MBTSContainerKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
ToolHandleArray< ITileRawChannelTool > m_noiseFilterTools
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ interfaceID()

const InterfaceID & TileCellBuilder::interfaceID ( )
static

Definition at line 43 of file TileCellBuilder.cxx.

43 {
45}
static const InterfaceID IID_ITileCellBuilder("TileCellBuilder", 1, 0)

◆ iquality()

unsigned char TileCellBuilder::iquality ( float qual) const
inlineprivate

< method to compute the cell quality

Definition at line 294 of file TileCellBuilder.h.

294 {
295 return std::min(255, abs((int) qual));
296 } // keep quality within 8 bits make it "unsigned char"

◆ maskBadChannel()

bool TileCellBuilder::maskBadChannel ( TileDrawerEvtStatusArray & drawerEvtStatus,
const TileDQstatus * DQstatus,
const TileDCSState * dcsState,
const TileBadChannels * badChannels,
TileCell * pCell,
HWIdentifier hwid ) const
private

method to check if channels are good or bad.

Puts zero if both channels are bad or recovers from single-channel failure. It returns true if cell was changed, false otherwise

Definition at line 737 of file TileCellBuilder.cxx.

740{
741 int ros = m_tileHWID->ros(hwid);
742 int drawer = m_tileHWID->drawer(hwid);
743 int chan = m_tileHWID->channel(hwid);
744 int gain = m_tileHWID->adc(hwid);
745 TileBchStatus chStatus = badChannels->getAdcStatus(hwid);
746
747 // check quality first
748 bool bad = ((int) pCell->qual1() > m_qualityCut);
749 if (bad) {
750 ++drawerEvtStatus[ros][drawer].nBadQuality;
751
752 } else {
753 // check bad status in DB
754 bad = chStatus.isBad();
755
756 // Now checking the DQ status
757 if (!bad && m_notUpgradeCabling && DQstatus) {
758 bad = !(DQstatus->isAdcDQgood(ros, drawer, chan, gain))
759 || (dcsState ? dcsState->isStatusBad(ros, drawer, chan) : false);
760 }
761 }
762
763 if (bad) {
764 // only one channel in this cell and it is bad
765 ++drawerEvtStatus[ros][drawer].nMaskedChannels;
766
767 //pCell->setEnergy(m_zeroEnergy,0.0,TileID::LOWGAIN,CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
768 //pCell->setTime(0.0); // reset time completely
769 //pCell->setQuality(255,TileCell::MASK_BADCH,0); // reset quality flag for first pmt
770
771 if (gain == CaloGain::INVALIDGAIN) {
772 pCell->setEnergy(0.0, 0.0, TileID::LOWGAIN, CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
773 } else {
774 pCell->setEnergy(0.0, 0.0); // reset energy completely without changing the gain
775 }
776 pCell->setTime(-100.0); // reset time to big negative number to distinguish this bad cell from good cells
777 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit1() & TileCell::MASK_ALGO)), 0); // reset quality flag for first pmt
778 pCell->setQuality(0, TileCell::MASK_BADCH, 1); // reset quality flag for second pmt
779
780 return true;
781
782 } else if (chStatus.isBadTiming()) {
783 pCell->setTime(0.0); // channel with bad timing - no cell time
784 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
785 pCell->setQuality(pCell->qual1(), qbit1, 0); // update qbits for first pmt
786 }
787
788 return false;
789}
const TileBchStatus & getAdcStatus(const HWIdentifier adc_id) const
Return Tile ADC status.
bool isBadTiming() const
bool isBad() const
@ MASK_TIME
Definition TileCell.h:67
@ MASK_ALGO
Definition TileCell.h:62
uint8_t qbit1(void) const
get quality bits of first PMT (data member)
Definition TileCell.h:203
bool isStatusBad(unsigned int ros, unsigned int drawer) const
Return true if given Tile drawer considered as bad by summary drawer states per LVPS otherwise return...
bool isAdcDQgood(int partition, int drawer, int ch, int gain) const
returns status of single ADC returns False if there are any errors

◆ maskBadChannels()

bool TileCellBuilder::maskBadChannels ( TileDrawerEvtStatusArray & drawerEvtStatus,
const TileDQstatus * DQstatus,
const TileDCSState * dcsState,
const TileBadChannels * badChannels,
TileCell * pCell ) const
private

Definition at line 793 of file TileCellBuilder.cxx.

796{
797 bool single_PMT_C10 = false;
798
799 const CaloDetDescrElement* caloDDE = pCell->caloDDE();
800
801 IdentifierHash hash1 = caloDDE->onl1();
802 IdentifierHash hash2 = caloDDE->onl2();
803
804 int gain1 = pCell->gain1();
805
806 HWIdentifier ch_id1 = m_tileHWID->channel_id(hash1);
807
808 int ros1 = m_tileHWID->ros(ch_id1);
809 int drawer1 = m_tileHWID->drawer(ch_id1);
810 int chan1 = m_tileHWID->channel(ch_id1);
811
812 HWIdentifier adc_id1 = m_tileHWID->adc_id(ros1, drawer1, chan1, ((gain1 < 0) ? 1 : gain1));
813 const TileBchStatus& chStatus1 = badChannels->getAdcStatus(adc_id1);
814
815 // check quality first
816 bool bad1 = ((int) pCell->qual1() > m_qualityCut);
817 if (bad1) {
818 ++drawerEvtStatus[ros1][drawer1].nBadQuality;
819
820 } else {
821 // check bad status in DB
822 bad1 = (gain1 < 0) || chStatus1.isBad();
823
824 // Now checking the DQ status
825 if (!bad1 && m_notUpgradeCabling && DQstatus) {
826 bad1 = !(DQstatus->isAdcDQgood(ros1, drawer1, chan1, gain1))
827 || (dcsState ? dcsState->isStatusBad(ros1, drawer1, chan1) : false);
828 }
829 }
830
831 if (hash2 == TileHWID::NOT_VALID_HASH) {
832 // gap/crack scintillators with one PMT per cell
833
834 if (bad1) {
835 // only one channel in this cell and it is bad
836 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
837
838 if (gain1 == CaloGain::INVALIDGAIN) {
839 pCell->setEnergy(m_zeroEnergy, 0.0, TileID::LOWGAIN, CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
840 } else {
841 pCell->setEnergy(m_zeroEnergy, 0.0); // reset energy completely without changing gain
842 }
843 pCell->setTime(0.0); // reset time completely
844 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit1() & TileCell::MASK_ALGO)), 0); // reset quality flag for first pmt
845 pCell->setQuality(0, TileCell::MASK_BADCH, 1); // reset quality flag for second pmt
846
847 return true;
848
849 } else if (chStatus1.isBadTiming()) {
850 pCell->setTime(0.0); // channel with bad timing - no cell time
851 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
852 pCell->setQuality(pCell->qual1(), qbit1, 0); // update qbits for first pmt
853 }
854
855 } else { //cell has both PMTs
856
857 int gain2 = pCell->gain2();
858
859 HWIdentifier ch_id2 = m_tileHWID->channel_id(hash2);
860
861 int ros2 = m_tileHWID->ros(ch_id2);
862 int drawer2 = m_tileHWID->drawer(ch_id2);
863 int chan2 = m_tileHWID->channel(ch_id2);
864
865 HWIdentifier adc_id2 = m_tileHWID->adc_id(ros2, drawer2, chan2, ((gain2 < 0) ? 1 : gain2));
866 const TileBchStatus& chStatus2 = badChannels->getAdcStatus(adc_id2);
867
868 // check quality first
869 bool bad2 = ((int) pCell->qual2() > m_qualityCut);
870 if (bad2) {
871 ++drawerEvtStatus[ros2][drawer2].nBadQuality;
872
873 } else {
874 // check bad status in DB
875 bad2 = (gain2 < 0) || chStatus2.isBad();
876
877 // Now checking the DQ status
878 if (!bad2 && m_notUpgradeCabling && DQstatus) {
879 bad2 = !(DQstatus->isAdcDQgood(ros2, drawer2, chan2, gain2))
880 || (dcsState ? dcsState->isStatusBad(ros2, drawer2, chan2) : false);
881 }
882 }
883
884 single_PMT_C10 = (((ros2 == TileHWID::EXTBAR_POS && chan1 == 4)
885 || (ros2 == TileHWID::EXTBAR_NEG && chan2 == 4))
886 && !m_cabling->C10_connected(drawer2));
887 if (single_PMT_C10) {
888 // for special C10 disconnected channel might be masked in DB
889 // and energy of good channel is taken twice with correct weight
890 // but if this channel is not masked in DB - set its bad status
891 // equal to bad status of real channel, so that cell is masked correctly
892 // if real channel connected to a cell is bad
893#ifdef ALLOW_DEBUG_COUT
894 static int cnt=0;
895 if (++cnt < 17) {
896 std::cout << "special C10 in " << ((ros2==TileHWID::EXTBAR_POS) ? "EBA" : "EBC")
897 << drawer2+1 << " status " << chan1 << "/" << chan2 << " "
898 << (chStatus1.isBad()?"bad":"good") << "/"
899 << (chStatus2.isBad()?"bad":"good") << "/"
900 << ((m_run2plus)?" RUN2+ cabling": "RUN1 cabling")
901 << std::endl;
902 }
903#endif
904 if (chan1 == 4) {
905 if (m_run2plus || !chStatus1.isBad()) {
906#ifdef ALLOW_DEBUG_COUT
907 if (cnt < 17) {
908 std::cout << "Ene of chan1 was " << pCell->ene1() << " changing to half of " << pCell->ene2()
909 << " and setting bad1=true" << std::endl;
910 }
911#endif
912 pCell->setEnergy(pCell->ene2()/2., pCell->ene2()/2., gain2, gain2);
913 //bad1 = bad2;
914 bad1 = true;
915 --drawerEvtStatus[ros1][drawer1].nMaskedChannels; // since it's fake masking, decrease counter by 1 in advance
916 }
917 } else {
918 if (m_run2plus || !chStatus2.isBad()) {
919#ifdef ALLOW_DEBUG_COUT
920 if (cnt < 17) {
921 std::cout << "Ene of chan2 was " << pCell->ene2() << " changing to half of " << pCell->ene1()
922 << " and setting bad2=true" << std::endl;
923 }
924#endif
925 pCell->setEnergy(pCell->ene1()/2., pCell->ene1()/2., gain1, gain1);
926 //bad2 = bad1;
927 bad2 = true;
928 --drawerEvtStatus[ros2][drawer2].nMaskedChannels; // since it's fake masking, decrease counter by 1 in advance
929 }
930 }
931 }
932 if (bad1 && bad2) {
933 // both channels are bad
934 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
935 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
936
937 if (gain1 == CaloGain::INVALIDGAIN || gain2 == CaloGain::INVALIDGAIN) {
938 if (gain1 == CaloGain::INVALIDGAIN) gain1 = 0; // this is TileID::LOWGAIN; - commented out to make Coverity happy
939 if (gain2 == CaloGain::INVALIDGAIN) gain2 = 0; // this is TileID::LOWGAIN; - commented out to make Coverity happy
940 pCell->setEnergy(m_zeroEnergy, m_zeroEnergy, gain1, gain2); // reset energy completely, indicate problem putting low gain
941 } else {
942 pCell->setEnergy(m_zeroEnergy, m_zeroEnergy); // reset energy completely without changing gain
943 }
944 pCell->setTime(0.0); // reset time completely
945 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit1() & TileCell::MASK_ALGO)), 0); // reset quality flag for first pmt
946 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit2() & TileCell::MASK_ALGO)), 1); // reset quality flag for second pmt
947
948 return true;
949
950 } else if (bad1 && !bad2) {
951 // first channel is bad
952 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
953
954 float ene2 = pCell->ene2();
955 pCell->setEnergy(ene2, ene2, gain2, gain2); // use energy/gain from second pmt for both pmts
956
957 uint8_t qualCorrection = (gain1 != CaloGain::INVALIDGAIN) ? (gain1 - gain2) : 0;
958 uint8_t qual2 = pCell->qual2();
959 uint8_t qual1 = qual2 + qualCorrection; // if gains are different, qua11 and qual2 will be different
960 if (qual1 > m_qualityCut && gain1 > gain2) qual1 = qual2 - qualCorrection; // new feature in release 17.2
961
962 if (chStatus2.isBadTiming()) {
963 pCell->setTime(0.0); // time in second pmt is bad - no cell time
964 uint8_t qbit2 = pCell->qbit2() & (~(TileCell::MASK_TIME)); // clear time bit for second pmt
965 uint8_t qbit1 = qbit2 | TileCell::MASK_BADCH; // set bad channel bit for first pmt
966 pCell->setQuality(qual1, qbit1, 0); // change quality and qbits for first pmt
967 pCell->setQuality(qual2, qbit2, 1); // update qbits for second pmt
968 } else {
969 pCell->setTime(pCell->time2()); // use time from second pmt as cell time
970 pCell->setQuality(qual1, (pCell->qbit2() | TileCell::MASK_BADCH), 0); // change quality flag for first pmt
971 }
972
973 return true;
974
975 } else if (!bad1 && bad2) {
976 // second channel is bad
977 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
978
979 float ene1 = pCell->ene1();
980 pCell->setEnergy(ene1, ene1, gain1, gain1); // use energy/gain from first pmt for both pmts
981
982 uint8_t qualCorrection = (gain2 != CaloGain::INVALIDGAIN) ? (gain2 - gain1) : 0;
983 uint8_t qual1 = pCell->qual1();
984 uint8_t qual2 = qual1 + qualCorrection; // if gains are different, qua11 and qual2 will be different
985 if (qual2 > m_qualityCut && gain2 > gain1) qual2 = qual1 - qualCorrection; // new feature in release 17.2
986
987 if (chStatus1.isBadTiming()) {
988 pCell->setTime(0.0); // time in first pmt is bad - no cell time
989 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
990 uint8_t qbit2 = qbit1 | TileCell::MASK_BADCH; // set bad channel bit for second pmt
991 pCell->setQuality(qual1, qbit1, 0); // update qbits for first pmt
992 pCell->setQuality(qual2, qbit2, 1); // change quality and qbits for second pmt
993 } else {
994 pCell->setTime(pCell->time1()); // use time from first pmt as cell time
995 pCell->setQuality(qual2, (pCell->qbit1() | TileCell::MASK_BADCH), 1); // change quality flag for second pmt
996 }
997
998 return true;
999
1000 } else {
1001
1002 if (chStatus1.isBadTiming()) {
1003
1004 if (chStatus2.isBadTiming()) {
1005 pCell->setTime(0.0); // time in both pmts is bad - no cell time
1006 uint8_t qbit2 = pCell->qbit2() & (~(TileCell::MASK_TIME)); // clear time bit for second pmt
1007 pCell->setQuality(pCell->qual2(), qbit2, 1); // update qbits for second pmt
1008 } else {
1009 pCell->setTime(pCell->time2()); // use time from second pmt as cell time
1010 }
1011 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
1012 pCell->setQuality(pCell->qual1(), qbit1, 0); // update qbits for first pmt
1013
1014 } else if (chStatus2.isBadTiming()) {
1015
1016 pCell->setTime(pCell->time1()); // use time from first pmt as cell time
1017 uint8_t qbit2 = pCell->qbit2() & (~(TileCell::MASK_TIME)); // clear time bit for second pmt
1018 pCell->setQuality(pCell->qual2(), qbit2, 1); // update qbits for second pmt
1019 }
1020 }
1021
1022 }
1023
1024 return single_PMT_C10;
1025}
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
IdentifierHash onl1() const
cell online identifier 1
int gain2(void) const
get gain of second PMT
Definition TileCell.cxx:175
uint8_t qbit2(void) const
get quality bits of second PMT (data member)
Definition TileCell.h:206
int gain1(void) const
get gain of first PMT
Definition TileCell.cxx:168
float ene1(void) const
get energy of first PMT
Definition TileCell.h:187
float ene2(void) const
get energy of second PMT
Definition TileCell.h:189
@ EXTBAR_NEG
Definition TileHWID.h:71
@ EXTBAR_POS
Definition TileHWID.h:70

◆ process()

StatusCode TileCellBuilder::process ( CaloCellContainer * theCellContainer,
const EventContext & ctx ) const
overridevirtual

method to process all raw channels and store them in container

Definition at line 272 of file TileCellBuilder.cxx.

274{
275 //**
276 //* Get TileRawChannels
277 //**
278
279 TileDrawerEvtStatusArray drawerEvtStatus;
280
281 SG::ReadHandle<TileRawChannelContainer> rawChannelContainer(m_rawChannelContainerKey, ctx);
282
283 if (!rawChannelContainer.isValid()) {
284 ATH_MSG_WARNING( " Could not find container " << m_rawChannelContainerKey.key() );
285 ATH_MSG_WARNING( " do not fill CaloCellContainer " );
286
287 } else {
288
289 ATH_MSG_DEBUG( "Container " << m_rawChannelContainerKey.key() << " with TileRawChannels found ");
290
291
293 params.m_RChType = rawChannelContainer->get_type();
294 params.m_RChUnit = rawChannelContainer->get_unit();
295 params.m_correctAmplitude = m_correctAmplitude;
296 params.m_correctTime = m_correctTime;
297 params.m_of2 = m_of2;
298 unsigned int bsflags = rawChannelContainer->get_bsflags();
299 if (params.m_correctAmplitude || params.m_correctTime) {
300 int DataType = (bsflags & 0x30000000) >> 28;
301 if (DataType < 3) { // real data
302 bool of2 = ((bsflags & 0x4000000) != 0);
303 if (of2 != params.m_of2) {
304 params.m_of2 = of2;
305 ATH_MSG_WARNING( "OF2 flag in data is " << ((params.m_of2)?"True":"False"));
306 }
307 params.m_maxTimeCorr = 63.9375; // 64-1/16 ns is hard limit in DSP
308 if (params.m_correctAmplitude && ((bsflags & 0x3000000) != 0)) {
309 ATH_MSG_WARNING( "Using results of Opt filter with interations from DSP, disabling amplitude correction" );
310 params.m_correctAmplitude = false;
311 }
312 if (params.m_correctTime && ((bsflags & 0x3000000) == 0)) {
313 ATH_MSG_WARNING( "Using results of Opt filter without interations from DSP, disabling time correction" );
314 params.m_correctTime = false;
315 }
316 } else {
317 params.m_maxTimeCorr = ((bsflags >> 27) & 1) ? 100.0 : 75.0; // 100 or 75 ns is the limit for 9 or 7 samples
318 if (params.m_correctAmplitude && ((bsflags & 0x6000) != 0)) {
319 ATH_MSG_WARNING( "Amplitude correction was done already in optimal filter, disabling it here" );
320 params.m_correctAmplitude = false;
321 }
322 if (params.m_correctTime && ((bsflags & 0x9000) != 0)) {
323 ATH_MSG_WARNING( "Time correction was done already in optimal filter or best phase is used, disabling it here" );
324 params.m_correctTime = false;
325 }
326 }
327 }
328
329 std::unique_ptr<TileCellContainer> MBTSCells;
330 if (!m_MBTSContainerKey.key().empty()) {
331 MBTSCells = std::make_unique<TileCellContainer>(SG::VIEW_ELEMENTS);
332 }
333
334 std::unique_ptr<TileCellContainer> E4prCells;
335 if (!m_E4prContainerKey.key().empty()) {
336 E4prCells = std::make_unique<TileCellContainer>(SG::VIEW_ELEMENTS);
337 }
338
340 SelectAllObject<TileRawChannelContainer>::const_iterator begin = selAll.begin();
341 SelectAllObject<TileRawChannelContainer>::const_iterator end = selAll.end();
342
345 && !m_dspRawChannelContainerKey.key().empty()) {
346
347 ATH_MSG_DEBUG( "Merging " << m_rawChannelContainerKey.key()
348 << " and " << m_dspRawChannelContainerKey.key() );
349
350 SG::ReadHandle<TileRawChannelContainer> dspRawChannelContainer(m_dspRawChannelContainerKey, ctx);
351
352 if (!dspRawChannelContainer.isValid()) {
353 // no DSP channels, build cells from primary container
354 ATH_MSG_DEBUG( " No " << m_dspRawChannelContainerKey.key() << " found, nothing to merge " );
355
356 } else {
357
358 const TileRawChannelContainer* dspContainer = dspRawChannelContainer.cptr();
359 std::unique_ptr<TileMutableRawChannelContainer> copiedDspContainer;
360
361 if (m_noiseFilterTools.size() > 0) {
362 ATH_MSG_DEBUG( " Running noise filter on " << m_dspRawChannelContainerKey.key()
363 << " (i.e. on second container only) " );
364
365 // apply noise filter on dsp container before merging it with offline container
366 copiedDspContainer = std::make_unique<TileMutableRawChannelContainer> (*dspContainer);
367 ATH_CHECK( copiedDspContainer->status() );
368 dspContainer = copiedDspContainer.get();
369
370 for (const ToolHandle<ITileRawChannelTool>& noiseFilterTool : m_noiseFilterTools) {
371 ATH_CHECK( noiseFilterTool->process(*copiedDspContainer, ctx) );
372 }
373 }
374
375 TileFragHash::TYPE dspType = dspContainer->get_type();
376 TileRawChannelUnit::UNIT dspUnit = dspContainer->get_unit();
377 unsigned int dspFlags = dspContainer->get_bsflags();
378 int DataType = (dspFlags & 0x30000000) >> 28;
379 float dspTimeCut = params.m_maxTimeCorr;
380 bool dspCorrectAmplitude = false, dspCorrectTime = false, dspOf2 = true;
381 if (DataType < 3) { // real data
382 dspOf2 = ((dspFlags & 0x4000000) != 0);
383 if (dspOf2 != params.m_of2) ATH_MSG_DEBUG( "OF2 flag in DSPcontainer is " << ((dspOf2)?"True":"False"));
384 dspTimeCut = 63.9375; // 64-1/16 ns is hard limit in DSP
385 dspCorrectAmplitude = ((dspFlags & 0x3000000) == 0);
386 dspCorrectTime = ((dspFlags & 0x3000000) != 0);
387 } else { // dsp container contains results of offline reco
388 dspTimeCut = ((dspFlags >> 27) & 1) ? 100.0 : 75.0; // 100 or 75 ns is the limit for 9 or 7 samples
389 }
390
391 SelectAllObject<TileRawChannelContainer> selAllDsp(dspContainer);
392 SelectAllObject<TileRawChannelContainer>::const_iterator beginDsp = selAllDsp.begin();
393 SelectAllObject<TileRawChannelContainer>::const_iterator endDsp = selAllDsp.end();
394
395 std::vector<const TileRawChannel *> oflVec;
396 std::vector<const TileRawChannel *> dspVec;
397
398 SelectAllObject<TileRawChannelContainer>::const_iterator oflItr = begin;
399 SelectAllObject<TileRawChannelContainer>::const_iterator dspItr = beginDsp;
400
401 if (oflItr != end) {
402 const TileRawChannel *p1 = (*oflItr);
403 HWIdentifier id1 = p1->adc_HWID();
404
405 for (; dspItr != endDsp; ++dspItr) {
406
407 const TileRawChannel *p2 = (*dspItr);
408 HWIdentifier id2 = p2->adc_HWID();
409
410 if (id2 < id1) {
411 dspVec.push_back(p2);
412 } else if (id2 == id1) {
413 oflVec.push_back(p1);
414 ++oflItr;
415 if (oflItr != end) {
416 p1 = (*oflItr);
417 id1 = p1->adc_HWID();
418 } else {
419 ++dspItr;
420 break;
421 }
422 } else {
423 while (id2 >= id1) {
424 oflVec.push_back(p1);
425 ++oflItr;
426 if (oflItr != end) {
427 p1 = (*oflItr);
428 bool id2gtid1 = (id2 > id1);
429 id1 = p1->adc_HWID();
430 if (id2gtid1 && (id2 < id1)) {
431 dspVec.push_back(p2); // id2 is in the gap between old and new id1 - keep it
432 }
433 } else {
434 if (id2 == id1) ++dspItr;
435 break;
436 }
437 }
438 if (id2 >= id1) break;
439 }
440 }
441 // copy all remaining channels
442 for (; oflItr != end; ++oflItr) {
443 oflVec.push_back(*oflItr);
444 }
445 }
446 for (; dspItr != endDsp; ++dspItr) {
447 dspVec.push_back(*dspItr);
448 }
449
450 VecParams params1 = params;
451 VecParams params2;
452 params2.m_RChType = dspType;
453 params2.m_RChUnit = dspUnit;
454 params2.m_maxTimeCorr = dspTimeCut;
455 params2.m_correctAmplitude = dspCorrectAmplitude;
456 params2.m_correctTime = dspCorrectTime;
457 params2.m_of2 = dspOf2;
458
459 // build here with special iterator over 2 vectors
460 DoubleVectorIterator<std::vector<const TileRawChannel *>, const TileRawChannel *> vecBeg(
461 params,
462 &oflVec, params1,
463 &dspVec, params2, 0);
464 DoubleVectorIterator<std::vector<const TileRawChannel *>, const TileRawChannel *> vecEnd(
465 params,
466 &oflVec, params1,
467 &dspVec, params2, 2);
468
469 ATH_MSG_DEBUG("Build raw channels from two vectors:"
470 << " offline vector size = " << oflVec.size()
471 << ", dsp vector size = " << dspVec.size() );
472
473 build (ctx, drawerEvtStatus, params, vecBeg, vecEnd, theCellContainer,
474 MBTSCells.get(), E4prCells.get());
475 begin = end;
476 }
477
478 }
479
480 if (begin != end) { // no merging applied, use original raw channel container
481
482 std::unique_ptr<TileMutableRawChannelContainer> copiedContainer;
483 std::unique_ptr<SelectAllObject<TileRawChannelContainer> > selCopied;
484
485 if (m_noiseFilterTools.size() > 0) {
486 ATH_MSG_DEBUG( " Running noise filter on " << m_rawChannelContainerKey.key() );
487 // apply noise filter on input container before sending it to the build() method
488 copiedContainer = std::make_unique<TileMutableRawChannelContainer> (*rawChannelContainer);
489 ATH_CHECK( copiedContainer->status() );
490
491 for (const ToolHandle<ITileRawChannelTool>& noiseFilterTool : m_noiseFilterTools)
492 {
493 ATH_CHECK( noiseFilterTool->process(*copiedContainer, ctx) );
494 }
495
496 selCopied = std::make_unique<SelectAllObject<TileRawChannelContainer> > (copiedContainer.get());
497 begin = selCopied->begin();
498 end = selCopied->end();
499 }
500
501 ATH_MSG_DEBUG( " Calling build() method for rawChannels from " << m_rawChannelContainerKey.key() );
502 build (ctx, drawerEvtStatus, params, begin, end, theCellContainer,
503 MBTSCells.get(), E4prCells.get());
504 }
505
506 if (!m_MBTSContainerKey.key().empty()) {
507 SG::WriteHandle<TileCellContainer> MBTSContainer(m_MBTSContainerKey, ctx);
508 ATH_CHECK( MBTSContainer.record(std::move(MBTSCells)) );
509 }
510
511 if (!m_E4prContainerKey.key().empty()) {
512 SG::WriteHandle<TileCellContainer> E4prContainer(m_E4prContainerKey, ctx);
513 ATH_CHECK( E4prContainer.record(std::move(E4prCells)) );
514 }
515
517
518 //specify that a given calorimeter has been filled
519 theCellContainer->setHasCalo(caloNum);
520 }
521
522 //enum EventFlagErrorState { NotSet, Warning, Error };
524 // flag will contain status of a given event
525 // every 4 bits - status of partitions LBA,LBC,EBA,EBC
526 // bits 0-3 - there is a signal above threshold in partitions
527 // bits 4-7 - there are channels with underflow (sample=0) in partition (since rel 17.2.6.4)
528 // bits 8-11 - there are channels with overflow (sample=m_tileInfo->ADCmax()) in partition (since rel 17.2.6.4)
529 // bits 12-15 - there are at least 16 drawers with bad quality in partition
530 // bits 16-19 - maximal length of consecutive bad area (since rel 17.2.6.5)
531 // bits 20-23 - there are at least 16 drawers which are completely masked in partition
532 // bits 24-27 - there are at least 16 drawers which do not send data in partition
533 // bits 28-31 - reserved for global good/warning/bad status
534 // bits 20-27 are also used for module number which gives warning status (since release 17.2.6.5)
535 // in case of warning we are sure that bits which indicates error are not filled
536 unsigned int flag = 0;
537
538 int drConsecMaxMax = 0;
539 int drConsecNum = 0;
540
541 for (int p = 1; p < 5; ++p) {
542 TileDrawerEvtStatus * evt = drawerEvtStatus[p];
543 //TileDrawerRunStatus * run = m_drawerRunStatus[p];
544 int drAbsent = 0;
545 int drMasked = 0;
546 int drConsec = 0;
547 int drConsecMax = 0;
548 int hasBadQ = 0;
549 int hasOver = 0;
550 int hasUnder = 0;
551 int hasSig = 0;
552 for (int d = 0; d < 64; ++d) {
553 if (evt[d].nChannels == 0) {
554 ++drConsec;
555 ++drAbsent;
556 //++(run[d].drawerAbsent);
557 } else if (evt[d].nMaskedChannels >= evt[d].nChannels) {
558 ++drConsec;
559 ++drMasked;
560 //++(run[d].drawerMasked);
561 } else {
562 if (drConsec > drConsecMax) {
563 drConsecMax = drConsec;
564 if (drConsecMax > drConsecMaxMax) {
565 drConsecMaxMax = drConsecMax;
566 drConsecNum = ((p - 1) << 6) | (d - drConsec);
567 }
568 }
569 drConsec = 0;
570 if (evt[d].nMaskedChannels > 0) {
571 //++(run[d].channelsMasked);
572 }
573 if (evt[d].nBadQuality) ++hasBadQ;
574 if (evt[d].nOverflow) ++hasOver;
575 if (evt[d].nUnderflow) ++hasUnder;
576 if (evt[d].nSomeSignal) ++hasSig;
577 }
578 }
579 if (drConsec != 0 && drConsecMax < 64) { // 64th drawer is bad - check transition from 64th to 1st drawer
580 for (int d = 0; d < drConsecMax; ++d) {
581 if (evt[d].nChannels == 0 || evt[d].nMaskedChannels >= evt[d].nChannels) {
582 ++drConsec;
583 } else {
584 break;
585 }
586 }
587 if (drConsec > drConsecMax) {
588 drConsecMax = drConsec;
589 }
590 }
591 unsigned int fl = 0;
592 if (drAbsent > 15) {
593 fl |= 0x01000000;
595 }
596 if (drMasked > 15) {
597 fl |= 0x00100000;
599 }
600 //if (drConsecMax > 1)fl |= 0x00010000; // want to use these bits for length of consecutive area
601 if (hasBadQ > 15) fl |= 0x00001000;
602 if (hasOver) fl |= 0x00000100;
603 if (hasUnder) fl |= 0x00000010;
604 if (hasSig) fl |= 0x00000001;
605
606#ifdef ALLOW_DEBUG_COUT
607 std::cout<<"partition "<<p<<" drAbsent "<<drAbsent<<" drMasked "<<drMasked<<" drConsec "<<drConsecMax
608 <<" hasBadQ "<<hasBadQ<<" hasOver "<<hasOver<<" hasUnder "<<hasUnder<<" hasSig "<<hasSig<<std::endl;
609#endif
610 flag |= fl << (p - 1);
611 }
612
613 // number of consecutively masked modules (if it's > 15 we have error already set)
614 flag |= (std::min(15, drConsecMaxMax) << 16);
615
616 if (drConsecMaxMax > 1 && error < xAOD::EventInfo::Warning) {
617 // setting warning flag
619 // putting starting module number of consecutive bad area
620 // instead of bits which indicates 16 masked or 16 absent modules in partition
621 flag |= (drConsecNum << 20);
622#ifdef ALLOW_DEBUG_COUT
623 std::cout<<"warning in partition " << (drConsecNum>>6)+1 << " for modules "
624 <<(drConsecNum)%64 <<" - " <<(drConsecNum+drConsecMaxMax-1)%64 <<std::endl;
625#endif
626 }
627
628#ifdef ALLOW_DEBUG_COUT
629 std::cout<<"partition flag 0x0"<<std::hex<<flag<<std::dec<<" error "<<error<<std::endl;
630#endif
631
632 //++m_eventErrorCounter[error]; // error index is 0 or 1 or 2 here
633 //++m_eventErrorCounter[3]; // count separately total number of events
634
635
636 // retrieve EventInfo
637 SG::ReadHandle<xAOD::EventInfo> eventInfo(m_eventInfoKey, ctx);
638
639 if (eventInfo.isValid()) {
640
641 if (flag != 0) {
642 ATH_MSG_DEBUG( " set eventInfo for Tile for this event to 0x" << MSG::hex << flag << MSG::dec );
643 if (!eventInfo->updateEventFlags(xAOD::EventInfo::Tile, flag)) {
644 ATH_MSG_WARNING( " cannot set eventInfo for Tile " );
645 }
646 }
647
648 if (error != xAOD::EventInfo::NotSet) {
649 ATH_MSG_DEBUG( " set error bits for Tile for this event to " << error );
650 if (!eventInfo->updateErrorState(xAOD::EventInfo::Tile, error)) {
651 ATH_MSG_WARNING( " cannot set error state for Tile " );
652 }
653 }
654
655 }
656 else {
657 ATH_MSG_WARNING( " cannot retrieve EventInfo, will not set Tile information " );
658 }
659
660 // Execution completed.
661 ATH_MSG_DEBUG( "TileCellBuilder execution completed." );
662
663 return StatusCode::SUCCESS;
664}
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
HWIdentifier id2
SelectAllObjectMT< DCC, OBJECT > SelectAllObject
Athena::TPCnvVers::Old Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current TileRawChannelContainer
void setHasCalo(const CaloCell_ID::SUBCALO caloNum)
set which calo has been filled.
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
TileDrawerEvtStatus TileDrawerEvtStatusArray[5][64]
status of every drawer
void build(const EventContext &ctx, TileDrawerEvtStatusArray &drawerEvtStatus, VecParams &params, const ITERATOR &begin, const ITERATOR &end, COLLECTION *coll, TileCellContainer *MBTSCells, TileCellContainer *E4prCells) const
< method to process raw channels from a given vector and store them in collection
TYPE
initialize
uint32_t get_bsflags() const
@ Tile
The Tile calorimeter.
EventFlagErrorState
States that a given sub-detector could be in.
@ Warning
The sub-detector issued a warning.
@ NotSet
The flag was not set to anything.
@ Error
The sub-detector issued an error.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
bool flag
Definition master.py:29
TileFragHash::TYPE m_RChType

◆ qbits()

unsigned char TileCellBuilder::qbits ( TileDrawerEvtStatusArray & drawerEvtStatus,
TileFragHash::TYPE RChType,
int ros,
int drawer,
bool count_over,
bool good_time,
bool good_ener,
bool overflow,
bool underflow,
bool good_overflowfit ) const
private

method to compute the cell quality bits

Definition at line 697 of file TileCellBuilder.cxx.

707{
708 ++drawerEvtStatus[ros][drawer].nChannels;
709 // new feature in rel 17.2.7 - count underflows and overflows
710 if (count_over) {
711 if (overflow) ++drawerEvtStatus[ros][drawer].nOverflow;
712 if (underflow) ++drawerEvtStatus[ros][drawer].nUnderflow;
713 }
714#ifdef ALLOW_DEBUG_COUT
715 if (overflow) std::cout << "channel with overflow " << ((count_over)?"":"MBTS") << std::endl;
716 if (underflow) std::cout << "channel with underflow " << ((count_over)?"":"MBTS") << std::endl;
717 if (overfit) std::cout << "channel with corrected overflow " << ((count_over)?"":"MBTS") << std::endl;
718#endif
719
720 unsigned char qbit = (overfit) ? (TileFragHash::FitFilter & TileCell::MASK_ALGO)
721 : (RChType & TileCell::MASK_ALGO);
722 if (good_time) qbit |= TileCell::MASK_TIME;
723 if (overflow || underflow) qbit |= TileCell::MASK_OVER;
724
725 if (good_ener) {
726 qbit |= TileCell::MASK_AMPL;
727 if (count_over) {
728 ++drawerEvtStatus[ros][drawer].nSomeSignal;
729 }
730 }
731
732 return qbit;
733}
@ MASK_AMPL
Definition TileCell.h:65
@ MASK_OVER
Definition TileCell.h:64

◆ reset()

void TileCellBuilder::reset ( bool fullSizeCont,
bool printReset = true )

Method to reset the options of the TileCellContainer.

Definition at line 236 of file TileCellBuilder.cxx.

236 {
237
238 if (printReset) ATH_MSG_INFO( "Resetting options in " << name() );
239
240 // check if any threshold was set in jobOptions
241 m_thresholdNotSet = ((fabs(m_eThreshold + 100000.) < 1)
242 && (fabs(m_maxTimeDiff - 100000.) < 1)
243 && (fabs(m_maxTime - 100000.) < 1)
244 && (fabs(m_minTime + 100000.) < 1)
245 && (fabs(m_maxChi2 - 100000.) < 1)
246 && (fabs(m_minChi2 + 100000.) < 1));
247
248 if (m_thresholdNotSet) {
249 ATH_MSG_INFO( "none of thresholds set, all RawChannels will be converted to Cells");
250 } else {
251 ATH_MSG_INFO( "Ene threshold " << m_eThreshold << " MeV" );
252 ATH_MSG_INFO( "max time diff " << m_maxTimeDiff << " ns" );
253 ATH_MSG_INFO( "max time thr " << m_maxTime << " ns" );
254 ATH_MSG_INFO( "min time thr " << m_minTime << " ns" );
255 ATH_MSG_INFO( "max qual thr " << m_maxChi2 );
256 ATH_MSG_INFO( "min qual thr " << m_minChi2 );
257 }
258
259 // prepare empty vector for all cell pointers
260 m_fullSizeCont = true;
261
262 ATH_MSG_INFO( "taking RawChannels from '" << m_rawChannelContainerKey.key() << "'" );
263}

◆ TileHid2RESrcID

friend class TileHid2RESrcID
friend

Definition at line 130 of file TileCellBuilder.h.

Member Data Documentation

◆ m_ADCmaskValueMinusEps

float TileCellBuilder::m_ADCmaskValueMinusEps
private

Definition at line 396 of file TileCellBuilder.h.

◆ m_ADCmaskValuePlusEps

float TileCellBuilder::m_ADCmaskValuePlusEps
private

Definition at line 397 of file TileCellBuilder.h.

◆ m_affectedRegionInfo_current_run

std::vector<CaloAffectedRegionInfo> TileCellBuilder::m_affectedRegionInfo_current_run
private

Definition at line 246 of file TileCellBuilder.h.

◆ m_affectedRegionInfo_global

std::vector<CaloAffectedRegionInfo> TileCellBuilder::m_affectedRegionInfo_global
private

Definition at line 245 of file TileCellBuilder.h.

◆ m_ampMinThresh

float TileCellBuilder::m_ampMinThresh
private

correct amplitude if it's above amplitude threshold (in ADC counts)

Definition at line 179 of file TileCellBuilder.h.

◆ m_badChannelsKey

SG::ReadCondHandleKey<TileBadChannels> TileCellBuilder::m_badChannelsKey
private
Initial value:
{this,
"TileBadChannels", "TileBadChannels", "Input Tile bad channel status"}

Name of TileBadChannels in condition store.

Definition at line 206 of file TileCellBuilder.h.

206 {this,
207 "TileBadChannels", "TileBadChannels", "Input Tile bad channel status"};

◆ m_cabling

const TileCablingService* TileCellBuilder::m_cabling
private

TileCabling instance.

Definition at line 201 of file TileCellBuilder.h.

◆ m_cablingSvc

ServiceHandle<TileCablingSvc> TileCellBuilder::m_cablingSvc
private
Initial value:
{ this,
"TileCablingSvc", "TileCablingSvc", "The Tile cabling service"}

Name of Tile cabling service.

Definition at line 230 of file TileCellBuilder.h.

230 { this,
231 "TileCablingSvc", "TileCablingSvc", "The Tile cabling service"};

◆ m_checkDCS

bool TileCellBuilder::m_checkDCS
private

Definition at line 196 of file TileCellBuilder.h.

◆ m_correctAmplitude

bool TileCellBuilder::m_correctAmplitude
private

If true, amplitude is corrected by parabolic function (needed for OF without iterations)

Definition at line 174 of file TileCellBuilder.h.

◆ m_correctTime

bool TileCellBuilder::m_correctTime
private

should time be corrected (deltat added from CondDB)

Definition at line 173 of file TileCellBuilder.h.

◆ m_DCSStateKey

SG::ReadCondHandleKey<TileDCSState> TileCellBuilder::m_DCSStateKey
private
Initial value:
{this,
"TileDCS", "TileDCS", "Input Tile DCS status"}

Name of TileDCSState object in condition store.

Definition at line 224 of file TileCellBuilder.h.

224 {this,
225 "TileDCS", "TileDCS", "Input Tile DCS status"};

◆ m_DQstatusKey

SG::ReadHandleKey<TileDQstatus> TileCellBuilder::m_DQstatusKey
private
Initial value:
{this, "TileDQstatus",
"TileDQstatus",
"TileDQstatus key"}

Definition at line 150 of file TileCellBuilder.h.

150 {this, "TileDQstatus",
151 "TileDQstatus",
152 "TileDQstatus key"};

◆ m_dspRawChannelContainer

std::string TileCellBuilder::m_dspRawChannelContainer
private

Definition at line 167 of file TileCellBuilder.h.

◆ m_dspRawChannelContainerKey

SG::ReadHandleKey<TileRawChannelContainer> TileCellBuilder::m_dspRawChannelContainerKey
private
Initial value:
{this, "TileDSPRawChannelContainer",
"TileRawChannelCnt",
"Input Tile DSP raw channel container key"}

Definition at line 140 of file TileCellBuilder.h.

140 {this, "TileDSPRawChannelContainer",
141 "TileRawChannelCnt",
142 "Input Tile DSP raw channel container key"};

◆ m_E4prContainerKey

SG::WriteHandleKey<TileCellContainer> TileCellBuilder::m_E4prContainerKey
private
Initial value:
{this, "E4prContainer",
"E4prContainer",
"Output Tile E4 prime container key"}

Definition at line 158 of file TileCellBuilder.h.

158 {this, "E4prContainer",
159 "E4prContainer",
160 "Output Tile E4 prime container key"};

◆ m_emScaleKey

SG::ReadCondHandleKey<TileEMScale> TileCellBuilder::m_emScaleKey
private
Initial value:
{this,
"TileEMScale", "TileEMScale", "Input Tile EMS calibration constants"}

Name of TileEMScale in condition store.

Definition at line 212 of file TileCellBuilder.h.

212 {this,
213 "TileEMScale", "TileEMScale", "Input Tile EMS calibration constants"};

◆ m_eneForTimeCut

float TileCellBuilder::m_eneForTimeCut
private

keep time for channels with energy above cut

Definition at line 169 of file TileCellBuilder.h.

◆ m_eneForTimeCutMBTS

float TileCellBuilder::m_eneForTimeCutMBTS
private

similar cut for MBTS in pC

Definition at line 170 of file TileCellBuilder.h.

◆ m_eThreshold

float TileCellBuilder::m_eThreshold
private

cell energy threshold to consider the cell

Definition at line 184 of file TileCellBuilder.h.

◆ m_eventInfoKey

SG::ReadHandleKey<xAOD::EventInfo> TileCellBuilder::m_eventInfoKey
private
Initial value:
{this, "EventInfo",
"EventInfo",
"EventInfo key"}

Definition at line 144 of file TileCellBuilder.h.

144 {this, "EventInfo",
145 "EventInfo",
146 "EventInfo key"};

◆ m_EventInfoTileStatusKey

SG::WriteDecorHandleKey<xAOD::EventInfo> TileCellBuilder::m_EventInfoTileStatusKey
private
Initial value:
{this, "EventInfoTileStatus",
m_eventInfoKey, "TileStatus",
"Dummy decoration key to aid scheduling"}

Definition at line 162 of file TileCellBuilder.h.

162 {this, "EventInfoTileStatus",
163 m_eventInfoKey, "TileStatus",
164 "Dummy decoration key to aid scheduling"};

◆ m_fakeCrackCells

bool TileCellBuilder::m_fakeCrackCells
private

if true=> fake E3/E4 cells added

Definition at line 193 of file TileCellBuilder.h.

◆ m_fullSizeCont

bool TileCellBuilder::m_fullSizeCont
private

Definition at line 191 of file TileCellBuilder.h.

◆ m_infoName

std::string TileCellBuilder::m_infoName
private

Definition at line 394 of file TileCellBuilder.h.

◆ m_maskBadChannels

bool TileCellBuilder::m_maskBadChannels
private

if true=> bad channels are masked

Definition at line 192 of file TileCellBuilder.h.

◆ m_maxChi2

float TileCellBuilder::m_maxChi2
private

maximum chi2 for the PMTs in the cels

Definition at line 188 of file TileCellBuilder.h.

◆ m_maxTime

float TileCellBuilder::m_maxTime
private

maximum time for the PMTs in the cels

Definition at line 186 of file TileCellBuilder.h.

◆ m_maxTimeDiff

float TileCellBuilder::m_maxTimeDiff
private

maximum time difference between the PMTs in the cell

Definition at line 185 of file TileCellBuilder.h.

◆ m_MBTSContainerKey

SG::WriteHandleKey<TileCellContainer> TileCellBuilder::m_MBTSContainerKey
private
Initial value:
{this, "MBTSContainer",
"MBTSContainer",
"Output Tile MBTS container key"}

Definition at line 154 of file TileCellBuilder.h.

154 {this, "MBTSContainer",
155 "MBTSContainer",
156 "Output Tile MBTS container key"};

◆ m_mbtsMgr

const MbtsDetDescrManager* TileCellBuilder::m_mbtsMgr
private

Pointer to MbtsDetDescrManager.

Definition at line 234 of file TileCellBuilder.h.

◆ m_mergeChannels

bool TileCellBuilder::m_mergeChannels
private

If true, missing raw channels are taken from DSP container.

Definition at line 176 of file TileCellBuilder.h.

◆ m_minChi2

float TileCellBuilder::m_minChi2
private

minimum chi2 for the PMTs in the cels

Definition at line 189 of file TileCellBuilder.h.

◆ m_minEneChan

float TileCellBuilder::m_minEneChan[3]
private

channel energy thresholds for masking (normal,gap,mbts)

Definition at line 183 of file TileCellBuilder.h.

◆ m_minTime

float TileCellBuilder::m_minTime
private

minimum time for the PMTs in the cels

Definition at line 187 of file TileCellBuilder.h.

◆ m_noiseFilterTools

ToolHandleArray<ITileRawChannelTool> TileCellBuilder::m_noiseFilterTools
private
Initial value:
{this,
"NoiseFilterTools", {}, "Tile noise filter tools"}

Definition at line 218 of file TileCellBuilder.h.

218 {this,
219 "NoiseFilterTools", {}, "Tile noise filter tools"};

◆ m_notUpgradeCabling

bool TileCellBuilder::m_notUpgradeCabling
private

Definition at line 390 of file TileCellBuilder.h.

◆ m_of2

bool TileCellBuilder::m_of2
private

If true, assume OF2 method for amplitude correction, otherwise - OF1.

Definition at line 175 of file TileCellBuilder.h.

◆ m_qualityCut

int TileCellBuilder::m_qualityCut
private

cut on channel quality (set energy to m_zeroEnergy for them)

Definition at line 172 of file TileCellBuilder.h.

◆ m_rawChannelContainerKey

SG::ReadHandleKey<TileRawChannelContainer> TileCellBuilder::m_rawChannelContainerKey
private
Initial value:
{this, "TileRawChannelContainer",
"TileRawChannelCnt",
"Input Tile raw channel container key"}

Definition at line 136 of file TileCellBuilder.h.

136 {this, "TileRawChannelContainer",
137 "TileRawChannelCnt",
138 "Input Tile raw channel container key"};

◆ m_run2

bool TileCellBuilder::m_run2
private

Definition at line 391 of file TileCellBuilder.h.

◆ m_run2plus

bool TileCellBuilder::m_run2plus
private

Definition at line 398 of file TileCellBuilder.h.

◆ m_skipGain

int TileCellBuilder::m_skipGain
private

for two-gain calib runs skip one of two gains

Definition at line 194 of file TileCellBuilder.h.

◆ m_thresholdNotSet

bool TileCellBuilder::m_thresholdNotSet
private

bool variable to check whether some threshold have been set

Definition at line 190 of file TileCellBuilder.h.

◆ m_tileHWID

const TileHWID* TileCellBuilder::m_tileHWID
private

Pointer to TileHWID.

Definition at line 200 of file TileCellBuilder.h.

◆ m_tileID

const TileID* TileCellBuilder::m_tileID
private

Pointer to TileID.

Definition at line 198 of file TileCellBuilder.h.

◆ m_tileInfo

const TileInfo* TileCellBuilder::m_tileInfo
private

Definition at line 395 of file TileCellBuilder.h.

◆ m_tileMgr

const TileDetDescrManager* TileCellBuilder::m_tileMgr
private

Pointer to TileDetDescrManager.

Definition at line 233 of file TileCellBuilder.h.

◆ m_tileTBID

const TileTBID* TileCellBuilder::m_tileTBID
private

Pointer to TileTBID.

Definition at line 199 of file TileCellBuilder.h.

◆ m_tileToolTiming

ToolHandle<TileCondToolTiming> TileCellBuilder::m_tileToolTiming
private
Initial value:
{this,
"TileCondToolTiming", "TileCondToolTiming", "Tile timing tool"}

Definition at line 215 of file TileCellBuilder.h.

215 {this,
216 "TileCondToolTiming", "TileCondToolTiming", "Tile timing tool"};

◆ m_timeMaxThresh

float TileCellBuilder::m_timeMaxThresh
private

correct amplitude is time is below time max threshold

Definition at line 181 of file TileCellBuilder.h.

◆ m_timeMinThresh

float TileCellBuilder::m_timeMinThresh
private

correct amplitude is time is above time min threshold

Definition at line 180 of file TileCellBuilder.h.

◆ m_towerE1

int TileCellBuilder::m_towerE1 = E1_TOWER
private

Definition at line 389 of file TileCellBuilder.h.

◆ m_useDemoCabling

int TileCellBuilder::m_useDemoCabling
private

Definition at line 195 of file TileCellBuilder.h.

◆ m_zeroEnergy

float TileCellBuilder::m_zeroEnergy
private

energy to store in every PMT if both PMT are bad

Definition at line 171 of file TileCellBuilder.h.


The documentation for this class was generated from the following files: