ATLAS Offline Software
Loading...
Searching...
No Matches
MuCTPIPhase1ByteStreamAlgo.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
10
11#include <atomic>
12
13static std::atomic<unsigned int> barrelROIFailCounter{0};
14
15//also inspired by Rafal's word decoding code from:
16//https://gitlab.cern.ch/atlas/athena/blob/release/22.0.91/Trigger/TrigT1/TrigT1ResultByteStream/src/MuonRoIByteStreamTool.cxx
17
22MuCTPIPhase1ByteStreamAlgo::MuCTPIPhase1ByteStreamAlgo( const std::string& name, ISvcLocator* svcLoc )
23 : AthReentrantAlgorithm( name, svcLoc) {}
24
26{
27 ATH_MSG_DEBUG("Initialising " << name());
28
29 ATH_CHECK( m_MuCTPI_Phase1_RDOKey.initialize(/*m_processMuctpi=*/true) );
30
31 //needed to enable the decoding of eta and phi
32 ATH_MSG_INFO("--- ENABLING THE DECODING");
33 const std::string barrelFileName = PathResolverFindCalibFile( m_barrelRoIFile );
34 ATH_MSG_INFO("--- - CHECK BARREL FILE NAME" << barrelFileName);
35 const std::string ecfFileName = PathResolverFindCalibFile( m_ecfRoIFile );
36 ATH_MSG_INFO("--- - CHECK ECF FILE NAME" << ecfFileName);
37 const std::string side0LUTFileName = PathResolverFindCalibFile( m_side0LUTFile );
38 ATH_MSG_INFO("--- - CHECK SIDE0 LUT FILE NAME" << side0LUTFileName);
39 const std::string side1LUTFileName = PathResolverFindCalibFile( m_side1LUTFile );
40 ATH_MSG_INFO("--- - INFO SIDE1 LUT FILE NAME" << side1LUTFileName);
41
42 CHECK( m_l1topoLUT.initializeLUT(barrelFileName,
43 ecfFileName,
44 side0LUTFileName,
45 side1LUTFileName) );
46
47 //return here while looking for fix for this
48 return StatusCode::SUCCESS;
49
50 //this didn't work yet locally (offline). Waiting for feedback and should cleanup or reinclude soon.
51 //not critical; can run without it.
108}
109
110StatusCode MuCTPIPhase1ByteStreamAlgo::execute(const EventContext& eventContext) const {
111 ATH_MSG_DEBUG("Executing " << name());
112
113 // Retrieve the BS data for all tools in one request to parallelise DCM->ROS network requests
115 std::vector<uint32_t> robID = { m_robId };// Source ID of MIROD
116 //get rob fragment(s)
117 m_robDataProviderSvc->getROBData(eventContext, robID, vrobf, name());
118 //should only receive exactly 1 fragment; make sure:
119 if(vrobf.size()!=1)
120 {
121 ATH_MSG_ERROR("Wrong number of MUCTPI fragment in event: vrobf.size()="<<vrobf.size());
122 return StatusCode::FAILURE;
123 }
124
125 //make the conversion, i.e. make the RDO, record it
127 ATH_CHECK(convert(vrobf[0],outputHandle));
128 return StatusCode::SUCCESS;
129}
130
136
137 ATH_MSG_DEBUG("executing convert() from ROBFragment to RDO");
138 // check ROD source ID
139 const uint32_t rodId = rob->rod_source_id();
140 // check BC ID
141 const uint32_t bcId = rob->rod_bc_id();
142
143 ATH_MSG_DEBUG(" expected ROD sub-detector ID: " << std::hex << m_robId << " ID found: " << std::hex << rodId << std::dec);
144
145 if( rodId != m_robId ) {
146 ATH_MSG_ERROR("Wrong ROD ID found in the MuCTPI ROB fragment!");
147 return StatusCode::FAILURE;
148 }
149
150 ATH_MSG_VERBOSE(" ROD Header BCID " << bcId << ", dumping MuCTPI words:");
151
152 const uint32_t* it_data;
153 rob->rod_data( it_data );
154 const uint32_t ndata = rob->rod_ndata();
155 ATH_MSG_DEBUG("MUCTPI DQ DEBUG: number of ROB data words: " << std::dec << ndata);
156
157 //slices
158 std::vector< LVL1::MuCTPIBits::Slice > slices;
160 bool firstSlice=true;
161 std::vector<size_t> errorBits;
162 uint64_t sliceMultiplicity=0;//grouping the 3 multiplicity words, to be processed at the end of the slice
163
164 for( uint32_t iWord = 0; iWord < ndata; ++iWord, ++it_data ) {
165
166 //for each word, get it, find type, and add in Slice struct.
167 uint32_t word = static_cast< uint32_t >( *it_data );
168 ATH_MSG_DEBUG("MUCTPI raw word " << iWord << ": 0x" << std::hex << word << std::dec);
170
171 switch (wordType) {
173
174 ATH_MSG_DEBUG(" MUCTPI DQ DEBUG: Timeslice found: "<< std::hex << word);
175
176 //add previous slice if any
177 if(!firstSlice)
178 {
179 ATH_MSG_DEBUG(" MUCTPI DQ DEBUG: new timeslice found (pushing)");
180 slices.push_back(slice);
181 }
182 else
183 firstSlice=false;
184
185 //make new slice (to be improved, since "new" will give pointer)
186 slice = LVL1::MuCTPIBits::Slice();
187
188 const auto header = LVL1::MuCTPIBits::timesliceHeader(word);
189 ATH_MSG_DEBUG("This is a timeslice header word with BCID=" << header.bcid
190 << ", NTOB=" << header.tobCount << ", NCAND=" << header.candCount);
191 slice.bcid = header.bcid;
192 slice.nCand = header.candCount;
193 slice.nTOB = header.tobCount;
194 break;
195 }
197 uint32_t tmNum = LVL1::MuCTPIBits::multiplicityWordNumber(word);
198 ATH_MSG_DEBUG("This is a multiplicity word #" << tmNum);
199
200 if(m_muctpi_Nbits.size()==32)
201 {
202 //fill mult word into temp container until 3rd word is found
203 if(tmNum==1)
205 else if(tmNum==2)
207 else if(tmNum==3)
209
210 //flags from third word
211 //AND: process multiplicity for the slice!!!
212 if(tmNum==3)
213 {
216 slice.mlt.bits = sliceMultiplicity;
217
218 //process the long mult word into 32 mlt thr counters
219 for(uint iThr=0;iThr<m_muctpi_Nbits.size();iThr++)
220 {
221 uint thismask=0;
222 if(m_muctpi_Nbits[iThr]==1)
223 thismask=0x1;
224 else if(m_muctpi_Nbits[iThr]==2)
225 thismask=0x3;
226 else if(m_muctpi_Nbits[iThr]==3)
227 thismask=0x7;
228
229 //keep only the part of the 64bit word corresponding to the nbits value
230 slice.mlt.cnt.push_back( sliceMultiplicity & thismask);
231 //"throw away" the part of the 64bit word that we just used
232 sliceMultiplicity >>= m_muctpi_Nbits[iThr];
233 }
234
235 sliceMultiplicity=0;//cleaning just in case..
236 }
237
238 }
239 else
240 {
241 //if nbits size !=32, then it's not set
242 //for now, ignore, and can fill the histos with the Mult bits, as they come
243 //without decoding
244 //=>suppress this warning
245 //ATH_MSG_WARNING("MUCTPI DQ DEBUG: skipping Mult processing, no nbits defined");
246
247 //todo: add code + histos for Mult bits
248 }
249
250 break;
251 }
253 ATH_MSG_DEBUG("This is a RoI candidate word");
254
255 LVL1::MuCTPIBits::Candidate thiscand(word);
256
257 // We calculate eta/phi coordinates for each candidate with the
258 // full resolution available.
260 {
261 thiscand.eta = m_l1topoLUT.getCoordinates(thiscand.side, thiscand.subsystem, thiscand.num, thiscand.roi).eta;
262 thiscand.phi = m_l1topoLUT.getCoordinates(thiscand.side, thiscand.subsystem, thiscand.num, thiscand.roi).phi;
263 //ATH_MSG_INFO("Candidate Pt " << thiscand.pt);
264 thiscand.mappedPt = LVL1::MuCTPIBits::RPCtoTGC_pt_map[thiscand.pt];
265 //ATH_MSG_INFO("Candidate mapped Pt " << thiscand.mappedPt);
266 }
267 else if(thiscand.type == LVL1::MuCTPIBits::SubsysID::Endcap)
268 {
269 thiscand.eta = m_l1topoLUT.getCoordinates(thiscand.side, thiscand.subsystem, thiscand.num, thiscand.roi).eta;
270 thiscand.phi = m_l1topoLUT.getCoordinates(thiscand.side, thiscand.subsystem, thiscand.num, thiscand.roi).phi;
271 }
272 else if(thiscand.type == LVL1::MuCTPIBits::SubsysID::Forward)
273 {
274 thiscand.eta = m_l1topoLUT.getCoordinates(thiscand.side, thiscand.subsystem, thiscand.num, thiscand.roi).eta;
275 thiscand.phi = m_l1topoLUT.getCoordinates(thiscand.side, thiscand.subsystem, thiscand.num, thiscand.roi).phi;
276 }
277 slice.cand.push_back(thiscand);
278 break;
279 }
281 ATH_MSG_DEBUG("This is a Topo TOB word "<< std::hex << word);
282 LVL1::MuCTPIBits::TopoTOB thistob(word);
283
284 if(thistob.det == 0) // BA
285 {
286 try
287 {
288 thistob.roi = m_l1topoLUT.getBarrelROI(thistob.side, thistob.sec, thistob.barrel_eta_lookup, thistob.barrel_phi_lookup);
289 }
290 catch (const std::out_of_range& e) // Occurs when getBarrelROI fails to find entry in the map
291 {
293 ATH_MSG_WARNING("TopoTOB word not found in LUT!"
294 << " (" << e.what() << " exception)"
295 << " Word info: det = " << thistob.det
296 << ", subsystem = " << thistob.subsystem
297 << ", side = " << thistob.side
298 << ", sector = " << thistob.sec
299 << ", ieta = " << thistob.barrel_eta_lookup
300 << ", iphi = " << thistob.barrel_phi_lookup);
301 break;
302 }
303 thistob.etaDecoded = m_l1topoLUT.getCoordinates(thistob.side, thistob.subsystem, thistob.sec, thistob.roi).eta;
304 thistob.phiDecoded = m_l1topoLUT.getCoordinates(thistob.side, thistob.subsystem, thistob.sec, thistob.roi).phi;
305 }
306 else // FW or EC
307 {
308 // FW and EC have the ROI initialized in the constructor of the Topo word, because it is encoded in eta_raw and phi_raw
309 thistob.etaDecoded = m_l1topoLUT.getCoordinates(thistob.side, thistob.subsystem, thistob.sec, thistob.roi).eta;
310 thistob.phiDecoded = m_l1topoLUT.getCoordinates(thistob.side, thistob.subsystem, thistob.sec, thistob.roi).phi;
311 }
312 slice.tob.push_back(thistob);
313 break;
314 }
316 ATH_MSG_DEBUG("This is a status word"<< std::hex << word);
318 if (!errorBits.empty()) {
319 ATH_MSG_DEBUG("MUCTPI ROD data flagged with errors. The data status word is 0x" << std::hex << word << std::dec);
320 for (size_t bit : errorBits) {
321 ATH_MSG_DEBUG("Error bit " << bit << ": " << LVL1::MuCTPIBits::DataStatusWordErrors.at(bit));
322 }
323 }
324 break;
325 }
326 default: {
327 ATH_MSG_ERROR("The MUCTPI word 0x" << std::hex << word << std::dec << " does not match any known word type");
328 return StatusCode::FAILURE;
329 }//default
330 }//switch
331 }//for each word
332
333 //add last timeslice in vector, since there is no end-slice flag
334 ATH_MSG_DEBUG(" MUCTPI DQ DEBUG: out of words (pushing last slice)");
335 slices.push_back( std::move(slice) );
336
337 // Check that the number of exceptions is below a limit based on the number of slices.
338 // Exceptions can occur if word is present in multiple timeslices for same event.
339 // This allows for cases where we have one or two bad words per event, but not where lots of map errors arise.
340 if (barrelROIFailCounter == slices.size() + 2 )
341 {
342 ATH_MSG_ERROR("TopoTOB word exception count exceeded limit!");
343 return StatusCode::FAILURE;
344 }
345
346 // create MuCTPI RDO
347 ATH_CHECK(outputHandle.record(
348 std::make_unique<MuCTPI_Phase1_RDO>(std::move(slices), std::move(errorBits))
349 ));
350 return StatusCode::SUCCESS;
351}
352
354{
355 if (barrelROIFailCounter != 0) ATH_MSG_WARNING(barrelROIFailCounter << " TopoTOB words could not retrieve RoIs in the barrel");
356 return StatusCode::SUCCESS;
357}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
unsigned int uint
static std::atomic< unsigned int > barrelROIFailCounter
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
uint16_t bcId(uint32_t data)
An algorithm that can be simultaneously executed in multiple threads.
OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment ROBF
std::vector< const ROBF * > VROBFRAG
virtual StatusCode initialize() override
std::vector< uint32_t > m_muctpi_Nbits
StatusCode convert(const IROBDataProviderSvc::ROBF *rob, SG::WriteHandle< MuCTPI_Phase1_RDO > &outputHandle) const
Convert ROBFragment to MuCTPI_RDO.
ServiceHandle< IROBDataProviderSvc > m_robDataProviderSvc
ROBDataProvider service handle.
SG::WriteHandleKey< MuCTPI_Phase1_RDO > m_MuCTPI_Phase1_RDOKey
virtual StatusCode execute(const EventContext &eventContext) const override
LVL1MUCTPIPHASE1::L1TopoLUT m_l1topoLUT
Helper members.
Gaudi::Property< uint32_t > m_robId
Object storing the various IDs of the MuCTPI fragment.
MuCTPIPhase1ByteStreamAlgo(const std::string &name, ISvcLocator *svcLoc)
Default constructor.
virtual StatusCode finalize() override
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
constexpr uint32_t maskedWord(uint32_t word, uint32_t shift, uint32_t mask)
Extract sub-word from 32-bit word by applying a shift and a mask.
static constexpr uint32_t RUN3_MULTIPLICITY_ENC_PART1_SHIFT
constexpr uint32_t multiplicityWordNumber(uint32_t word)
Decode the index of the multitpicity word, which is 1, 2, or 3.
static constexpr uint32_t RUN3_MULTIPLICITY_PART1_MASK
static constexpr uint32_t RUN3_NSW_MONITORING_TRIGGER_SHIFT
static constexpr std::array< std::string_view, 16 > DataStatusWordErrors
constexpr auto timesliceHeader(uint32_t word)
Decode timeslice word.
static constexpr uint32_t RUN3_MULTIPLICITY_ENC_PART2_SHIFT
static constexpr uint32_t RUN3_NSW_MONITORING_TRIGGER_MASK
static constexpr uint32_t RUN3_MULTIPLICITY_PART1_SHIFT
constexpr WordType getWordType(uint32_t word)
Determine the type of a MUCTPI ROD word.
static constexpr uint32_t RUN3_MULTIPLICITY_ENC_PART3_SHIFT
static constexpr uint32_t RUN3_MULTIPLICITY_OVERFLOW_MASK
static constexpr uint32_t RUN3_MULTIPLICITY_PART2_MASK
std::vector< size_t > getDataStatusWordErrors(uint32_t word)
Decode the data status word (returns a vector of bit indices for the errors set - empty if no errors)
static constexpr uint32_t RUN3_MULTIPLICITY_PART3_SHIFT
const uint32_t RPCtoTGC_pt_map[7]
static constexpr uint32_t RUN3_MULTIPLICITY_PART3_MASK
static constexpr uint32_t RUN3_MULTIPLICITY_PART2_SHIFT
static constexpr uint32_t RUN3_MULTIPLICITY_OVERFLOW_SHIFT