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