CMS 3D CMS Logo

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