CMS 3D CMS Logo

ClustersFromRawProducer.cc
Go to the documentation of this file.
1 /*
2  */
5 
8 
9 
12 
16 
18 
19 
26 
27 
29 #include <sstream>
30 #include <memory>
31 #include <atomic>
32 #include <mutex>
33 
35 
36 
37 // #define VIDEBUG
38 #ifdef VIDEBUG
39 #include<iostream>
40 #define COUT std::cout << "VI "
41 #else
42 #define COUT LogDebug("")
43 #endif
44 
45 
46 namespace {
47  std::unique_ptr<sistrip::FEDBuffer> fillBuffer(int fedId, const FEDRawDataCollection& rawColl) {
48  std::unique_ptr<sistrip::FEDBuffer> buffer;
49 
50  // Retrieve FED raw data for given FED
51  const FEDRawData& rawData = rawColl.FEDData(fedId);
52 
53  // Check on FEDRawData pointer
54  if UNLIKELY( !rawData.data() ) {
55  if (edm::isDebugEnabled()) {
57  << "[ClustersFromRawProducer::"
58  << __func__
59  << "]"
60  << " NULL pointer to FEDRawData for FED id "
61  << fedId;
62  }
63  return buffer;
64  }
65 
66  // Check on FEDRawData size
67  if UNLIKELY( !rawData.size() ) {
68  if (edm::isDebugEnabled()) {
70  << "[ClustersFromRawProducer::"
71  << __func__ << "]"
72  << " FEDRawData has zero size for FED id "
73  << fedId;
74  }
75  return buffer;
76  }
77 
78  // construct FEDBuffer
79  try {
80  buffer.reset(new sistrip::FEDBuffer(rawData.data(),rawData.size()));
81  if UNLIKELY(!buffer->doChecks(false)) throw cms::Exception("FEDBuffer") << "FED Buffer check fails for FED ID" << fedId << ".";
82  }
83  catch (const cms::Exception& e) {
84  if (edm::isDebugEnabled()) {
86  << "Exception caught when creating FEDBuffer object for FED " << fedId << ": " << e.what();
87  }
88  return std::unique_ptr<sistrip::FEDBuffer>();
89  }
90 
91  /*
92  // dump of FEDRawData to stdout
93  if ( dump_ ) {
94  std::stringstream ss;
95  RawToDigiUnpacker::dumpRawData( fedId, rawData, ss );
96  LogTrace(mlRawToDigi_)
97  << ss.str();
98  }
99  */
100 
101  return buffer;
102 
103  }
104 
105 
106  class ClusterFiller final : public StripClusterizerAlgorithm::output_t::Getter {
107  public:
108  ClusterFiller(const FEDRawDataCollection& irawColl,
109  StripClusterizerAlgorithm & iclusterizer,
110  SiStripRawProcessingAlgorithms & irawAlgos,
111  bool idoAPVEmulatorCheck):
112  rawColl(irawColl),
113  clusterizer(iclusterizer),
114  rawAlgos(irawAlgos),
115  doAPVEmulatorCheck(idoAPVEmulatorCheck){
116  incTot(clusterizer.allDetIds().size());
117  for (auto & d : done) d=nullptr;
118  }
119 
120 
121  ~ClusterFiller() override { printStat();}
122 
124 
125  private:
126 
127 
128  std::unique_ptr<sistrip::FEDBuffer> buffers[1024];
129  std::atomic<sistrip::FEDBuffer*> done[1024];
130 
131 
132  const FEDRawDataCollection& rawColl;
133 
136 
137 
138  // March 2012: add flag for disabling APVe check in configuration
139  bool doAPVEmulatorCheck;
140 
141 
142 #ifdef VIDEBUG
143  struct Stat {
144  Stat() : totDet(0), detReady(0),detSet(0),detAct(0),detNoZ(0),detAbrt(0),totClus(0){}
145  std::atomic<int> totDet; // all dets
146  std::atomic<int> detReady; // dets "updated"
147  std::atomic<int> detSet; // det actually set not empty
148  std::atomic<int> detAct; // det actually set with content
149  std::atomic<int> detNoZ; // det actually set with content
150  std::atomic<int> detAbrt; // det aborted
151  std::atomic<int> totClus; // total number of clusters
152  };
153 
154  mutable Stat stat;
155  // void zeroStat() const { stat = std::move(Stat()); }
156  void incTot(int n) const { stat.totDet=n;}
157  void incReady() const { stat.detReady++;}
158  void incSet() const { stat.detSet++;}
159  void incAct() const { stat.detAct++;}
160  void incNoZ() const { stat.detNoZ++;}
161  void incAbrt() const { stat.detAbrt++;}
162  void incClus(int n) const { stat.totClus+=n;}
163  void printStat() const {
164  COUT << "VI clusters " << stat.totDet <<','<< stat.detReady <<','<< stat.detSet <<','<< stat.detAct<<','<< stat.detNoZ <<','<<stat.detAbrt <<','<<stat.totClus << std::endl;
165  }
166 
167 #else
168  static void zeroStat(){}
169  static void incTot(int){}
170  static void incReady() {}
171  static void incSet() {}
172  static void incAct() {}
173  static void incNoZ() {}
174  static void incAbrt(){}
175  static void incClus(int){}
176  static void printStat(){}
177 #endif
178 
179  };
180 
181 
182 } // namespace
183 
184 
185 
187 
188  public:
189 
191  onDemand(conf.getParameter<bool>("onDemand")),
192  cabling_(nullptr),
193  clusterizer_(StripClusterizerAlgorithmFactory::create(conf.getParameter<edm::ParameterSet>("Clusterizer"))),
194  rawAlgos_(SiStripRawProcessingFactory::create(conf.getParameter<edm::ParameterSet>("Algorithms"))),
195  doAPVEmulatorCheck_(conf.existsAs<bool>("DoAPVEmulatorCheck") ? conf.getParameter<bool>("DoAPVEmulatorCheck") : true)
196  {
197  productToken_ = consumes<FEDRawDataCollection>(conf.getParameter<edm::InputTag>("ProductLabel"));
198  produces< edmNew::DetSetVector<SiStripCluster> > ();
199  assert(clusterizer_.get());
200  assert(rawAlgos_.get());
201  }
202 
203 
204  void beginRun( const edm::Run&, const edm::EventSetup& es) override {
205  initialize(es);
206  }
207 
208 
209  void produce(edm::Event& ev, const edm::EventSetup& es) override {
210 
211  initialize(es);
212 
213  // get raw data
215  ev.getByToken( productToken_, rawData);
216 
217 
218  std::unique_ptr< edmNew::DetSetVector<SiStripCluster> >
219  output( onDemand ?
220  new edmNew::DetSetVector<SiStripCluster>(std::shared_ptr<edmNew::DetSetVector<SiStripCluster>::Getter>(std::make_shared<ClusterFiller>(*rawData, *clusterizer_,
221  *rawAlgos_, doAPVEmulatorCheck_)
222  ),
223  clusterizer_->allDetIds())
225 
226  if(onDemand) assert(output->onDemand());
227 
228  output->reserve(15000,24*10000);
229 
230 
231  if (!onDemand) {
232  run(*rawData, *output);
233  output->shrink_to_fit();
234  COUT << output->dataSize() << " clusters from "
235  << output->size() << " modules"
236  << std::endl;
237  }
238 
239  ev.put(std::move(output));
240 
241  }
242 
243 private:
244 
245  void initialize(const edm::EventSetup& es);
246 
248 
249 
250  private:
251 
252  bool onDemand;
253 
255 
257 
258  std::unique_ptr<StripClusterizerAlgorithm> clusterizer_;
259  std::unique_ptr<SiStripRawProcessingAlgorithms> rawAlgos_;
260 
261 
262  // March 2012: add flag for disabling APVe check in configuration
264 
265 };
266 
269 
270 
271 
272 
274 
275  (*clusterizer_).initialize(es);
276  cabling_ = (*clusterizer_).cabling();
277  (*rawAlgos_).initialize(es);
278 
279 }
280 
283 
284  ClusterFiller filler(rawColl, *clusterizer_, *rawAlgos_, doAPVEmulatorCheck_);
285 
286  // loop over good det in cabling
287  for ( auto idet : clusterizer_->allDetIds()) {
288 
290 
291  filler.fill(record);
292 
293  if(record.empty()) record.abort();
294 
295  } // end loop over dets
296 }
297 
299 try { // edmNew::CapacityExaustedException
300  incReady();
301 
302  auto idet= record.id();
303 
304  COUT << "filling " << idet << std::endl;
305 
306  auto const & det = clusterizer.stripByStripBegin(idet);
307  if (!det.valid()) return;
309 
310  incSet();
311 
312  // Loop over apv-pairs of det
313  for (auto const conn : clusterizer.currentConnection(det)) {
314  if UNLIKELY(!conn) continue;
315 
316  const uint16_t fedId = conn->fedId();
317 
318  // If fed id is null or connection is invalid continue
319  if UNLIKELY( !fedId || !conn->isConnected() ) { continue; }
320 
321 
322  // If Fed hasnt already been initialised, extract data and initialise
323  sistrip::FEDBuffer * buffer = done[fedId];
324  if (!buffer) {
325  buffer = fillBuffer(fedId, rawColl).release();
326  if (!buffer) { continue;}
327  sistrip::FEDBuffer * exp = nullptr;
328  if (done[fedId].compare_exchange_strong(exp, buffer)) buffers[fedId].reset(buffer);
329  else { delete buffer; buffer = done[fedId]; }
330  }
331  assert(buffer);
332 
333  // check channel
334  const uint8_t fedCh = conn->fedCh();
335 
336  if UNLIKELY(!buffer->channelGood(fedCh,doAPVEmulatorCheck)) {
337  if (edm::isDebugEnabled()) {
338  std::ostringstream ss;
339  ss << "Problem unpacking channel " << fedCh << " on FED " << fedId;
341  }
342  continue;
343  }
344 
345  // Determine APV std::pair number
346  uint16_t ipair = conn->apvPairNumber();
347 
348 
349  const sistrip::FEDReadoutMode mode = buffer->readoutMode();
350 
351 
353 
354  try {
355  // create unpacker
357 
358  // unpack
359  clusterizer.addFed(state,unpacker,ipair,record);
360  /*
361  while (unpacker.hasData()) {
362  clusterizer.stripByStripAdd(unpacker.sampleNumber()+ipair*256,unpacker.adc(),record);
363  unpacker++;
364  }
365  */
367  throw;
368  } catch (const cms::Exception& e) {
369  if (edm::isDebugEnabled()) {
370  std::ostringstream ss;
371  ss << "Unordered clusters for channel " << fedCh << " on FED " << fedId << ": " << e.what();
373  }
374  continue;
375  }
376  } else {
377 
379  try {
380  // create unpacker
382 
383  // unpack
384  clusterizer.addFed(state,unpacker,ipair,record);
385  /*
386  while (unpacker.hasData()) {
387  clusterizer.stripByStripAdd(unpacker.sampleNumber()+ipair*256,unpacker.adc(),record);
388  unpacker++;
389  }
390  */
392  throw;
393  }catch (const cms::Exception& e) {
394  if (edm::isDebugEnabled()) {
395  std::ostringstream ss;
396  ss << "Unordered clusters for channel " << fedCh << " on FED " << fedId << ": " << e.what();
398  }
399  continue;
400  }
401  } else if (mode == sistrip::READOUT_MODE_VIRGIN_RAW ) {
402 
403  // create unpacker
405 
406  // unpack
407  std::vector<int16_t> digis;
408  while (unpacker.hasData()) {
409  digis.push_back(unpacker.adc());
410  unpacker++;
411  }
412 
413  //process raw
414  uint32_t id = conn->detId();
415  edm::DetSet<SiStripDigi> zsdigis(id);
416  //rawAlgos_->subtractorPed->subtract( id, ipair*256, digis);
417  //rawAlgos_->subtractorCMN->subtract( id, digis);
418  //rawAlgos_->suppressor->suppress( digis, zsdigis);
419  uint16_t firstAPV = ipair*2;
420  rawAlgos.SuppressVirginRawData(id, firstAPV,digis, zsdigis);
421  for( edm::DetSet<SiStripDigi>::const_iterator it = zsdigis.begin(); it!=zsdigis.end(); it++) {
422  clusterizer.stripByStripAdd(state, it->strip(), it->adc(), record);
423  }
424  }
425 
426  else if (mode == sistrip::READOUT_MODE_PROC_RAW ) {
427 
428  // create unpacker
430 
431  // unpack
432  std::vector<int16_t> digis;
433  while (unpacker.hasData()) {
434  digis.push_back(unpacker.adc());
435  unpacker++;
436  }
437 
438  //process raw
439  uint32_t id = conn->detId();
440  edm::DetSet<SiStripDigi> zsdigis(id);
441  //rawAlgos_->subtractorCMN->subtract( id, digis);
442  //rawAlgos_->suppressor->suppress( digis, zsdigis);
443  uint16_t firstAPV = ipair*2;
444  rawAlgos.SuppressProcessedRawData(id, firstAPV,digis, zsdigis);
445  for( edm::DetSet<SiStripDigi>::const_iterator it = zsdigis.begin(); it!=zsdigis.end(); it++) {
446  clusterizer.stripByStripAdd(state, it->strip(), it->adc(), record);
447  }
448  } else {
450  << "[ClustersFromRawProducer::"
451  << __func__ << "]"
452  << " FEDRawData readout mode "
453  << mode
454  << " from FED id "
455  << fedId
456  << " not supported.";
457  continue;
458  }
459  }
460 
461  } // end loop over conn
462  clusterizer.stripByStripEnd(state,record);
463 
464  incAct();
465 
466  if (record.full()) {
467  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand for " << record.id() << ' ' << record.size();
468  record.abort();
469  incAbrt();
470  }
471 
472  if(!record.empty()) incNoZ();
473 
474  COUT << "filled " << record.size() << std::endl;
475  for ( auto const & cl : record ) COUT << cl.firstStrip() << ','<< cl.amplitudes().size() << std::endl;
476  incClus(record.size());
478  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand";
479 }
480 
481 }
482 
483 
iterator end()
Definition: DetSet.h:60
static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel &channel)
T getParameter(std::string const &) const
static AlgebraicMatrix initialize()
bool isDebugEnabled()
static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel &channel)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
void beginRun(const edm::Run &, const edm::EventSetup &es) override
void run(const FEDRawDataCollection &rawColl, edmNew::DetSetVector< SiStripCluster > &output)
static const char mlRawToCluster_[]
JetCorrectorParameters::Record record
Definition: classes.h:7
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel)
FEDReadoutMode readoutMode() const
bool ev
char const * what() const override
Definition: Exception.cc:141
void initialize(const edm::EventSetup &es)
#define nullptr
virtual bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck=true) const
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
void produce(edm::Event &ev, const edm::EventSetup &es) override
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
static std::auto_ptr< StripClusterizerAlgorithm > create(const edm::ParameterSet &)
std::unique_ptr< StripClusterizerAlgorithm > clusterizer_
const FEDChannel & channel(const uint8_t internalFEDChannelNum) const
iterator begin()
Definition: DetSet.h:59
static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel)
SiStripDetCabling const * cabling_
SiStripClusterizerFromRaw(const edm::ParameterSet &conf)
HLT enums.
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
#define LIKELY(x)
#define COUT
collection_type::const_iterator const_iterator
Definition: DetSet.h:33
std::unique_ptr< SiStripRawProcessingAlgorithms > rawAlgos_
edm::EDGetTokenT< FEDRawDataCollection > productToken_
def move(src, dest)
Definition: eostools.py:510
Definition: Run.h:44
#define UNLIKELY(x)