CMS 3D CMS Logo

SiStripSpyDigiConverter.cc
Go to the documentation of this file.
1 #include <memory>
2 
3 #include <vector>
4 
7 
13 
16 
19 
22 
23 namespace sistrip {
24 
25  std::unique_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::extractPayloadDigis(
26  const DSVRawDigis* inputScopeDigis,
27  std::vector<uint32_t>* pAPVAddresses,
28  const bool discardDigisWithAPVAddrErr,
30  const uint16_t expectedPos) {
31  // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
32  std::vector<DetSetRawDigis> outputData;
33  outputData.reserve(inputScopeDigis->size());
34 
35  //APV address vector indexed by fedid, majority value written.
36  pAPVAddresses->resize(sistrip::FED_ID_MAX + 1, 0);
37  std::vector<uint16_t> lAddrVec;
38  lAddrVec.reserve(2 * sistrip::FEDCH_PER_FED);
39  uint16_t lPreviousFedId = 0;
40  std::vector<uint16_t> lHeaderBitVec;
41  lHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
42  std::vector<uint16_t> lTrailBitVec;
43  lTrailBitVec.reserve(sistrip::FEDCH_PER_FED);
44 
45  //local DSVRawDigis per FED
46  std::vector<DSVRawDigis::const_iterator> lFedScopeDigis;
47  lFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
48 
49  // Loop over channels in input collection
50  DSVRawDigis::const_iterator inputChannel = inputScopeDigis->begin();
51  const DSVRawDigis::const_iterator endChannels = inputScopeDigis->end();
52  bool hasBeenProcessed = false;
53 
54  for (; inputChannel != endChannels; ++inputChannel) {
55  const uint32_t lFedIndex = inputChannel->detId();
56  const uint16_t fedId = static_cast<uint16_t>((lFedIndex >> 16) & 0xFFFF);
57 
58  // Fill frame parameters. Second parameter is to print debug info (if logDebug enabled....)
59  const sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*inputChannel, false);
60 
61  if (lPreviousFedId == 0) {
62  lPreviousFedId = fedId;
63  }
64 
65  //print out warning only for non-empty frames....
66  if (!sistrip::SpyUtilities::isValid(lFrame, aQuality, expectedPos)) {
68  // edm::LogWarning("SiStripSpyDigiConverter") << " FED ID: " << fedId << ", channel: " << fedCh << std::endl
69  // << sistrip::SpyUtilities::print(lFrame,
70  // std::string(" -- Invalid Frame ")
71  // );
72  }
73  continue;
74  }
75 
76  //fill local vectors per FED
77  if (fedId == lPreviousFedId) {
78  if (hasBeenProcessed)
79  hasBeenProcessed = false;
80  }
81  if (fedId != lPreviousFedId) {
82  SpyDigiConverter::processFED(lPreviousFedId,
83  discardDigisWithAPVAddrErr,
84  pAPVAddresses,
85  outputData,
86  lAddrVec,
87  lHeaderBitVec,
88  lTrailBitVec,
89  lFedScopeDigis);
90  lPreviousFedId = fedId;
91  hasBeenProcessed = true;
92  }
93  // add digis
94  lFedScopeDigis.push_back(inputChannel);
95  lAddrVec.push_back(lFrame.apvAddress.first);
96  lAddrVec.push_back(lFrame.apvAddress.second);
97  lHeaderBitVec.push_back(lFrame.firstHeaderBit);
98  lTrailBitVec.push_back(lFrame.firstTrailerBit);
99 
100  } // end of loop over channels.
101 
102  //process the last one if not already done.
103  if (!hasBeenProcessed) {
104  SpyDigiConverter::processFED(lPreviousFedId,
105  discardDigisWithAPVAddrErr,
106  pAPVAddresses,
107  outputData,
108  lAddrVec,
109  lHeaderBitVec,
110  lTrailBitVec,
111  lFedScopeDigis);
112  }
113 
114  //return DSV of output
115  return std::make_unique<DSVRawDigis>(outputData, true);
116 
117  } // end of SpyDigiConverter::extractPayloadDigis method
118 
119  void SpyDigiConverter::processFED(const uint16_t aPreviousFedId,
120  const bool discardDigisWithAPVAddrErr,
121  std::vector<uint32_t>* pAPVAddresses,
122  std::vector<DetSetRawDigis>& outputData,
123  std::vector<uint16_t>& aAddrVec,
124  std::vector<uint16_t>& aHeaderBitVec,
125  std::vector<uint16_t>& aTrailBitVec,
126  std::vector<DSVRawDigis::const_iterator>& aFedScopeDigis) {
127  //extract majority address
128  uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(aAddrVec, aPreviousFedId).first;
129  if (pAPVAddresses)
130  (*pAPVAddresses)[aPreviousFedId] = lMaj;
131 
132  //loop over iterators and fill payload
133  std::vector<DSVRawDigis::const_iterator>::iterator lIter;
134  unsigned int lCh = 0;
135  for (lIter = aFedScopeDigis.begin(); lIter != aFedScopeDigis.end(); ++lIter, ++lCh) {
136  //discard if APV address different from majority.
137  //Keep if only one of them is wrong: the other APV might be alright ??
138 
139  if (discardDigisWithAPVAddrErr && aAddrVec[2 * lCh] != lMaj && aAddrVec[2 * lCh + 1] != lMaj) {
140  continue;
141  }
142 
143  DetSetRawDigis::const_iterator iDigi = (*lIter)->begin();
144  const DetSetRawDigis::const_iterator endOfChannel = (*lIter)->end();
145 
146  if (iDigi == endOfChannel) {
147  continue;
148  }
149 
150  //header starts in sample firstHeaderBit and is 18+6 samples long
151  const DetSetRawDigis::const_iterator payloadBegin = iDigi + aHeaderBitVec[lCh] + 24;
152  const DetSetRawDigis::const_iterator payloadEnd = payloadBegin + STRIPS_PER_FEDCH;
153 
154  if (payloadEnd - iDigi >= endOfChannel - iDigi)
155  continue; // few-cases where this is possible, i.e. nothing above frame-threhsold
156 
157  // Copy data into output collection
158  // Create new detSet with same key (in this case it is the fedKey, not detId)
159  outputData.push_back(DetSetRawDigis((*lIter)->detId()));
160  std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
161  outputDetSetData.resize(STRIPS_PER_FEDCH);
162  std::vector<SiStripRawDigi>::iterator outputBegin = outputDetSetData.begin();
163  std::copy(payloadBegin, payloadEnd, outputBegin);
164  }
165 
166  aFedScopeDigis.clear();
167  aAddrVec.clear();
168  aHeaderBitVec.clear();
169  aTrailBitVec.clear();
170 
171  aAddrVec.reserve(2 * sistrip::FEDCH_PER_FED);
172  aHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
173  aTrailBitVec.reserve(sistrip::FEDCH_PER_FED);
174  aFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
175  }
176 
177  std::unique_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::reorderDigis(const DSVRawDigis* inputPayloadDigis) {
178  // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
179  std::vector<DetSetRawDigis> outputData;
180  outputData.reserve(inputPayloadDigis->size());
181 
182  // Loop over channels in input collection
183  for (DSVRawDigis::const_iterator inputChannel = inputPayloadDigis->begin();
184  inputChannel != inputPayloadDigis->end();
185  ++inputChannel) {
186  const std::vector<SiStripRawDigi>& inputDetSetData = inputChannel->data;
187  outputData.push_back(DetSetRawDigis(inputChannel->detId()));
188  std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
189  outputDetSetData.resize(STRIPS_PER_FEDCH);
190  // Copy the data into the output vector reordering
191  for (uint16_t readoutOrderStripIndex = 0; readoutOrderStripIndex < inputDetSetData.size();
192  ++readoutOrderStripIndex) {
193  const uint16_t physicalOrderStripIndex =
194  FEDStripOrdering::physicalOrderForStripInChannel(readoutOrderStripIndex);
195  outputDetSetData.at(physicalOrderStripIndex) = inputDetSetData.at(readoutOrderStripIndex);
196  }
197  }
198 
199  //return DSV of output
200  return std::make_unique<DSVRawDigis>(outputData, true);
201  } // end of SpyDigiConverter::reorderDigis method.
202 
203  std::unique_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::mergeModuleChannels(
204  const DSVRawDigis* inputPhysicalOrderChannelDigis, const SiStripFedCabling& cabling) {
205  // Create filler for detSetVector to create output (with maximum number of DetSets and digis)
206  uint16_t nFeds = static_cast<uint16_t>(FED_ID_MAX - FED_ID_MIN + 1);
207 
208  RawDigiDetSetVectorFiller dsvFiller(nFeds * FEDCH_PER_FED / 2, nFeds * FEDCH_PER_FED * STRIPS_PER_FEDCH);
209  // Loop over FEDs in cabling
210  auto iFed = cabling.fedIds().begin();
211  auto endFeds = cabling.fedIds().end();
212  for (; iFed != endFeds; ++iFed) {
213  // Loop over cabled channels
214  auto conns = cabling.fedConnections(*iFed);
215  auto iConn = conns.begin();
216  auto endConns = conns.end();
217  for (; iConn != endConns; ++iConn) {
218  // Skip channels not connected to a detector.
219  if (!iConn->isConnected())
220  continue;
221  if (iConn->detId() == sistrip::invalid32_)
222  continue;
223 
224  // Find the data from the input collection
225  const uint32_t fedIndex = ((iConn->fedId() & sistrip::invalid_) << 16) | (iConn->fedCh() & sistrip::invalid_);
226  const DSVRawDigis::const_iterator iDetSet = inputPhysicalOrderChannelDigis->find(fedIndex);
227  if (iDetSet == inputPhysicalOrderChannelDigis->end()) {
228  // NOTE: It will display this warning if channel hasn't been unpacked...
229  // Will comment out for now.
230  //edm::LogWarning("SiStripSpyDigiConverter") << "No data found for FED ID: " << iConn->fedId() << " channel: " << iConn->fedCh();
231  continue;
232  }
233 
234  // Start a new channel indexed by the detId in the filler
235  dsvFiller.newChannel(iConn->detId(), iConn->apvPairNumber() * STRIPS_PER_FEDCH);
236 
237  // Add the data
238  DetSetRawDigis::const_iterator iDigi = iDetSet->begin();
239  const DetSetRawDigis::const_iterator endDetSetDigis = iDetSet->end();
240  for (; iDigi != endDetSetDigis; ++iDigi) {
241  dsvFiller.addItem(*iDigi);
242  } // end of loop over the digis.
243  } // end of loop over channels.
244  } // end of loop over FEDs
245 
246  return dsvFiller.createDetSetVector();
247  } // end of SpyDigiConverter::mergeModuleChannels method.
248 
249 } // namespace sistrip
static uint8_t physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel)
std::pair< uint8_t, uint8_t > apvAddress
static const uint16_t FED_ID_MIN
iterator find(det_id_type id)
Definition: DetSetVector.h:264
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
static std::unique_ptr< DSVRawDigis > reorderDigis(const DSVRawDigis *inputPayloadDigis)
static const uint32_t invalid32_
Definition: Constants.h:15
void newChannel(const uint32_t key, const uint16_t firstItem=0)
DSVRawDigis::detset DetSetRawDigis
static const uint16_t SPY_SAMPLES_PER_CHANNEL
const Frame extractFrameInfo(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, bool aPrintDebug=false)
void fedIndex(uint32_t aFedIndex, uint16_t &aFedId, uint16_t &aFedChannel)
sistrip classes
static std::unique_ptr< DSVRawDigis > extractPayloadDigis(const DSVRawDigis *inputScopeDigis, std::vector< uint32_t > *pAPVAddresses, const bool discardDigisWithAPVAddrErr, const sistrip::SpyUtilities::FrameQuality &aQuality, const uint16_t expectedPos)
Extract frames from the scope digis.
size_type size() const
Return the number of contained DetSets.
Definition: DetSetVector.h:259
std::unique_ptr< edm::DetSetVector< T > > createDetSetVector()
static std::unique_ptr< DSVRawDigis > mergeModuleChannels(const DSVRawDigis *inputPhysicalOrderChannelDigis, const SiStripFedCabling &cabling)
std::pair< uint16_t, uint32_t > findMajorityValue(std::vector< uint16_t > &values, const uint16_t aFedId=0)
iterator end()
Return the off-the-end iterator.
Definition: DetSetVector.h:325
static const uint16_t STRIPS_PER_FEDCH
Constants and enumerated types for FED/FEC systems.
static const uint16_t invalid_
Definition: Constants.h:16
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
static const uint16_t FEDCH_PER_FED
static void processFED(const uint16_t aPreviousFedId, const bool discardDigisWithAPVAddrErr, std::vector< uint32_t > *pAPVAddresses, std::vector< DetSetRawDigis > &outputData, std::vector< uint16_t > &aAddrVec, std::vector< uint16_t > &aHeaderBitVec, std::vector< uint16_t > &aTrailBitVec, std::vector< DSVRawDigis::const_iterator > &aFedScopeDigis)
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:314
static const uint16_t FED_ID_MAX
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:102
FedsConstIterRange fedIds() const
ConnsConstIterRange fedConnections(uint16_t fed_id) const