Belle II Software  release-08-01-10
SVDLocalCalibrationsImporter.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 <svd/calibration/SVDLocalCalibrationsImporter.h>
11 
12 // Map from the online world (FADC id, ADC id, APV ch id)
13 // to the offline world (layer, ladder, sensor, view, cell)
14 #include <svd/online/SVDOnlineToOfflineMap.h>
15 
16 // framework - Database
17 #include <framework/database/Database.h>
18 #include <framework/database/DBObjPtr.h>
19 #include <framework/database/PayloadFile.h>
20 #include <framework/database/IntervalOfValidity.h>
21 #include <framework/database/DBImportObjPtr.h>
22 
23 // framework aux
24 #include <framework/logging/Logger.h>
25 
26 #include <framework/utilities/FileSystem.h>
27 
28 // wrapper objects
29 #include <svd/calibration/SVDNoiseCalibrations.h>
30 #include <svd/calibration/SVDPedestalCalibrations.h>
31 #include <svd/calibration/SVDPulseShapeCalibrations.h>
32 #include <svd/calibration/SVDHotStripsCalibrations.h>
33 #include <svd/calibration/SVDFADCMaskedStrips.h>
34 
35 #include <vxd/dataobjects/VxdID.h>
36 
37 #include <boost/property_tree/ptree.hpp>
38 #include <boost/property_tree/xml_parser.hpp>
39 
40 #include <sstream>
41 
42 using namespace std;
43 using namespace Belle2;
44 using boost::property_tree::ptree;
45 
46 void SVDLocalCalibrationsImporter::importSVDChannelMapping(const std::string& fileName)
47 {
48 
49  IntervalOfValidity iov(m_firstExperiment, m_firstRun, m_lastExperiment, m_lastRun);
50  const std::string filename = FileSystem::findFile(fileName); //phase 3 xmlMapping
51  B2INFO("Importing the svd online -> offline map " << fileName << "\n");
52  // const std::string filename = FileSystem::findFile("testbeam/vxd/data/2017_svd_mapping.xml");
53  const std::string payloadname = "SVDChannelMapping.xml";
54  if (Database::Instance().addPayload(payloadname, filename, iov))
55  B2INFO("Success!");
56  else
57  B2INFO("Failure :( ua uaa uaa uaa uaaaa)");
58 }
59 
60 
61 void SVDLocalCalibrationsImporter::importSVDNoiseCalibrationsFromXML(const std::string& xmlFileName, bool errorTollerant)
62 {
63  // We do initialize the noise to a negative value so that
64  // the SNR for not properly initialized channels is negative
65  // CAVEAT EMPTOR: if thou will disable an APV25 chip and will
66  // not update the noise.... the hits on the previously disabled
67  // chips will be discarded by the clusterizer.
68  // That is: please please pleaseeee do not upload calibrations
69  // with incomplete setup.
70  importSVDCalibrationsFromXML< SVDNoiseCalibrations::t_payload >(SVDNoiseCalibrations::name,
71  xmlFileName, "noises",
72  -1.0, errorTollerant);
73 }
74 
75 void SVDLocalCalibrationsImporter::importSVDPedestalCalibrationsFromXML(const std::string& xmlFileName, bool errorTollerant)
76 {
77  importSVDCalibrationsFromXML< SVDPedestalCalibrations::t_payload >(SVDPedestalCalibrations::name,
78  xmlFileName, "pedestals",
79  -1.0, errorTollerant);
80 }
81 
82 void SVDLocalCalibrationsImporter::importSVDHotStripsCalibrationsFromXML(const std::string& xmlFileName, bool errorTollerant)
83 {
84  importSVDCalibrationsFromXML< SVDHotStripsCalibrations::t_payload >(SVDHotStripsCalibrations::name,
85  xmlFileName, "hot_strips",
86  false, errorTollerant);
87 }
88 
89 void SVDLocalCalibrationsImporter::importSVDFADCMaskedStripsFromXML(const std::string& xmlFileName, bool errorTollerant)
90 {
91  importSVDCalibrationsFromXML< SVDFADCMaskedStrips::t_payload >(SVDFADCMaskedStrips::name,
92  xmlFileName, "masks",
93  false, errorTollerant);
94 }
95 
96 
97 
98 
99 template< class SVDcalibration >
100 void SVDLocalCalibrationsImporter::importSVDCalibrationsFromXML(const std::string& condDbname,
101  const std::string& xmlFileName,
102  const std::string& xmlTag,
103  typename SVDcalibration::t_perSideContainer::calibrationType defaultValue,
104  bool errorTollerant)
105 {
106  DBImportObjPtr< SVDcalibration> payload(condDbname);
107 
108  DBObjPtr<PayloadFile> OnlineToOfflineMapFileName("SVDChannelMapping.xml");
109 
110  OnlineToOfflineMapFileName.hasChanged();
111 
112  unique_ptr<SVDOnlineToOfflineMap> map =
113  make_unique<SVDOnlineToOfflineMap>(OnlineToOfflineMapFileName->getFileName());
114 
115  payload.construct(defaultValue, xmlFileName);
116 
117  // This is the property tree
118  ptree pt;
119 
120  // Load the XML file into the property tree. If reading fails
121  // (cannot open file, parse error), an exception is thrown.
122  read_xml(xmlFileName, pt);
123 
124  for (ptree::value_type const& backEndLayoutChild :
125  pt.get_child("cfg_document.back_end_layout")) {
126 
127  if (backEndLayoutChild.first == "fadc") {
128  int FADCid(0);
129  string FADCidString = backEndLayoutChild.second.get<string>("<xmlattr>.id");
130  stringstream ss;
131  ss << std::hex << FADCidString;
132  ss >> FADCid;
133 
134  for (ptree::value_type const& fadcChild : backEndLayoutChild.second.get_child("")) {
135  if (fadcChild.first == "adc") {
136  int ADCid = fadcChild.second.get<int>("<xmlattr>.id") ;
137  B2DEBUG(1, " ADC id = " << ADCid);
138 
139  int layerId = fadcChild.second.get<int>("<xmlattr>.layer_id");
140  B2DEBUG(1, " layer_id = " << layerId);
141 
142  int ladderId = fadcChild.second.get<int>("<xmlattr>.ladder_id") ;
143  B2DEBUG(1, " ladder_id = " << ladderId);
144 
145  int hybridId = fadcChild.second.get<int>("<xmlattr>.hybrid_id");
146  B2DEBUG(1, " hybrid_id = " << hybridId);
147 
148  B2DEBUG(1, " delay25 = " <<
149  fadcChild.second.get<int>("<xmlattr>.delay25"));
150 
151  for (ptree::value_type const& apvChild : fadcChild.second.get_child("")) {
152  if (apvChild.first == "apv25") {
153  int apv25ADCid = apvChild.second.get<int>("<xmlattr>.id");
154  string valuesString = apvChild.second.get<string>(xmlTag) ;
155  B2DEBUG(10, xmlTag << " APV25ID" << apv25ADCid << " "
156  << valuesString << "\n~~~~~~~~\n");
157 
158  stringstream ssn;
159  ssn << valuesString;
160  double value;
161  for (int apvChannel = 0 ; apvChannel < 128; apvChannel ++) {
162  ssn >> value;
164  map->getSensorInfo(FADCid, ADCid * 6 + apv25ADCid);
165 
166  short strip = map->getStripNumber(apvChannel, info);
167  int side = info.m_uSide ?
168  SVDcalibration::Uindex :
169  SVDcalibration::Vindex ;
170  int layer = info.m_sensorID.getLayerNumber();
171  int ladder = info.m_sensorID.getLadderNumber();
172  int sensor = info.m_sensorID.getSensorNumber();
173  if (apvChannel % 127 == 0)
174  B2DEBUG(100, layer << "_" << ladder << "_" <<
175  sensor << "_" << side << "_" << strip << "( " <<
176  apvChannel << ") " << value);
177  if (errorTollerant || layer != layerId || ladder != ladderId
178  // ||
179  // test on the sensor != f( hybrid) anr apv perhaps
180  )
181  B2FATAL("Inconsistency among maps: xml files tells \n" <<
182  "layer " << layerId << " ladder " << ladderId <<
183  " hybridID " << hybridId << "\n" <<
184  "while the basf2 map tells \n" <<
185  "layer " << layer << " ladder " << ladder <<
186  " sensor " << sensor << "\n");
187 
188 
189  payload->set(layer, ladder, sensor, side, strip, value);
190  }
191  }
192  }
193  }
194  }
195  }
196  }
197 
198 
199 
200  IntervalOfValidity iov(m_firstExperiment, m_firstRun,
201  m_lastExperiment, m_lastRun);
202 
203  payload.import(iov);
204 
205  B2RESULT("Imported to database.");
206 
207 }
208 
209 /****
210  * HERE!
211  */
212 void SVDLocalCalibrationsImporter::importSVDCalAmpCalibrationsFromXML(const std::string& xmlFileName, bool errorTollerant)
213 {
214 
215  DBImportObjPtr< typename SVDPulseShapeCalibrations::t_calAmp_payload > pulseShapes(SVDPulseShapeCalibrations::calAmp_name);
216 
217  DBObjPtr<PayloadFile> OnlineToOfflineMapFileName("SVDChannelMapping.xml");
218 
219  OnlineToOfflineMapFileName.hasChanged();
220 
221  unique_ptr<SVDOnlineToOfflineMap> map =
222  make_unique<SVDOnlineToOfflineMap>(OnlineToOfflineMapFileName->getFileName());
223 
224  pulseShapes.construct(SVDStripCalAmp(), xmlFileName);
225 
226  // This is the property tree
227  ptree pt;
228 
229  // Load the XML file into the property tree. If reading fails
230  // (cannot open file, parse error), an exception is thrown.
231  read_xml(xmlFileName, pt);
232 
233  for (ptree::value_type const& backEndLayoutChild :
234  pt.get_child("cfg_document.back_end_layout")) {
235 
236  if (backEndLayoutChild.first == "fadc") {
237  int FADCid(0);
238  string FADCidString = backEndLayoutChild.second.get<string>("<xmlattr>.id");
239  stringstream ss;
240  ss << std::hex << FADCidString;
241  ss >> FADCid;
242 
243  for (ptree::value_type const& fadcChild : backEndLayoutChild.second.get_child("")) {
244  if (fadcChild.first == "adc") {
245  int ADCid = fadcChild.second.get<int>("<xmlattr>.id") ;
246  B2DEBUG(1, " ADC id = " << ADCid);
247 
248  int layerId = fadcChild.second.get<int>("<xmlattr>.layer_id");
249  B2DEBUG(1, " layer_id = " << layerId);
250 
251  int ladderId = fadcChild.second.get<int>("<xmlattr>.ladder_id") ;
252  B2DEBUG(1, " ladder_id = " << ladderId);
253 
254  int hybridId = fadcChild.second.get<int>("<xmlattr>.hybrid_id");
255  B2DEBUG(1, " hybrid_id = " << hybridId);
256 
257  B2DEBUG(1, " delay25 = " << fadcChild.second.get<int>("<xmlattr>.delay25"));
258 
259  for (ptree::value_type const& apvChild : fadcChild.second.get_child("")) {
260  if (apvChild.first == "apv25") {
261  int apv25ADCid = apvChild.second.get<int>("<xmlattr>.id");
262  string ampString = apvChild.second.get<string>("cal_peaks") ;
263  string widthString = apvChild.second.get<string>("cal_width") ;
264  string peakTimeString = apvChild.second.get<string>("cal_peak_time") ;
265 
266  stringstream ssAmp;
267  ssAmp << ampString;
268 
269  stringstream ssWidth;
270  ssWidth << widthString;
271 
272  stringstream ssPeak;
273  ssPeak << peakTimeString;
274 
275  double amp, width, peakTime;
276  for (int apvChannel = 0 ; apvChannel < 128; apvChannel ++) {
277  ssAmp >> amp;
278  ssWidth >> width;
279  ssPeak >> peakTime;
280 
281  const SVDOnlineToOfflineMap::SensorInfo& info = map->getSensorInfo(FADCid, ADCid * 6 + apv25ADCid);
282 
283  short strip = map->getStripNumber(apvChannel, info);
284  int side = info.m_uSide ?
285  SVDPulseShapeCalibrations::t_calAmp_payload::Uindex :
286  SVDPulseShapeCalibrations::t_calAmp_payload::Vindex;
287 
288  int layer = info.m_sensorID.getLayerNumber();
289  int ladder = info.m_sensorID.getLadderNumber();
290  int sensor = info.m_sensorID.getSensorNumber();
291  if (errorTollerant || layer != layerId || ladder != ladderId // ||
292  // test on the sensor != f( hybrid) anr apv perhaps
293  )
294  B2ERROR("Inconsistency among maps: xml files tels \n" <<
295  "layer " << layerId << " ladder " << ladderId << " hybridID " << hybridId << "\n" <<
296  "while the basf2 map tels \n" <<
297  "layer " << layer << " ladder " << ladder << " sensor " << sensor << "\n");
298 
299  SVDStripCalAmp stripCalAmp;
300  // UGLY: 22500. 31.44/8 should be written somewhere in the XML file provided by Hao
301  stripCalAmp.gain = amp / 22500.;
302  stripCalAmp.peakTime = peakTime * 31.44 / 8;
303  stripCalAmp.pulseWidth = width * 31.44 / 8 ;
304  pulseShapes->set(layer, ladder, sensor, side, strip, stripCalAmp);
305 
306  }
307  }
308  }
309  }
310  }
311  }
312  }
313 
314 
315 
316  IntervalOfValidity iov(m_firstExperiment, m_firstRun,
317  m_lastExperiment, m_lastRun);
318 
319  pulseShapes.import(iov);
320 
321  B2RESULT("Imported to database.");
322 
323 
324 }
325 
326 
327 
Class for importing a single object to the database.
Specialization of DBObjPtr in case of PayloadFiles.
Definition: PayloadFile.h:54
A class that describes the interval of experiments/runs for which an object in the database is valid.
Abstract base class for different kinds of events.
Struct to hold data about a sensor.
contains the parameter of the APV pulse
float pulseWidth
pulseWidth (in ns) is the width of the shaper output TO BE CLARIFIED: how this width is defined?
float peakTime
peakTimes (in ns) is the time at wich the shaper output reach the maximum.
float gain
gain is expressed in ADC counts / # electrons injected in the channel