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