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) const {
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 
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  const auto st_buffer = preconstructCheckFEDSpyBuffer(input);
115  if (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
116  edm::LogWarning("SiStripSpyUnpacker")
117  << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": "
118  << "An exception of category 'FEDBuffer' occurred.\n"
119  << st_buffer;
120  continue;
121  }
123  if (!buffer.doChecks() && !allowIncompleteEvents_) {
124  edm::LogWarning("SiStripSpyUnpacker")
125  << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": "
126  << "An exception of category 'FEDSpyBuffer' occurred.\n"
127  << "FED Buffer check fails for FED ID " << lFedId << ".";
128  continue;
129  }
130  // end of buffer reset try.
131 
132  // Get the event counter values
133  uint32_t totalEvCount = buffer.spyHeaderTotalEventCount();
134  uint32_t l1ID = buffer.spyHeaderL1ID();
135 
136  uint32_t lGRun = buffer.globalRunNumber();
137 
138  //for the first fed, put it as reference value for others
139  if (lRef == 0)
140  lRef = lGRun;
141  if (lGRun != lRef) {
142  edm::LogError("SiStripSpyUnpacker") << " -- Global run encoded in buffer for FED " << lFedId << ": " << lGRun
143  << " is different from reference value " << lRef << std::endl;
144  }
145 
146  // Add event counters
147  (*pL1ACounts)[lFedId] = l1ID;
148  (*pTotalEventCounts)[lFedId] = totalEvCount;
149 
150  //iterate through FED channels, extract payload and create Digis
151  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
152  std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
153  for (; iconn != endconn; ++iconn) {
154  //check if fed connection is valid
155  if (!iconn->isConnected()) {
156  continue;
157  }
158 
159  //FED channel
160  uint16_t chan = iconn->fedCh();
161 
162  //check values are valid:
163  if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId) {
164  if (edm::isDebugEnabled()) {
165  std::ostringstream ss;
166  ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId
167  << ", iconn->fedCh() = " << chan << std::endl;
168  edm::LogWarning("SiStripSpyUnpacker") << ss.str();
169  }
170  continue;
171  }
172 
173  //check FED channel
174  if (!buffer.channelGood(chan)) {
175  if (edm::isDebugEnabled()) {
176  std::ostringstream ss;
177  ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
178  edm::LogWarning("SiStripSpyUnpacker") << ss.str();
179  }
180  continue;
181  }
182 
183  //determine key from cabling
184  const uint32_t key = ((lFedId & sistrip::invalid_) << 16) | (chan & sistrip::invalid_);
185 
186  // Start a new channel in the filler
187  dsvFiller.newChannel(key);
188  // Create the unpacker object
190 
191  // Unpack the data into dsv filler
192  while (unpacker.hasData()) {
193  dsvFiller.addItem(SiStripRawDigi{unpacker.adc()});
194  unpacker++;
195  }
196  } // end of channel loop
197 
198  } //fed loop
199 
200  //set the run number
201  *aRunRef = lRef;
202 
203  //create DSV to return
204  std::unique_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
205  pDigis->swap(*pResult);
206 
207  } // end of SpyUnpacker::createDigis method.
208 
209 } // namespace sistrip
bool isDebugEnabled()
static const uint16_t FED_ID_MIN
FEDBufferStatusCode preconstructCheckFEDSpyBuffer(const FEDRawData &fedBuffer)
void newChannel(const uint32_t key, const uint16_t firstItem=0)
static const uint16_t SPY_SAMPLES_PER_CHANNEL
std::vector< uint32_t > Counters
Log< level::Error, false > LogError
void swap(DetSetVector &other)
sistrip classes
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:47
std::unique_ptr< edm::DetSetVector< T > > createDetSetVector()
const bool allowIncompleteEvents_
void createDigis(const SiStripFedCabling &, const FEDRawDataCollection &, RawDigis *pDigis, const std::vector< uint32_t > &ids, Counters *pTotalEventCounts, Counters *pL1ACounts, uint32_t *aRunRef) const
Creates the scope mode digis for the supplied FED IDs or detIds and stores event counters.
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
static const uint16_t invalid_
Definition: Constants.h:16
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
static const uint16_t FED_ID_MAX
Log< level::Warning, false > LogWarning
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
FedsConstIterRange fedIds() const
ConnsConstIterRange fedConnections(uint16_t fed_id) const