SdEACalibrationFiller.cc
Go to the documentation of this file.
2 
3 #include <fwk/CentralConfig.h>
4 #include <det/VManager.h>
5 #include <utl/Branch.h>
6 
7 #include <evt/Event.h>
8 #include <sevt/SEvent.h>
9 #include <sevt/Station.h>
10 #include <sevt/SmallPMT.h>
11 #include <sevt/SmallPMTCalibData.h>
12 #include <sdet/PMTConstants.h>
13 #include <sdet/SDetector.h>
14 
15 #include <utl/ErrorLogger.h>
16 
17 using namespace std;
18 
19 using namespace fwk;
20 using namespace det;
21 using namespace utl;
22 using namespace evt;
23 using namespace sevt;
24 
25 
26 namespace SdEACalibrationFillerKG {
27 
30  {
31  auto topB = CentralConfig::GetInstance()->GetTopBranch("SdEACalibrationFiller");
32 
33  auto onlineValuesUUBB = topB.GetChild("onlineValuesUUB");
34  onlineValuesUUBB.GetChild("rawCharge").GetData(fRawChargeUUB);
35  onlineValuesUUBB.GetChild("rawPeak").GetData(fRawPeakUUB);
36  onlineValuesUUBB.GetChild("hgBaseline").GetData(fHgBaselineUUB);
37  onlineValuesUUBB.GetChild("lgBaseline").GetData(fLgBaselineUUB);
38  onlineValuesUUBB.GetChild("DARatio").GetData(fDARatioUUB);
39 
40  auto onlineValuesPPAB = topB.GetChild("onlineValuesPPA");
41  onlineValuesPPAB.GetChild("rawCharge").GetData(fRawChargePPA);
42  onlineValuesPPAB.GetChild("rawPeak").GetData(fRawPeakPPA);
43 
44  auto offlineValuesUUBB = topB.GetChild("offlineValuesUUB");
45  offlineValuesUUBB.GetChild("beta").GetData(fBeta);
46  offlineValuesUUBB.GetChild("betaErr").GetData(fBetaErr);
47  offlineValuesUUBB.GetChild("betaChi2").GetData(fBetaChi2);
48  offlineValuesUUBB.GetChild("betaCorrectionFact").GetData(fBetaCorrectionFact);
49 
50  return eSuccess;
51  }
52 
53 
55  SdEACalibrationFiller::Run(Event& event)
56  {
57  if (!event.HasSEvent())
58  return eSuccess;
59 
60  auto& sEvent = event.GetSEvent();
61 
62  for (auto& station : sEvent.StationsRange()) {
63 
64  const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
65 
66  const bool isUub = dStation.IsUUB();
67  const bool hasSmallPMT = dStation.HasSmallPMT();
68  const bool hasScintillator = dStation.HasScintillator(); // for stations that have SSD conected to UB through kit-box
69  // up to now (Mar 2018) UUB stations are EA stations
70  if (isUub || hasScintillator) {
71  FillCalibrationInfo(station);
72  if (hasSmallPMT)
73  FillCalibrationInfoSmallPMT(station);
74  } else
75  continue;
76 
77  }
78 
79  return eSuccess;
80  }
81 
82 
83  void
84  SdEACalibrationFiller::FillCalibrationInfo(Station& station)
85  {
86  /*
87  Values needed for Pre Production Array (PPA) stations:
88  Estimate MIP Charge (for SSD)
89  Estimate of MIP Peak (in CDAS is estimated as Charge / 1.8)
90  SetIsTubeOk & SetIsLowGainOk for SSD
91 
92  Values needed for Engineering Array stations (with UUB):
93  Estimate of VEM and MIP Charge
94  Estimate of VEM and MIP Peak
95  Estimate of HG and LG baseline
96  Set values of DA ratio
97  SetIsLowGainOk
98  SetIsTubeOk
99  */
100 
101  const auto& dStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
102 
103  const bool hasScintillator = dStation.HasScintillator();
104  const bool isUub = dStation.IsUUB();
105 
106  typedef VariableBinHistogramWrap<short, int> CalibHistogram;
107 
108  for (auto& pmt : station.PMTsRange(sdet::PMTConstants::eAnyType)) {
109 
110  if (!pmt.HasCalibData())
111  continue;
112 
113  auto& pmtCalibData = pmt.GetCalibData();
114  auto& stationCalibData = station.GetCalibData();
115 
116  const auto type = pmt.GetType();
117 
118  const auto& chargeHistoBinning = dStation.GetMuonChargeHistogramBinning<short>(type, stationCalibData.GetVersion());
119 
120  double rawPeak = 0;
121  double rawCharge = 0;
122  double hgBaseline = 0;
123  double lgBaseline = 0;
124  double daRatio = 0;
125 
126  // load raw values from XML
127  if (isUub) {
128 
129  const unsigned int i = pmt.GetId() - 1;
130  rawPeak = fRawPeakUUB[i];
131  rawCharge = fRawChargeUUB[i];
132  hgBaseline = fHgBaselineUUB[i];
133  lgBaseline = fLgBaselineUUB[i];
134  daRatio = fDARatioUUB[i];
135 
136  } else if (hasScintillator) {
137 
138  const unsigned int pmtId = (type == sdet::PMTConstants::eScintillator) ? 2 : 1;
139  rawPeak = fRawPeakPPA[pmtId-1];
140  rawCharge = fRawChargePPA[pmtId-1];
141 
142  // change raw values by online estimates if they exist (only for WCD)
144  const double vemPeak = pmtCalibData.GetVEMPeak();
145  const double vemCharge = pmtCalibData.GetVEMCharge();
146 
147  if (vemPeak > 0)
148  rawPeak = vemPeak;
149  if (vemCharge > 0)
150  rawCharge = vemCharge;
151 
152  // for WCD we trust the online estimates (from LS)
153  pmtCalibData.SetVEMPeak(rawPeak);
154  pmtCalibData.SetVEMCharge(rawCharge);
155  continue;
156 
157  } else if (type == sdet::PMTConstants::eScintillator) {
158  pmtCalibData.SetIsTubeOk(true);
159  pmtCalibData.SetIsLowGainOk(true);
160  }
161  }
162 
163  // estimate HG and LG baseline for EA stations
164  if (isUub && pmt.HasFADCTrace()) {
165 
166  const auto& lgTrace = pmt.GetFADCTrace(sdet::PMTConstants::eLowGain, sevt::StationConstants::SignalComponent::eTotal);
168 
169  // compute baselines of HG and LG traces as median of the first 500 bins
170  vector<double> hgPiece;
171  vector<double> lgPiece;
172 
173  hgPiece.reserve(500);
174  lgPiece.reserve(500);
175 
176  for (int i = 0; i < 500; ++i) {
177  hgPiece.push_back(hgTrace[i]);
178  lgPiece.push_back(lgTrace[i]);
179  }
180 
181  sort(hgPiece.begin(), hgPiece.end());
182  sort(lgPiece.begin(), lgPiece.end());
183 
184  if (hgPiece.size() % 2 == 0)
185  hgBaseline = (hgPiece[hgPiece.size() / 2 - 1] + hgPiece[hgPiece.size() / 2]) / 2;
186  else
187  hgBaseline = hgPiece[hgPiece.size() / 2];
188 
189  if (lgPiece.size() % 2 == 0)
190  lgBaseline = (lgPiece[lgPiece.size() / 2 - 1] + lgPiece[lgPiece.size() / 2]) / 2;
191  else
192  lgBaseline = lgPiece[lgPiece.size() / 2];
193 
194  pmtCalibData.SetBaseline(hgBaseline, 2);
195  pmtCalibData.SetBaseline(lgBaseline, 2, sdet::PMTConstants::eLowGain);
196  pmtCalibData.SetDynodeAnodeRatio(daRatio, 0);
197  pmtCalibData.SetIsTubeOk(true);
198  pmtCalibData.SetIsLowGainOk(true);
199  }
200 
201  // skip small PMT in VEM / MIP estimations
203  continue;
204 
205  // find estimate of VEM / MIP charge using calibration histograms
206  double estimate = 0;
207  double res = 0;
208  const int muonChargeHistoSize = pmtCalibData.GetMuonChargeHisto().size();
209 
210  if (!muonChargeHistoSize || int(chargeHistoBinning.size()) - 1 != muonChargeHistoSize) {
211  WARNING("There should be a muon charge histogram!");
212  } else {
213 
214  const CalibHistogram chargeHisto(chargeHistoBinning, pmtCalibData.GetMuonChargeHisto());
215  const double baseEstimate =
216  pmtCalibData.GetBaseline() * 20 - pmtCalibData.GetMuonChargeHistoOffset();
217  const double base = (fabs(baseEstimate) < 20) ? baseEstimate : 0;
218 
219  if (chargeHisto.GetMaximum() > 500) {
220 
221  int max = 0;
222  unsigned int bin = chargeHisto.GetNBins() - 1;
223  unsigned int nbbin = bin;
224  int v = 0;
225  int v1 = 0;
226  int v2 = 0;
227  unsigned int binmin = 0;
228  unsigned int binmax = 0;
229  int dir = -1;
230  // range for the MIP / VEM charge taken from EA Analysis (only UUB stations)
231  const double humpvMin = (type == sdet::PMTConstants::eScintillator) ? 100 : 800;
232  const double humpvMax = (type == sdet::PMTConstants::eScintillator) ? 600 : 2500;
233  // max value "vmax" different between UB and UUB (due to different histogram binning)
234  // also different between SSD and WCD
235  if (isUub)
236  vmax = (type == sdet::PMTConstants::eScintillator) ? 20 : 40;
237  else if (hasScintillator)
238  vmax = (type == sdet::PMTConstants::eScintillator) ? 100 : 300;
239 
240  while (!binmax) {
241  v = int(chargeHisto.GetBinAverage(bin));
242  v1 = int(chargeHisto.GetBinAverage(bin + dir));
243  v2 = int(chargeHisto.GetBinAverage(bin + 2*dir));
244 
245  if (v > vmax && v > max)
246  max = v;
247 
248  if (binmin && double(max) / v > 1.3 && double(max) / v1 > 1.3 && double(max) / v2 > 1.3)
249  binmax = bin;
250  if (!binmin && max && double(max) / v > 1.3 && double(max) / v1 > 1.3 && double(max) / v2 > 1.3) {
251  binmin = bin;
252  dir = 1;
253  }
254  bin += dir;
255  if (bin == nbbin)
256  binmax = -1;
257  if (bin == 2)
258  binmax = -1;
259  }
260 
261  estimate = (binmin + binmax) / 2;
262 
263  if (!isUub) {
264  res = estimate;
265  } else if (estimate < binmax && estimate > binmin && binmin > 0 && binmax < chargeHisto.GetNBins() && binmin < binmax) {
266  double x = 0;
267  double x2 = 0;
268  double x3 = 0;
269  double x4 = 0;
270  double y = 0;
271  double xy = 0;
272  double x2y = 0;
273  int nb = 0;
274  for (unsigned int i = binmin; i < binmax; ++i) {
275  const double v = chargeHisto.GetBinAverage(i);
276  const double a = chargeHisto.GetBinCenter(i);
277  x += a;
278  const double a2 = a * a;
279  x2 += a2;
280  const double a3 = a2 * a;
281  x3 += a3;
282  x4 += a3 * a;
283  y += v;
284  xy += a * v;
285  x2y += a2 * v;
286  ++nb;
287  }
288 
289  const double B =
290  (y * (x4 * x - x2 * x3) + xy * (x2 * x2 - nb * x4) +
291  x2y * (nb * x3 - x * x2));
292  const double A =
293  (y * (x2 * x2 - x * x3) + xy * (nb * x3 - x * x2) +
294  x2y * (x * x - nb * x2));
295  res = -B / (2 * A);
296 
297  if (res > chargeHisto.GetBinCenter(binmin) && res < chargeHisto.GetBinCenter(binmax))
298  res -= base;
299  }
300 
301  // check that value is within range for UUB
302  if (isUub && !(res > humpvMin && res < humpvMax))
303  res = 0;
304 
305  }
306  }
307 
308  if (res) {
309  rawCharge = res / 1.045;
310  /*
311  A factor is multiplied to the "online" estimate
312  of the VEM charge in the SdCalibrator (fOnlineChargeVEMFactor).
313  This factor is intended to correct the estimate given by the LS
314  (which is off from the value of the "hump" by ~4.5%),
315  but it should not be applied to the estimates obtained here.
316  */
317  if (!isUub)
318  rawPeak = rawCharge / 1.8; // hardcoded for SSD-UB (also in CDAS...)
319  } else {
320  rawCharge = -1; // no calibration available
321  pmtCalibData.SetIsTubeOk(false);
322  }
323 
324  pmtCalibData.SetVEMPeak(rawPeak);
325  pmtCalibData.SetVEMCharge(rawCharge);
326 
327  }
328  }
329 
330 
331  void
332  SdEACalibrationFiller::FillCalibrationInfoSmallPMT(Station& station)
333  {
334  /*
335  Filling SmallPMT calibration (different from standard PMTCalibData)
336  -) Beta factor ( Q[VEM] = beta * Q[FADC counts] )
337  -) Beta factor error
338  -) Chi2 of the spectra comparison calibration procedure
339  -) Correction factor ( != 1 only if needed)
340  Also SetIsTubeOk for the SmallPMTCalibData class
341  The standard PMTCalibData for the SmallPMT (pmt id 4) is left empty
342  */
343 
344  auto& spmt = station.GetSmallPMT();
345  if (spmt.HasCalibData())
346  return;
347 
348  spmt.MakeCalibData();
349  auto& spmtCalib = spmt.GetCalibData();
350  spmtCalib.SetIsTubeOk(true);
351  spmtCalib.SetVersion(0);
352  spmtCalib.SetBeta(fBeta);
353  spmtCalib.SetBetaError(fBetaErr);
354  spmtCalib.SetChi2(fBetaChi2);
355  spmtCalib.SetCorrectionFactor(fBetaCorrectionFact);
356 
357  // The values w.r.t. each single LPMT are put equal to the overall ones
358  for (auto& pmt : station.PMTsRange(sdet::PMTConstants::eWaterCherenkovLarge)) {
359  spmtCalib.SetBeta(fBeta, pmt.GetId());
360  spmtCalib.SetBetaError(fBetaErr, pmt.GetId());
361  spmtCalib.SetChi2(fBetaChi2, pmt.GetId());
362  spmtCalib.SetCorrectionFactor(fBetaCorrectionFact, pmt.GetId());
363  }
364  }
365 
366 }
const std::vector< int > & GetMuonChargeHisto() const
histogram of the sum of muon charges (not really used anywhere)
void Init()
Initialise the registry.
#define max(a, b)
class to hold data at Station level
void MakeCalibData()
Make PMT calibration data object.
Definition: SEvent/PMT.cc:47
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
sevt::StationCalibData & GetCalibData()
Get calibration data for the station.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
total (shower and background)
PMT & GetSmallPMT()
bool HasSEvent() const

, generated on Tue Sep 26 2023.