ATLAS Offline Software
TrigT1MBTS.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 
4 #include "TrigT1MBTS.h"
8 #include "TrigConfData/L1Menu.h"
9 
11 
12 
13 LVL1::TrigT1MBTS::TrigT1MBTS(const std::string& name, ISvcLocator* pSvcLocator)
14  : AthAlgorithm(name, pSvcLocator),
15  m_thresholdNumber{{0,1,2,3,4,5,6,7}, {8,9,10,11,12,13,14,15}},
16  m_thresholdNumber12{{0,1,2,3,4,5,6,7}, {8,1000,9,1000,10,1000,11,1000}} // in Run 2 the outer MBTS were reduced to 4
17 {}
18 
21 {
22  ATH_MSG_INFO("Initialising TrigT1MBTS, name = " << name());
23 
24  m_thresholds_a.clear();
25  m_thresholds_c.clear();
26  m_thresholds_short_a.clear();
27  m_thresholds_short_c.clear();
28  m_thresholds_a.resize(16,0);// set the threshold to zero here -
29  // override again further down
30  m_thresholds_c.resize(16,0);// set the threshold to zero here -
31  // override again further down
32  m_thresholds_short_a.resize(12,0);// set the threshold to zero here -
33  // override again further down
34  m_thresholds_short_c.resize(12,0);// set the threshold to zero here -
35  // override again further down
36  m_cablestarts_a.clear();
37  m_cablestarts_c.clear();
38  m_cablestarts_a.resize(16,0);// default is bit 0
39  m_cablestarts_c.resize(16,0);// default is bit 0
40 
41  // Retrieve TileTBID helper from det store
42  // (The MBTS was added to the Test Beam (TB) list.)
43  ATH_CHECK(detStore()->retrieve(m_tileTBID));
44 
45  const TrigConf::L1Menu * l1menu = nullptr;
47 
48  // MBTS
49  for (std::shared_ptr<TrigConf::L1Threshold> thr : l1menu->thresholds("MBTS")) {
50  if(thr->name() != "MBTS_A" && thr->name() != "MBTS_C") {
51  continue;
52  }
53  std::string connName = l1menu->connectorNameFromThreshold(thr->name());
54  unsigned int startbit = l1menu->connector(connName).triggerLine(thr->name()).startbit();
55  m_ThrVecSize12 = true; // TODO: check for (thresholds[0]->thresholdValueVector().size() == 12);
56  std::vector<float> hwThrValues(12, 0.0); // TODO need to add configuration access in TrigConfData/Threshold.h
57  if(thr->name() == "MBTS_A") {
58  m_cablestart_a = startbit;
59  if(m_ThrVecSize12) {
60  m_thresholds_short_a = std::move(hwThrValues);
61  } else {
62  m_thresholds_a = std::move(hwThrValues);
63  }
64  } else {
65  m_cablestart_c = startbit;
66  if(m_ThrVecSize12) {
67  m_thresholds_short_c = std::move(hwThrValues);
68  } else {
69  m_thresholds_c = std::move(hwThrValues);
70  }
71  }
72  }
73 
74  // MBTSSI
75  for (std::shared_ptr<TrigConf::L1Threshold> thr : l1menu->thresholds("MBTSSI")) {
76  //m_singleCounterInputs = true;
77  std::string thrname = thr->name();
78  // figure out module number from threshold name
79  size_t module = std::stoi(thrname.substr(6));
80  float hwValue = 0; // TODO implement access
81  std::string connName = l1menu->connectorNameFromThreshold(thr->name());
82  unsigned int startbit = l1menu->connector(connName).triggerLine(thr->name()).startbit();
83  ATH_MSG_INFO("Read " << thrname << " with voltage " << hwValue << "mV at bit " << startbit << " on " << connName);
84  // Get the discriminator threshold settings (single inputs) for the C side.
85  bool isCSide = thrname.find("MBTS_C")==0;
86  if(isCSide) {
87  if(module >= m_thresholds_c.size()) {
88  ATH_MSG_WARNING("Module number " << module << " on side C out of range");
89  } else {
90  m_thresholds_c[module] = hwValue;
91  m_cablestarts_c[module] = startbit;
92  }
93  } else if(thrname.starts_with("MBTS_A") && thrname.size()>6) {
94  // Get the discriminator threshold settings (single inputs) for the A side.
95  // figure out module number from threshold name
96  if(module >= m_thresholds_a.size()) {
97  ATH_MSG_WARNING("Module number " << module << " on side A out of range");
98  } else {
99  m_thresholds_a[module] = hwValue;
100  m_cablestarts_a[module] = startbit;
101  }
102  }
103  }
104 
105 
106  // MBTS_A, MBTS_C or MBTS_A, MBTS_C, MBTS_0, MBTS_1,...,MBTS_15 are used.
107  // Therefore thess messages are just INFO rather than warning.
108  if(m_thresholds_a.size() != 16) {
109  ATH_MSG_INFO("MBTS_A Lvl 1 single input thresholds not set. Triggers will be disabled.");
110  m_thresholds_a.clear();
111  for(size_t i=0;i<16;i++) {
112  m_thresholds_a.push_back(10000000);
113  }
114  }
115  if(m_thresholds_c.size() != 16) {
116  ATH_MSG_INFO("MBTS_C Lvl 1 single input thresholds not set. Triggers will be disabled.");
117  m_thresholds_c.clear();
118  for(size_t i=0;i<16;i++) {
119  m_thresholds_c.push_back(10000000);
120  }
121  }
122 
123  // Print out the state of this algorithm
124  if(msgLvl(MSG::INFO)) {
125  msg(MSG::INFO) << "=================== Settings ==================" << endmsg;
126  msg(MSG::INFO) << "TileTTL1ContainerName = " << m_tileTTL1ContainerName << endmsg;
127  msg(MSG::INFO) << "Sample t0 bin index = " << m_tZeroBin << endmsg;
128  msg(MSG::INFO) << "CFD fraction constant = " << m_CFD_fraction << endmsg;
129  if(m_ThrVecSize12){
130  msg(MSG::INFO) << "C side thresholds for single inputs = {";
131  for(size_t i=0;i<12;i++) {
132  msg(MSG::INFO) << m_thresholds_short_c[i];
133  if(i<11) msg(MSG::INFO) << ",";
134  }
135  msg(MSG::INFO) << "}" << endmsg;
136  msg(MSG::INFO) << "A side thresholds for single inputs = {";
137  for(size_t i=0;i<12;i++) {
138  msg(MSG::INFO) << m_thresholds_short_a[i];
139  if(i<11) msg(MSG::INFO) << ",";
140  }
141  msg(MSG::INFO) << "}" << endmsg;
142  if(msgLvl(MSG::INFO)) {
143  msg(MSG::DEBUG) << "thresholdNumber12: ";
144  for(size_t j=0;j<2;j++) {
145  for(size_t i=0;i<8;i++) {
146  msg(MSG::DEBUG) << m_thresholdNumber12[j][i];
147  if(i<7) msg(MSG::DEBUG) << ",";
148  }
149  msg(MSG::DEBUG) << endmsg;
150  }
151  }
152  } else {
153  msg(MSG::INFO) << "C side thresholds for single inputs = {";
154  for(size_t i=0;i<16;i++) {
155  msg(MSG::INFO) << m_thresholds_c[i];
156  if(i<15) msg(MSG::INFO) << ",";
157  }
158  msg(MSG::INFO) << "}" << endmsg;
159  msg(MSG::INFO) << "A side thresholds for single inputs = {";
160  for(size_t i=0;i<16;i++) {
161  msg(MSG::INFO) << m_thresholds_a[i];
162  if(i<15) msg(MSG::INFO) << ",";
163  }
164  msg(MSG::INFO) << "}" << endmsg;
165  }
166 
167  msg(MSG::DEBUG) << "thresholdNumber: " << endmsg;
168  for(size_t j=0;j<2;j++) {
169  for(size_t i=0;i<8;i++) {
170  msg(MSG::DEBUG) << m_thresholdNumber[j][i];
171  if(i<7) msg(MSG::DEBUG) << ",";
172  }
173  msg(MSG::DEBUG) << endmsg;
174  }
175  msg(MSG::INFO) << "===============================================" << endmsg;
176  }
177  return StatusCode::SUCCESS;
178 }
179 
182 {
183  // Retrieve the TileTTL1 container that contains the input MBTS information.
184  const TileTTL1Container* tileTTL1MBTSContainer{nullptr};
185  StatusCode sc = evtStore()->retrieve(tileTTL1MBTSContainer, m_tileTTL1ContainerName);
186  if( sc.isFailure() || !tileTTL1MBTSContainer ) {
187  ATH_MSG_WARNING(m_tileTTL1ContainerName << " not found. This event will be skipped.");
188  return StatusCode::SUCCESS;
189  }
190 
191  // Check for previous bug: there should be 24 or less depending on
192  // the configuration of the Tile algorithm that creates the
193  // TileTTL1MBTS container.
194  if(tileTTL1MBTSContainer->size() > 32) {
195  if(!m_badDataFound) {
196  ATH_MSG_WARNING("BAD DATA!!! tileTTL1MBTSContainer->size() = " << tileTTL1MBTSContainer->size());
197  ATH_MSG_WARNING("There should be no more than 24 TileTTL1MBTS elements in one event.");
198  ATH_MSG_WARNING("This event will be skipped. Any further bad data will be skipped.");
199  m_badDataFound = true;
200  }
201  return StatusCode::SUCCESS;
202  }
203 
204  unsigned int triggersEBA = 0; // Number of triggers in EBA
205  unsigned int triggersEBC = 0; // Number of triggers in EBC
206  unsigned int single_triggers_A = 0;
207  unsigned int single_triggers_C = 0;
208 
209  // Loop over all Lvl 1 MBTS trigger paddles
210  for(const TileTTL1 * ttl1_mbts : *tileTTL1MBTSContainer) {
211 
212  // Find out which MBTS paddle this is.
213  Identifier id = ttl1_mbts->identify();
214  if (!m_tileTBID->is_tiletb(id)) {
215  ATH_MSG_ERROR("This is not an MBTS identifier!");
216  return StatusCode::FAILURE;
217  }
218 
219  int phi = m_tileTBID->phi(id);
220  if(phi < 0 || phi > 7) {
221  ATH_MSG_ERROR("Phi value " << phi << " is out of range!");
222  return StatusCode::FAILURE;
223  }
224 
225  int channel = m_tileTBID->channel(id);
226  if(channel < 0 || channel > 1) {
227  ATH_MSG_ERROR("Channel value " << channel << " is out of range!");
228  return StatusCode::FAILURE;
229  }
230 
231  int detSide = m_tileTBID->type(id);
232  if(detSide != -1 && detSide != 1) {
233  ATH_MSG_ERROR("Side value " << detSide << " is out of range!");
234  return StatusCode::FAILURE;
235  }
236 
237  // Retrieve the MBTS signal samples.
238  const std::vector<double> & samples = ttl1_mbts->samples();
239  unsigned int numSamples = samples.size();
240  if(m_tZeroBin >= numSamples) {
241  ATH_MSG_ERROR("t0 bin index " << m_tZeroBin << " is greater than the number of bins " << numSamples);
242  return StatusCode::FAILURE;
243  }
244 
245  ATH_MSG_DEBUG("Sample [" << m_tZeroBin << "]=" << samples[m_tZeroBin]);
246  /*
247  // Only the even counters are used for RunII
248  if(channel == 1 && phi > 7 && phi%2 != 0) {
249  ATH_MSG_DEBUG("Out counter " << phi << " is not used for RunII! This counter will be skipped!");
250  continue;
251  }
252  */
253  // Single input triggers.
254  unsigned int thresholdIndex = m_thresholdNumber[channel][phi];
255  unsigned int thresholdIndex12 = m_thresholdNumber12[channel][phi];
256  if(thresholdIndex > (unsigned int)m_thresholds_c.size() || thresholdIndex > (unsigned int)m_thresholds_a.size()) {
257  ATH_MSG_ERROR("Threshold index \"" << thresholdIndex << "\" for single triggers is out of range.");
258  return StatusCode::FAILURE;
259  }
260 
261  if(thresholdIndex12 == 1000){
262  ATH_MSG_DEBUG("this is a needless counter for run2, the sample will be skipped!");
263  continue;
264  }
265 
266  // Emulate CFD samples[m_tZeroBin]*m_CFD_fraction
267  float ThrValue_a = 0;
268  float ThrValue_c = 0;
269  if(m_ThrVecSize12) {
270  ThrValue_a = m_thresholds_short_a[thresholdIndex12];
271  ThrValue_c = m_thresholds_short_c[thresholdIndex12];
272  } else {
273  ThrValue_a = m_thresholds_a[thresholdIndex];
274  ThrValue_c = m_thresholds_c[thresholdIndex];
275  }
276 
277  if((samples[m_tZeroBin]*m_CFD_fraction > ThrValue_c && detSide == -1) ||
278  (samples[m_tZeroBin]*m_CFD_fraction > ThrValue_a && detSide == 1))
279  {
280  // Add the trigger bit to the correct trigger word
281  if(detSide == -1)
282  { // EBC
283  single_triggers_C += (1<<m_cablestarts_c[thresholdIndex]);
284  triggersEBC++; // Increment the number of EBC triggers
285  }
286  else if (detSide == 1)
287  { // EBA
288  single_triggers_A += (1<<m_cablestarts_a[thresholdIndex]);
289  triggersEBA++; // Increment the number of EBA triggers.
290  }
291 
292  ATH_MSG_DEBUG( "Single input triggered on sample " << m_tZeroBin << " of " << numSamples << " bins.");
293  }
294  }
295 
296  // Cropping to 3 bits
297  if (triggersEBA>7) triggersEBA=7;
298  if (triggersEBC>7) triggersEBC=7;
299 
300  ATH_MSG_DEBUG( "Multis: "<< triggersEBA <<" and "<< triggersEBC );
301 
302  unsigned int cableWordA = single_triggers_A + (triggersEBA<<m_cablestart_a);
303  unsigned int cableWordC = single_triggers_C + (triggersEBC<<m_cablestart_c);
304 
305  // Record the CTP trigger word in StoreGate.
306  MbtsCTP *mbtsACTP = new MbtsCTP(cableWordA);
307  MbtsCTP *mbtsCCTP = new MbtsCTP(cableWordC);
308 
309  // Methods used in CTPsimulation are added for testing
310  ATH_MSG_DEBUG( " (in CTPSimulation) mbtsA cable word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << mbtsACTP->cableWord0() );
311  ATH_MSG_DEBUG( " (in CTPSimulation) Mult of mbtsA is: "<< static_cast<int>( (mbtsACTP->cableWord0() >> m_cablestart_a) & static_cast<unsigned int>( pow( 2, 3 ) - 1 ) ) );
312  ATH_MSG_DEBUG( " mbtsC cable " << mbtsCCTP->print() );
313  ATH_MSG_DEBUG( " (in CTPSimulation) mbtsC cable word 0 is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << mbtsCCTP->cableWord0() );
314  ATH_MSG_DEBUG( " (in CTPSimulation) Mult of mbtsC is: "<< static_cast<int>( (mbtsCCTP->cableWord0() >> m_cablestart_c) & static_cast<unsigned int>( pow( 2, 3 ) - 1 ) ) );
315 
316  ATH_CHECK(evtStore()->record(mbtsACTP, DEFAULT_MbtsACTPLocation, false));
317  ATH_CHECK(evtStore()->record(mbtsCCTP, DEFAULT_MbtsCCTPLocation, false));
318 
319  return StatusCode::SUCCESS;
320 }
321 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:24
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
LVL1::TrigT1MBTS::initialize
StatusCode initialize()
Definition: TrigT1MBTS.cxx:20
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TileTTL1
Definition: TileTTL1.h:26
TrigConf::L1Menu
L1 menu configuration.
Definition: L1Menu.h:28
LVL1::TrigT1MBTS::execute
StatusCode execute()
Definition: TrigT1MBTS.cxx:181
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
TrigT1MBTS.h
TrigT1StoreGateKeys.h
python.PyAthena.module
module
Definition: PyAthena.py:131
IBLCalibrationConfig.thr
thr
Definition: IBLCalibrationConfig.py:39
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LVL1::MbtsCTP
MBTS input class to the CTP simulation.
Definition: MbtsCTP.h:27
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
AthAlgorithm
Definition: AthAlgorithm.h:47
TrigConf::name
Definition: HLTChainList.h:35
LVL1::TrigT1MBTS::TrigT1MBTS
TrigT1MBTS(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TrigT1MBTS.cxx:13
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
LVL1::MbtsCTP::cableWord0
uint32_t cableWord0(void) const
Returns an unsigned integer trigger word containing two 3bit trigger multiplicities: backward and for...
Definition: MbtsCTP.h:37
MbtsCTP.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.Constants.INFO
int INFO
Definition: Control/AthenaCommon/python/Constants.py:15
DEBUG
#define DEBUG
Definition: page_access.h:11
python.XMLReader.l1menu
l1menu
Definition: XMLReader.py:73
TileTBID.h
L1Menu.h
TileContainer.h
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
TileContainer
Definition: TileContainer.h:38
LVL1::MbtsCTP::print
const std::string print() const
print object content in a human readable form to string
Definition: MbtsCTP.cxx:30
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
Identifier
Definition: IdentifierFieldParser.cxx:14