9#include <pxd/unpacking/PXDRawDataDefinitions.h>
10#include <pxd/modules/pxdUnpacking/PXDPackerModule.h>
11#include <framework/datastore/DataStore.h>
12#include <framework/logging/Logger.h>
13#include <framework/dataobjects/EventMetaData.h>
14#include <framework/datastore/StoreObjPtr.h>
15#include <framework/core/ModuleParam.templateDetails.h>
17#include <boost/crc.hpp>
18#include <boost/algorithm/clamp.hpp>
20#include <pxd/unpacking/PXDMappingLookup.h>
38using boost::crc_optimal;
39typedef crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhe_crc_32_type;
57 addParam(
"PXDDigitsName",
m_PXDDigitsName,
"The name of the StoreArray of PXDDigits to be processed", std::string(
""));
58 addParam(
"RawPXDsName",
m_RawPXDsName,
"The name of the StoreArray of generated RawPXDs", std::string(
""));
60 addParam(
"dhe_to_dhc",
m_dhe_to_dhc,
"DHE to DHC mapping (DHC_ID, DHE1, DHE2, ..., DHE5) ; -1 disable port");
61 addParam(
"InvertMapping",
m_InvertMapping,
"Use invers mapping to DHP row/col instead of \"remapped\" coordinates",
false);
85 B2DEBUG(27,
"PXD Packer --> DHC/DHE");
89 B2WARNING(
"PXD Packer --> DHC/DHE maps 1 dhc to 5 dhe (1+5 values), but I found " << it.size());
91 for (
auto& it2 : it) {
95 B2DEBUG(27,
"PXD Packer --> ... DHE " << it2);
96 if (it2 < -1 || it2 >= 64) {
97 if (it2 != -1) B2ERROR(
"PXD Packer --> DHC id " << it2 <<
" is out of range (0-64 or -1)! disable channel.");
104 B2DEBUG(27,
"PXD Packer --> DHC .. " << it2);
105 if (dhc_id < 0 || dhc_id >= 16) {
106 B2ERROR(
"PXD Packer --> DHC id " << it2 <<
" is out of range (0-15)! skip");
113 B2DEBUG(27,
"PXD Packer --> DHC/DHE done");
121 B2DEBUG(27,
"PXD Packer --> DHC " << it.first);
122 for (
auto& it2 : it.second) {
123 B2DEBUG(27,
"PXD Packer --> .. connects to DHE " << it2 <<
" port " << port);
135 B2WARNING(
"Could not read PXD Firmware version from db, assume default (new) firmware");
166 B2DEBUG(27,
"PXD Packer --> Nr of Digis: " << nDigis);
170 VxdID lastVxdId = -1;
175 currentVxdId = it->getSensorID();
177 if (currentVxdId != lastVxdId) {
179 lastVxdId = currentVxdId;
180 B2DEBUG(27,
"VxdId: " << currentVxdId <<
" " << (
int)currentVxdId);
182 unsigned int layer, ladder, sensor, segment, dhe_id;
183 layer = currentVxdId.getLayerNumber();
184 ladder = currentVxdId.getLadderNumber();
185 sensor = currentVxdId.getSensorNumber();
186 segment = currentVxdId.getSegmentNumber();
187 dhe_id = ((layer - 1) << 5) | ((ladder) << 1) | (sensor - 1);
188 B2DEBUG(27,
"Layer: " << layer <<
" Ladder " << ladder <<
" Sensor " << sensor <<
" Segment(Frame) " << segment <<
" =>DHEID: " <<
192 if (
startOfVxdID.count(currentVxdId) > 0) B2FATAL(
"PXD Digits are not sorted by VxdID!");
199 m_run_nr_word1 = ((evtPtr->getRun() & 0xFF) << 8) | (evtPtr->getSubrun() & 0xFF);
200 m_run_nr_word2 = ((evtPtr->getExperiment() & 0x3FF) << 6) | ((evtPtr->getRun() >> 8) & 0x3F);
210 int dhe_ids[5] = {0, 0, 0, 0, 0};
211 B2DEBUG(27,
"PXD Packer --> pack_event");
216 int port = 1, port_inx = 0;
219 for (
auto& it2 : it.second) {
220 if (it2 >= 0) act_port += port;
222 dhe_ids[port_inx] = it2;
224 if (port_inx == 5)
break;
234 pack_dhc(it.first, act_port, dhe_ids);
245 B2ERROR(
"Frame is not 32bit aligned!!! Unsupported by Unpacker!");
248 dhe_crc_32_type current_crc;
289 B2DEBUG(27,
"PXD Packer --> pack_dhc ID " << dhc_id <<
" DHE act: " << dhe_active);
308 append_int32((EDHCFrameHeaderDataType::c_DHC_START << 27) | ((dhc_id & 0xF) << 21) | ((dhe_active & 0x1F) << 16) |
312 uint32_t mm = (
unsigned int)std::round((
m_meta_time % 1000000000ull) * 0.127216);
313 uint32_t ss = (
unsigned int)(
m_meta_time / 1000000000ull) ;
315 append_int16(((mm >> 12) & 0x7FFF) | ((ss & 1) ? 0x8000 : 0x0));
324 for (
int i = 0; i < 5; i++) {
325 if (dhe_active & 0x1)
pack_dhe(dhe_ids[i], 0xF);
348 B2DEBUG(27,
"PXD Packer --> pack_dhe ID " << dhe_id <<
" DHP act: " << dhp_active);
356 B2FATAL(
"Inverse Mapping not implemented in Packer");
362 append_int32((EDHCFrameHeaderDataType::c_DHE_START << 27) | ((dhe_id & 0x3F) << 20) | ((dhp_active & 0xF) << 16) |
378 if (dhp_active != 0) {
380 const int ladder_max_row = PACKER_NUM_ROWS - 1;
382 const int ladder_max_col = PACKER_NUM_COLS - 1;
387 VxdID currentVxdId = 0;
394 unsigned short sensor, ladder, layer;
395 sensor = (dhe_id & 0x1) + 1;
396 ladder = (dhe_id & 0x1E) >> 1;
397 layer = ((dhe_id & 0x20) >> 5) + 1;
398 currentVxdId =
VxdID(layer, ladder, sensor);
400 B2DEBUG(27,
"pack_dhe: VxdId: " << currentVxdId <<
" " << (
int)currentVxdId);
407 auto id = it->getSensorID();
408 id.setSegmentNumber(0);
409 if (currentVxdId !=
id)
break;
412 unsigned int row, col;
413 row = it->getVCellID();
414 col = it->getUCellID();
415 if (row > ladder_max_row || col > ladder_max_col) {
416 B2ERROR(
"U/V out of range U: " << col <<
" V: " << row);
419 B2DEBUG(26,
"Pixel: V: " << row <<
", U: " << col <<
", Ch " << it->getCharge());
420 if (!dhe_has_remapped) {
423 halfladder_pixmap[row][col] = (
unsigned char) boost::algorithm::clamp(lrint(it->getCharge()), 0, 255);
430 B2FATAL(
"Clusterizer not supported in Packer");
432 for (
int i = 0; i < 4; i++) {
433 if (dhp_active & 0x1) {
434 pack_dhp(i, dhe_id, dhe_has_remapped ? 1 : 0);
460 B2FATAL(
"code needs to be written");
470 B2FATAL(
"This code needs to be checked agains new firmware");
471 B2DEBUG(27,
"PXD Packer --> pack_dhp Raw Chip " << chip_id <<
" of DHE id: " << dhe_id);
474 append_int32((EDHCFrameHeaderDataType::c_DHP_RAW << 27) | ((dhe_id & 0x3F) << 20) | ((chip_id & 0x03) << 16) |
476 append_int32((EDHPFrameHeaderDataType::c_RAW << 29) | ((dhe_id & 0x3F) << 18) | ((chip_id & 0x03) << 16) |
482 if (c2 >= PACKER_NUM_COLS) c2 = PACKER_NUM_COLS;
485 for (
int row = 0; row < PACKER_NUM_ROWS; row++) {
486 for (
int col = c1; col < c2; col++) {
490 for (
int col = c2; col < c1 + 64; col++) {
500 B2DEBUG(27,
"PXD Packer --> pack_dhp Chip " << chip_id <<
" of DHE id: " << dhe_id);
503 unsigned short last_rowstart = 0;
505 if (dhe_has_remapped == 0) {
508 B2FATAL(
"dhe_has_remapped == 0");
513 append_int32((EDHCFrameHeaderDataType::c_DHP_ZSD << 27) | ((dhe_id & 0x3F) << 20) | ((dhe_has_remapped & 0x1) << 19) | ((
515 append_int32((EDHPFrameHeaderDataType::c_ZSD << 29) | ((dhe_id & 0x3F) << 18) | ((chip_id & 0x03) << 16) |
521 if (c2 >= PACKER_NUM_COLS) c2 = PACKER_NUM_COLS;
522 for (
int rr = startrow; rr < startrow + PACKER_NUM_ROWS; rr++) {
523 int row = (rr % PACKER_NUM_ROWS);
527 bool rowstart =
true;
528 for (
int col = c1; col < c2; col++) {
532 B2DEBUG(26,
"Pixel: ROW: " << row <<
", COL: " << col <<
", Ch " << (
int)
halfladder_pixmap[row][col]);
534 last_rowstart = ((row & 0x3FE) << (6 - 1)) | 0;
545 B2DEBUG(27,
"Repeat last rowstart to align to 32bit.");
550 B2DEBUG(27,
"Found no data for halfladder! DHEID: " << dhe_id <<
" Chip: " << chip_id);
563 append_int32((EDHCFrameHeaderDataType::c_GHOST << 27) | ((dhe_id & 0x3F) << 20) | ((chip_id & 0x03) << 16) |
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
void do_the_reverse_mapping(unsigned int &row, unsigned int &col, unsigned short layer, unsigned short sensor)
function still to be implemented
std::vector< std::vector< unsigned char > > m_onsen_payload
For one DHC event, we utilize one payload for all DHE/DHP frames.
int m_overrideFirmwareVersion
override firmware version from DB.
void initialize() override final
Initialize the module.
StoreObjPtr< PXDInjectionBGTiming > m_storeInjectionBGTiming
Input Obj InjectionBGTiming.
void add_frame_to_payload(void)
Add Frame to Event payload.
unsigned short m_run_nr_word2
Exp+Run Nr.
std::map< VxdID, int > startOfVxdID
Store start of Vxd Detector related digits.
void append_int16(unsigned short w)
cat 16bit value to frame
void pack_dhe(int dhe_id, int dhp_mask)
Pack one DHE (several DHP) to buffer.
void pack_dhp(int dhp_id, int dhe_id, int dhe_reformat, int startrow=0)
Pack one DHP to buffer.
void pack_dhp_raw(int dhp_id, int dhe_id)
Pack one DHP RAW to buffer.
std::string m_RawPXDsName
The name of the StoreArray of generated RawPXDs.
void pack_dhc(int dhc_id, int dhe_mask, int *dhe_ids)
Pack one DHC (several DHE) stored in one RawPXD object.
PXDPackerModule()
Constructor defining the parameters.
void pack_event(void)
Pack one event (several DHC) stored in seperate RawPXD object.
void terminate() override final
Terminate the module.
void event() override final
do the packing
std::string m_InjectionBGTimingName
The name of the StoreObj InjectionBGTiming.
unsigned int dhc_byte_count
Byte count in current DHC package.
std::vector< std::vector< int > > m_dhe_to_dhc
Parameter dhc<->dhe list, mapping from steering file.
bool m_Clusterize
Use clusterizer (FCE format)
unsigned short m_run_nr_word1
Run+Subrun Nr.
OptionalDBObjPtr< PXDDHHFirmwareVersionPar > m_firmwareFromDB
firmware version from DB.
std::vector< unsigned int > m_onsen_header
For one DHC event, we utilize one header (writing out, beware of endianess!)
int m_firmware
Firmware version, must be read from database on run change.
void append_int32(unsigned int w)
cat 32value value to frame
StoreArray< RawPXD > m_storeRaws
Output array for RawPxds.
unsigned int m_trigger_dhp_framenr
DHP Readout Frame Nr for DHP and DHE headers.
unsigned int dhe_byte_count
Byte count in current DHE package.
std::map< int, std::vector< int > > m_dhc_mapto_dhe
mapping calculated from m_dhe_to_dhc for easier handling
void start_frame(void)
Start with a new Frame.
void append_int8(unsigned char w)
cat 8bit value to frame
unsigned int m_trigger_dhe_gate
DHE Trigger Gate for DHE headers.
void beginRun() override final
begin run
unsigned int m_packed_events
Event counter.
bool m_InvertMapping
Flag if we invert mapping to DHP row/col or use premapped coordinates.
std::string m_PXDDigitsName
The name of the StoreArray of PXDDigits to be processed.
unsigned long long int m_meta_time
Time(Tag) from MetaInfo.
std::vector< unsigned char > m_current_frame
For current processed frames.
unsigned char halfladder_pixmap[PACKER_NUM_ROWS][PACKER_NUM_COLS]
temporary hitmap buffer for pixel to raw data conversion
unsigned int m_trigger_nr
Trigger Nr.
StoreArray< PXDDigit > m_storeDigits
Input array for Digits.
Type-safe access to single objects in the data store.
Class to uniquely identify a any structure of the PXD and SVD.
void setSegmentNumber(baseType segment)
Set the sensor segment.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
Abstract base class for different kinds of events.