CMS 3D CMS Logo

CastorMergerData.cc
Go to the documentation of this file.
1 /*
2  * \author A. Campbell - DESY
3  */
4 #ifndef HTBDAQ_DATA_STANDALONE
6 #else
7 #include "CastorMergerData.h"
8 #endif
9 #include <cstring>
10 #include <cstdio>
11 #include <algorithm>
12 
13 CastorMergerData::CastorMergerData() : m_formatVersion(-2), m_rawLength(0), m_rawConst(nullptr), m_ownData(nullptr) {}
14 CastorMergerData::CastorMergerData(const unsigned short* data, int length) {
15  adoptData(data, length);
16  m_ownData = nullptr;
17 }
19  : m_formatVersion(hd.m_formatVersion), m_rawLength(hd.m_rawLength), m_rawConst(hd.m_rawConst), m_ownData(nullptr) {}
20 
21 CastorMergerData::CastorMergerData(int version_to_create) : m_formatVersion(version_to_create) {
22  allocate(version_to_create);
23 }
24 
25 void CastorMergerData::allocate(int version_to_create) {
26  m_formatVersion = version_to_create;
27  // the needed space is for the biggest possible event...
28  const int needed = 0x200;
29  // create a buffer big enough...
30  m_ownData = new unsigned short[needed];
31  m_rawLength = 0;
33 }
34 
36  if (m_ownData == nullptr) {
40  }
41  return (*this);
42 }
43 
44 void CastorMergerData::adoptData(const unsigned short* data, int length) {
45  m_rawLength = length;
46  m_rawConst = data;
47  if (m_rawLength < 5) {
48  m_formatVersion = -2; // invalid!
49  } else {
50  m_formatVersion = (m_rawConst[4] >> 12) & 0xF;
51  }
52 }
53 
54 // check :: not EE, length is reasonable, length matches wordcount
55 // length required for tp+daq is correct
56 
58  // length checks
59  // minimum length
60  if (m_rawLength < 6 + 12)
61  return false;
62  // matches wordcount
64  return false;
65 
66  return true;
67 }
68 
69 void CastorMergerData::unpack(unsigned char* tp_lengths, unsigned short* tp_samples) const {
70  if (tp_lengths != nullptr)
71  memset(tp_lengths, 0, 1);
72 
73  int tp_words_total, headerLen, trailerLen;
74  determineSectionLengths(tp_words_total, headerLen, trailerLen);
75 
76  int wordPtr;
77  const unsigned short* tpBase = m_rawConst + headerLen;
78  // process the trigger primitive words
79  if (tp_lengths != nullptr) {
80  for (wordPtr = 0; wordPtr < tp_words_total; wordPtr++) {
81  tp_samples[tp_lengths[0]] = tpBase[wordPtr];
82  tp_lengths[0]++;
83  }
84  }
85 }
86 void CastorMergerData::determineSectionLengths(int& tpWords, int& headerWords, int& trailerWords) const {
87  tpWords = m_rawConst[5] >> 8; // should be 8 but could be up to 12
88  headerWords = 8;
89  trailerWords = 0; // minimum, may be more...
90 }
91 
92 void CastorMergerData::determineStaticLengths(int& headerWords, int& trailerWords) const {
93  headerWords = 8;
94  trailerWords = 0; // minimum, may be more...
95 }
96 void CastorMergerData::pack(unsigned char* tp_lengths, unsigned short* tp_samples) {
97  int tp_words_total = 0, headerLen, trailerLen;
98  determineStaticLengths(headerLen, trailerLen);
99 
100  tp_words_total = 0;
101  int isample;
102 
103  // trigger words
104  unsigned short* ptr = m_ownData + headerLen;
105  if (tp_samples != nullptr && tp_lengths != nullptr) {
106  for (isample = 0; isample < tp_lengths[0] && isample < 12; isample++) {
107  ptr[tp_words_total] = tp_samples[isample];
108  tp_words_total++;
109  }
110  }
111 
112  m_ownData[5] = (tp_words_total << 8) | 0x1;
113  unsigned short totalLen = headerLen + tp_words_total + trailerLen;
114 
115  m_rawLength = totalLen;
116  m_ownData[totalLen - 2] = totalLen / 2; // 32-bit words
117  m_ownData[totalLen - 3] = totalLen;
118  m_ownData[totalLen - 4] = tp_words_total;
119 }
120 
122  int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev) {
123  m_ownData[0] = L1Anumber & 0xFF;
124  m_ownData[1] = (L1Anumber & 0xFFFF00) >> 8;
125 
126  m_ownData[2] = 0x8000; // Version is valid, no error bits - status bits need definition
127  m_ownData[3] = ((orbitn & 0x1F) << 11) | (submodule & 0x7FF);
128  m_ownData[4] = ((m_formatVersion & 0xF) << 12) | (bcn & 0xFFF);
129  m_ownData[5] |= ((nps & 0xF) << 4) | 0x1;
130  m_ownData[6] = ((firmwareRev & 0x70000) >> 3) | (firmwareRev & 0x1FFF);
131  m_ownData[7] = (pipeline & 0xFF) | ((ndd & 0x1F) << 8);
132  m_ownData[m_rawLength - 4] &= 0x7FF;
133  m_ownData[m_rawLength - 4] |= (ndd & 0x1F) << 11;
134 
135  m_ownData[m_rawLength - 2] = m_rawLength / 2; // 32-bit words
136  m_ownData[m_rawLength - 1] = (L1Anumber & 0xFF) << 8;
137 }
138 
139 unsigned int CastorMergerData::getOrbitNumber() const { return (m_rawConst[3] >> 11); }
140 
141 unsigned int CastorMergerData::getFirmwareRevision() const { return (m_rawConst[6]); }
void unpack(unsigned char *tp_lengths, unsigned short *tp_samples) const
Unpack the HTR data into TP and DAQ data sorted by channel.
void adoptData(const unsigned short *data, int length)
unsigned int getFirmwareRevision() const
Get the Merger firmware version.
void allocate(int version_to_create=0)
bool check() const
Check for a good event Requires a minimum length, matching wordcount and length, not an empty event...
CastorMergerData & operator=(const CastorMergerData &)
const unsigned short * m_rawConst
void packHeaderTrailer(int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev=0)
pack header and trailer (call after pack)
unsigned int getOrbitNumber() const
Get the HTR orbit number.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
unsigned short * m_ownData
void determineSectionLengths(int &tpWords, int &headerWords, int &trailerWords) const
void determineStaticLengths(int &headerWords, int &trailerWords) const
void pack(unsigned char *tp_lengths, unsigned short *tp_samples)
Unpack the HTR data into TP and DAQ data sorted by channel.