ATLAS Offline Software
ResultBuilder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Local includes:
6 #include "./ResultBuilder.h"
8 #include "./CTPUtil.h"
9 #include "./CTPTriggerItem.h"
10 #include "./SpecialTrigger.h"
11 
12 // eformat for data fragments:
13 #include "eformat/eformat.h"
14 #include "eformat/SourceIdentifier.h"
15 
16 // Output to the DAQ:
17 #include "TrigT1Result/Header.h"
18 #include "TrigT1Result/Trailer.h"
19 
20 // random number generator
21 #include "CLHEP/Random/RandomEngine.h"
22 #include "CLHEP/Random/RandFlat.h"
23 
24 // L1 configuration data
26 
27 // STL includes:
28 #include <vector>
29 #include <map>
30 
31 using namespace std;
32 
34  const std::string& name,
35  const IInterface* parent )
37 {
38  m_ctpDataFormat = new CTPdataformatVersion(m_ctpVersionNumber);
39 }
40 
41 
43  delete m_ctpDataFormat;
44  for(auto & x : m_internalTrigger) {
45  delete x.second;
46  }
47 }
48 
49 
52 {
53  ATH_MSG_DEBUG( "Set configuration with CTP version " << m_ctpVersionNumber );
54 
55  return createTriggerConfigMaps(l1menu);
56 }
57 
58 
61 {
62  ATH_MSG_DEBUG("Creating trigger configuration maps from run-3-style menu");
63 
64  std::vector<unsigned int> bg{1};
65  std::vector<unsigned int> bgEmpty{1};
66 
67  // declare internal bunch group triggers
68  for (size_t i = 0; i < 16; ++i) {
69  auto bgrp = new BunchGroupTrigger(i, bg, m_ctpDataFormat);
70  m_internalTrigger[ bgrp->name() ] = bgrp;
71  }
72 
73  // declare internal random triggers
74  for(int rndmIdx = 0; rndmIdx<4; rndmIdx++) {
75  auto rndm = new RandomTrigger(rndmIdx, m_ctpDataFormat);
76  m_internalTrigger[ rndm->name() ] = rndm;
77  }
78 
79  // build map of name to ctp thresholds
80  m_thrConfigMap = std::make_unique<ThresholdMap>( &l1menu );
81 
82  // build map of name to ctp items
83  m_itemConfigMap = std::make_unique<ItemMap>( &l1menu );
84 
85  return StatusCode::SUCCESS;
86 }
87 
89 LVL1CTP::ResultBuilder::constructTIPVector( const std::map<std::string, unsigned int> & thrMultiMap,
90  std::vector<uint32_t> & tip ) const
91 {
92  tip.resize( m_ctpDataFormat->getTIPwords(), 0 );
93 
94  for( auto & entry : thrMultiMap ) {
95  const std::string & thrName = entry.first;
96  size_t multiplicity = entry.second;
97 
98  // if multiplicity is 0 then there is nothing to set
99  if(multiplicity==0) {
100  continue;
101  }
102 
103  auto x = m_internalTrigger.find(thrName);
104  if(x != m_internalTrigger.end()) {
105  // internal triggers (BGRP or RNDM)
106 
107  size_t wordNr = m_ctpDataFormat->getTIPwords() - 1; // internal triggers are stored in the last word
108  size_t posWithinWord = x->second->pitPos() % 32;
109 
110  tip[wordNr] |= ( 1L << posWithinWord );
111 
112  } else {
113  // all other trigger threshold multiplicities
114 
115  const CTPTriggerThreshold & ctpTT = m_thrConfigMap->getCTPThreshold( thrName );
116  size_t startBit = ctpTT.startBit();
117  size_t nBits = ctpTT.endBit() - startBit + 1;
118 
119  // restrict to the maximum possible multiplicity
120  if(multiplicity >= (1U<<nBits)) {
121  multiplicity = (1U<<nBits)-1;
122  }
123 
124  size_t wordNr = startBit / 32;
125  size_t posWithinWord = startBit % 32;
126 
127  uint64_t result = multiplicity; // need 64 bit in case the word boundary is crossed by the threshold start..end
128  result <<= posWithinWord;
129 
130  tip[wordNr] |= result & 0xFFFFFFFF;
131  if(wordNr+1 < m_ctpDataFormat->getTIPwords()-1) {
132  tip[wordNr+1] |= uint32_t((result & 0xFFFFFFFF00000000) >> 32);
133  }
134  }
135  }
136 
137  size_t wrdNr(0);
138  for( uint32_t word : tip ) {
139  ATH_MSG_DEBUG( "REGTEST - " << "TIP word #" << std::dec << wrdNr++
140  << " is: 0x" << std::hex << std::setw( 8 ) << std::setfill( '0' ) << word );
141  }
142 
143  return StatusCode::SUCCESS;
144 }
145 
146 
147 
149 LVL1CTP::ResultBuilder::buildItemDecision( const std::map<std::string, unsigned int> & thrMultiMap,
150  std::map<std::string, unsigned int> & itemDecisionMap,
151  CLHEP::HepRandomEngine* rndmEngine ) const
152 {
153  // build trigger result for all items
154  itemDecisionMap.clear();
155 
156  try {
157  for( const auto & itemName : m_itemConfigMap->itemNames() ) {
158  auto ctpItem = m_itemConfigMap->getItem(itemName);
159 
160  bool pass_beforePrescale = ctpItem->evaluate(thrMultiMap);
161  bool pass_afterPrescale = false;
162  bool pass_afterVeto = false;
163 
164  if ( pass_beforePrescale ) {
165  long random = CLHEP::RandFlat::shootInt( rndmEngine, pow(2,24) );
166  int32_t cut = TrigConf::PrescaleSet::getCutFromPrescale( m_itemConfigMap->getItem( itemName )->prescale() );
167  pass_afterPrescale = (random >= cut) && (cut > 0); // no pass if PS set to "-1"
168  pass_afterVeto = pass_afterPrescale; // dead time is not simulated
169  }
170 
171  unsigned int result = (pass_beforePrescale ? TBP : 0) + (pass_afterPrescale ? TAP : 0) + (pass_afterVeto ? TAV : 0);
172 
173  itemDecisionMap[itemName] = result;
174  }
175  } catch (TrigConf::LogicParsingException & ex) {
176  ATH_MSG_FATAL("Error in evaluating logic. " << ex.msg());
177  return StatusCode::FAILURE;
178  }
179  return StatusCode::SUCCESS;
180 }
181 
183 LVL1CTP::ResultBuilder::constructResultVectors( const std::map<std::string, unsigned int> & itemDecisionMap,
184  std::vector<uint32_t> & tbp, std::vector<uint32_t> & tap, std::vector<uint32_t> & tav,
185  unsigned char & triggerType ) const
186 {
187  tbp.resize( m_ctpDataFormat->getTBPwords(), 0 );
188  tap.resize( m_ctpDataFormat->getTAPwords(), 0 );
189  tav.resize( m_ctpDataFormat->getTAVwords(), 0 );
190  triggerType = 0;
191 
192  for( auto & entry : itemDecisionMap ) {
193  const std::string & itemName = entry.first;
194  unsigned int result = entry.second;
195  bool passBP = (result & TBP) != 0;
196  bool passAP = (result & TAP) != 0;
197  bool passAV = (result & TAV) != 0;
198 
199 
200 
201 
202  auto l1Item = m_itemConfigMap->getItem( itemName );
203 
204  if( passAV ) {
205  triggerType |= l1Item->triggerType();
206  }
207 
208  auto ctpId = l1Item->ctpId();
209  unsigned int wordNr = ctpId / 32;
210  unsigned int posWithinWord = ctpId % 32;
211 
212  if( passBP ) { tbp[wordNr] |= 1L << posWithinWord; }
213  if( passAP ) { tap[wordNr] |= 1L << posWithinWord; }
214  if( passAV ) { tav[wordNr] |= 1L << posWithinWord; }
215 
216  ATH_MSG_DEBUG( " --> Trigger item " << itemName <<
217  " is " << ( !passBP ? "INACTIVE" : ( passAV ? "ACTIVE" : "ACTIVE (but PRESCALED)" ) ) );
218  }
219  ATH_MSG_DEBUG( "REGTEST - " << "TriggerType byte is: 0x" << std::setw( 2 ) << std::setfill( '0' ) << std::hex << int(triggerType) );
220 
221  return StatusCode::SUCCESS;
222 }
223 
224 
225 
226 
227 std::unique_ptr<LVL1CTP::CTPSLink>
228 LVL1CTP::ResultBuilder::constructRoIResult( const EventIDBase & eventID,
229  const std::vector<uint32_t> & tbp,
230  const std::vector<uint32_t> & tap,
231  const std::vector<uint32_t> & tav,
232  const std::vector<uint32_t> & tip,
233  const std::vector<uint32_t> & extra,
234  const unsigned char triggerType ) const
235 {
236  //
237  // Build the data words:
238  //
239  std::vector<uint32_t> roi_vector;
240  roi_vector.push_back( eventID.time_stamp_ns_offset() ); // Time stamp: 28-bit nanoseconds
241  roi_vector.push_back( eventID.time_stamp() ); // Time stamp: 32-bit UTC seconds
242 
243  roi_vector.insert(roi_vector.end(), tip.begin(), tip.end()); // TIP + 1 extra word
244  roi_vector.insert(roi_vector.end(), tbp.begin(), tbp.end()); // TBP
245  roi_vector.insert(roi_vector.end(), tap.begin(), tap.end()); // TAP
246  roi_vector.insert(roi_vector.end(), tav.begin(), tav.end()); // TAV
247  roi_vector.insert(roi_vector.end(), extra.begin(), extra.end()); // Extra words
248 
249  ATH_MSG_VERBOSE( "Stored data elements of RoI result" );
250 
251  //
252  // Build the trailer:
253  //
254 
255  std::vector<unsigned int> trailer(ROIB::Trailer(roi_vector.size()).trailer());
256  roi_vector.insert(roi_vector.end(), trailer.begin(), trailer.end());
257  ATH_MSG_VERBOSE( "Created trailer of RoI result" );
258 
259  //
260  // Build the header:
261  //
262 
263  // convention for source id in LVL1: 0 for DAQ, 1 for RoIB
264  const uint32_t source_id{eformat::helper::SourceIdentifier(eformat::TDAQ_CTP, 1).code()};
265 
266  // version word
267  uint32_t version_word = eformat::DEFAULT_ROD_VERSION;
268  const uint32_t l1a_pos{0}; // there's only one BC in RoIB fragment, which is the L1A one
269  version_word |= ((extra.size() & m_ctpDataFormat->getProgrammableExtraWordsMask()) << m_ctpDataFormat->getProgrammableExtraWordsShift());
270  version_word |= ((l1a_pos & m_ctpDataFormat->getL1APositionMask()) << m_ctpDataFormat->getL1APositionShift());
271  version_word |= ((m_ctpVersionNumber & m_ctpDataFormat->getCTPFormatVersionMask()) << m_ctpDataFormat->getCTPFormatVersionShift());
272 
273  ROIB::Header helperHeader(source_id, 0, version_word);
274 
275  helperHeader.setRunNumber( eventID.run_number());
276  //helperHeader.setL1ID( eventID.extendedL1ID());
277  helperHeader.setBCID( eventID.bunch_crossing_id());
278  helperHeader.setTriggerType(triggerType);
279  //helperHeader.setEventType(EventInfo::instance().eventType());
280 
281  std::vector<unsigned int> header(helperHeader.header());
282  roi_vector.insert(roi_vector.begin(), header.begin(), header.end());
283  ATH_MSG_VERBOSE( "Created header of RoI result" );
284 
285  //
286  // Build the SLink:
287  //
288 
289  std::unique_ptr<CTPSLink> result ( new CTPSLink( roi_vector, m_ctpVersionNumber ));
290  ATH_MSG_DEBUG( "Created CTPSlink object" );
291  ATH_MSG_VERBOSE( "Dump CTPSlink object:\n" + result->dump() );
292 
293  //
294  // Debug output for ART
295  //
296  if( msgLvl(MSG::VERBOSE) ) {
297  for( auto & itemName : firedItems(tbp) ) {
298  ATH_MSG_VERBOSE( "REGTEST - Items fired before prescale: " << itemName );
299  }
300  for( auto & itemName : firedItems(tap) ) {
301  ATH_MSG_VERBOSE( "REGTEST - Items fired after prescale: " << itemName );
302  }
303  for( auto & itemName : firedItems(tav) ) {
304  ATH_MSG_VERBOSE( "REGTEST - Items fired after veto: " << itemName );
305  }
306  }
307  return result;
308 }
309 
310 
311 std::unique_ptr<CTP_RDO>
312 LVL1CTP::ResultBuilder::constructRDOResult( const EventIDBase & eventID,
313  const std::vector<uint32_t> & tbp,
314  const std::vector<uint32_t> & tap,
315  const std::vector<uint32_t> & tav,
316  const std::vector<uint32_t> & tip,
317  const std::vector<uint32_t> & extra ) const
318 {
319  auto wrongSize = [this](const std::vector<uint32_t> & vec, uint32_t exp, std::string_view name) {
320  if (vec.size() == exp) {return false;}
321  ATH_MSG_ERROR("Wrong " << name << " vector size passed to constructRDOResult, " << vec.size() << " instead of " << exp);
322  return true;
323  };
324  if (wrongSize(tip, m_ctpDataFormat->getTIPwords(), "TIP")
325  || wrongSize(tbp, m_ctpDataFormat->getTBPwords(), "TBP")
326  || wrongSize(tap, m_ctpDataFormat->getTAPwords(), "TAP")
327  || wrongSize(tav, m_ctpDataFormat->getTAVwords(), "TAV")) {
328  return nullptr;
329  }
330 
331  std::vector<uint32_t> data(static_cast<size_t>(m_ctpDataFormat->getNumberTimeWords()), uint32_t{0});
332  data.reserve(m_ctpDataFormat->getNumberTimeWords() + m_ctpDataFormat->getDAQwordsPerBunch() + extra.size());
333  data.insert(data.end(),tip.begin(),tip.end());
334  data.insert(data.end(),tbp.begin(),tbp.end());
335  data.insert(data.end(),tap.begin(),tap.end());
336  data.insert(data.end(),tav.begin(),tav.end());
337  data.insert(data.end(),extra.begin(),extra.end());
338 
339  std::unique_ptr<CTP_RDO> result( new CTP_RDO(m_ctpVersionNumber, std::move(data), extra.size()) );
340  result->setTimeSec(eventID.time_stamp()); // Time stamp: 32-bit UTC seconds
341  result->setTimeNanoSec(eventID.time_stamp_ns_offset()); // Time stamp: 28-bit nanoseconds
342  ATH_MSG_DEBUG( "Created CTP_RDO object" );
343  return result;
344 }
345 
346 
347 
348 
349 
350 
351 std::vector<std::string>
352 LVL1CTP::ResultBuilder::firedItems(const std::vector<uint32_t>& triggerWords) const {
353  std::vector<std::string> passedItems;
354  for( const std::string & itemName : m_itemConfigMap->itemNames() ) {
355  auto item = m_itemConfigMap->getItem(itemName);
356  size_t idx = item->ctpId() / 32;
357  size_t bit = item->ctpId() % 32;
358  if ( triggerWords[idx] % (1L << bit) ) {
359  passedItems.push_back(item->name());
360  }
361  }
362  std::sort(passedItems.begin(), passedItems.end());
363  return passedItems;
364 }
365 
PrescaleSet.h
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
SpecialTrigger.h
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
get_generator_info.result
result
Definition: get_generator_info.py:21
header
Definition: hcg.cxx:526
LVL1CTP::ResultBuilder::~ResultBuilder
~ResultBuilder()
Definition: ResultBuilder.cxx:42
Trailer.h
StandaloneBunchgroupHandler.bg
bg
Definition: StandaloneBunchgroupHandler.py:243
CTP_RDO
CTP_RDO
Definition: TrigT1EventTPCnv.cxx:102
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
LVL1CTP::ResultBuilder::constructRoIResult
std::unique_ptr< CTPSLink > constructRoIResult(const EventIDBase &eventID, const std::vector< uint32_t > &tbp, const std::vector< uint32_t > &tap, const std::vector< uint32_t > &tav, const std::vector< uint32_t > &tip, const std::vector< uint32_t > &extra, const unsigned char triggerType) const
build RoI result (LVL1CTP::CTPSLink)
Definition: ResultBuilder.cxx:228
LVL1CTP::ResultBuilder::constructResultVectors
StatusCode constructResultVectors(const std::map< std::string, unsigned int > &itemDecisionMap, std::vector< uint32_t > &tbp, std::vector< uint32_t > &tap, std::vector< uint32_t > &tav, unsigned char &triggerType) const
Definition: ResultBuilder.cxx:183
LVL1CTP::ResultBuilder::firedItems
std::vector< std::string > firedItems(const std::vector< uint32_t > &triggerWords) const
build list of fired items and dump to string
Definition: ResultBuilder.cxx:352
CTPUtil.h
LVL1CTP::CTPTriggerThreshold::endBit
unsigned int endBit() const
Get the end position of the threshold.
Definition: CTPTriggerThreshold.cxx:35
ROIB::Header::header
const std::vector< uint32_t > & header() const
get full header
CTPTriggerItem.h
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
TrigConf::L1Menu
L1 menu configuration.
Definition: L1Menu.h:28
LVL1CTP::ResultBuilder::m_ctpDataFormat
CTPdataformatVersion * m_ctpDataFormat
CTP data format details.
Definition: ResultBuilder.h:92
ROIB::Trailer::trailer
const std::vector< uint32_t > & trailer() const
get full trailer
LVL1CTP::ResultBuilder::setConfiguration
StatusCode setConfiguration(const TrigConf::L1Menu &l1menu)
Definition: ResultBuilder.cxx:51
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
LVL1CTP::CTPTriggerThreshold::startBit
unsigned int startBit() const
Get the start position of the threshold.
Definition: CTPTriggerThreshold.cxx:25
LVL1CTP::BunchGroupTrigger
Class for simulating the internal bunch group trigger.
Definition: SpecialTrigger.h:48
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
x
#define x
xAOD::tap
setBGCode tap
Definition: TrigDecision_v1.cxx:43
LVL1CTP::ResultBuilder::constructTIPVector
StatusCode constructTIPVector(const std::map< std::string, unsigned int > &thrMultiMap, std::vector< uint32_t > &tip) const
Definition: ResultBuilder.cxx:89
CxxUtils::vec
typename vecDetail::vec_typedef< T, N >::type vec
Define a nice alias for the vectorized type.
Definition: vec.h:207
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
LVL1CTP::RandomTrigger
Definition: SpecialTrigger.h:30
ROIB::Header
Header models the LVL1 ROD Header.
Definition: TrigT1Result/TrigT1Result/Header.h:37
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
BindingsTest.cut
cut
This script demonstrates how to call a C++ class from Python Also how to use PyROOT is shown.
Definition: BindingsTest.py:13
test_pyathena.parent
parent
Definition: test_pyathena.py:15
TrigConf::PrescaleSet::getCutFromPrescale
static int32_t getCutFromPrescale(double prescale)
calculate cut value for hardware configuration cut = 2*24/prescale - 1
Definition: PrescaleSet.cxx:33
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
LVL1CTP::ResultBuilder::constructRDOResult
std::unique_ptr< CTP_RDO > constructRDOResult(const EventIDBase &eventID, const std::vector< uint32_t > &tbp, const std::vector< uint32_t > &tap, const std::vector< uint32_t > &tav, const std::vector< uint32_t > &tip, const std::vector< uint32_t > &extra) const
build RDO result (CTP_RDO)
Definition: ResultBuilder.cxx:312
LVL1CTP::ResultBuilder::buildItemDecision
StatusCode buildItemDecision(const std::map< std::string, unsigned int > &thrMultiMap, std::map< std::string, unsigned int > &itemDecisionMap, CLHEP::HepRandomEngine *rndmEngine) const
Definition: ResultBuilder.cxx:149
TrigConf::LogicParsingException::msg
const std::string & msg() const
Definition: Logic.h:21
python.handimod.extra
int extra
Definition: handimod.py:522
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
Header.h
LVL1CTP::ResultBuilder::m_ctpVersionNumber
unsigned int m_ctpVersionNumber
CTP data format version (4 in most of Run 2 and in Run 3)
Definition: ResultBuilder.h:91
ROIB::Trailer
ROIB::Trailer models the LVL1 ROD Trailer.
Definition: Trailer.h:37
item
Definition: ItemListSvc.h:43
ResultBuilder.h
LVL1CTP::CTPTriggerThreshold
Helper class holding trigger threshold multiplicity.
Definition: CTPTriggerThreshold.h:17
ROIB::Header::setTriggerType
void setTriggerType(const uint32_t i)
set LVL1 trigger type
LVL1CTP::ResultBuilder::ResultBuilder
ResultBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Definition: ResultBuilder.cxx:33
std::sort
void sort(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, const Compare &comp)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:623
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
python.XMLReader.l1menu
l1menu
Definition: XMLReader.py:73
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
RunTileMonitoring.triggerType
triggerType
Definition: RunTileMonitoring.py:162
LVL1CTP::ResultBuilder::createTriggerConfigMaps
StatusCode createTriggerConfigMaps(const TrigConf::L1Menu &l1menu)
Definition: ResultBuilder.cxx:60
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
AthAlgTool
Definition: AthAlgTool.h:26
makeTOC.header
header
Definition: makeTOC.py:28
ROIB::Header::setBCID
void setBCID(const uint32_t i)
set bunch crossing ID
ROIB::Header::setRunNumber
void setRunNumber(const uint32_t)
set run number
TrigConf::LogicParsingException
Definition: Logic.h:16
CTPTriggerThreshold.h