Belle II Software development
SVDOnlineToOfflineMap.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 "svd/online/SVDOnlineToOfflineMap.h"
10#include <boost/property_tree/xml_parser.hpp>
11#include <framework/logging/Logger.h>
12#include <framework/utilities/FileSystem.h>
13#include <vxd/geometry/GeoCache.h>
14
15using namespace Belle2;
16using namespace std;
17using boost::property_tree::ptree;
18
19
21 : m_MapUniqueName("")
22 , m_currentChipInfo()
23 , m_currentSensorInfo()
24{
25
26 // Create an empty property tree object
27
28 ptree propertyTree;
29
30 // Load the XML file into the property tree. If reading fails
31 // (cannot open file, parse error), an exception is thrown.
32 string xmlFullPath = FileSystem::findFile(xmlFilename);
33
34 if (! FileSystem::fileExists(xmlFullPath)) {
35 B2ERROR("The xml filename: " << xmlFilename << endl <<
36 "resolved to: " << xmlFullPath << endl <<
37 "by FileSystem::findFile does not exist." << endl <<
38 "SVD online to offline map cannot be initialized." << endl <<
39 "Be aware: no SVDShaperDigit will be produced by this module." << endl
40 );
41 return;
42 }
43
44 try {
45 read_xml(xmlFullPath, propertyTree);
46 } catch (std::exception const& ex) {
47 B2ERROR("STD excpetion rised during xml parsing " << ex.what() << endl <<
48 "SVD online to offline map cannot be initialized." << endl <<
49 "Be aware: no SVDShaperDigits will be produced by this module." << endl);
50 return;
51 } catch (...) {
52 B2ERROR("Unknown excpetion rised during xml parsing "
53 "SVD online to offline map cannot be initialized." << endl <<
54 "Be aware: no SVDShaperDigits will be produced by this module." << endl);
55 return;
56 }
57
58 try {
59 // traverse pt: let us navigate through the daughters of <SVD>
60 for (ptree::value_type const& v : propertyTree.get_child("SVD")) {
61 if (v.first == "unique") {
62 m_MapUniqueName = v.second.get<string>("<xmlattr>.name");
63 B2INFO("Loading the offline -> online SVD map named " << m_MapUniqueName);
64 }
65 // if the daughter is a <layer> then read it!
66 if (v.first == "layer")
67 ReadLayer(v.second.get<int>("<xmlattr>.n"), v.second);
68 }
69 } catch (...) {
70 B2ERROR("Unknown excpetion rised during map initialization! "
71 "SVD online to offline map corrupted." << endl <<
72 "Be aware: the SVDShaperDigits will be unreliable." << endl);
73 // To Do: rise an exception so that the calling module will skip the
74 // SVDShaperDigits filling
75 return;
76 }
77}
78
79const SVDOnlineToOfflineMap::SensorInfo& SVDOnlineToOfflineMap::getSensorInfo(unsigned char FADC, unsigned char APV25)
80{
81
82 ChipID id(FADC, APV25);
83 auto sensorIter = m_sensors.find(id);
84
85 if (sensorIter == m_sensors.end()) {
87
88 if (!(nBadMappingErrors % m_errorRate)) B2ERROR("Combination not found in the SVD On-line to Off-line map:" << LogVar("FADC",
89 int(FADC)) << LogVar("APV", int(APV25)));
90
95 }
96 m_currentSensorInfo = sensorIter->second;
98}
99
100
101
102const SVDOnlineToOfflineMap::ChipInfo& SVDOnlineToOfflineMap::getChipInfo(unsigned short layer, unsigned short ladder,
103 unsigned short dssd, bool side, unsigned short strip)
104{
105 SensorID id(layer, ladder, dssd, side);
106 auto chipIter = m_chips.find(id);
107
108 if (chipIter == m_chips.end()) B2WARNING(" The following combination: sensorID: " << layer << "." << ladder << "." << dssd <<
109 ", isU=" << side << ", strip=" << strip <<
110 " - is not found in the SVD Off-line to On-line map! The payload retrieved from database may be wrong! ");
111
112
113 vector<ChipInfo> vecChipInfo = chipIter->second;
114
115 ChipInfo info = {0, 0, 0, 0, 0};
116 ChipInfo* pinfo = &info;
117
118 for (std::vector<ChipInfo>::iterator it = vecChipInfo.begin() ; it != vecChipInfo.end(); ++it) {
119 ChipInfo& chipInfo = *it;
120 unsigned short channelFirst = min(chipInfo.stripFirst, chipInfo.stripLast);
121 unsigned short channelLast = max(chipInfo.stripFirst, chipInfo.stripLast);
122
123 if (strip >= channelFirst and strip <= channelLast) {
124 pinfo = &chipInfo;
125 pinfo->apvChannel = abs(strip - (pinfo->stripFirst));
126 }
127 }
128 if (pinfo->fadc == 0) B2WARNING("The strip number " << strip << " is not found in the SVDOnlineToOfflineMap for sensor " << layer <<
129 "." << ladder << "." << dssd << " on side " << (side ? "u" : "v") << "! Related APV chip is excluded in the hardware mapping.");
130
131 m_currentChipInfo = *pinfo;
132 return m_currentChipInfo;
133}
134
135bool SVDOnlineToOfflineMap::isAPVinMap(unsigned short layer, unsigned short ladder,
136 unsigned short dssd, bool side, unsigned short strip)
137{
138 SensorID id(layer, ladder, dssd, side);
139 auto chipIter = m_chips.find(id);
140
141 if (chipIter == m_chips.end()) return false;
142
143 vector<ChipInfo> vecChipInfo = chipIter->second;
144
145 ChipInfo info = {0, 0, 0, 0, 0};
146 ChipInfo* pinfo = &info;
147
148 for (std::vector<ChipInfo>::iterator it = vecChipInfo.begin() ; it != vecChipInfo.end(); ++it) {
149 ChipInfo& chipInfo = *it;
150 unsigned short channelFirst = min(chipInfo.stripFirst, chipInfo.stripLast);
151 unsigned short channelLast = max(chipInfo.stripFirst, chipInfo.stripLast);
152
153 if (strip >= channelFirst and strip <= channelLast) {
154 pinfo = &chipInfo;
155 pinfo->apvChannel = abs(strip - (pinfo->stripFirst));
156 }
157 }
158 if (pinfo->fadc == 0) return false;
159
160 return true;
161}
162
163bool SVDOnlineToOfflineMap::isAPVinMap(VxdID sensorID, bool side, unsigned short strip)
164{
165 return isAPVinMap(sensorID.getLayerNumber(), sensorID.getLadderNumber(), sensorID.getSensorNumber(), side, strip);
166}
167
168
170 unsigned char APV25, unsigned char channel, short samples[6], float time)
171{
172 // Issue a warning, we'll be sending out a null pointer.
173 if (channel > 127) {
174 B2WARNING(" channel out of range (0-127):" << LogVar("channel", int(channel)));
175 return nullptr;
176 }
177 const SensorInfo& info = getSensorInfo(FADC, APV25);
178 short strip = getStripNumber(channel, info);
179
181 copy(samples, samples + SVDShaperDigit::c_nAPVSamples, rawSamples.begin());
182
183 // create SVDShaperDigit only for existing sensor
184 if (info.m_sensorID) {
185 return new SVDShaperDigit(info.m_sensorID, info.m_uSide, strip, rawSamples, time);
186 } else {
187 return nullptr;
188 }
189}
190
191
192void
193SVDOnlineToOfflineMap::ReadLayer(int nlayer, ptree const& xml_layer)
194{
195 // traverse xml_layer: let us navigate through the daughters of <layer>
196 for (ptree::value_type const& v : xml_layer) {
197 // if the daughter is a <ladder> then read it!
198 if (v.first == "ladder") {
199 ReadLadder(nlayer, v.second.get<int>("<xmlattr>.n"), v.second);
200 }
201 }
202}
203
204void
205SVDOnlineToOfflineMap::ReadLadder(int nlayer, int nladder, ptree const& xml_ladder)
206{
207 // traverse xml_ladder: let us navigate through the daughters of <ladder>
208 for (ptree::value_type const& v : xml_ladder) {
209 // if the daughter is a <sensor> then read it!
210 if (v.first == "sensor") {
211 ReadSensor(nlayer, nladder, v.second.get<int>("<xmlattr>.n"), v.second);
212 }
213 }
214}
215
216void
217SVDOnlineToOfflineMap::ReadSensor(int nlayer, int nladder, int nsensor, ptree const& xml_sensor)
218{
219 // traverse xml_sensor: let us navigate through the daughters of <sensor>
220 for (ptree::value_type const& v : xml_sensor) {
221 // if the daughter is one side <> then read it!
222 if (v.first == "side") {
223 std::string tagSide = v.second.get<std::string>("<xmlattr>.side");
224
225 bool isOnSideU = (tagSide == "U" || tagSide == "u");
226 bool isOnSideV = (tagSide == "V" || tagSide == "v");
227
228 if ((! isOnSideU) && (! isOnSideV)) {
229 B2ERROR("Side '" << tagSide << "' on layer " << nlayer
230 << " ladder " << nladder << " sensor " << nsensor
231 << " is neither 'U' nor 'V'");
232 }
233
234 ReadSensorSide(nlayer, nladder, nsensor, isOnSideU, v.second);
235 }
236 }
237
238}
239
240void
241SVDOnlineToOfflineMap::ReadSensorSide(int nlayer, int nladder, int nsensor, bool isU,
242 ptree const& xml_side)
243{
244
245 // traverse xml_sensor: let us navigate through the daughters of <side>
246
247
248 vector<ChipInfo> vecInfo; // for packer
249 SensorID sid(nlayer, nladder, nsensor, isU);
250
251 for (ptree::value_type const& v : xml_side) {
252 // if the daughter is a <chip>
253
254 if (v.first == "chip") {
255 auto tags = v.second;
256 unsigned char chipN = tags.get<unsigned char>("<xmlattr>.n");
257 unsigned char FADCn = tags.get<unsigned char>("<xmlattr>.FADCn");
258
259 //storing info on FADC numbers and related APV chips
260 FADCnumbers.insert(FADCn);
261 APVforFADCmap.insert(std::pair<unsigned char, unsigned char>(FADCn, chipN));
262
263 ChipID cid(FADCn, chipN);
264
265 auto sensorIter = m_sensors.find(cid);
266
267 if (sensorIter != m_sensors.end()) {
268 B2WARNING("Repeated insertion for FADC " << FADCn << " and APV "
269 << chipN << ", layer/ladder/sensor " << nlayer << "/" << nladder
270 << "/" << nsensor << ", side " << (isU ? "u" : "v"));
271 }
272 unsigned short stripNumberCh0 = tags.get<unsigned short>("<xmlattr>.strip_number_of_ch0");
273 unsigned short stripNumberCh127 = tags.get<unsigned short>("<xmlattr>.strip_number_of_ch127");
274
275
276 SensorInfo sinfo;
277 sinfo.m_sensorID = VxdID(nlayer, nladder, nsensor);
278 sinfo.m_uSide = isU;
279 sinfo.m_parallel = (stripNumberCh127 > stripNumberCh0);
280 sinfo.m_channel0 = stripNumberCh0;
281 sinfo.m_channel127 = stripNumberCh127;
282
283 m_sensors[cid] = sinfo;
284
285 // for packer
286 ChipInfo cinfo;
287 cinfo.fadc = FADCn;
288 cinfo.apv = chipN;
289 cinfo.stripFirst = stripNumberCh0;
290 cinfo.stripLast = stripNumberCh127;
291 cinfo.apvChannel = 0;
292
293 vecInfo.push_back(cinfo);
294
295 } //chip
296
297 } // for daughters
298
299 m_chips[sid] = vecInfo; // for packer
300}
301
303{
304 unsigned short it = 0;
305
306 for (auto ifadc = FADCnumbers.begin(); ifadc != FADCnumbers.end(); ++ifadc) {
307 map2[it] = *ifadc;
308 map1[*ifadc] = it++;
309 }
310}
311
313{
314
315
317
318 for (auto layer : geoCache.getLayers(VXD::SensorInfoBase::SVD))
319 for (auto ladder : geoCache.getLadders(layer))
320 for (Belle2::VxdID sensor : geoCache.getSensors(ladder))
321 for (int view = 0; view < 2; view++) {
322
323 int nAPVs = 6;
324 if (layer.getLayerNumber() != 3 && view == 0)
325 nAPVs = 4;
326
327 //loop on all APVs of the side
328 for (int apv = 0; apv < nAPVs; apv++) {
329 B2DEBUG(29, "checking " << sensor.getLayerNumber() << "." << sensor.getLadderNumber() << "." << sensor.getSensorNumber() <<
330 ", view = " << view << ", apv = " << apv);
331 if (! isAPVinMap(sensor, view, apv * 128 + 63.5)) {
332 missingAPV tmp_missingAPV;
333 tmp_missingAPV.m_sensorID = sensor;
334 tmp_missingAPV.m_isUSide = view;
335 tmp_missingAPV.m_halfStrip = apv * 128 + 63.5;
336
337 m_missingAPVs.push_back(tmp_missingAPV);
338 B2DEBUG(29, "FOUND MISSING APV: " << sensor << ", " << view << ", " << apv);
339 }
340
341 }
342
343 }
344
345}
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:151
static bool fileExists(const std::string &filename)
Check if the file with given filename exists.
Definition: FileSystem.cc:32
Class to hold FADC+APV25 numbers.
Class to hold numbers related to sensor.
void prepareListOfMissingAPVs()
prepares the list of the missing APVs using the channel mapping
std::unordered_map< unsigned short, unsigned short > FADCmap
FADC map typedef.
const SensorInfo & getSensorInfo(unsigned char FADC, unsigned char APV25)
Get SensorInfo for a given FADC/APV combination.
SensorInfo m_currentSensorInfo
current sensor info
void ReadSensor(int nLayer, int nLadder, int nSensor, boost::property_tree::ptree const &xml_sensor)
Read from the ptree xml_sensor the sensor nSensor in ladder nLadder in layer nLayer.
SVDShaperDigit * NewShaperDigit(unsigned char FADC, unsigned char APV25, unsigned char channel, short samples[6], float time=0.0)
Return a pointer to a new SVDShpaerDigit whose VxdID, isU and cellID is set.
std::unordered_multimap< unsigned char, unsigned char > APVforFADCmap
map containing FADC numbers assigned to multiple APVs, from xml file
int m_errorRate
The suppression factor of BadMapping ERRORs messages to be shown.
const ChipInfo & getChipInfo(unsigned short layer, unsigned short ladder, unsigned short dssd, bool side, unsigned short strip)
Get ChipInfo for a given layer/ladder/dssd/side/strip combination.
unsigned int nBadMappingErrors
Counter of the BadMapping errors.
SVDOnlineToOfflineMap()=delete
No default constructor.
std::unordered_map< ChipID::baseType, SensorInfo > m_sensors
m_sensors[ChipID(FADC,APV25)] gives the SensorInfo for the given APV25 on the given FADC (Unpacker)
void ReadLadder(int nLayer, int nLadder, boost::property_tree::ptree const &xml_ladder)
Read from the ptree xml_ladde the ladder nLadder in layer nLayer.
std::unordered_set< unsigned char > FADCnumbers
container for FADC numbers from current mapping file
ChipInfo m_currentChipInfo
internal instance of chipinfo used by the getter
void ReadLayer(int nLayer, boost::property_tree::ptree const &xml_layer)
Read from the ptree v in the xml file the layer nLayer.
std::string m_MapUniqueName
Human readable unique name of this map.
std::unordered_map< SensorID::baseType, std::vector< ChipInfo > > m_chips
needed for the packer, map of VxdID to chips
void ReadSensorSide(int nLayer, int nLadder, int nSensor, bool isU, boost::property_tree::ptree const &xml_side)
Read from the ptree xml_side the U-side, if isU, (the V-side otherwise) of the sensor nSensor in ladd...
void prepFADCmaps(FADCmap &, FADCmap &)
function that maps FADC numbers as 0-(nFADCboards-1) from FADCnumbers unordered_set
bool isAPVinMap(unsigned short layer, unsigned short ladder, unsigned short dssd, bool side, unsigned short strip)
is the APV of the strips in the map? for a given layer/ladder/dssd/side/strip combination.
short getStripNumber(unsigned char channel, const SensorInfo &info) const
Convert APV channel number to a strip number using a ChipInfo object.
std::vector< missingAPV > m_missingAPVs
list of the missing APVs
The SVD ShaperDigit class.
static const std::size_t c_nAPVSamples
Number of APV samples stored.
std::array< APVRawSampleType, c_nAPVSamples > APVRawSamples
array of APVRawSamplesType objects
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getSensorNumber() const
Get the sensor id.
Definition: VxdID.h:100
baseType getLadderNumber() const
Get the ladder id.
Definition: VxdID.h:98
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.
STL namespace.
Struct to hold data about an APV25 chip.
unsigned short stripLast
last strip number
unsigned short stripFirst
first strip number
Struct to hold data about a sensor.
unsigned short m_channel127
Strip corresponding to channel 127.
unsigned short m_channel0
Strip corresponding to channel 0.
struct to hold missing APVs informations
float m_halfStrip
floating strip in the middle of the APV
bool m_isUSide
True if u-side of the sensor.