Belle II Software  release-08-01-10
CDCTriggerUnpackerModule.h
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 
9 #ifndef CDCTRIGGERUNPACKERMODULE_H
10 #define CDCTRIGGERUNPACKERMODULE_H
11 
12 #include <framework/core/Module.h>
13 #include <rawdata/dataobjects/RawTRG.h>
14 #include <framework/datastore/StoreArray.h>
15 #include <framework/datastore/StoreObjPtr.h>
16 #include <framework/database/DBObjPtr.h>
17 
18 #include <trg/cdc/dataobjects/Bitstream.h>
19 #include <trg/cdc/Unpacker.h>
20 #include <trg/cdc/dataobjects/CDCTriggerTrack.h>
21 #include <trg/cdc/dataobjects/CDCTriggerSegmentHit.h>
22 #include <trg/cdc/dataobjects/CDCTriggerFinderClone.h>
23 #include <trg/cdc/dataobjects/CDCTriggerMLPInput.h>
24 #include <trg/cdc/dbobjects/CDCTrigger2DConfig.h>
25 #include <trg/cdc/dataobjects/CDCTriggerMLP.h>
26 #include <trg/cdc/dbobjects/CDCTriggerNeuroConfig.h>
27 #include <framework/dataobjects/BinnedEventT0.h>
28 
29 #include <array>
30 #include <bitset>
31 #include <vector>
32 #include <string>
33 #include <iomanip>
34 
35 namespace Belle2 {
42  using NodeList = std::vector<std::vector<int> >;
43 
45  static constexpr int mergerWidth = 256;
47  static constexpr int nAllMergers = 146;
49  static constexpr int wordWidth = 32;
51  static constexpr int nFinesse = 48;
53  using MergerBus = std::array<std::bitset<mergerWidth>, nAllMergers>;
56 
58  struct SubTrigger {
60  SubTrigger(const std::string& inName,
61  unsigned inEventWidth, unsigned inOffset,
62  int inHeaderSize, const std::vector<int>& inNodeID, const std::vector<int>& inNodeID_pcie40,
63  int& inDelay, int& inCnttrg, int inDebugLevel = 0) :
64  name(inName), eventWidth(inEventWidth), offset(inOffset),
65  headerSize(inHeaderSize), iNode(inNodeID.front()),
66  iFinesse(inNodeID.back()),
67  iNode_pcie40(inNodeID_pcie40.front()), iFinesse_pcie40(inNodeID_pcie40.back()),
68  delay(inDelay), cnttrg(inCnttrg),
69  debugLevel(inDebugLevel) {};
70 
72  std::string name;
74  unsigned eventWidth;
76  unsigned offset;
80  int iNode;
82  int iFinesse;
87 
88  /* information from Belle2Link header */
90  std::string firmwareType;
92  std::string firmwareVersion;
94  int& delay;
96  int& cnttrg;
97 
100 
109  virtual void reserve(int, std::array<int, nFinesse>, bool) {};
110 
120  virtual void unpack(int,
121  std::array<int*, nFinesse>,
122  std::array<int, nFinesse>,
123  bool) {};
124 
136  virtual int getHeaders(int subDetectorId,
137  std::array<int*, 48> data32tab,
138  std::array<int, 48> nWords,
139  bool pciedata)
140  {
141 
142  int iNode_i = 0;
143  int iFinesse_i = 0;
144  if (pciedata) {
145  iNode_i = iNode_pcie40;
146  iFinesse_i = iFinesse_pcie40;
147  } else {
148  iNode_i = iNode;
149  iFinesse_i = iFinesse;
150  }
151 
152  if (subDetectorId != iNode_i) {
153  return 0;
154  }
155  // int nWordsize = 3075; // temporary solution to hard coded the correct event size (for 2D only?)
156  // empty data buffer
157  if (nWords[iFinesse_i] < headerSize) {
158  B2WARNING("The module " << name << " does not have enough data (" <<
159  nWords[iFinesse_i] << "). Nothing will be unpacked.");
160  return 0;
161  } else if (nWords[iFinesse_i] == headerSize) {
162  B2DEBUG(20, "The module " << name <<
163  " contains only the header. Nothing will be unpacked.");
164  return 0;
165  }
166 
167  // need one more check, give a warning if the event has wrong data size
168 
169  // event data block header:
170  // 0xdddd --> correct event data (for 2D only?)
171  // 0xbbbb --> dummy buffer supposed to be used for only suppressed events.
172  if (nWords[iFinesse_i] > headerSize) {
173  //dataHeader = CDCTriggerUnpacker::rawIntToAscii(data32tab.at(iFinesse)[headerSize]&0xFFFF0000 >> 16);
174  //bool dataHeader = ( (data32tab.at(iFinesse)[headerSize]&0xffff0000) == 0xdddd0000);
175  long dataHeader = (data32tab.at(iFinesse_i)[headerSize] & 0xffff0000);
176  if (dataHeader != 0xdddd0000) {
177  B2DEBUG(30, "The module " << name << " has an event data header " << std::hex << std::setfill('0') << std::setw(4) <<
178  (dataHeader >> 16) <<
179  " in this event. It will be ignore.");
180  return 0;
181  }
182  B2DEBUG(50, "subdet and head size " << std::setfill('0') << std::hex << std::setw(8) << iNode_i << ", " << std::dec << std::setw(
183  0) << nWords[iFinesse_i] <<
184  " : " << std::hex << std::setw(8) << data32tab.at(iFinesse_i)[0] << " " << data32tab.at(iFinesse_i)[1] << " " << data32tab.at(
185  iFinesse_i)[2] <<
186  " " << data32tab.at(iFinesse_i)[3] << " dataheader = " << dataHeader);
187  }
188 
189  /* get event header information
190  * Ideally, these parameters should not change in the same run,
191  * so it is more efficiency to do it in beginRun().
192  * However, since they are present in all events,
193  * let's check if they really remain unchanged.
194  */
195  if (headerSize >= 2) {
196  // supposedly these two Words will stay for all the versions
197  firmwareType = CDCTriggerUnpacker::rawIntToAscii(data32tab.at(iFinesse_i)[0]);
198  firmwareVersion = CDCTriggerUnpacker::rawIntToString(data32tab.at(iFinesse_i)[1]);
199  //int cnttrg = 0; // temporary solution, this should be one as a reference for comparison
200  int l1_revoclk = -1;
201 
202  if (headerSize >= 3) {
203  std::bitset<wordWidth> thirdWord(data32tab.at(iFinesse_i)[2]);
204  l1_revoclk = CDCTriggerUnpacker::subset<32, 0, 11>(thirdWord).to_ulong();
205 
206  if (firmwareType == "2D ") { // temporary solcuion, the following version number check is valid only for 2D
207 
208  if (firmwareVersion > "19041700") { // started since 19041705
209  // the third word is cnttrg and L1_revoclk
210  int newCnttrg = CDCTriggerUnpacker::subset<32, 12, 31>(thirdWord).to_ulong();
211  cnttrg = newCnttrg;
212  } else if (firmwareVersion > "17121900") { // upto that version, headerSize == 2?
213  // the third word is b2l delay and L1_revoclk
214  int newDelay = CDCTriggerUnpacker::subset<32, 12, 20>
215  (thirdWord).to_ulong(); // or should be <32,12,19>? bit 31-20 are for prescale?
216  if (delay > 0 && delay != newDelay) {
217  B2WARNING(" the Belle2Link delay for " << name <<
218  "has changed from " << delay << " to " << newDelay << "!");
219  }
220  delay = newDelay;
221  }
222  }
223  }
224 
225  B2DEBUG(20, name << ": " << firmwareType << ", version " <<
226  firmwareVersion << ", node " << std::hex << iNode_i <<
227  ", finesse " << iFinesse_i << ", delay: " << delay <<
228  ", cnttrg: " << cnttrg << std::dec << " == " << cnttrg << ", L1_revoclk " << l1_revoclk);
229 
230 
231  }
232  return 1;
233  };
235  virtual ~SubTrigger() {};
236  };
237 
249 
250  public:
251 
256 
258  void initialize() override;
259 
261  void terminate() override;
262 
264  void beginRun() override;
265 
267  void event() override;
268 
270  std::vector<float> unscaleNNOutput(std::vector<float> input) const;
273  static constexpr std::array<int, 9> nMergers = {10, 10, 12, 14, 16, 18, 20, 22, 24};
274 
275  private:
278 
286  bool m_decodeTSHit = false;
293  int m_n2DTS = 0; //TODO whats the best def val? /**< flag to unpack 2D tracker data with 15TS*/
294 
300  std::vector<int> m_delayNNOutput;
301  std::vector<int> m_delayNNSelect;
305 
308 
311 
314 
317 
318 
321 
324 
327 
330 
333 
336 
339 
341  int m_debugLevel = 0;
342 
344  int m_mergerDelay = 0;
345 
347  //int m_2DFinderDelay = 0;
348  // since version 19041705, the B2L delay is removed, it should a fixed number for a long period and recorded in database.
349  int m_2DFinderDelay = 45; // 0x2d: changed from 0x28 since some time in 201902-03
350 
352  int m_NeuroDelay = 0;
353 
355  // int m_Cnttrg = 0; // not used, commented out at 2019/07/31 by ytlai
357  int m_mergerCnttrg = 0;
361  int m_NeuroCnttrg = 0;
362 
364  unsigned m_exp = 0;
366  unsigned m_run = 0;
367 
369  std::vector<SubTrigger*> m_subTrigger;
370 
371  //condition database for number of TS in 2D
376  std::vector<float> m_NNOutputScale;
380  bool m_useDB;
382  bool m_sim13dt;
385  };
386 
387 
389 }
390 
391 #endif /* CDCTRIGGERUNPACKERMODULE_H */
Class to keep all parameters of an expert MLP for the neuro trigger.
Definition: CDCTriggerMLP.h:20
Unpack the trigger data recorded in B2L.
static constexpr std::array< int, 9 > nMergers
data width of a single merger unit
CDCTriggerMLP m_mlp_scale
fake object to assign the user set scaling values to
int m_debugLevel
debug level specified in the steering file
StoreArray< RawTRG > m_rawTriggers
array containing the raw trigger data object
bool m_pciedata
PCIe40 data or copper data.
NodeList m_tracker2DNodeID_pcie40
list of (PCIe40 ID, ch ID) of 2D tracker
DBObjPtr< CDCTriggerNeuroConfig > m_cdctriggerneuroconfig
current neurotrigger config from database; used for unscaling network target
std::vector< float > m_NNOutputScale
output scale for the neural network output
int m_headerSize
number of words (number of bits / 32) of the B2L header
int m_mergerDelay
Belle2Link delay of the merger reader.
bool m_sim13dt
bool value wether to simulate 13 bit drift time by using 2dcc
StoreArray< MergerBits > m_mergerBits
merger output bitstream
StoreArray< CDCTriggerMLPInput > m_NeuroInputs
decoded input vector for neural network
void initialize() override
Register input and output data.
int m_NeuroDelay
Belle2Link delay of the neurotrigger.
void event() override
convert raw data (in B2L buffer to bitstream)
std::vector< int > m_delayNNOutput
delay of the NN output values clock cycle after the NN enable bit (by quadrant)
NodeList m_neuroNodeID
list of (COPPER ID, HSLB ID) of neurotrigger
StoreArray< CDCTriggerUnpacker::T2DOutputBitStream > m_bits2DTo3D
bitstream of 2D output to 3D/Neuro
bool m_decodeNeuro
flag to decode neurotrigger data
void terminate() override
Delete dynamically allocated variables.
int m_2DFinderDelay
Belle2Link delay of the 2D finder.
StoreArray< CDCTriggerSegmentHit > m_TSHits
decoded track segment hit
bool m_alignFoundTime
flag to align found time in different sub-modules
bool m_unpackTracker2D
flag to unpack 2D tracker data
CDCTriggerUnpackerModule()
Constructor: Sets the description, the properties and the parameters of the module.
NodeList m_tracker2DNodeID
list of (COPPER ID, HSLB ID) of 2D tracker
StoreArray< CDCTriggerSegmentHit > m_NNInputTSHitsAll
all decoded stereo track segment hits from the neural network input
StoreArray< CDCTriggerTrack > m_2DFinderTracks
decoded 2D finder track
bool m_decodeTSHit
flag to decode track segment
StoreArray< CDCTriggerTrack > m_NeuroTracks
decoded Neuro tracks
StoreArray< CDCTriggerTrack > m_NNInput2DFinderTracks
decoded 2D finder tracks from the neural network input
StoreObjPtr< BinnedEventT0 > m_ETFTime
store object for unpacked etf event time from neuro b2link
bool m_decode2DFinderInputTS
flag to decode 2D finder input TS
NodeList m_neuroNodeID_pcie40
list of (PCIe40 ID, ch ID) of neurotrigger
StoreArray< CDCTriggerUnpacker::NNBitStream > m_bitsNN
bitstream of Neuro input and output (including intermediate results)
MergerBits m_mergerBitsPerClock
Merger bits per clock.
NodeList m_mergerNodeID
list of (COPPER ID, HSLB ID) of Merger reader (TSF)
std::vector< int > m_delayNNSelect
delay of the NN selected TS clock cycle after the NN enable bit (by quadrant)
std::vector< float > unscaleNNOutput(std::vector< float > input) const
small function to rescale the NN output from -1, 1 to output scale
StoreArray< CDCTriggerFinderClone > m_2DFinderClones
additional information of the 2D finder track
StoreArray< CDCTriggerUnpacker::TSFOutputBitStream > m_bitsTo2D
bitstream of TSF output to 2D tracker
StoreArray< CDCTriggerSegmentHit > m_NNInputTSHits
decoded track segment hits from the neural network input
bool m_unpackNeuro
flag to unpack neurotrigger data
std::vector< SubTrigger * > m_subTrigger
vector holding the pointers to all the dynamically allocated SubTriggers
bool m_decode2DFinderTrack
flag to decode 2D finder track
bool m_useDB
bool value for wether to use the conditions database
bool m_unpackMerger
flag to unpack merger data (recorded by Merger Reader / TSF)
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
Base class for Modules.
Definition: Module.h:72
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
static constexpr int wordWidth
width of a single word in the raw int buffer
std::array< std::bitset< mergerWidth >, nAllMergers > MergerBus
Merger data bus.
static constexpr int nFinesse
Number of FINESSE in a PCIe40.
static constexpr int mergerWidth
Merger data width.
std::vector< std::vector< int > > NodeList
Node list.
static constexpr int nAllMergers
Number of Mergers.
Abstract base class for different kinds of events.
enum class SubTriggerType : unsigned char {Merger, TSF, T2D, T3D, Neuro, ETF};
int iNode_pcie40
PCIe40 id of the board.
virtual void unpack(int, std::array< int *, nFinesse >, std::array< int, nFinesse >, bool)
Unpack the Belle2Link data and fill the Bitstream.
int headerSize
Size of the B2L header in words.
unsigned offset
The starting point of the data in an event.
virtual int getHeaders(int subDetectorId, std::array< int *, 48 > data32tab, std::array< int, 48 > nWords, bool pciedata)
Get the Belle2Link header information.
int debugLevel
debug level in the steering file
virtual ~SubTrigger()
destructor
SubTrigger(const std::string &inName, unsigned inEventWidth, unsigned inOffset, int inHeaderSize, const std::vector< int > &inNodeID, const std::vector< int > &inNodeID_pcie40, int &inDelay, int &inCnttrg, int inDebugLevel=0)
constructor
std::string firmwareVersion
version of the FPGA firmware
std::string firmwareType
type of the FPGA firmware
int iFinesse
FINESSE (HSLB) id) of the board.
int & delay
Reference to the variable of its Belle2Link delay.
int iFinesse_pcie40
PCIe40 ch id of the board.
int & cnttrg
counter of trgger signal, total 32 bits, the 20 LSBs recorded in the event header
std::string name
Name of the UT3.
unsigned eventWidth
Size of an event in the Belle2Link data in 32-bit words.
int iNode
COPPER id of the board.
virtual void reserve(int, std::array< int, nFinesse >, bool)
Calculate the number of clocks in the data, reserve that much of clocks in the Bitstream(s)