Belle II Software  release-08-01-10
FrontEndMapper.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 <top/geometry/FrontEndMapper.h>
10 #include <framework/database/DBImportArray.h>
11 #include <framework/logging/LogSystem.h>
12 #include <iostream>
13 
14 
15 using namespace std;
16 
17 namespace Belle2 {
22  namespace TOP {
23 
24  FrontEndMapper::FrontEndMapper()
25  {
26  for (unsigned i = 0; i < c_numModules; i++) {
27  for (unsigned k = 0; k < c_numColumns; k++) {
28  m_fromModule[i][k] = 0;
29  }
30  }
31  }
32 
33 
34  FrontEndMapper::~FrontEndMapper()
35  {
36  if (m_mappingDB) delete m_mappingDB;
37  }
38 
39 
40  void FrontEndMapper::initialize(const GearDir& frontEndMapping)
41  {
42 
43  clear();
44 
45  // unordered sets used to check that ...
46 
47  unordered_set<unsigned short> scrodIDs; // all SCROD ID's are different
48  unordered_set<string> coppers; // COPPER inputs are used only once
49  unordered_set<int> modules; // (moduleID, col) mapped only once
50 
51  // read parameters from gerabox
52  int numModules = 0; // counter of mapped modules
53  for (const GearDir& topModule : frontEndMapping.getNodes("TOPModule")) {
54 
55  int moduleCNumber = topModule.getInt("@CNumber");
56  int moduleID = topModule.getInt("moduleID");
57  if (moduleID == 0) continue; // module is not installed into barrel
58  if (moduleID < 0 or moduleID > c_numModules) {
59  B2ERROR("TOP::FrontEndMapper: invalid moduleID in xml file"
60  << LogVar("moduleID", moduleID)
61  << LogVar("path", topModule.getPath()));
62  return;
63  }
64 
65  bool moduleMapped = false; // to count mapped modules
66  for (const GearDir& boardstack : topModule.getNodes("Boardstack")) {
67 
68  int col = boardstack.getInt("@col");
69  if (col < 0 or col >= c_numColumns) {
70  B2ERROR("TOP::FrontEndMapper: invalid boardstack number in xml file"
71  << LogVar("moduleID", moduleID)
72  << LogVar("boardstack", col)
73  << LogVar("path", boardstack.getPath()));
74  return;
75  }
76  if (!modules.insert(moduleID * c_numColumns + col).second) {
77  B2ERROR("TOP::FrontEndMapper: this boardstack is already mapped."
78  << LogVar("moduleID", moduleID)
79  << LogVar("boardstack", col)
80  << LogVar("path", boardstack.getPath()));
81  return;
82  }
83 
84  unsigned short scrodID = (unsigned short) boardstack.getInt("SCRODid");
85  if (!scrodIDs.insert(scrodID).second) {
86  B2ERROR("TOP::FrontEndMapper: this SCROD ID is already used."
87  << LogVar("moduleID", moduleID)
88  << LogVar("boardstack", col)
89  << LogVar("scrod", scrodID)
90  << LogVar("path", boardstack.getPath() + "/SCRODid"));
91  return;
92  }
93 
94  string finesseSlot = boardstack.getString("FinesseSlot");
95  int finesse = 0;
96  if (finesseSlot == "A") {finesse = 0;}
97  else if (finesseSlot == "B") {finesse = 1;}
98  else if (finesseSlot == "C") {finesse = 2;}
99  else if (finesseSlot == "D") {finesse = 3;}
100  else {
101  B2ERROR("TOP::FrontEndMapper: invalid finesse slot (valid are A, B, C, D)."
102  << LogVar("FinesseSlot", finesseSlot)
103  << LogVar("path", boardstack.getPath() + "/FinesseSlot"));
104  return;
105  }
106 
107  unsigned copperID = (unsigned) boardstack.getInt("COPPERid");
108  m_copperIDs.insert(copperID);
109  string copper = boardstack.getString("COPPERid") + " " + finesseSlot;
110  if (!coppers.insert(copper).second) {
111  B2ERROR("TOP::FrontEndMapper: this COPPER ID is already used."
112  << LogVar("moduleID", moduleID)
113  << LogVar("boardstack", col)
114  << LogVar("copperID", copper)
115  << LogVar("path", boardstack.getPath() + "/COPPERid"));
116  return;
117  }
118 
119  TOPFrontEndMap feemap(moduleID, moduleCNumber, col, scrodID, copperID, finesse,
120  m_mapping.size());
121  m_mapping.push_back(feemap);
122  moduleMapped = true;
123  }
124  if (moduleMapped) numModules++;
125  }
126 
127  // set conversion objects
128 
129  for (const auto& feemap : m_mapping) {
130  m_fromModule[feemap.getModuleID() - 1][feemap.getBoardstackNumber()] = &feemap;
131  m_fromScrod[feemap.getScrodID()] = &feemap;
132  m_fromCopper[feemap.getCopperID() * 4 + feemap.getFinesseSlot()] = &feemap;
133  }
134  m_valid = true;
135 
136  B2INFO("TOP::FrontEndMapper: " << m_mapping.size() << " SCROD's mapped to "
137  << numModules << " TOP module(s)");
138 
139  // print mappings if debug level for package 'top' is set to 100 or larger
140  const auto& logSystem = LogSystem::Instance();
141  if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100, "top")) {
142  print();
143  }
144 
145  }
146 
147 
148  void FrontEndMapper::initialize()
149  {
150 
151  if (m_mappingDB) delete m_mappingDB;
152  m_mappingDB = new DBArray<TOPFrontEndMap>();
153 
154  if (!m_mappingDB->isValid()) {
155  clear();
156  return;
157  }
158  update();
159 
160  m_mappingDB->addCallback(this, &FrontEndMapper::update);
161 
162  const auto& logSystem = LogSystem::Instance();
163  if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100, "top")) {
164  print();
165  }
166 
167  }
168 
169 
170  void FrontEndMapper::importPayload(const IntervalOfValidity& iov) const
171  {
173  for (const auto& map : m_mapping) {
174  array.appendNew(map);
175  }
176  array.import(iov);
177  }
178 
179 
180  void FrontEndMapper::clear()
181  {
182  m_mapping.clear();
183  m_copperIDs.clear();
184  m_fromScrod.clear();
185  m_fromCopper.clear();
186  for (unsigned i = 0; i < c_numModules; i++) {
187  for (unsigned k = 0; k < c_numColumns; k++) {
188  m_fromModule[i][k] = 0;
189  }
190  }
191  m_valid = false;
192  m_fromDB = false;
193  }
194 
195 
196  void FrontEndMapper::update()
197  {
198  clear();
199  if (!m_mappingDB->isValid()) return;
200 
201  for (const auto& feemap : *m_mappingDB) {
202  m_copperIDs.insert(feemap.getCopperID());
203  m_fromModule[feemap.getModuleID() - 1][feemap.getBoardstackNumber()] = &feemap;
204  m_fromScrod[feemap.getScrodID()] = &feemap;
205  m_fromCopper[feemap.getCopperID() * 4 + feemap.getFinesseSlot()] = &feemap;
206  }
207  m_valid = true;
208  m_fromDB = true;
209  }
210 
211 
212  void FrontEndMapper::print() const
213  {
214  cout << endl;
215  cout << " Mapping of TOP front-end electronics" << endl << endl;
216 
217  const char label[5] = "ABCD";
218  for (int i = 0; i < c_numModules; i++) {
219  int moduleID = i + 1;
220  cout << " slot " << moduleID
221  << " (module " << getModuleCNumber(moduleID) << "):" << endl;
222  for (int bs = 0; bs < c_numColumns; bs++) {
223  const auto* map = getMap(moduleID, bs);
224  if (!map) continue;
225  cout << " BS" << bs;
226  cout << " scrod " << map->getScrodID();
227  if (map->getScrodID() < 10) cout << " ";
228  if (map->getScrodID() < 100) cout << " ";
229  cout << " copper " << map->getCopperID();
230  cout << " " << label[map->getFinesseSlot()];
231  cout << endl;
232  }
233  }
234  cout << endl;
235 
236  }
237 
238 
239 
240  } // TOP namespace
242 } // Belle2 namespace
Class for accessing arrays of objects in the database.
Definition: DBArray.h:26
Class for importing array of objects to the database.
Definition: DBImportArray.h:25
T * appendNew()
Construct a new T object at the end of the array.
Definition: DBImportArray.h:67
bool import(const IntervalOfValidity &iov)
Import the object to database.
Definition: DBImportBase.cc:36
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
A class that describes the interval of experiments/runs for which an object in the database is valid.
Mapping of a boardstack number within a module to SCROD and COPPER/Finesse.
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Definition: Interface.cc:21
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.