ATLAS Offline Software
Loading...
Searching...
No Matches
CscRODReadOut.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef MUONCSC_CNVTOOL_CSCRODREADOUT_H
6#define MUONCSC_CNVTOOL_CSCRODREADOUT_H
7
8#include <stdint.h>
9
10#include <atomic>
11#include <cmath>
12#include <string>
13#include <vector>
14#include <stdexcept>
15
17
18// TGC ROD encoder/decoder for CscRDO
19// Author Ketevi A. Assamagan
20// BNL December 27 2003
21
23public:
25 CscRODReadOut(double startTime, double signalWidth, uint16_t numIntegration);
26 ~CscRODReadOut() = default;
27
28 // more static header/footer information
29 uint32_t getHeaderSize() const { return ROD_HEADER_SIZE; }
30 uint32_t getFooterSize() const { return ROD_FOOTER_SIZE; }
31 uint32_t numSamples() const { return NUM_SAMPLES; }
32 uint32_t latency() const { return LATENCY; }
33 uint32_t samplingRate() const { return RATE; }
34 uint32_t numDPU() const { return NUM_DPU; }
35
36 // DPU header info
37 uint32_t dpuHeader() const { return DPU_HEADER_MARKER; }
38 uint32_t dpuHeaderSize() const { return DPU_HEADER_SIZE; }
39
40 // get additional info
41 double getStartTime() const { return m_TIME_OFFSET; }
42 double getConversion() const { return m_CHARGE_TO_ADC_COUNT; }
43 double getMaxTimeBin() const { return m_Z0; }
44
45 // encoding
46 uint32_t getSourceID(uint16_t side, uint16_t rodId) const;
47 void encodeFragments(const std::vector<uint16_t>& amplitude, std::vector<uint32_t>& v) const;
48
49 // initialize helper
50 void set(const CscIdHelper* cscIdHelper) { m_cscIdHelper = cscIdHelper; }
51 void setChamberBitVaue(uint32_t value) { m_chamberBitValue = value; }
52
53 void setParams(double timeOffset, double signalWidth);
54
55 // testing
56 bool isDPU(const uint32_t fragment) const;
57 bool discard(const uint32_t fragment) const;
58 bool isAmplitude(const uint16_t fragment) const;
59 bool isAddress(const uint32_t fragment) const;
60
61 // Decoding
62 void decodeSourceID(uint32_t sourceIdIDIn, uint16_t& sourceID, uint16_t& moduleType, uint16_t& subDetectorId, uint16_t& rodId) const;
63 void decodeAmplitude(const uint32_t fragment, uint16_t& amp1, uint16_t& amp2) const;
64 uint32_t fragmentToAddress(const uint32_t fragment) const;
65 Identifier decodeAddress(const uint32_t address) const;
66 uint32_t hashIdentifier(const uint32_t address, const Identifier& moduleId) const;
67
68 uint32_t numberOfStrips(const uint32_t fragment) const;
69 Identifier decodeAddress(const uint32_t address, const Identifier& moduleId) const;
70 Identifier decodeAddress(const uint32_t address, const Identifier& moduleId, int j) const;
71 static int findCharge(double samplingTime, const std::vector<uint16_t>& amplitude, double& time) ;
72 double signal_amplitude(double samplingTime) const;
73 uint32_t address(const Identifier& channelId, int& eta, int& phi) const;
74
75private:
78 double m_norm;
79
84 double m_Z0;
85
86 static const uint32_t ROD_HEADER_SIZE = 12;
87
88 static const uint32_t ROD_FOOTER_SIZE = 0x0;
89
90 static const uint16_t SOURCE_ID = 0x00;
91 static const uint16_t MODULE_TYPE = 0x00;
92
93 static const uint16_t BODY_AMPLITUDE = 0x0000;
94 static const uint32_t BODY_ADDRESS = 0x00000000;
95
96 static const uint32_t NUM_SAMPLES = 25;
97 static const uint32_t LATENCY = 0;
98 static const uint32_t RATE = 40;
99 static const uint32_t NUM_DPU = 12;
100
101 static const uint32_t DPU_HEADER_MARKER = 0xC5F38856;
102 static const uint32_t DPU_HEADER_SIZE = 13;
103
104 static const uint32_t DPU_DISCARD = 0xFFFFFFFF;
105
106 void set32bits(const uint16_t* v16, uint32_t& v32) const;
107 double signal(double z) const;
108};
109
110inline void CscRODReadOut::setParams(double timeOffset, double signalWidth) {
111 m_TIME_OFFSET = timeOffset;
112 m_SIGNAL_WIDTH = signalWidth;
113}
114
115inline uint32_t CscRODReadOut::getSourceID(uint16_t side, uint16_t rodId) const {
116 uint32_t sourceIdentifier = 0;
117 sourceIdentifier = SOURCE_ID << 24 | MODULE_TYPE << 16 | side << 8 | rodId;
118 return sourceIdentifier;
119}
120
121inline void CscRODReadOut::decodeSourceID(uint32_t sourceIDIn, uint16_t& sourceID, uint16_t& moduleType, uint16_t& subDetectorId,
122 uint16_t& rodId) const {
123 sourceID = (sourceIDIn & 0xff000000) >> 24;
124 moduleType = (sourceIDIn & 0x00ff0000) >> 16;
125 subDetectorId = (sourceIDIn & 0x0000ff00) >> 8;
126 rodId = (sourceIDIn & 0x000000ff);
127}
128
129inline void CscRODReadOut::set32bits(const uint16_t* v16, uint32_t& v32) const {
130 uint32_t p = 0, v = 0;
131 uint16_t n = 2;
132 uint16_t pos[] = {16, 0};
133 for (uint16_t i = 0; i < n; i++) {
134 v = (uint32_t)(*(v16 + i));
135 p = (uint32_t)(*(pos + i));
136 v32 = v32 | (v << p);
137 }
138}
139
140inline bool CscRODReadOut::isDPU(const uint32_t fragment) const { return (fragment == DPU_HEADER_MARKER); }
141
142inline bool CscRODReadOut::discard(const uint32_t fragment) const { return (fragment == DPU_DISCARD); }
143
144inline bool CscRODReadOut::isAmplitude(const uint16_t fragment) const {
145 uint16_t amplitudeTest = (fragment >> 12);
146 return (amplitudeTest == BODY_AMPLITUDE);
147}
148
149inline bool CscRODReadOut::isAddress(const uint32_t fragment) const {
150 uint32_t addressTest = (fragment >> 17);
151 return (addressTest == BODY_ADDRESS);
152}
153
154inline void CscRODReadOut::decodeAmplitude(const uint32_t fragment, uint16_t& amp1, uint16_t& amp2) const {
155 amp2 = 0x0000FFFF & fragment;
156 amp1 = (0xFFFF0000 & fragment) >> 16;
157}
158
159inline uint32_t CscRODReadOut::fragmentToAddress(const uint32_t fragment) const { return 0x0001FFFF & fragment; }
160
161inline Identifier CscRODReadOut::decodeAddress(const uint32_t address) const {
162 int stationName = ((address & 0x00010000) >> 16) + 50;
163 int stationEta = (((address & 0x00001000) >> 12) == 0x0) ? -1 : 1;
164 int stationPhi = ((address & 0x0000E000) >> 13) + 1;
165
166 return m_cscIdHelper->elementID(stationName, stationEta, stationPhi);
167}
168
169// module Id is given and strip is from address.
170// This should be flipped.
171inline Identifier CscRODReadOut::decodeAddress(const uint32_t address, const Identifier& moduleId) const {
172 int chamberLayer = ((address & 0x00000800) >> 11) + m_chamberBitValue;
173
174 int wireLayer = ((address & 0x00000600) >> 9) + 1;
175 int measuresPhi = ((address & 0x00000100) >> 8);
176
177 int strip = (address & 0x000000FF) + 1;
178
179 int stationEta = (((address & 0x00001000) >> 12) == 0x0) ? -1 : 1;
180
181 // Added to Online -> Offline id in A side number is opposite bug#56002
182 if (measuresPhi) {
183 if (stationEta > 0) strip = 49 - strip;
184 }
185
186 return m_cscIdHelper->channelID(moduleId, chamberLayer, wireLayer, measuresPhi, strip);
187}
188
189// module Id is given and strip is from address.
190// This should be flipped.
191inline Identifier CscRODReadOut::decodeAddress(const uint32_t address, const Identifier& moduleId, int j) const {
192 int chamberLayer = ((address & 0x00000800) >> 11) + m_chamberBitValue;
193
194 int wireLayer = ((address & 0x00000600) >> 9) + 1;
195 int measuresPhi = ((address & 0x00000100) >> 8);
196 int strip = (address & 0x000000FF) + 1 + j;
197
198 // Added to Online -> Offline id in A side number is opposite bug#56002
199 if (measuresPhi) {
200 int stationEta = (((address & 0x00001000) >> 12) == 0x0) ? -1 : 1;
201 if (stationEta > 0) strip = 49 - strip;
202 }
203
204 return m_cscIdHelper->channelID(moduleId, chamberLayer, wireLayer, measuresPhi, strip);
205}
206
207// module Id is given and strip is from address.
208// This should be flipped.
209inline uint32_t CscRODReadOut::hashIdentifier(const uint32_t address, const Identifier& moduleId) const {
210 int chamberLayer = ((address & 0x00000800) >> 11) + m_chamberBitValue;
211
212 int wireLayer = ((address & 0x00000600) >> 9) + 1;
213 int measuresPhi = ((address & 0x00000100) >> 8);
214 int strip = (address & 0x000000FF) + 1;
215
216 // Added to Online -> Offline id in A side number is opposite bug#56002
217 if (measuresPhi) {
218 int stationEta = (((address & 0x00001000) >> 12) == 0x0) ? -1 : 1;
219 if (stationEta > 0) strip = 49 - strip;
220 }
221
222 Identifier id = m_cscIdHelper->channelID(moduleId, chamberLayer, wireLayer, measuresPhi, strip);
223 IdContext context = m_cscIdHelper->channel_context();
224 IdentifierHash hash;
225 if (m_cscIdHelper->get_hash(id, hash, &context)){
226 throw (std::runtime_error("CscRODReadOut::hashIdentifier: Unable to get identifier!"));
227 };
228 return (uint32_t)hash;
229}
230
231inline uint32_t CscRODReadOut::numberOfStrips(const uint32_t fragment) const {
232 uint32_t address = fragmentToAddress(fragment);
233 Identifier moduleId = decodeAddress(address);
234 Identifier channelId = decodeAddress(address, moduleId);
235 return uint32_t(m_cscIdHelper->stripMax(channelId));
236}
237
238// get the signal amplitude for a given sampling time (ns)
239inline double CscRODReadOut::signal_amplitude(double samplingTime) const {
240 if (samplingTime <= m_TIME_OFFSET) return 0.0;
241 double z = (samplingTime - m_TIME_OFFSET) / m_SIGNAL_WIDTH;
242 return signal(z) / m_norm;
243}
244
245// signal amplitude as a function of the time bin z
246inline double CscRODReadOut::signal(double z) const {
247 double amplitude = (1.0 - z / (1 + m_NUMBER_OF_INTEGRATION)) * std::pow(z, m_NUMBER_OF_INTEGRATION) * exp(-z);
248 return amplitude;
249}
250
251// find the address of this strip
252// This function is called by CscDigitToCscRdoTool
253// so return address should be consistent to online
254inline uint32_t CscRODReadOut::address(const Identifier& channelId, int& eta, int& phi) const {
255 // unpack the strip identifier
256 int name = m_cscIdHelper->stationName(channelId);
257 eta = m_cscIdHelper->stationEta(channelId);
258 phi = m_cscIdHelper->stationPhi(channelId);
259 int chamberLayer = m_cscIdHelper->chamberLayer(channelId);
260 int wireLayer = m_cscIdHelper->wireLayer(channelId);
261 int orientation = m_cscIdHelper->measuresPhi(channelId);
262 int strip = m_cscIdHelper->strip(channelId);
263
264 // NOPE. Don't flip it!! This strip is for CscDigitToCscRdoTool online address
265
266 // redefine the ranges
267 uint32_t nameIndex = uint32_t(name - 50);
268 uint32_t etaIndex = (eta == -1) ? 0 : 1;
269 uint32_t phiIndex = uint32_t(phi - 1);
270 uint32_t chamberIndex = uint32_t(chamberLayer - 0);
271 uint32_t layerIndex = uint32_t(wireLayer - 1);
272 uint32_t stripType = uint32_t(orientation);
273 uint32_t stripNumber = uint32_t(strip - 1);
274
275 if (m_chamberBitValue == 1) chamberIndex = uint32_t(chamberLayer - 1);
276
277 // build the address
278 uint32_t address =
279 nameIndex << 16 | phiIndex << 13 | etaIndex << 12 | chamberIndex << 11 | layerIndex << 9 | stripType << 8 | stripNumber;
280
281 return address;
282}
283
284#endif // MUONCSC_CNVTOOL_CSCRODREADOUT_H
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define z
void decodeSourceID(uint32_t sourceIdIDIn, uint16_t &sourceID, uint16_t &moduleType, uint16_t &subDetectorId, uint16_t &rodId) const
static const uint32_t BODY_ADDRESS
static const uint16_t MODULE_TYPE
Identifier decodeAddress(const uint32_t address) const
bool isAddress(const uint32_t fragment) const
uint32_t numSamples() const
uint32_t m_chamberBitValue
uint32_t dpuHeader() const
void setParams(double timeOffset, double signalWidth)
static const uint32_t ROD_FOOTER_SIZE
uint32_t hashIdentifier(const uint32_t address, const Identifier &moduleId) const
bool discard(const uint32_t fragment) const
uint32_t numDPU() const
static const uint16_t SOURCE_ID
double signal_amplitude(double samplingTime) const
void set32bits(const uint16_t *v16, uint32_t &v32) const
bool isAmplitude(const uint16_t fragment) const
static const uint32_t RATE
uint32_t numberOfStrips(const uint32_t fragment) const
~CscRODReadOut()=default
void encodeFragments(const std::vector< uint16_t > &amplitude, std::vector< uint32_t > &v) const
void set(const CscIdHelper *cscIdHelper)
static const uint32_t ROD_HEADER_SIZE
double m_TIME_OFFSET
void decodeAmplitude(const uint32_t fragment, uint16_t &amp1, uint16_t &amp2) const
static const uint32_t DPU_DISCARD
static const uint32_t NUM_DPU
MHz.
static const uint32_t LATENCY
uint32_t latency() const
static const uint16_t BODY_AMPLITUDE
double getMaxTimeBin() const
static int findCharge(double samplingTime, const std::vector< uint16_t > &amplitude, double &time)
int m_NUMBER_OF_INTEGRATION
void setChamberBitVaue(uint32_t value)
uint32_t getHeaderSize() const
bool isDPU(const uint32_t fragment) const
uint32_t fragmentToAddress(const uint32_t fragment) const
static const uint32_t NUM_SAMPLES
uint32_t getSourceID(uint16_t side, uint16_t rodId) const
uint32_t dpuHeaderSize() const
double getConversion() const
double m_SIGNAL_WIDTH
uint32_t address(const Identifier &channelId, int &eta, int &phi) const
uint32_t samplingRate() const
double m_CHARGE_TO_ADC_COUNT
const CscIdHelper * m_cscIdHelper
uint32_t getFooterSize() const
double getStartTime() const
static const uint32_t DPU_HEADER_MARKER
static const uint32_t DPU_HEADER_SIZE
double signal(double z) const
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.