ATLAS Offline Software
Loading...
Searching...
No Matches
RpcDigitToRpcRDO.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "RpcDigitToRpcRDO.h"
6
7#include <algorithm>
8#include <cmath>
9
11#include "GaudiKernel/PhysicalConstants.h"
17
18namespace {
19 constexpr unsigned int rpcRawHitWordLength = 7;
20 constexpr double inverseSpeedOfLight = 1 / Gaudi::Units::c_light; // need 1/299.792458
21} // namespace
22
25
26RpcDigitToRpcRDO::RpcDigitToRpcRDO(const std::string& name, ISvcLocator* pSvcLocator) :
27 AthReentrantAlgorithm(name, pSvcLocator) {}
28
29// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
30
32 ATH_MSG_DEBUG(" in initialize()");
33
34 ATH_CHECK(m_idHelperSvc.retrieve());
35
36
37 ATH_CHECK(m_readKey.initialize());
38 ATH_CHECK(m_DetectorManagerKey.initialize());
39
40 // Fill Tag Info
41 if (fillTagInfo() != StatusCode::SUCCESS) {
42 ATH_MSG_WARNING("Unable to fill Tag Info ");
43 return StatusCode::FAILURE;
44 } else {
45 ATH_MSG_DEBUG("Tag info filled successfully");
46 }
47
48 ATH_CHECK(m_padContainerKey.initialize());
49 ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_padContainerKey);
50 ATH_CHECK(m_digitContainerKey.initialize());
51 ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_digitContainerKey);
52 for (const std::string& statName : m_exclStat) {
53 m_exclStatNames.insert(m_idHelperSvc->rpcIdHelper().stationNameIndex(statName));
54 }
55 if(m_nobxs>8){
56 //The RPC simulation uses many arrays that assume maximum 8 BCs are readout
57 //See TrigT1/TrigT1RPChardware/Matrix.h for example
58 ATH_MSG_ERROR("Readout of more than 8 BCs is not supported by the simulation");
59 return StatusCode::FAILURE;
60 }
61
62 return StatusCode::SUCCESS;
63}
64
65// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
66
67StatusCode RpcDigitToRpcRDO::execute(const EventContext& ctx) const {
68 ATH_MSG_DEBUG("in execute()");
69
70 // create an empty pad container and record it
72 ATH_CHECK(padContainer.record((std::make_unique<RpcPadContainer>(600))));
73 ATH_MSG_DEBUG("Recorded RpcPadContainer called " << padContainer.name() << " in store " << padContainer.store());
74
75 RPCsimuData data; // instantiate the container for the RPC digits
76
78 const RpcCablingCondData* readCdo{*readHandle};
79
80 // fill the data with RPC simulated digits
81 if (fill_RPCdata(data, ctx, readCdo).isFailure()) { ATH_MSG_ERROR("Fail to produce RPC data for byte stream simulation "); }
82 ATH_MSG_DEBUG("RPC data loaded from G3:" << std::endl << ShowData<RPCsimuData>(data, "", m_data_detail));
83
84
85 // ******************** Start of Level-1 simulation section *****************
86
87 // Setting the algorithm type
88 // AlgoType type;
89 // if(m_detailed_algo) type = DetailedAlgo;
90 // else if(m_geometric_algo) type = GeometricAlgo;
91
92 unsigned long int debug;
93
96 //
97 CMAdata patterns(&data, readCdo, debug); //
98 //
99 ATH_MSG_DEBUG("CMApatterns created from RPC digits:" << std::endl //
102
103 // ******************* Start Byte Stream production *************************
104
105 RPCbytestream bytestream(patterns, (std::string)m_bytestream_file, msg(), (unsigned long int)m_cma_ro_debug,
106 (unsigned long int)m_pad_ro_debug, (unsigned long int)m_rx_ro_debug, (unsigned long int)m_sl_ro_debug,
107 (unsigned long int)m_cma_rostruct_debug, (unsigned long int)m_pad_rostruct_debug,
108 (unsigned long int)m_rx_rostruct_debug, (unsigned long int)m_sl_rostruct_debug, m_nobxs, m_bczero);
109
110 // ********************** create the RPC RDO's *****************************
111
112 std::vector<RpcPad*> rpcpads;
113 ATH_MSG_DEBUG("Start decoding");
114 PAD_Readout padReadout = bytestream.pad_readout();
115 // Iterate on the readout PADS and decode them
116 for (auto& padro : padReadout) {
117 RpcPad* newpad = decodePad(padro.second, readCdo);
118 // Push back the decoded pad in the vector
119 rpcpads.push_back(newpad);
120 }
121 ATH_MSG_DEBUG("Total number of pads in this event is " << rpcpads.size());
122
123 for (const auto& pad : rpcpads) {
124 const int elementHash1 = pad->identifyHash();
125 if (padContainer->addCollection(pad, elementHash1).isFailure()) { ATH_MSG_ERROR("Unable to record RPC Pad in IDC"); }
126 }
127 rpcpads.clear();
128
129
130 return StatusCode::SUCCESS;
131}
132
133StatusCode RpcDigitToRpcRDO::fill_RPCdata(RPCsimuData& data, const EventContext& ctx, const RpcCablingCondData* readCdo) const {
134 std::string space = " ";
135
136 ATH_MSG_DEBUG("in execute(): fill RPC data");
137
138 IdContext rpcContext = m_idHelperSvc->rpcIdHelper().module_context();
139
141 if (!container.isValid()) {
142 ATH_MSG_ERROR("Could not find RpcDigitContainer called " << container.name() << " in store " << container.store());
143 return StatusCode::SUCCESS;
144 }
145 ATH_MSG_DEBUG("Found RpcDigitContainer called " << container.name() << " in store " << container.store());
147 if (!muonDetMgr.isValid()) {
148 ATH_MSG_FATAL("Failed to retrieve the readout geometry "<<muonDetMgr.fullKey());
149 return StatusCode::FAILURE;
150 }
151 for (const RpcDigitCollection* rpcCollection : *container) {
152 ATH_MSG_DEBUG("RPC Digit -> Pad loop :: digitCollection at " << rpcCollection);
153
154 IdentifierHash moduleHash = rpcCollection->identifierHash();
155 Identifier moduleId{0};
156 if (m_idHelperSvc->rpcIdHelper().get_id(moduleHash, moduleId, &rpcContext)) {
157 ATH_MSG_FATAL("Invalid identifier module ");
158 return StatusCode::FAILURE;
159 }
160 if (m_exclStatNames.count(m_idHelperSvc->stationName(moduleId))){
161 ATH_MSG_VERBOSE("Do not turn digit from "<<m_idHelperSvc->toString(moduleId)<<" to RDO");
162 continue;
163 }
164
165 for (const RpcDigit* rpcDigit : *rpcCollection) {
166 const Identifier channelId = rpcDigit->identify();
167 int stationType = m_idHelperSvc->rpcIdHelper().stationName(channelId);
168 std::string StationName = m_idHelperSvc->rpcIdHelper().stationNameString(stationType);
169 // BIS stations have different readout, so they are treated separately
170 int StationEta = m_idHelperSvc->rpcIdHelper().stationEta(channelId);
171 int StationPhi = m_idHelperSvc->rpcIdHelper().stationPhi(channelId);
172 int DoubletR = m_idHelperSvc->rpcIdHelper().doubletR(channelId);
173 int DoubletZ = m_idHelperSvc->rpcIdHelper().doubletZ(channelId);
174 int DoubletP = m_idHelperSvc->rpcIdHelper().doubletPhi(channelId);
175 int GasGap = m_idHelperSvc->rpcIdHelper().gasGap(channelId);
176 int MeasuresPhi = m_idHelperSvc->rpcIdHelper().measuresPhi(channelId);
177 int Strip = m_idHelperSvc->rpcIdHelper().strip(channelId);
178
179 ATH_MSG_DEBUG("RPC Digit Type, Eta, Phi, dbR, dbZ, dbP, gg, mPhi, Strip "
180 << stationType << " " << StationEta << " " << StationPhi << " " << DoubletR << " " << DoubletZ << " "
181 << DoubletP << " " << GasGap << " " << MeasuresPhi << " " << Strip);
182 const MuonGM::RpcReadoutElement* descriptor = muonDetMgr->getRpcReadoutElement(channelId);
183
184 // Get the global position of RPC strip from MuonDetDesc
185 Amg::Vector3D pos = descriptor->stripPos(channelId);
186
187 // get now strip_code from cablingSvc
188 unsigned long int strip_code_cab = readCdo->strip_code_fromOffId(StationName, StationEta, StationPhi, DoubletR,
189 DoubletZ, DoubletP, GasGap, MeasuresPhi, Strip);
190
191 ATH_MSG_DEBUG("From RPC Cabling Layout, strip_code = " << strip_code_cab);
192
193 if (strip_code_cab) {
194 // Fill data for the Level-1 RPC digit
195 float xyz[4];
196 double tp = pos.mag() * inverseSpeedOfLight;
197 // time of flight
198 xyz[0] = (m_patch_for_rpc_time) ? rpcDigit->time() - tp : rpcDigit->time();
199 xyz[1] = pos.x() / 10.; // coo[0]; //RPC strip x coordinate
200 xyz[2] = pos.y() / 10.; // coo[1]; //RPC strip y coordinate
201 xyz[3] = pos.z() / 10.; // coo[2]; //RPC strip z coordinate
202
203 int param[3] = {0, 0, 0};
204
205 ATH_MSG_DEBUG("Digit with strip_code = " << strip_code_cab << " passed to RDO/LVL1 Simulation (RPCsimuDigit)");
206 RPCsimuDigit digit(0, strip_code_cab, param, xyz);
207 data << digit;
208 }
209 }
210 }
211 return StatusCode::SUCCESS;
212}
213
214
215
216// NOTE: although this function has no clients in release 22, currently the Run2 trigger simulation is still run in
217// release 21 on RDOs produced in release 22. Since release 21 accesses the TagInfo, it needs to be written to the
218// RDOs produced in release 22. The fillTagInfo() function thus needs to stay in release 22 until the workflow changes
220 ServiceHandle<ITagInfoMgr> tagInfoMgr("TagInfoMgr", name());
221 ATH_CHECK(tagInfoMgr.retrieve());
222
223 std::string cablingType = "MuonRPC_Cabling";
224 StatusCode sc = tagInfoMgr->addTag("RPC_CablingType", cablingType);
225 if (sc.isFailure()) {
226 ATH_MSG_WARNING("RPC_CablingType " << cablingType << " not added to TagInfo ");
227 return sc;
228 } else {
229 ATH_MSG_DEBUG("RPC_CablingType " << cablingType << " is Added TagInfo ");
230 }
231
232 return StatusCode::SUCCESS;
233}
234
235// Decode a pad and return a pointer to a RpcPad RDO
237 ATH_MSG_DEBUG("Decoding a new RpcPad");
238
239 // Identifier elements
240 int name = 0;
241 int eta = 0;
242 int phi = 0;
243 int doublet_r = 0;
244 int doublet_z = 0;
245 int doublet_phi = 0;
246 int gas_gap = 0;
247 int measures_phi = 0;
248 int strip = 0;
249
250 PadReadOut* readout = pad.give_pad_readout();
251
252 // Retrieve PAD sector and PAD ID
253 int sector = pad.sector();
254 int pad_id = pad.PAD();
255 // Compute side and logic sector
256 int side = (sector < 32) ? 0 : 1;
257 int logic_sector = sector % 32;
258 // Compute the key to retrieve the offline id from the map (as from LVL1 sim.)
259 int key = side * 10000 + logic_sector * 100 + pad_id;
260
261 ATH_MSG_DEBUG("Pad: Side " << side << " Sector logic" << logic_sector << " Id " << pad_id);
262
263 // Retrieve the identifier elements from the map
264 const RpcCablingCondData::RDOmap& pad_map = readCdo->give_RDOs();
265 RDOindex index = (*pad_map.find(key)).second;
266
267 index.offline_indexes(name, eta, phi, doublet_r, doublet_z, doublet_phi, gas_gap, measures_phi, strip);
268
269 // Build the pad offline identifier
270 bool valid{false};
271 Identifier id = m_idHelperSvc->rpcIdHelper().padID(name, eta, phi, doublet_r, doublet_z, doublet_phi, valid);
272
273 ATH_MSG_DEBUG("Invalid pad offline indices ");
274 ATH_MSG_DEBUG("Name : " << name);
275 ATH_MSG_DEBUG("Eta " << eta << " Phi " << phi);
276 ATH_MSG_DEBUG("Doublet r " << doublet_r << " Doublet_z " << doublet_z << " Doublet_phi " << doublet_phi);
277 ATH_MSG_DEBUG("Gas gap " << gas_gap << " Measures_phi " << measures_phi << " Strip " << strip);
278
279 // Retrieve Pad status and error code from Pad header and footer
280 PadReadOutStructure pad_header = readout->getHeader();
281 PadReadOutStructure pad_footer = readout->getFooter();
282 // Check the data format
283 if(!pad_header.isHeader()) std::abort();
284 if(!pad_footer.isFooter()) std::abort();
285
286 unsigned int hashId = index.hash();
287 unsigned int onlineId = pad_id;
288 unsigned int status = 0;
289 unsigned int errorCode = pad_footer.errorCode();
290
291 // Construct the new Pad
292 RpcPad* rpc_pad = new RpcPad(id, hashId, onlineId, status, errorCode, sector);
293
294 // Iterate on the matrices and decode them
295 for (int i = 0; i < readout->numberOfCMROFragments(); ++i) {
296 MatrixReadOut* matrix = pad.matrices_readout(i);
297 RpcCoinMatrix* coinMatrix = decodeMatrix(matrix, id);
298 // Add the matrix to the pad
299 rpc_pad->push_back(coinMatrix);
300 }
301
302 ATH_MSG_DEBUG("Number of matrices in Pad : " << rpc_pad->size());
303
304 return rpc_pad;
305}
306
307// Function decoding a coincidence matrix
309 ATH_MSG_DEBUG("Decoding a new RpcCoinMatrix");
310
311 // Matrix Header and SubHeader
312 MatrixReadOutStructure matrix_header = matrix->getHeader();
313 MatrixReadOutStructure matrix_subheader = matrix->getSubHeader();
314 MatrixReadOutStructure matrix_footer = matrix->getFooter();
315 // Check the data structure
316 if(!matrix_header.isHeader()) std::abort();
317 if(!matrix_subheader.isSubHeader()) std::abort();
318 if(!matrix_footer.isFooter()) std::abort();
319
320 // Create the coincidence matrix
321 RpcCoinMatrix* coinMatrix =
322 new RpcCoinMatrix(id, matrix_header.cmid(), matrix_footer.crc(), matrix_header.fel1id(), matrix_subheader.febcid());
323
324 // Iterate on fired channels and decode them
326 for (int j = 0; j < matrix->numberOfBodyWords(); ++j) {
327 cm_hit = matrix->getCMAHit(j);
328 if(!cm_hit.isBody()) std::abort();
329 RpcFiredChannel* firedChannel = nullptr;
330
331 if (cm_hit.ijk() < rpcRawHitWordLength) {
332 firedChannel = new RpcFiredChannel(cm_hit.bcid(), cm_hit.time(), cm_hit.ijk(), cm_hit.channel());
333 } else if (cm_hit.ijk() == rpcRawHitWordLength) {
334 firedChannel = new RpcFiredChannel(cm_hit.bcid(), cm_hit.time(), cm_hit.ijk(), cm_hit.threshold(), cm_hit.overlap());
335 }
336
337 coinMatrix->push_back(firedChannel);
338 }
339
340 ATH_MSG_DEBUG("Number of Fired Channels in Matrix : " << coinMatrix->size());
341 return coinMatrix;
342}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sc
const bool debug
Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Current RpcCoinMatrix
Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Current Athena::TPCnvVers::Current RpcPad
#define xyz
An algorithm that can be simultaneously executed in multiple threads.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
PadReadOut * give_pad_readout(void)
MatrixReadOut * matrices_readout(int) const
int sector(void) const
Definition PADreadout.h:40
int PAD(void) const
Definition PADreadout.h:41
PadReadOutStructure getFooter()
PadReadOutStructure getHeader()
ubit16 numberOfCMROFragments()
Definition PadReadOut.h:30
const PAD_Readout & pad_readout(void) const
std::map< int, RDOindex, std::less< int > > RDOmap
const RDOmap & give_RDOs(void) const
unsigned long int strip_code_fromOffId(const std::string &stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
IntegerProperty m_fast_debug
BooleanProperty m_detailed_algo
virtual StatusCode initialize() override final
IntegerProperty m_cma_debug
SG::WriteHandleKey< RpcPadContainer > m_padContainerKey
StatusCode fillTagInfo() const
RpcCoinMatrix * decodeMatrix(MatrixReadOut *matrix, Identifier &id) const
Gaudi::Property< int > m_bczero
IntegerProperty m_pad_ro_debug
IntegerProperty m_cma_ro_debug
StringProperty m_bytestream_file
SG::ReadHandleKey< RpcDigitContainer > m_digitContainerKey
StatusCode fill_RPCdata(RPCsimuData &data, const EventContext &ctx, const RpcCablingCondData *) const
std::map< int, PADreadout, std::less< int > > PAD_Readout
Gaudi::Property< std::vector< std::string > > m_exclStat
BooleanProperty m_patch_for_rpc_time
Gaudi::Property< int > m_nobxs
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
BooleanProperty m_data_detail
IntegerProperty m_cma_rostruct_debug
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
RpcPad * decodePad(PADreadout &pad, const RpcCablingCondData *readCdo) const
IntegerProperty m_sl_ro_debug
std::set< int > m_exclStatNames
SG::ReadCondHandleKey< RpcCablingCondData > m_readKey
IntegerProperty m_rx_rostruct_debug
IntegerProperty m_pad_rostruct_debug
IntegerProperty m_sl_rostruct_debug
RpcDigitToRpcRDO(const std::string &name, ISvcLocator *pSvcLocator)
IntegerProperty m_rx_ro_debug
virtual StatusCode execute(const EventContext &ctx) const override final
const DataObjID & fullKey() const
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
std::vector< std::string > patterns
Definition listroot.cxx:187
Eigen::Matrix< double, 3, 1 > Vector3D
Definition index.py:1