Belle II Software  release-08-01-10
CDCPackerModule.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 
9 #include <cdc/modules/cdcPacker/CDCPackerModule.h>
10 #include <cdc/modules/cdcPacker/CDCChannelData.h>
11 #include <cdc/dbobjects/CDCChannelMap.h>
12 
13 #include <framework/logging/Logger.h>
14 #include <framework/utilities/FileSystem.h>
15 
16 #include <framework/database/DBArray.h>
17 
18 #include <iostream>
19 #include <cstring>
20 
21 using namespace std;
22 using namespace Belle2;
23 using namespace CDC;
24 
25 #define NUM_CDC_COPPER 75
26 //-----------------------------------------------------------------
27 // Register the Module
28 //-----------------------------------------------------------------
29 REG_MODULE(CDCPacker);
30 
31 //-----------------------------------------------------------------
32 // Implementation
33 //-----------------------------------------------------------------
34 
35 CDCPackerModule::CDCPackerModule() : Module()
36 {
37  //Set module properties
38  setDescription("Generate RawCDC object from CDCHit");
40 
41  addParam("rawCDCName", m_rawCDCName, "Name of the RawCDC List name..", string(""));
42  addParam("cdcRawHitName", m_cdcRawHitName, "Name of the CDCRawHit (Suppressed mode).", string(""));
43  addParam("cdcHitName", m_cdcHitName, "Name of the CDCHit List name..", string(""));
44  addParam("fadcThreshold", m_fadcThreshold, "Threshold voltage (mV).", 10);
45  addParam("xmlMapFileName", m_xmlMapFileName, "path+name of the xml file",
46  string("/cdc/data/ch_map.dat"));
47  addParam("enableStoreRawCDC", m_enableStoreCDCRawHit, "Enable to store to the RawCDC object", true);
48  addParam("enablePrintOut", m_enablePrintOut, "Enable to print out the data to the terminal", true);
49  addParam("enableDatabase", m_enableDatabase, "Enable database to read the channel map.", true);
50 
51  m_channelMapFromDB.addCallback(this, &CDCPackerModule::loadMap);
52 }
53 
55 {
56 }
57 
59 {
60 
61  B2INFO("CDCPacker: initialize() Called.");
62 
63  m_rawCDCs.registerInDataStore(m_rawCDCName);
64  m_CDCRawHits.registerInDataStore(m_cdcRawHitName);
65  m_CDCHits.registerInDataStore(m_cdcHitName);
66 
67  loadMap();
68 
69  B2INFO("CDCPacker: FADC threshold: " << m_fadcThreshold);
70 
71  m_event = 0;
72 
73 }
74 
76 {
77  B2INFO("CDCPacker: beginRun() called.");
78 }
79 
80 int CDCPackerModule::getFEEID(int copper_id, int slot_id)
81 {
82  //
83  // The releation between COPPER ID and FEE ID depends on
84  // cable connection, which has not been finalized yet. ( 2015.6.16 )
85  //
86 
87  //#define DEFAULT
88 #ifdef DEFAULT
89  return (copper_id * 4 + slot_id);
90 #endif
91 
92  //#define PATTERN1
93 #ifdef PATTERN1
94  return (copper_id + slot_id * NUM_CDC_COPPER);
95 #endif
96 
97 #define PATTERN2
98 #ifdef PATTERN2
99  return ((copper_id / 15) * 60 + (copper_id % 15) + slot_id * 15);
100 #endif
101 
102 }
103 
105 {
106  // std::vector<int> eWire_nhit(36882, 0);
107 
108  int tot_chdata_bytes[302];
109  memset(tot_chdata_bytes, 0, sizeof(int) * 302);
110 
111  const int ch_data_bytes = 8; // 8bytes ( 1hit/ch case)
112 
113  std::vector<CDCChannelData> chData;
114  chData.clear();
115 
116  for (const auto& hit : m_CDCHits) {
117  int eWire = (int)(hit.getID());
118  int sly = eWire / 4096;
119  int ily = (eWire % 4096) / 512;
120  int iwire = (eWire % 512);
121  short tdc = hit.getTDCCount();
122  short adc = hit.getADCCount();
123  unsigned short tot = hit.getTOT();
124  //
125  // If not prepared the map element for this cell, exit.
126  //
127  if (m_fee_board[ sly ][ ily ][ iwire] < 0 || m_fee_ch[ sly ][ ily ][ iwire] < 0) {
128  printf("Hit WireID %8d SL %3d IL %3d WI %4d BOARD %3d CH %3d\n",
129  (int)(hit.getID()), sly, ily, iwire,
130  m_fee_board[ sly ][ ily ][ iwire], m_fee_ch[ sly ][ ily ][ iwire]);
131  exit(1);
132  }
133 
134  if (hit.is2ndHit() == false) { // first hit timing for one cell.
135  // increase 8 bytes (4 bhytes).
136  tot_chdata_bytes[ m_fee_board[ sly ][ ily ][ iwire] ] += ch_data_bytes;
137  CDCChannelData chd(m_fee_board[sly][ily][iwire], m_fee_ch[sly][ily][iwire], 8, tot, adc, tdc);
138  chData.push_back(chd);
139  } else { // second hit timing
140  // Search ChData object for this cell.
141  const int boardId = m_fee_board[sly][ily][iwire];
142  const int channel = m_fee_ch[sly][ily][iwire];
143  auto fi = std::find_if(chData.begin(), chData.end(),
144  [&](CDCChannelData & ch) {
145  return (ch.getBoard() == boardId && ch.getChannel() == channel);
146  });
147  if (fi != chData.end()) {
148  tot_chdata_bytes[ m_fee_board[ sly ][ ily ][ iwire] ] += 2;
149  const size_t index = std::distance(chData.begin(), fi);
150  chData[index].setTDC2ndHit(tdc);
151  }
152  }
153 
154  }
155 
156  for (const auto& c : chData) {
157  int board = c.getBoard();
158  int ch = c.getChannel();
159  bool flag = c.is2ndHit();
160  int len = c.getDataLength();
161  if (!((len == 8 && flag == false) ||
162  (len == 10 && flag == true))) {
163  B2ERROR("inconsistent data object board : " << board << " ch " << ch);
164  }
165  }
166 
167 
168  RawCOPPERPackerInfo rawcprpacker_info;
169  rawcprpacker_info.exp_num = 0;
170  rawcprpacker_info.run_subrun_num = 1; // run number : 14bits, subrun # : 8bits
171  rawcprpacker_info.eve_num = m_event;
172  rawcprpacker_info.tt_ctime = 0x7123456;
173  rawcprpacker_info.tt_utime = 0xF1234567;
174  rawcprpacker_info.b2l_ctime = 0x7654321;
175 
176  const int packet_header_words = 3; // 12bytes
177 
178  for (int i = 0 ; i < NUM_CDC_COPPER; i++) {
179 
180  rawcprpacker_info.node_id = 0x02000000 + i + 1; // CDC detector ID + (node ID).
181  int nwords[4] = {0, 0, 0, 0};
182  int* buf[4] = {0, 0, 0, 0};
183 
184  for (int j = 0; j < 4; j++) {
185  int fee_id = getFEEID(i, j);
186  nwords[ j ] = ((tot_chdata_bytes[ fee_id ] + 3) / 4) + packet_header_words;
187 
188  buf[ j ] = new int[ nwords[ j ] ];
189 
190  // Store CDC header in buffer.
191  const char type = 0x20; // suppressed mode.
192  const char ver = 0x0; // version (always 0).
193  const short trigTime = 0x0;
194  const short dataLength = nwords[j] * 4 - packet_header_words * 4;
195  const int trigNum = m_event;
196 
197  *(buf[j] + 0) = (type << 24) | (ver << 16) | fee_id;
198  *(buf[j] + 1) = ((trigTime << 16) | dataLength);
199  *(buf[j] + 2) = trigNum;
200 
201  short* sbuf = (short*)(buf[j] + 3);
202 
203  bool halfOffset = false;
204  short reservedValue = 0xcccc;
205  for (const auto& c : chData) {
206  const int board = c.getBoard();
207  const int ch = c.getChannel();
208  const int len = c.getDataLength();
209  if (board == fee_id) {
210  // printf("board %.8x ch %.8d adc %.8x tdc %.8x\n" ,board, ch, c.getADCCount(), c.getTDCCount());
211  if (halfOffset == false) {
212  *sbuf++ = c.getTOT();
213  *sbuf++ = ((ch << 8) | len);
214  *sbuf++ = c.getTDCCount();
215  *sbuf++ = c.getADCCount();
216  if (c.is2ndHit()) {
217  reservedValue = c.getTDCCount2ndHit();
218  halfOffset = true;
219  }
220  } else {
221  *sbuf++ = ((ch << 8) | len);
222  *sbuf++ = reservedValue;
223  *sbuf++ = c.getADCCount();
224  *sbuf++ = c.getTOT();
225  if (c.is2ndHit()) {
226  *sbuf++ = c.getTDCCount2ndHit();
227  *sbuf++ = c.getTDCCount();
228  halfOffset = false;
229  } else {
230  reservedValue = c.getTDCCount();
231  }
232  }
233  }
234  }
235  if (halfOffset == true) {
236  *sbuf++ = 0xff02;
237  *sbuf = reservedValue;
238  }
239  }
240 
241  RawCDC* raw_cdc = m_rawCDCs.appendNew();
242  raw_cdc->PackDetectorBuf(buf[0], nwords[0],
243  buf[1], nwords[1],
244  buf[2], nwords[2],
245  buf[3], nwords[3],
246  rawcprpacker_info);
247 
248  for (int j = 0; j < 4; j++) {
249  if (buf[j] != nullptr) delete [] buf[j];
250  }
251  }
252  m_event++;
253 
254 }
255 
257 {
258  B2INFO("CDCPacker : End run.");
259 }
260 
262 {
263  B2INFO("CDCPacker : Terminated.");
264 }
265 
266 
267 const WireID CDCPackerModule::getWireID(int iBoard, int iCh)
268 {
269  return m_map[iBoard][iCh];
270 }
271 
273 {
274 
275  // Frontend : 48 channels/board
276  // Number of board : 302
277 
278  for (int i = 0 ; i < 9; ++i) {
279  for (int j = 0 ; j < 8; ++j) {
280  for (int k = 0 ; k < 384; ++k) {
281  m_fee_board[i][j][k] = -1;
282  m_fee_ch[i][j][k] = -1;
283  }
284  }
285  }
286 
287  if (m_enableDatabase == false) {
288 
289  // Read the channel map from the local text.
290  std::string fileName = FileSystem::findFile(m_xmlMapFileName);
291  std::cout << fileName << std::endl;
292  if (fileName == "") {
293  B2ERROR("CDCPacker can't fine a filename: " << m_xmlMapFileName);
294  exit(1);
295  }
296 
297  ifstream ifs;
298  ifs.open(fileName.c_str());
299  int isl;
300  int il;
301  int iw;
302  int iBoard;
303  int iCh;
304 
305  while (!ifs.eof()) {
306 
307  ifs >> isl >> il >> iw >> iBoard >> iCh;
308  if (isl >= 9) continue; // Super layers should be from 0 t0 8.
309  const WireID wireId(isl, il, iw);
310  m_map[iBoard][iCh] = wireId;
311  m_fee_board[isl][il][iw] = iBoard;
312  m_fee_ch[isl][il][iw] = iCh;
313  }
314  } else {
315  // Read the channel map from the database.
316  for (const auto& cm : m_channelMapFromDB) {
317  const int isl = cm.getISuperLayer();
318  if (isl >= 9) continue; // Super layers should be from 0 t0 8.
319  const int il = cm.getILayer();
320  const int iw = cm.getIWire();
321  const int iBoard = cm.getBoardID();
322  const int iCh = cm.getBoardChannel();
323  const WireID wireId(isl, il, iw);
324  m_map[iBoard][iCh] = wireId;
325  m_fee_board[isl][il][iw] = iBoard;
326  m_fee_ch[isl][il][iw] = iCh;
327  }
328  }
329 }
330 
StoreArray< RawCDC > m_rawCDCs
Raw CDC array.
int m_fee_ch[9][8][384]
Assignment map of FE board channel to the cell.
bool m_enableDatabase
Enable/Disable to read the channel map from the database.
virtual ~CDCPackerModule()
Destructor of the module.
std::string m_rawCDCName
Name of the RawCDC dataobject (supressed mode).
void initialize() override
Initializes the Module.
DBArray< CDCChannelMap > m_channelMapFromDB
Channel map retrieved from DB.
void event() override
Event action (main routine).
int getFEEID(int copper_id, int slot_id)
Getter for Front End Electronics ID.
int m_fee_board[9][8][384]
Assignment map of FE board ID to the cell.
StoreArray< CDCRawHit > m_CDCRawHits
CDC raw hits.
void endRun() override
End run action.
const WireID getWireID(int iBoard, int iCh)
Getter of Wire ID.
void terminate() override
Termination action.
int m_fadcThreshold
FADC threshold.
std::string m_xmlMapFileName
Name of the assignment map of FE board channel to the cell.
WireID m_map[300][48]
Assignment map of FE board channel to the cell.
std::string m_cdcRawHitName
Name of the CDCRawHit dataobject (supressed mode).
void beginRun() override
Begin run action.
void loadMap()
Load FE channel to cell ID map.
bool m_enablePrintOut
Enable/Disable to print out the data to the terminal.
std::string m_cdcHitName
Tree name of the CDCHit object.
StoreArray< CDCHit > m_CDCHits
CDC hits.
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:148
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
The Raw CDC class Class for RawCOPPER class data taken by CDC Currently, this class is almost same as...
Definition: RawCDC.h:27
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
Class to identify a wire inside the CDC.
Definition: WireID.h:34
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#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.