9 #include <ecl/modules/eclPacker/eclPackerModule.h>
16 #include <framework/logging/Logger.h>
19 #include <ecl/dataobjects/ECLDigit.h>
20 #include <ecl/dataobjects/ECLDsp.h>
23 #include <rawdata/dataobjects/RawECL.h>
31 ECLPackerModule::ECLPackerModule() :
35 m_EclWaveformSamples(),
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);
57 ECLPackerModule::~ECLPackerModule()
78 B2FATAL(
"ECL Packer: Can't initialize eclChannelMapper!");
87 B2DEBUG(50,
"EclPacker:: event called ");
91 B2DEBUG(50,
"EclPacker:: output data arrays created");
93 int nActiveChannelsWithADCData, nActiveDSPChannels;
94 int triggerPhase = 0, dspMask = 0;
98 int nEclWaveform =
m_eclDsps.getEntries();
100 for (
int i = 0; i < ECL_CRATES; i++) {
102 for (
int j = 0; j < ECL_BARREL_SHAPERS_IN_CRATE; j++) {
110 for (
int j = 0; j < ECL_TOTAL_CHANNELS; j++) {
115 B2DEBUG(100,
"EclPacker:: N_Digits = " << nEclDigits);
116 B2DEBUG(100,
"EclPacker:: N_Waveforms = " << nEclWaveform);
118 int iCOPPER, iFINESSE, iCrate, iShaper, iChannel, nShapers;
120 B2DEBUG(100,
"EclPacker:: Hits ======>> ");
121 int tot_dsp_hits = 0;
123 for (
int i_digit = 0; i_digit < nEclDigits; i_digit++) {
134 if (iCrate < 1 && iShaper < 1 && iChannel < 1) {
135 B2ERROR(
"Wrong crate/shaper/channel ids: " << iCrate <<
" " << iShaper <<
" " << iChannel <<
" for CID " << cid);
136 throw eclPacker_internal_error();
147 B2DEBUG(100,
"ECL Packer:: N Hits above threshold = " << tot_dsp_hits <<
" nWaveforms = " << nEclWaveform);
151 B2DEBUG(100,
"ECL Packer:: Pack waveform data for this event: " <<
m_EvtNum);
152 for (
int i_wf = 0; i_wf < nEclWaveform; i_wf++) {
160 for (
int i_digit = 0; i_digit < nEclDigits; i_digit++) {
180 rawcprpacker_info.
tt_ctime = 0x7123456;
181 rawcprpacker_info.
tt_utime = 0xF1234567;
185 B2DEBUG(100,
"EclPacker:: proceed COPPERs... ");
186 B2DEBUG(100,
"EclPacker:: ECL_COPPERS = " << ECL_COPPERS);
189 for (iCOPPER = 1; iCOPPER <= ECL_COPPERS; iCOPPER++) {
191 std::vector <unsigned int> buff[ECL_FINESSES_IN_COPPER];
192 for (
int i = 0; i < ECL_FINESSES_IN_COPPER; i++) buff[i].clear();
194 int iCOPPERNode = (iCOPPER <= ECL_BARREL_COPPERS) ? BECL_ID + iCOPPER : EECL_ID + iCOPPER - ECL_BARREL_COPPERS;
199 B2DEBUG(200,
"iCOPPERNode = 0x" << std::hex << iCOPPERNode << std::dec <<
" nCrate1 = " << icr1 <<
" nCrate2 = " << icr2);
202 rawcprpacker_info.
node_id = iCOPPERNode;
205 int nwords[2] = {0, 0};
206 const int finesseHeaderNWords = 3;
209 for (iFINESSE = 0; iFINESSE < ECL_FINESSES_IN_COPPER; iFINESSE++) {
213 if (!nShapers) B2ERROR(
"Ecl packer:: Wrong shapers number " << nShapers);
216 B2DEBUG(200,
"Pack data for iCrate = " << iCrate <<
" nShapers = " << nShapers);
219 unsigned int eclCollectorHeader = (1 << nShapers) - 1;
221 buff[iFINESSE].push_back(eclCollectorHeader);
223 for (iShaper = 1; iShaper <= nShapers; iShaper++) {
225 nActiveDSPChannels =
shaperNHits[iCrate - 1][iShaper - 1];
226 B2DEBUG(200,
"iCrate = " << iCrate <<
" iShaper = " << iShaper <<
" nActiveDSPChannels = " << nActiveDSPChannels);
228 B2DEBUG(200,
"nActiveChannelsWithADCData = " << nActiveChannelsWithADCData);
232 unsigned int shaperDataLength = 4 + nActiveDSPChannels + nActiveChannelsWithADCData * ECL_ADC_SAMPLES_PER_CHANNEL;
234 unsigned int shaper_header_w0 = (0x10 << 16) + (shaperDataLength & 0xFFFF);
235 buff[iFINESSE].push_back(shaper_header_w0);
238 unsigned int shaper_header_w1 = (nActiveChannelsWithADCData & 0x1F) << 24;
239 shaper_header_w1 |= (ECL_ADC_SAMPLES_PER_CHANNEL & 0x7F) << 16;
240 shaper_header_w1 |= (nActiveDSPChannels & 0x1F) << 8;
241 shaper_header_w1 |= triggerPhase;
242 buff[iFINESSE].push_back(shaper_header_w1);
245 B2DEBUG(200,
"dspMask = " << std::hex << dspMask);
246 unsigned int shaper_header_w2 = (dspMask & 0xFFFF) << 16;
247 shaper_header_w2 |= (
m_EvtNum & 0xFFFF);
248 buff[iFINESSE].push_back(shaper_header_w2);
251 B2DEBUG(100,
"adcMask = " << std::hex << adcMask);
252 unsigned int shaper_header_w3 = (adcMask & 0xFFFF);
253 buff[iFINESSE].push_back(shaper_header_w3);
256 for (iChannel = 1; iChannel <= ECL_CHANNELS_IN_SHAPER; iChannel++) {
260 if (cid < 1)
continue;
263 if (i_digit < 0)
continue;
264 const int qua =
m_eclDigits[i_digit]->getQuality();
271 int chi_mantissa = 0, chi_exponent = 0;
272 int n_bits = ceil(log2(
double(chi)));
274 chi_exponent = ceil(
float(n_bits - 9) / 2.0);
275 chi_mantissa = chi >> chi_exponent * 2;
280 tim = (chi_exponent << 9) | chi_mantissa;
285 unsigned int hit_data = ((qua & 3) << 30) & 0xC0000000;
286 hit_data |= (tim & 0xFFF) << 18;
287 hit_data |= ((amp + 128) & 0x3FFFF);
288 buff[iFINESSE].push_back(hit_data);
290 B2DEBUG(100,
"cid = " << cid <<
" amp = " << amp <<
" tim = " << tim);
293 for (
int i = 0; i < ECL_CHANNELS_IN_SHAPER; i++)
adcBuffer_temp[i] = 0;
295 setBuffLength(ECL_ADC_SAMPLES_PER_CHANNEL * ECL_CHANNELS_IN_SHAPER);
296 for (iChannel = 1; iChannel <= ECL_CHANNELS_IN_SHAPER; iChannel++) {
298 if (cid < 1)
continue;
300 if (i_wf < 0)
continue;
301 B2DEBUG(200,
"i_wf = " << i_wf);
305 unsigned int adc_data_base = 0;
306 unsigned int adc_data_diff_width = 0;
312 for (
unsigned int iSample = 0; iSample < ECL_ADC_SAMPLES_PER_CHANNEL; iSample++) {
317 B2DEBUG(250,
"ampMin = " << ampMin <<
" ampMax = " << ampMax);
319 adc_data_base = ampMin & 0x3FFFF;
321 adc_data_diff_width = (
unsigned int)(log2((
float)ampMax - (
float)ampMin)) + 1;
322 adc_data_diff_width &= 0x1F;
325 B2DEBUG(250,
"Width = " << adc_data_diff_width <<
" Base = " << adc_data_base);
327 for (
unsigned int iSample = 0; iSample < ECL_ADC_SAMPLES_PER_CHANNEL; iSample++) {
329 B2DEBUG(250,
"offset = " << adc_data_offset);
333 for (
unsigned int iSample = 0; iSample < ECL_ADC_SAMPLES_PER_CHANNEL; iSample++) {
342 for (
int i = 0; i <
m_bufPos; i++) {
353 nwords[0] = buff[0].size();
354 nwords[1] = buff[1].size();
356 buff[0][0] |= (nwords[0] - finesseHeaderNWords) * 4;
357 buff[1][0] |= (nwords[1] - finesseHeaderNWords) * 4;
359 B2DEBUG(100,
"**** iEvt = " <<
m_EvtNum <<
" node= " << iCOPPERNode);
360 for (
unsigned int i = 0; i < 2; i++)
361 for (
unsigned int j = 0; j < buff[i].size(); j++) {
362 B2DEBUG(210,
">> " << std::hex << setfill(
'0') << setw(8) << buff[i][j]);
365 B2DEBUG(100,
"Call PackDetectorBuf");
366 newRawECL->
PackDetectorBuf((
int*)buff[0].data(), nwords[0], (
int*)buff[1].data(), nwords[1],
367 nullptr, 0,
nullptr, 0, rawcprpacker_info);
394 if (!bitsToWrite)
return;
396 if (value > (
unsigned int)(1 << bitsToWrite) - 1) {
397 B2ERROR(
"Error compressing ADC samples: tying to write too long word");
398 throw Write_adc_samples_error();
403 B2ERROR(
"Error compressing ADC samples: unexpectedly reach end of buffer");
404 throw Write_adc_samples_error();
406 unsigned tmpval = (1 <<
m_bitPos) - 1;
415 unsigned tmpval = (1 <<
m_bitPos) - 1;
In the store you can park objects that have to be accessed by various modules.
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.
void setBuffLength(int bufLength)
set buffer length
virtual void beginRun() override
beginRun
StoreArray< RawECL > m_eclRawCOPPERs
Output 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
unsigned int adcBuffer_temp[ECL::ECL_CHANNELS_IN_SHAPER *ECL_ADC_SAMPLES_PER_CHANNEL]
temporary buffer to store ADC data
bool initFromDB()
Initialize channel mapper from the conditions database.
int getCrateID(int iCOPPERNode, int iFINESSE)
get crate number by given COPPER node number and FINESSE number
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
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.
The Raw ECL class Class for RawCOPPER class data taken by ECL Currently, this class is almost same as...
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.