Belle II Software  release-08-01-10
eclPackerModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 //This module
9 #include <ecl/modules/eclPacker/eclPackerModule.h>
10 
11 //STL
12 #include <ios>
13 #include <iomanip>
14 
15 //Framework
16 #include <framework/logging/Logger.h>
17 
18 //ECL
19 #include <ecl/dataobjects/ECLDigit.h>
20 #include <ecl/dataobjects/ECLDsp.h>
21 
22 //Raw data
23 #include <rawdata/dataobjects/RawECL.h>
24 
25 using namespace std;
26 using namespace Belle2;
27 using namespace ECL;
28 
29 REG_MODULE(ECLPacker);
30 
31 ECLPackerModule::ECLPackerModule() :
32  m_bufPos(0),
33  m_bufLength(0),
34  m_bitPos(0),
35  m_EclWaveformSamples(),
36  m_eclMapper(),
37  m_eclRawCOPPERs("", DataStore::c_Event),
38  adcBuffer_temp(),
39  collectorMaskArray(),
40  shaperMaskArray(),
41  shaperADCMaskArray(),
42  shaperNWaveform(),
43  shaperNHits(),
44  iEclDigIndices(),
45  iEclWfIndices()
46 {
47  setDescription("The module reads ECLDigits from the DataStore and writes ECLRaw data.");
48  addParam("InitFileName", m_eclMapperInitFileName, "Initialization file", string("/ecl/data/ecl_channels_map.txt"));
49  addParam("RawCOPPERsName", m_eclRawCOPPERsName, "Name of the RawECL container", string("RawECLs"));
50  addParam("CompressMode", m_compressMode, "compress mode for ADC samples", true);
51  addParam("AmpThreshold", m_ampThreshold, "Amplitude threshold", -50);
52  addParam("PackWfRareFactor", m_WaveformRareFactor, "Pack ADC samples for one of N events. No waveform is packed if 0", 100);
53  addParam("Pcie40Data", m_pcie40Data,
54  "If true: pack data as if sent from PCIe40 boards. Otherwise: pack data as if sent from COPPERs", false);
55 }
56 
57 ECLPackerModule::~ECLPackerModule()
58 {
59 }
60 
62 {
63  // require input data
64  m_eclDigits.isRequired();
65  m_eclDsps.isOptional();
66 
67  // register output container in data store
68  m_eclRawCOPPERs.registerInDataStore(m_eclRawCOPPERsName);
69 
70  B2INFO("ECL Packer: Compress mode = " << m_compressMode);
71 }
72 
74 {
75  // Initialize channel mapper at run start to account for possible
76  // changes in ECL mapping between runs.
77  if (!m_eclMapper.initFromDB()) {
78  B2FATAL("ECL Packer: Can't initialize eclChannelMapper!");
79  }
80 
81  //TODO
82 }
83 
85 {
86  if (m_eventMetaData.isValid()) {
87  m_EvtNum = m_eventMetaData->getEvent();
88  } else {
89  m_EvtNum = -1;
90  }
91 
92  B2DEBUG(50, "EclPacker:: event called ");
93  // output data
94  m_eclRawCOPPERs.clear();
95 
96  B2DEBUG(50, "EclPacker:: output data arrays created");
97 
98  int nActiveChannelsWithADCData, nActiveDSPChannels;
99  int triggerPhase = 0, dspMask = 0;
100 
101  // get total number of hits
102  int nEclDigits = m_eclDigits.getEntries();
103  int nEclWaveform = m_eclDsps.getEntries();
104 
105  for (int i = 0; i < ECL_CRATES; i++) {
106  collectorMaskArray[i] = 0;
107  for (int j = 0; j < ECL_BARREL_SHAPERS_IN_CRATE; j++) {
108  shaperMaskArray[i][j] = 0;
109  shaperNHits[i][j] = 0;
110  shaperADCMaskArray[i][j] = 0;
111  shaperNWaveform[i][j] = 0;
112  }
113  }
114 
115  for (int j = 0; j < ECL_TOTAL_CHANNELS; j++) {
116  iEclDigIndices[j] = -1;
117  iEclWfIndices[j] = -1;
118  }
119 
120  B2DEBUG(100, "EclPacker:: N_Digits = " << nEclDigits);
121  B2DEBUG(100, "EclPacker:: N_Waveforms = " << nEclWaveform);
122 
123  int iCOPPER, iFINESSE, iCrate, iShaper, iChannel, nShapers;
124 
125  B2DEBUG(100, "EclPacker:: Hits ======>> ");
126  int tot_dsp_hits = 0;
127  // fill number of hits, masks and fill correspondance between cellID and index in container
128  for (int i_digit = 0; i_digit < nEclDigits; i_digit++) {
129  int cid = m_eclDigits[i_digit]->getCellId();
130  int amp = m_eclDigits[i_digit]->getAmp();
131 
132  if (amp < m_ampThreshold) continue;
133 
134  //TODO: Threshold
135  iCrate = m_eclMapper.getCrateID(cid);
136  iShaper = m_eclMapper.getShaperPosition(cid);
137  iChannel = m_eclMapper.getShaperChannel(cid);
138 
139  if (iCrate < 1 && iShaper < 1 && iChannel < 1) {
140  B2ERROR("Wrong crate/shaper/channel ids: " << iCrate << " " << iShaper << " " << iChannel << " for CID " << cid);
141  throw eclPacker_internal_error();
142  }
143  collectorMaskArray[iCrate - 1] |= (1 << (iShaper - 1));
144 
145  shaperMaskArray[iCrate - 1][iShaper - 1] |= (1 << (iChannel - 1));
146  shaperNHits[iCrate - 1][iShaper - 1]++;
147 
148  iEclDigIndices[cid - 1] = i_digit;
149  tot_dsp_hits++;
150  }
151 
152  B2DEBUG(100, "ECL Packer:: N Hits above threshold = " << tot_dsp_hits << " nWaveforms = " << nEclWaveform);
153 
154  if (m_WaveformRareFactor != 0)
155  if (m_EvtNum % m_WaveformRareFactor == 0) {
156  B2DEBUG(100, "ECL Packer:: Pack waveform data for this event: " << m_EvtNum);
157  for (int i_wf = 0; i_wf < nEclWaveform; i_wf++) {
158  int cid = m_eclDsps[i_wf]->getCellId();
159  iCrate = m_eclMapper.getCrateID(cid);
160  iShaper = m_eclMapper.getShaperPosition(cid);
161  iChannel = m_eclMapper.getShaperChannel(cid);
162 
163  //check corresponding amplitude in ecl digits
164  int amp = 0;
165  for (int i_digit = 0; i_digit < nEclDigits; i_digit++) {
166  if (m_eclDigits[i_digit]->getCellId() == cid) {
167  amp = m_eclDigits[i_digit]->getAmp();
168  break;
169  }
170  }
171  if (amp < m_ampThreshold) continue;
172 
173  shaperADCMaskArray[iCrate - 1][iShaper - 1] |= (1 << (iChannel - 1));
174  shaperNWaveform[iCrate - 1][iShaper - 1]++;
175 
176  iEclWfIndices[cid - 1] = i_wf;
177  }
178  }
179 
180  // fill rawCOPPERPacker data
181  RawCOPPERPackerInfo rawcprpacker_info;
182  rawcprpacker_info.exp_num = 0;
183  rawcprpacker_info.run_subrun_num = 1; // run number : 14bits, subrun # : 8bits
184  rawcprpacker_info.eve_num = m_EvtNum;
185  rawcprpacker_info.tt_ctime = 0x7123456; //??? (copy-past from CDC)
186  rawcprpacker_info.tt_utime = 0xF1234567; //???
187  rawcprpacker_info.b2l_ctime = 0x7654321; //???
188 
189 
190  B2DEBUG(100, "EclPacker:: proceed COPPERs... ");
191  B2DEBUG(100, "EclPacker:: ECL_COPPERS = " << ECL_COPPERS);
192 
193  //Set the number of nodes
194  int max_nodes;
195  if (m_pcie40Data) {
196  max_nodes = 3;
197  } else {
198  max_nodes = ECL_COPPERS;
199  }
200  const static int max_channels = MAX_PCIE40_CH;
201 
202  //cycle over all coppers
203  for (iCOPPER = 1; iCOPPER <= max_nodes; iCOPPER++) {
204  std::vector <unsigned int> buff[max_channels];
205  int channels_count;
206  if (m_pcie40Data) {
207  channels_count = iCOPPER < 3 ? 18 : 16;
208  } else {
209  channels_count = 2;
210  }
211 
212  for (int i = 0; i < max_channels; i++) buff[i].clear();
213 
214  int iCOPPERNode;
215  if (m_pcie40Data) {
216  iCOPPERNode = BECL_ID + iCOPPER;
217  } else {
218  iCOPPERNode = (iCOPPER <= ECL_BARREL_COPPERS) ? BECL_ID + iCOPPER : EECL_ID + iCOPPER - ECL_BARREL_COPPERS;
219  }
220 
221  bool skipNode = true;
222 
223  //check if at least one of FINESSES have hits
224  for (int i = 0; i < channels_count; i++) {
225  int icr = m_eclMapper.getCrateID(iCOPPERNode, i, m_pcie40Data);
226  B2DEBUG(200, "iCOPPERNode = 0x" << std::hex << iCOPPERNode << std::dec << " nCrate = " << icr);
227  if (!collectorMaskArray[icr - 1]) continue;
228  skipNode = false;
229  break;
230  }
231 
232  if (skipNode) continue;
233 
234  rawcprpacker_info.node_id = iCOPPERNode;
235 
236  // Create RawECL object
237 
238  int nwords[max_channels] = {0, 0};
239  const int finesseHeaderNWords = 3;
240 
241  //cycle over finesses in copper
242  for (iFINESSE = 0; iFINESSE < channels_count; iFINESSE++) {
243  iCrate = m_eclMapper.getCrateID(iCOPPERNode, iFINESSE, m_pcie40Data);
244 
245  nShapers = m_eclMapper.getNShapersInCrate(iCrate);
246  if (!nShapers) B2ERROR("Ecl packer:: Wrong shapers number " << nShapers);
247 
248  if (!shaperMaskArray[iCrate - 1]) continue;
249  B2DEBUG(200, "Pack data for iCrate = " << iCrate << " nShapers = " << nShapers);
250 
251  // write EclCollector header to the buffer
252  unsigned int eclCollectorHeader = (1 << nShapers) - 1;
253  if (m_compressMode) eclCollectorHeader += (1 << 12);
254  buff[iFINESSE].push_back(eclCollectorHeader);
255 
256  for (iShaper = 1; iShaper <= nShapers; iShaper++) {
257 
258  nActiveDSPChannels = shaperNHits[iCrate - 1][iShaper - 1];
259  B2DEBUG(200, "iCrate = " << iCrate << " iShaper = " << iShaper << " nActiveDSPChannels = " << nActiveDSPChannels);
260  nActiveChannelsWithADCData = shaperNWaveform[iCrate - 1][iShaper - 1];
261  B2DEBUG(200, "nActiveChannelsWithADCData = " << nActiveChannelsWithADCData);
262 
263  // write 4 words of shaper header
264 
265  unsigned int shaperDataLength = 4 + nActiveDSPChannels + nActiveChannelsWithADCData * ECL_ADC_SAMPLES_PER_CHANNEL;
266  // fill shaperDsp header
267  unsigned int shaper_header_w0 = (0x10 << 16) + (shaperDataLength & 0xFFFF);
268  buff[iFINESSE].push_back(shaper_header_w0);
269 
270  triggerPhase = 0; //?????
271  unsigned int shaper_header_w1 = (nActiveChannelsWithADCData & 0x1F) << 24;
272  shaper_header_w1 |= (ECL_ADC_SAMPLES_PER_CHANNEL & 0x7F) << 16;
273  shaper_header_w1 |= (nActiveDSPChannels & 0x1F) << 8;
274  shaper_header_w1 |= triggerPhase;
275  buff[iFINESSE].push_back(shaper_header_w1);
276 
277  dspMask = shaperMaskArray[iCrate - 1][iShaper - 1];
278  B2DEBUG(200, "dspMask = " << std::hex << dspMask);
279  unsigned int shaper_header_w2 = (dspMask & 0xFFFF) << 16;
280  shaper_header_w2 |= (m_EvtNum & 0xFFFF); // trigger tag
281  buff[iFINESSE].push_back(shaper_header_w2);
282 
283  unsigned int adcMask = shaperADCMaskArray[iCrate - 1][iShaper - 1];
284  B2DEBUG(100, "adcMask = " << std::hex << adcMask);
285  unsigned int shaper_header_w3 = (adcMask & 0xFFFF);
286  buff[iFINESSE].push_back(shaper_header_w3);
287 
288  // cycle over shaper channels and push DSP data to buffer
289  for (iChannel = 1; iChannel <= ECL_CHANNELS_IN_SHAPER; iChannel++) {
290 
291  const int cid = m_eclMapper.getCellId(iCrate, iShaper, iChannel);
292 
293  if (cid < 1) continue;
294 
295  const int i_digit = iEclDigIndices[cid - 1];
296  if (i_digit < 0) continue;
297  const int qua = m_eclDigits[i_digit]->getQuality();
298  const int amp = m_eclDigits[i_digit]->getAmp();
299  const int chi = m_eclDigits[i_digit]->getChi();
300  int tim = 0;
301  if (qua == 2) {
302  // pack chisquare
303 
304  int chi_mantissa = 0, chi_exponent = 0;
305  int n_bits = ceil(log2(double(chi)));
306  if (n_bits > 9) {
307  chi_exponent = ceil(float(n_bits - 9) / 2.0);
308  chi_mantissa = chi >> chi_exponent * 2;
309  } else {
310  chi_exponent = 0;
311  chi_mantissa = chi;
312  }
313  tim = (chi_exponent << 9) | chi_mantissa;
314  } else {
315  // pack time
316  tim = m_eclDigits[i_digit]->getTimeFit();
317  }
318  unsigned int hit_data = ((unsigned int)(qua & 3) << 30) & 0xC0000000;
319  hit_data |= (tim & 0xFFF) << 18;
320  hit_data |= ((amp + 128) & 0x3FFFF);
321  buff[iFINESSE].push_back(hit_data);
322 
323  B2DEBUG(100, "cid = " << cid << " amp = " << amp << " tim = " << tim);
324  }
325 
326  for (int i = 0; i < ECL_CHANNELS_IN_SHAPER; i++) adcBuffer_temp[i] = 0;
328  setBuffLength(static_cast<int>(ECL_ADC_SAMPLES_PER_CHANNEL) * static_cast<int>(ECL_CHANNELS_IN_SHAPER));
329  for (iChannel = 1; iChannel <= ECL_CHANNELS_IN_SHAPER; iChannel++) {
330  int cid = m_eclMapper.getCellId(iCrate, iShaper, iChannel);
331  if (cid < 1) continue;
332  int i_wf = iEclWfIndices[cid - 1];
333  if (i_wf < 0) continue;
334  B2DEBUG(200, "i_wf = " << i_wf);
335  m_eclDsps[i_wf]->getDspA(m_EclWaveformSamples); // Check this method in implementation of ECLDsp.h!!!
336 
337  if (m_compressMode) {
338  unsigned int adc_data_base = 0;
339  unsigned int adc_data_diff_width = 0;
340 
341  // calculate adc_data_base and adc_data_diff_width for compressed mode
342  unsigned int ampMin = m_EclWaveformSamples[0];
343  unsigned int ampMax = m_EclWaveformSamples[0];
344 
345  for (unsigned int iSample = 0; iSample < ECL_ADC_SAMPLES_PER_CHANNEL; iSample++) {
346  if ((unsigned int) m_EclWaveformSamples[iSample] > ampMax) ampMax = m_EclWaveformSamples[iSample];
347  if ((unsigned int) m_EclWaveformSamples[iSample] < ampMin) ampMin = m_EclWaveformSamples[iSample];
348  }
349 
350  B2DEBUG(250, "ampMin = " << ampMin << " ampMax = " << ampMax);
351 
352  adc_data_base = ampMin & 0x3FFFF;
353  writeNBits(adcBuffer_temp, adc_data_base, 18);
354  adc_data_diff_width = (unsigned int)(log2((float)ampMax - (float)ampMin)) + 1;
355  adc_data_diff_width &= 0x1F;
356  writeNBits(adcBuffer_temp, adc_data_diff_width, 5);
357 
358  B2DEBUG(250, "Width = " << adc_data_diff_width << " Base = " << adc_data_base);
359 
360  for (unsigned int iSample = 0; iSample < ECL_ADC_SAMPLES_PER_CHANNEL; iSample++) {
361  unsigned int adc_data_offset = m_EclWaveformSamples[iSample] - adc_data_base;
362  B2DEBUG(250, "offset = " << adc_data_offset);
363  writeNBits(adcBuffer_temp, adc_data_offset, adc_data_diff_width);
364  }
365  } else {
366  for (unsigned int iSample = 0; iSample < ECL_ADC_SAMPLES_PER_CHANNEL; iSample++) {
367  buff[iFINESSE].push_back(m_EclWaveformSamples[iSample]);
368  }
369 
370  }
371 
372  }
373  if (m_compressMode) {
374  if (m_bitPos > 0) m_bufPos++;
375  for (int i = 0; i < m_bufPos; i++) {
376  buff[iFINESSE].push_back(adcBuffer_temp[i]);
377 
378  B2DEBUG(500, "Buff word " << std::hex << adcBuffer_temp[i]);
379  }
380  }
381  }
382  }
383 
384  RawECL* newRawECL = m_eclRawCOPPERs.appendNew();
385 
386  for (int i = 0; i < channels_count; i++) {
387  nwords[i] = buff[i].size();
388 
389  buff[i][0] |= (nwords[i] - finesseHeaderNWords) * 4;
390  }
391 
392  B2DEBUG(100, "**** iEvt = " << m_EvtNum << " node= " << iCOPPERNode);
393  for (int i = 0; i < channels_count; i++)
394  for (unsigned int j = 0; j < buff[i].size(); j++) {
395  B2DEBUG(210, ">> " << std::hex << setfill('0') << setw(8) << buff[i][j]);
396  }
397 
398  B2DEBUG(100, "Call PackDetectorBuf");
399  if (m_pcie40Data) {
400  int* pcie40_words[MAX_PCIE40_CH];
401  int pcie40_nwords[MAX_PCIE40_CH] = {};
402 
403  for (int i = 0; i < channels_count; i++) {
404  pcie40_nwords[i] = nwords[i];
405  pcie40_words[i] = new int[ nwords[i] ];
406  for (int j = 0; j < nwords[i]; j++) {
407  pcie40_words[i][j] = buff[i][j];
408  }
409  }
410 
411  newRawECL->PackDetectorBuf(pcie40_words, pcie40_nwords, rawcprpacker_info);
412  } else { // COPPER data
413  newRawECL->PackDetectorBuf((int*)buff[0].data(), nwords[0], (int*)buff[1].data(), nwords[1],
414  nullptr, 0, nullptr, 0, rawcprpacker_info);
415  }
416  }
417 }
418 
420 {
421  //TODO
422 }
423 
425 {
426 }
427 
429 {
430  m_bufLength = bufLength;
431 }
432 
434 {
435  m_bufPos = 0;
436  m_bitPos = 0;
437 }
438 
439 void ECLPackerModule::writeNBits(unsigned int* buff, unsigned int value, unsigned int bitsToWrite)
440 {
441  if (!bitsToWrite) return;
442 
443  if (bitsToWrite > sizeof(value) * 8) {
444  B2ERROR("Error compressing ADC samples: tying to write too long word");
445  throw Write_adc_samples_error();
446  }
447 
448  if (m_bitPos + bitsToWrite > 32) {
449  if (m_bufPos == m_bufLength) {
450  B2ERROR("Error compressing ADC samples: unexpectedly reach end of buffer");
451  throw Write_adc_samples_error();
452  } else {
453  unsigned tmpval = (1 << m_bitPos) - 1;
454  buff[m_bufPos] &= tmpval;
455  buff[m_bufPos] += value << m_bitPos;
456  m_bufPos++;
457  buff[m_bufPos] = value >> (32 - m_bitPos);
458  m_bitPos += bitsToWrite;
459  m_bitPos -= 32;
460  }
461  } else {
462  unsigned tmpval = (1 << m_bitPos) - 1;
463  buff[m_bufPos] &= tmpval;
464  buff[m_bufPos] += value << m_bitPos;
465  m_bitPos += bitsToWrite;
466  if (m_bitPos == 32) {
467  m_bufPos++;
468  m_bitPos -= 32;
469  }
470  }
471 
472 }
In the store you can park objects that have to be accessed by various modules.
Definition: DataStore.h:51
StoreArray< ECLDsp > m_eclDsps
ECLDSP dataStore object.
int m_ampThreshold
DSP amplitude threshold.
int iEclDigIndices[ECL::ECL_TOTAL_CHANNELS]
indexes of related eclDigits
int shaperNHits[ECL::ECL_CRATES][ECL::ECL_BARREL_SHAPERS_IN_CRATE]
Number of hits per shaper.
int shaperMaskArray[ECL::ECL_CRATES][ECL::ECL_BARREL_SHAPERS_IN_CRATE]
triggered shapers
int m_EvtNum
Event number.
ECL::ECLChannelMapper m_eclMapper
channel mapper
int iEclWfIndices[ECL::ECL_TOTAL_CHANNELS]
indexes of related waveforms
int shaperADCMaskArray[ECL::ECL_CRATES][ECL::ECL_BARREL_SHAPERS_IN_CRATE]
shapers with ADC data
virtual void initialize() override
initialize
int m_bufPos
position in the data array
int m_EclWaveformSamples[ECL_ADC_SAMPLES_PER_CHANNEL]
array of ADC samples
virtual void event() override
event
int shaperNWaveform[ECL::ECL_CRATES][ECL::ECL_BARREL_SHAPERS_IN_CRATE]
Number of waveforms per shaper.
int m_WaveformRareFactor
the rate of writing of the ADC samples
virtual void endRun() override
endRun
int m_bitPos
bit position for bit-by-bit data read
virtual void terminate() override
terminate
StoreArray< ECLDigit > m_eclDigits
ECLDigit dataStore object.
StoreObjPtr< EventMetaData > m_eventMetaData
store objptr for EventMetaData
bool m_pcie40Data
true-pack data in PCIe40 format, false-pack data in COPPER format
void setBuffLength(int bufLength)
set buffer length
virtual void beginRun() override
beginRun
StoreArray< RawECL > m_eclRawCOPPERs
Output data
unsigned int adcBuffer_temp[static_cast< int >(ECL::ECL_CHANNELS_IN_SHAPER) *static_cast< int >(ECL_ADC_SAMPLES_PER_CHANNEL)]
temporary buffer to store ADC data
bool m_compressMode
eneble/disable compression of waveform data
int m_bufLength
length data
int collectorMaskArray[ECL::ECL_CRATES]
array of triggered collectors
void writeNBits(unsigned int *buff, unsigned int value, unsigned int bitsToWrite)
write N bits to the collector buffer
void resetBuffPosition()
reset current position in the buffer
std::string m_eclRawCOPPERsName
name of output collection for RawCOPPER
bool initFromDB()
Initialize channel mapper from the conditions database.
int getNShapersInCrate(int iCrate)
Get number of ShaperDSP modules in the given VME crate number.
int getCellId(int iCrate, int iShaper, int iChannel)
Get CellId by given crate number, shaper position in the crate and DSP channel number in the shaper.
int getShaperChannel(int cellID)
Get number of DSP channel in the shaper by given number of CellId.
int getShaperPosition(int cellID)
Get position of the shaper in the crate by given CellId.
int getCrateID(int iCOPPERNode, int iFINESSE, bool pcie40=false)
Get crate number by given COPPER node number and FINESSE number.
struct to contain header information used by RawCOPPERFormat::Packer()
unsigned int b2l_ctime
32bit unitx time at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user ...
unsigned int eve_num
Run # and subrun # ( 22bit )
unsigned int tt_ctime
Node ID (32bit)
unsigned int tt_utime
27bit clock ticks at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user...
unsigned int node_id
Event Number (32bit)
unsigned int run_subrun_num
Experiment number (10bit)
unsigned int exp_num
Experiment number (10bit)
void PackDetectorBuf(int *detector_buf_1st, int nwords_1st, int *detector_buf_2nd, int nwords_2nd, int *detector_buf_3rd, int nwords_3rd, int *detector_buf_4th, int nwords_4th, RawCOPPERPackerInfo rawcprpacker_info)
Packer for RawCOPPER class Pack data (format ver.
Definition: RawCOPPER.cc:183
The Raw ECL class Class for RawCOPPER class data taken by ECL Currently, this class is almost same as...
Definition: RawECL.h:26
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.