Belle II Software  release-08-01-10
ECLChannelMapper.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 /* Own header. */
10 #include <ecl/mapper/ECLChannelMapper.h>
11 
12 /* Basf2 headers. */
13 #include <framework/database/DBObjPtr.h>
14 #include <framework/utilities/FileSystem.h>
15 #include <rawdata/dataobjects/RawCOPPERFormat.h>
16 
17 /* C++ headers. */
18 #include <fstream>
19 #include <string>
20 
21 using namespace Belle2;
22 using namespace std;
23 using namespace ECL;
24 
26 {
27  int i;
28  for (i = 0; i < ECL_BARREL_CRATES * ECL_BARREL_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER; i++)
29  convertArrayBarrel[i] = 0;
30  for (i = 0; i < ECL_FWD_CRATES * ECL_FWD_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER; i++)
31  convertArrayFWD[i] = 0;
32  for (i = 0; i < ECL_BKW_CRATES * ECL_BKW_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER; i++)
33  convertArrayBKW[i] = 0;
34  for (i = 0; i < ECL_TOTAL_CHANNELS; i++)
35  for (int j = 0; j < 3; j++)
36  convertArrayInv[i][j] = 0;
37 
38  isInitialized = false;
39 
40 }
41 
43 {
44  std::string filePath = FileSystem::findFile("ecl/data/ecl_channels_map.txt");
45  return initFromFile(filePath.c_str());
46 }
47 
50 {
51  if (!instance) {
52  instance = new ECLChannelMapper();
53  if (use_db) instance->initFromDB();
54  else instance->initFromFile();
55  }
56  return instance;
57 }
58 
59 bool ECLChannelMapper::initFromFile(const char* eclMapFileName)
60 {
61  B2WARNING("Reading possibly outdated ECLChannelMap from " << eclMapFileName);
62 
63  ifstream mapFile(eclMapFileName);
64  if (mapFile.is_open()) {
65 
66  float iCrate, iShaper, iChannel, thetaID, phiID, cellID;
67  int arrayIndex = 0;
68  int arrayCount = 0;
69  while (mapFile.good()) {
70 
71  // Ignoring commented lines
72  char ch = mapFile.get();
73  if (ch == '#') {
74  mapFile.ignore(256, '\n');
75  continue;
76  } else if (ch == '\n') {
77  continue;
78  } else {
79  mapFile.unget();
80  }
81 
82  mapFile >> iCrate >> iShaper >> iChannel >> thetaID >> phiID >> cellID;
83 
84  if (cellID > static_cast<float>(ECL_TOTAL_CHANNELS)) {
85  B2ERROR("ECLChannelMapper:: wrong cellID in the init file " << eclMapFileName);
86  return false;
87  }
88 
89  if (cellID > 0) {
90  convertArrayInv[(int)cellID - 1][0] = (int)iCrate;
91  convertArrayInv[(int)cellID - 1][1] = (int)iShaper;
92  convertArrayInv[(int)cellID - 1][2] = (int)iChannel;
93  }
94 
95  // Barrel
96  if (iCrate >= 1 && iCrate <= 36) {
97  arrayIndex = arrayCount;
98  convertArrayBarrel[arrayIndex] = (int)cellID;
99  }
100 
101  // Forward endcap
102  if (iCrate > 36 && iCrate < 45) {
103  arrayIndex = arrayCount - 36 * 12 * 16;
104 
105  if (arrayIndex >= 0 && arrayIndex < ECL_FWD_CRATES * ECL_FWD_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER)
106  convertArrayFWD[arrayIndex] = (int)cellID;
107  }
108 
109  // Backward endcap
110  if (iCrate > 44) {
111  arrayIndex = arrayCount - 36 * 12 * 16 - 8 * 10 * 16;
112  if (arrayIndex >= 0 && arrayIndex < ECL_BKW_CRATES * ECL_BKW_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER)
113  convertArrayBKW[arrayIndex] = (int)cellID;
114  }
115  arrayCount++;
116  }
117  } else {
118  B2ERROR("ERROR:: file " << eclMapFileName << " doesn't found");
119  return false;
120  }
121 
122  isInitialized = true;
123 
124  return true;
125 }
126 
128 {
129  DBObjPtr<Belle2::ECLChannelMap> channelMap("ECLChannelMap");
130  // Re-initialize only if interval of validity was changed
131  if (isInitialized && !channelMap.hasChanged()) {
132  return true;
133  }
134 
135  if (!channelMap.isValid()) {
136  B2FATAL("ECLChannelMapper:: Could not get ECLChannelMap from the database.");
137  }
138 
139  B2INFO("ECLChannelMapper:: loaded ECLChannelMap from the database"
140  << LogVar("IoV", channelMap.getIoV()));
141 
142  const auto& mappingBAR = channelMap->getMappingBAR();
143  const auto& mappingFWD = channelMap->getMappingFWD();
144  const auto& mappingBWD = channelMap->getMappingBWD();
145 
146  int cellID;
147  // Loop variables
148  int iCrate = 1, iShaper = 1, iChannel = 1;
149  // Index in currently used array (converArrayBarrel,*FWD,*BKW)
150  int arrayIndex = 0;
151  int iMaxShapers = ECL_BARREL_SHAPERS_IN_CRATE;
152 
153  while (iCrate <= ECL_CRATES) {
154  if (iCrate <= ECL_BARREL_CRATES) {
155  // Barrel
156  cellID = mappingBAR[arrayIndex];
157  convertArrayBarrel[arrayIndex] = cellID;
158  } else if (iCrate <= ECL_BARREL_CRATES + ECL_FWD_CRATES) {
159  // Forward endcap
160  cellID = mappingFWD[arrayIndex];
161  convertArrayFWD[arrayIndex] = cellID;
162  } else {
163  // Backward endcap
164  cellID = mappingBWD[arrayIndex];
165  convertArrayBKW[arrayIndex] = cellID;
166  }
167 
168  if (cellID > ECL_TOTAL_CHANNELS) {
169  B2FATAL("ECLChannelMapper:: wrong cellID (" << cellID << ") in the database payload");
170  return false;
171  }
172 
173  if (cellID > 0) {
174  convertArrayInv[cellID - 1][0] = iCrate;
175  convertArrayInv[cellID - 1][1] = iShaper;
176  convertArrayInv[cellID - 1][2] = iChannel;
177  }
178 
179  arrayIndex++;
180  // Increment all indices, accounting for hierarchical
181  // structure of channels <- shapers <- crates
182  iChannel++;
183  if (iChannel > ECL_CHANNELS_IN_SHAPER) {
184  iChannel = 1;
185  iShaper++;
186  if (iShaper > iMaxShapers) {
187  iShaper = 1;
188  if (iCrate == ECL_BARREL_CRATES) {
189  arrayIndex = 0;
190  iMaxShapers = getNShapersInCrate(iCrate + 1);
191  } else if (iCrate == ECL_BARREL_CRATES + ECL_FWD_CRATES) {
192  arrayIndex = 0;
193  iMaxShapers = getNShapersInCrate(iCrate + 1);
194  }
195  iCrate++;
196  }
197  }
198  }
199 
200  isInitialized = true;
201 
202  return true;
203 }
204 
206 {
207  ECLChannelMap map;
208 
209  if (!isInitialized) {
210  B2FATAL("ECLChannelMapper:: Tried to generate dbobject before initialization");
211  }
212 
213  int mappingBAR_size = ECL_BARREL_CRATES * ECL_BARREL_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER;
214  int mappingFWD_size = ECL_FWD_CRATES * ECL_FWD_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER;
215  int mappingBWD_size = ECL_BKW_CRATES * ECL_BKW_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER;
216 
217  std::vector<int> mappingBAR(mappingBAR_size);
218  std::vector<int> mappingFWD(mappingFWD_size);
219  std::vector<int> mappingBWD(mappingBWD_size);
220 
221  for (int i = 0; i < mappingBAR_size; i++)
222  mappingBAR[i] = convertArrayBarrel[i];
223  for (int i = 0; i < mappingFWD_size; i++)
224  mappingFWD[i] = convertArrayFWD[i];
225  for (int i = 0; i < mappingBWD_size; i++)
226  mappingBWD[i] = convertArrayBKW[i];
227 
228  map.setMappingVectors(mappingBAR, mappingFWD, mappingBWD);
229 
230  return map;
231 }
232 
233 int ECLChannelMapper::getCrateID(int iCOPPERNode, int iFINESSE, bool pcie40)
234 {
235  int iCrate;
236 
237  if (!pcie40) {
238  // Converting from COPPER nodes
239  if (iFINESSE > ECL_FINESSES_IN_COPPER - 1) {
240  B2ERROR("ECLChannelMapper::ERROR:: wrong FINESSE " << iFINESSE);
241  return -1;
242  }
243 
244  if ((iCOPPERNode & BECL_ID) == BECL_ID) {
245  iCrate = (iCOPPERNode - BECL_ID - 1) * ECL_FINESSES_IN_COPPER + iFINESSE + 1;
246  } else if ((iCOPPERNode & EECL_ID) == EECL_ID) {
247  iCrate = ECL_BARREL_CRATES + iFINESSE * ECL_FWD_CRATES + (iCOPPERNode - EECL_ID - 1) + 1;
248  } else {
249  B2ERROR("ECLChannelMapper::ERROR:: wrong COPPER NodeID 0x" << std::hex << iCOPPERNode << " BECL_ID 0x" << BECL_ID << " EECL_ID 0x"
250  << EECL_ID);
251  return -1;
252  }
253  } else {
254  // Converting from PCIe40 nodes
255  const int ECL_BARREL_FEE_IN_PCIE40 = 18;
256  const int ECL_ENDCAP_FEE_IN_PCIE40 = 16;
257 
258  // crates 1..18 -> PCIe40, #1
259  // crates 19..36 -> PCIe40, #2
260  // crates 37,45,38,46,..,44,52 -> PCIe40, #3
261 
262  if (iCOPPERNode == BECL_ID + 1 || iCOPPERNode == BECL_ID + 2) {
263  // Barrel crates
264  iCrate = (iCOPPERNode - BECL_ID - 1) * ECL_BARREL_FEE_IN_PCIE40 + iFINESSE + 1;
265  if (iFINESSE >= ECL_BARREL_FEE_IN_PCIE40) {
266  B2ERROR("ECLChannelMapper:: slot id must be less than 18, got slot id " << iFINESSE);
267  return -1;
268  }
269  } else if (iCOPPERNode == BECL_ID + 3) {
270  // Endcap crates
271  iCrate = 2 * ECL_BARREL_FEE_IN_PCIE40 + (iFINESSE % 2) * 8 + iFINESSE / 2 + 1;
272  if (iFINESSE >= ECL_ENDCAP_FEE_IN_PCIE40) {
273  B2ERROR("ECLChannelMapper:: slot id must be less than 16, got slot id " << iFINESSE);
274  return -1;
275  }
276  } else {
277  B2ERROR("ECLChannelMapper:: wrong COPPER NodeID 0x" << std::hex << iCOPPERNode << " expected BECL_ID 0x" << BECL_ID);
278  return -1;
279  }
280  }
281 
282  if (iCrate > ECL_CRATES || iCrate < 1) {
283  B2ERROR("ECLChannelMapper::getCrateID::ERROR:: wrong crate number " << iCrate << " return -1");
284  return -1;
285  }
286 
287  return iCrate;
288 }
289 
290 int ECLChannelMapper::getCellId(int iCrate, int iShaper, int iChannel)
291 {
292  // iCrate = 1 - 36 -- Barrel
293  // 37 - 44 -- Forward
294  // 45 - 52 -- Backward
295  int cellID = 0;
296  int arrayIndex;
297 
298  if (iCrate < 1 || iCrate > 52) return -1;
299  if (iShaper < 1 || iShaper > 12) return -1;
300  if (iChannel < 1 || iChannel > 16) return -1;
301 
302  if (iCrate >= 1 && iCrate <= 36) {
303  //int thetaID = 1 + (iShaper - 1) * 4 + (iChannel - 1) % 4;
304  //int phiID = 1 + (iCrate - 1) * 4 + (iChannel - 1) / 4;
305  //cellID = 1 + ECL_FWD_CHANNELS + (phiID - 1) + (thetaID - 1) * 144;
306 
307  arrayIndex = (iCrate - 1) * ECL_BARREL_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER
308  + (iShaper - 1) * ECL_CHANNELS_IN_SHAPER + (iChannel - 1);
309  cellID = convertArrayBarrel[arrayIndex];
310 
311  }
312 
313  if (iCrate > 36 && iCrate < 45) {
314  arrayIndex = (iCrate - 37) * ECL_FWD_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER
315  + (iShaper - 1) * ECL_CHANNELS_IN_SHAPER + (iChannel - 1);
316  cellID = convertArrayFWD[arrayIndex];
317  }
318 
319  if (iCrate > 44) {
320  arrayIndex = (iCrate - 45) * ECL_BKW_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER
321  + (iShaper - 1) * ECL_CHANNELS_IN_SHAPER + (iChannel - 1);
322  cellID = convertArrayBKW[arrayIndex];
323  }
324 
325 
326  return cellID;
327 }
329 {
330  if (cellID > 0 && cellID <= ECL_TOTAL_CHANNELS) {
331  return convertArrayInv[cellID - 1 ][0];
332  } else return -1;
333 }
334 
336 {
337  if (cellID > 0 && cellID <= ECL_TOTAL_CHANNELS) {
338  return convertArrayInv[cellID - 1][1];
339  } else return -1;
340 }
341 
343 {
344  if (cellID > 0 && cellID <= ECL_TOTAL_CHANNELS) {
345  return convertArrayInv[cellID - 1][2];
346  } else return -1;
347 }
348 
350 {
351  if (cellID < 1 || cellID > ECL_TOTAL_CHANNELS) return -1;
352 
353  int crate = getCrateID(cellID);
354  int shaper = getShaperPosition(cellID);
355  int channel = getShaperChannel(cellID);
356 
357  int arrayIndex = 0;
358  // Total number of electronic IDs in barrel
359  const int bar_eid_count = ECL_BARREL_CRATES * ECL_BARREL_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER;
360  // Total number of electronic IDs in forward endcap
361  const int fwd_eid_count = ECL_FWD_CRATES * ECL_FWD_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER;
362 
363  if (crate <= 36) {
364  arrayIndex += (crate - 1) * ECL_BARREL_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER
365  + (shaper - 1) * ECL_CHANNELS_IN_SHAPER + (channel - 1);
366  } else if (crate <= 44) {
367  arrayIndex += bar_eid_count;
368  arrayIndex += (crate - 37) * ECL_FWD_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER
369  + (shaper - 1) * ECL_CHANNELS_IN_SHAPER + (channel - 1);
370  } else {
371  arrayIndex += bar_eid_count + fwd_eid_count;
372  arrayIndex += (crate - 45) * ECL_BKW_SHAPERS_IN_CRATE * ECL_CHANNELS_IN_SHAPER
373  + (shaper - 1) * ECL_CHANNELS_IN_SHAPER + (channel - 1);
374  }
375 
376  return arrayIndex;
377 }
378 
380 {
381  int systemID, iNode, iCOPPERNode;
382 
383  if (iCrate < 1 || iCrate > ECL_CRATES) return -1;
384  systemID = (iCrate <= ECL_BARREL_CRATES) * BECL_ID + (iCrate > ECL_BARREL_CRATES) * EECL_ID;
385  iNode = (iCrate <= ECL_BARREL_CRATES) ? (iCrate - 1) / 2 : (iCrate - ECL_BARREL_CRATES - 1) % 8;
386  iCOPPERNode = systemID + iNode + 1;
387 
388  return iCOPPERNode;
389 }
390 
392 {
393  if (iCrate < 1 || iCrate > ECL_CRATES) return -1;
394 
395  return (iCrate <= ECL_BARREL_CRATES) ? (iCrate - 1) % 2 : (iCrate - ECL_BARREL_CRATES - 1) / 8;
396 }
397 
399 {
400  if (iCrate <= ECL_BARREL_CRATES) return 0;
401  if (ECL_BARREL_CRATES < iCrate && iCrate <= ECL_BARREL_CRATES + ECL_FWD_CRATES)
402  return 1;
403  if (ECL_BARREL_CRATES + ECL_FWD_CRATES < iCrate && iCrate <= ECL_CRATES) return 2;
404  return -1;
405 }
406 
bool isValid() const
Check whether a valid object was obtained from the database.
IntervalOfValidity getIoV() const
Return current IoV of the object.
bool hasChanged()
Check whether the object has changed since the last call to hasChanged of the accessor).
DB object to store correspondence table of type (Crate id, ShaperDSP id, Channel id) <-> (ECL CellID)
Definition: ECLChannelMap.h:51
void setMappingVectors(const std::vector< int > &mappingBAR, const std::vector< int > &mappingFWD, const std::vector< int > &mappingBWD)
Set three vectors of map entries.
const std::vector< int > & getMappingBAR() const
Get vector of map entries for ECL barrel.
Definition: ECLChannelMap.h:59
const std::vector< int > & getMappingBWD() const
Get vector of map entries for ECL backward endcap.
Definition: ECLChannelMap.h:63
const std::vector< int > & getMappingFWD() const
Get vector of map entries for ECL forward endcap.
Definition: ECLChannelMap.h:61
This class provides access to ECL channel map that is either a) Loaded from the database (see ecl/dbo...
int getSubSystem(int iCrate)
Get ECL subsystem ID by given crate number: 0 – barrel, 1 – forward. 2 – backward endcap.
static ECLChannelMapper * instance
Main instance of ECLChannelMapper.
bool initFromDB()
Initialize channel mapper from the conditions database.
ECLChannelMap getDBObject()
Convert internal data to ECLChannelMap database object.
bool initFromFile()
Initialize channel mapper using data stored in default location.
int getElectronicsID(int cellID)
Return channel index in ECLChannelMap.
int getFINESSE(int iCrate)
Get number of FINESSE (0/1) in COPPER by given crate number.
ECLChannelMapper()
Default constructor.
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.
int getCOPPERNode(int iCrate)
Get number of COPPER node by given crate number.
static ECLChannelMapper * getInstance(bool use_db=true)
Return main instance of ECLChannelMapper.
int getCrateID(int iCOPPERNode, int iFINESSE, bool pcie40=false)
Get crate number by given COPPER node number and FINESSE number.
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
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.