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) :
30  allowIncompleteEvents_(allowIncompleteEvents)
31  {
32  if ( edm::isDebugEnabled() ) {
33  LogTrace("SiStripSpyUnpacker")
34  << "[sistrip::SpyUnpacker::"<<__func__<<"]"
35  <<" Constructing object...";
36  }
37  } // end of SpyUnpacker constructor.
38 
40  if ( edm::isDebugEnabled() ) {
41  LogTrace("SiStripSpyUnpacker")
42  << "[sistrip::SpyUnpacker::"<<__func__<<"]"
43  << " Destructing object...";
44  }
45  } // end of SpyUnpacker destructor.
46 
48  const FEDRawDataCollection& buffers,
49  RawDigis* pDigis,
50  const std::vector<uint32_t> & ids,
51  Counters* pTotalEventCounts,
52  Counters* pL1ACounts,
53  uint32_t* aRunRef)
54  {
55  //create DSV filler to fill output
56 
57  //As of Feb 2010, bug in DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h:
58  //number of feds=max-min+1 (440...). Corrected in head of DataFormats/SiStripCommon package.
59 
60  uint16_t nFeds = static_cast<uint16_t>( FED_ID_MAX - FED_ID_MIN + 1);
61 
62  RawDigiDetSetVectorFiller dsvFiller(nFeds*FEDCH_PER_FED,nFeds*FEDCH_PER_FED*SPY_SAMPLES_PER_CHANNEL);
63 
64  //check if FEDs found in cabling map and event data
65  if ( edm::isDebugEnabled() ) {
66  if ( cabling.fedIds().empty() ) {
67  edm::LogWarning("SiStripSpyUnpacker")
68  << "[sistrip::SpyUnpacker::" << __func__ << "]"
69  << " No FEDs found in cabling map!";
70  }
71  }
72 
73  //retrieve FED ids from cabling map and iterate through
74  std::vector<uint32_t>::const_iterator ifed = ids.begin();
75  std::vector<uint32_t>::const_iterator endfed = ids.end();
76 
77  //reference value for run number
78  //encoded per fed but should be the same for all feds
79  uint32_t lRef = 0;
80 
81  //initialise counter vectors to FED_ID_MAX+1
82  pTotalEventCounts->resize(FED_ID_MAX+1,0);
83  pL1ACounts->resize(FED_ID_MAX+1,0);
84 
85  for ( ; ifed != endfed; ++ifed ) {
86 
87  uint32_t lFedId = (*ifed);
88 
89  //check the fedid is valid:
90  if (lFedId < FED_ID_MIN || lFedId > FED_ID_MAX) {
91  if ( edm::isDebugEnabled() ) {
92  edm::LogWarning("SiStripSpyUnpacker")
93  << "[sistrip::SpyUnpacker::" << __func__ << "]"
94  << " Invalid FED id provided: "
95  << lFedId;
96  }
97  continue;
98  }
99 
100  //retrieve FED raw data for given FED
101  const FEDRawData& input = buffers.FEDData( static_cast<int>(lFedId) );
102  //check on FEDRawData pointer
103  if ( !input.data() ) {
104  if ( edm::isDebugEnabled() ) {
105  edm::LogWarning("SiStripSpyUnpacker")
106  << "[sistrip::SpyUnpacker::" << __func__ << "]"
107  << " NULL pointer to FEDRawData for FED id "
108  << lFedId;
109  }
110  continue;
111  }
112  //check on FEDRawData size
113  if ( !input.size() ) {
114  if ( edm::isDebugEnabled() ) {
115  edm::LogWarning("SiStripSpyUnpacker")
116  << "[sistrip::SpyUnpacker::" << __func__ << "]"
117  << " FEDRawData has zero size for FED id "
118  << lFedId;
119  }
120  continue;
121  }
122 
123  //get the cabling connections for this FED
124  auto conns = cabling.fedConnections(lFedId);
125 
126  //construct FEDBuffer
127  std::unique_ptr<sistrip::FEDSpyBuffer> buffer;
128  try {
129  buffer.reset(new sistrip::FEDSpyBuffer(input.data(),input.size()));
130  if (!buffer->doChecks() && !allowIncompleteEvents_) {
131  throw cms::Exception("FEDSpyBuffer") << "FED Buffer check fails for FED ID " << lFedId << ".";
132  }
133  } catch (const cms::Exception& e) {
134  if ( edm::isDebugEnabled() ) {
135  edm::LogWarning("SiStripSpyUnpacker")
136  << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": " << e.what();
137  }
138  continue;
139  } // end of buffer reset try.
140 
141  // Get the event counter values
142  uint32_t totalEvCount = buffer->spyHeaderTotalEventCount();
143  uint32_t l1ID = buffer->spyHeaderL1ID();
144 
145  uint32_t lGRun = buffer->globalRunNumber();
146 
147  //for the first fed, put it as reference value for others
148  if (lRef == 0) lRef = lGRun;
149  if (lGRun != lRef){
150  edm::LogError("SiStripSpyUnpacker")
151  << " -- Global run encoded in buffer for FED " << lFedId << ": "
152  << lGRun << " is different from reference value " << lRef
153  << std::endl;
154  }
155 
156  // Add event counters
157  (*pL1ACounts)[lFedId] = l1ID;
158  (*pTotalEventCounts)[lFedId] = totalEvCount;
159 
160  //iterate through FED channels, extract payload and create Digis
161  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
162  std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
163  for ( ; iconn != endconn; ++iconn ) {
164 
165  //check if fed connection is valid
166  if ( !iconn->isConnected()) { continue; }
167 
168  //FED channel
169  uint16_t chan = iconn->fedCh();
170 
171  //check values are valid:
172  if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId){
173  if (edm::isDebugEnabled()) {
174  std::ostringstream ss;
175  ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId << ", iconn->fedCh() = " << chan << std::endl;
176  edm::LogWarning("SiStripSpyUnpacker") << ss.str();
177  }
178  continue;
179  }
180 
181  //check FED channel
182  if (!buffer->channelGood(chan)) {
183  if (edm::isDebugEnabled()) {
184  std::ostringstream ss;
185  ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
186  edm::LogWarning("SiStripSpyUnpacker") << ss.str();
187  }
188  continue;
189  }
190 
191  //determine key from cabling
192  const uint32_t key = ( ( lFedId & sistrip::invalid_ ) << 16 ) | ( chan & sistrip::invalid_ );
193 
194  // Start a new channel in the filler
195  dsvFiller.newChannel(key);
196  // Create the unpacker object
197  sistrip::FEDSpyChannelUnpacker unpacker = sistrip::FEDSpyChannelUnpacker(buffer->channel(chan));
198 
199  // Unpack the data into dsv filler
200  while (unpacker.hasData()) {
201  dsvFiller.addItem(unpacker.adc());
202  unpacker++;
203  }
204  } // end of channel loop
205 
206  } //fed loop
207 
208  //set the run number
209  *aRunRef = lRef;
210 
211  //create DSV to return
212  std::unique_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
213  pDigis->swap(*pResult);
214 
215  } // end of SpyUnpacker::createDigis method.
216 
217 } // end of sistrip namespace.
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:47
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:28
static const uint16_t FED_ID_MAX