CMS 3D CMS Logo

SiStripSpyUnpacker.cc
Go to the documentation of this file.
1 /* \file SiStripSpyUnpacker.cc
2  * \brief Source code for the SpyChannel unpacking factory.
3  */
6 
9 
15 
17 
20 
21 #include <algorithm>
22 #include <vector>
23 #include <ext/algorithm>
24 
25 using namespace std;
26 
27 namespace sistrip {
28 
29  SpyUnpacker::SpyUnpacker(const bool allowIncompleteEvents) : allowIncompleteEvents_(allowIncompleteEvents) {
30  if (edm::isDebugEnabled()) {
31  LogTrace("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
32  << " Constructing object...";
33  }
34  } // end of SpyUnpacker constructor.
35 
37  if (edm::isDebugEnabled()) {
38  LogTrace("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
39  << " Destructing object...";
40  }
41  } // end of SpyUnpacker destructor.
42 
44  const FEDRawDataCollection& buffers,
45  RawDigis* pDigis,
46  const std::vector<uint32_t>& ids,
47  Counters* pTotalEventCounts,
48  Counters* pL1ACounts,
49  uint32_t* aRunRef) {
50  //create DSV filler to fill output
51 
52  //As of Feb 2010, bug in DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h:
53  //number of feds=max-min+1 (440...). Corrected in head of DataFormats/SiStripCommon package.
54 
55  uint16_t nFeds = static_cast<uint16_t>(FED_ID_MAX - FED_ID_MIN + 1);
56 
57  RawDigiDetSetVectorFiller dsvFiller(nFeds * FEDCH_PER_FED, nFeds * FEDCH_PER_FED * SPY_SAMPLES_PER_CHANNEL);
58 
59  //check if FEDs found in cabling map and event data
60  if (edm::isDebugEnabled()) {
61  if (cabling.fedIds().empty()) {
62  edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
63  << " No FEDs found in cabling map!";
64  }
65  }
66 
67  //retrieve FED ids from cabling map and iterate through
68  std::vector<uint32_t>::const_iterator ifed = ids.begin();
69  std::vector<uint32_t>::const_iterator endfed = ids.end();
70 
71  //reference value for run number
72  //encoded per fed but should be the same for all feds
73  uint32_t lRef = 0;
74 
75  //initialise counter vectors to FED_ID_MAX+1
76  pTotalEventCounts->resize(FED_ID_MAX + 1, 0);
77  pL1ACounts->resize(FED_ID_MAX + 1, 0);
78 
79  for (; ifed != endfed; ++ifed) {
80  uint32_t lFedId = (*ifed);
81 
82  //check the fedid is valid:
83  if (lFedId < FED_ID_MIN || lFedId > FED_ID_MAX) {
84  if (edm::isDebugEnabled()) {
85  edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
86  << " Invalid FED id provided: " << lFedId;
87  }
88  continue;
89  }
90 
91  //retrieve FED raw data for given FED
92  const FEDRawData& input = buffers.FEDData(static_cast<int>(lFedId));
93  //check on FEDRawData pointer
94  if (!input.data()) {
95  if (edm::isDebugEnabled()) {
96  edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
97  << " NULL pointer to FEDRawData for FED id " << lFedId;
98  }
99  continue;
100  }
101  //check on FEDRawData size
102  if (!input.size()) {
103  if (edm::isDebugEnabled()) {
104  edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
105  << " FEDRawData has zero size for FED id " << lFedId;
106  }
107  continue;
108  }
109 
110  //get the cabling connections for this FED
111  auto conns = cabling.fedConnections(lFedId);
112 
113  //construct FEDBuffer
114  std::unique_ptr<sistrip::FEDSpyBuffer> buffer;
115  try {
116  buffer.reset(new sistrip::FEDSpyBuffer(input.data(), input.size()));
117  if (!buffer->doChecks() && !allowIncompleteEvents_) {
118  throw cms::Exception("FEDSpyBuffer") << "FED Buffer check fails for FED ID " << lFedId << ".";
119  }
120  } catch (const cms::Exception& e) {
121  if (edm::isDebugEnabled()) {
122  edm::LogWarning("SiStripSpyUnpacker")
123  << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": " << e.what();
124  }
125  continue;
126  } // end of buffer reset try.
127 
128  // Get the event counter values
129  uint32_t totalEvCount = buffer->spyHeaderTotalEventCount();
130  uint32_t l1ID = buffer->spyHeaderL1ID();
131 
132  uint32_t lGRun = buffer->globalRunNumber();
133 
134  //for the first fed, put it as reference value for others
135  if (lRef == 0)
136  lRef = lGRun;
137  if (lGRun != lRef) {
138  edm::LogError("SiStripSpyUnpacker") << " -- Global run encoded in buffer for FED " << lFedId << ": " << lGRun
139  << " is different from reference value " << lRef << std::endl;
140  }
141 
142  // Add event counters
143  (*pL1ACounts)[lFedId] = l1ID;
144  (*pTotalEventCounts)[lFedId] = totalEvCount;
145 
146  //iterate through FED channels, extract payload and create Digis
147  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
148  std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
149  for (; iconn != endconn; ++iconn) {
150  //check if fed connection is valid
151  if (!iconn->isConnected()) {
152  continue;
153  }
154 
155  //FED channel
156  uint16_t chan = iconn->fedCh();
157 
158  //check values are valid:
159  if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId) {
160  if (edm::isDebugEnabled()) {
161  std::ostringstream ss;
162  ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId
163  << ", iconn->fedCh() = " << chan << std::endl;
164  edm::LogWarning("SiStripSpyUnpacker") << ss.str();
165  }
166  continue;
167  }
168 
169  //check FED channel
170  if (!buffer->channelGood(chan)) {
171  if (edm::isDebugEnabled()) {
172  std::ostringstream ss;
173  ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
174  edm::LogWarning("SiStripSpyUnpacker") << ss.str();
175  }
176  continue;
177  }
178 
179  //determine key from cabling
180  const uint32_t key = ((lFedId & sistrip::invalid_) << 16) | (chan & sistrip::invalid_);
181 
182  // Start a new channel in the filler
183  dsvFiller.newChannel(key);
184  // Create the unpacker object
185  sistrip::FEDSpyChannelUnpacker unpacker = sistrip::FEDSpyChannelUnpacker(buffer->channel(chan));
186 
187  // Unpack the data into dsv filler
188  while (unpacker.hasData()) {
189  dsvFiller.addItem(unpacker.adc());
190  unpacker++;
191  }
192  } // end of channel loop
193 
194  } //fed loop
195 
196  //set the run number
197  *aRunRef = lRef;
198 
199  //create DSV to return
200  std::unique_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
201  pDigis->swap(*pResult);
202 
203  } // end of SpyUnpacker::createDigis method.
204 
205 } // namespace sistrip
bool isDebugEnabled()
static const uint16_t FED_ID_MIN
void createDigis(const SiStripFedCabling &, const FEDRawDataCollection &, RawDigis *pDigis, const std::vector< uint32_t > &ids, Counters *pTotalEventCounts, Counters *pL1ACounts, uint32_t *aRunRef)
Creates the scope mode digis for the supplied FED IDs or detIds and stores event counters.
void newChannel(const uint32_t key, const uint16_t firstItem=0)
static const uint16_t SPY_SAMPLES_PER_CHANNEL
std::vector< uint32_t > Counters
char const * what() const override
Definition: Exception.cc:103
void swap(DetSetVector &other)
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
sistrip classes
static std::string const input
Definition: EdmProvDump.cc:48
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
std::unique_ptr< edm::DetSetVector< T > > createDetSetVector()
const bool allowIncompleteEvents_
FedsConstIterRange fedIds() const
#define LogTrace(id)
static const uint16_t invalid_
Definition: Constants.h:16
ConnsConstIterRange fedConnections(uint16_t fed_id) const
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
static const uint16_t FEDCH_PER_FED
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
static const uint16_t FED_ID_MAX