1 #ifndef EXPLORER_CONVERTER_PLUGIN_HELPERS_H
2 #define EXPLORER_CONVERTER_PLUGIN_HELPERS_H
11 #include "Windows4Root.h"
17 #include "TFitResultPtr.h"
20 #include "TGraphErrors.h"
32 static const int n_pix;
33 static const int n_sec;
34 static const int n_rst;
35 static const int n_mem;
36 static const int w[2];
37 static const int p[2];
38 static const int n_pitch;
43 const int Ex1Prop::n_pix = 11700;
44 const int Ex1Prop::n_sec = 9;
45 const int Ex1Prop::n_rst = 2;
46 const int Ex1Prop::n_mem = 3;
47 const int Ex1Prop::w[] = {90, 60};
48 const int Ex1Prop::p[] = {20, 30};
49 const int Ex1Prop::n_pitch =
sizeof(Ex1Prop::p) /
sizeof(
int);
50 const float Ex1Prop::meas_offset =
54 Float_t ADC_counts_to_V(Float_t val, Bool_t apply_offset = kTRUE) {
67 return (apply_offset) ? (6101.8 - val) / 4507.8 : -val / 4507.8;
71 Float_t V_to_ADC_counts(Float_t val, Bool_t apply_offset = kTRUE) {
84 return (apply_offset) ? 6101.8 - val * 4507.8 : -val * 4507.8;
88 Float_t DAC_counts_to_V(Int_t val) {
91 return val / 4096. * 5.;
95 Float_t V_to_C(Float_t val) {
100 return 1640 * 1.602e-19 / val;
104 bool read_list_file(std::string name, std::vector<float> *vec) {
105 std::ifstream f(name.c_str());
110 if (l.length() > 0) {
111 vec->push_back(atof(l.c_str()));
120 int pix_pitch(
int ipix) {
121 return (ipix < Ex1Prop::w[0] * Ex1Prop::w[0]) ? Ex1Prop::p[0] : Ex1Prop::p[1];
125 int pix_row(
int ipix) {
126 return (ipix < Ex1Prop::w[0] * Ex1Prop::w[0])
127 ? ipix % Ex1Prop::w[0]
128 : (ipix - Ex1Prop::w[0] * Ex1Prop::w[0]) % Ex1Prop::w[1];
132 int pix_col(
int ipix) {
133 return (ipix < Ex1Prop::w[0] * Ex1Prop::w[0])
134 ? ipix / Ex1Prop::w[0]
135 : (ipix - Ex1Prop::w[0] * Ex1Prop::w[0]) / Ex1Prop::w[1];
139 int pix_sec(
int ipix) {
141 (ipix < Ex1Prop::w[0] * Ex1Prop::w[0]) ? Ex1Prop::w[0] : Ex1Prop::w[1];
142 int r_sec = (pix_row(ipix) * 3) / w;
143 int c_sec = (pix_col(ipix) * 3) / w;
144 return r_sec + c_sec * 3;
148 std::string mem_str(
int i) {
167 std::string rst_str(
int i) {
173 return "non-perm-rst";
183 int transpose_sec(
int i) {
return (i % 3) * 3 + (i / 3); }
186 int centre_pix_sec(
int i_sec,
int i_pitch) {
192 int offset = i_pitch * Ex1Prop::w[0] * Ex1Prop::w[0];
193 int row = Ex1Prop::w[i_pitch] * (0.5 + i_sec % 3) / 3.;
194 int col = Ex1Prop::w[i_pitch] * (0.5 + i_sec / 3) / 3.;
195 return offset + col * Ex1Prop::w[i_pitch] + row;
199 Int_t get_index(Double_t *x, Float_t val, Int_t n) {
200 for (Int_t i = 0; i < n; ++i) {
201 if ((x[i] <= val && x[i + 1] > val) || (x[i] > val && x[i + 1] <= val)) {
202 if (x[i] - val < x[i + 1] - val)
212 Float_t calc_gain(Float_t *x, Float_t *y, Int_t index, Int_t mode = 0) {
215 return (y[index + 1] - y[index]) / (x[index + 1] - x[index]);
218 return (y[index + 1] - y[index - 1]) / (x[index + 1] - x[index - 1]);
225 Float_t calc_inl(Double_t *x, Double_t *y, Int_t i_start, Int_t i_end,
227 Float_t expected_sig = gain * (x[i_end] - x[i_start]);
228 Float_t real_sig = y[i_end] - y[i_start];
229 return (real_sig / expected_sig - 1.);
233 Float_t calc_dnl(Float_t x, Float_t x2) {
234 return TMath::Abs(TMath::Abs(x - x2) / x);
238 void average(Int_t n, Float_t *y, Float_t *y_err, Int_t mode = 0,
239 Int_t avg_width = 11) {
243 Float_t *t =
new Float_t[n];
244 Float_t *t_err =
new Float_t[n];
246 memcpy(t, y,
sizeof(Float_t) * n);
247 memcpy(t_err, y_err,
sizeof(Float_t) * n);
249 for (Int_t a = 0; a < avg_width; ++a) {
253 y_err[n - 1 - a] = 0.;
256 for (Int_t i = 0; i < n - avg_width; ++i) {
257 Float_t sum_of_weights = 0.;
259 Float_t mean_sq = 0.;
260 for (Int_t a = 0; a < avg_width; ++a) {
261 Float_t w = (mode == 0) ? 1. / (t_err[i + a] * t_err[i + a]) : 1.;
263 mean += w * t[i + a];
264 mean_sq += w * t[i + a] * t[i + a];
266 mean /= sum_of_weights;
267 mean_sq /= sum_of_weights;
268 y[i + avg_width / 2] = mean;
269 y_err[i + avg_width / 2] = (mode == 0) ? TMath::Sqrt(1 / sum_of_weights)
270 : TMath::Sqrt(mean_sq - mean * mean);
275 float read_vrst(std::string file) {
276 std::ifstream f(file.c_str());
281 if (l.length() > 0) {
282 return atof(l.c_str());
286 std::cerr <<
"Couldn't read input file" << std::endl;
293 struct gain_fit_result {
329 gain_fit_result *do_gain_fits(TGraphErrors *g, Float_t v_rst = 0.8,
330 Float_t v_sig = 0.10) {
331 if ((v_rst - v_sig) < 0.51) {
332 std::cout <<
"-->>>>> WARNING: fit range might be going to a to small "
333 "value!!!, please check results" << std::endl;
334 std::cout << g->GetName() << std::endl;
337 gain_fit_result *result =
new gain_fit_result;
340 new TF1(
"f_lin", TString::Format(
"[0]+[1]*(x-%f)", v_rst - .5 * v_sig),
341 v_rst - v_sig, v_rst);
342 f_lin->SetLineWidth(1);
344 new TF1(
"f_quad", TString::Format(
"[0]+[1]*(x-%f)+[2]*(x-%f)*(x-%f)",
345 v_rst - .5 * v_sig, v_rst - .5 * v_sig,
347 v_rst - v_sig, v_rst);
348 f_quad->SetLineWidth(1);
349 TF1 *f_cube =
new TF1(
350 "f_cube", TString::Format(
351 "[0]+[1]*(x-%f)+[2]*(x-%f)*(x-%f)+[3]*(x-%f)*(x-%f)*(x-%f)",
352 v_rst - .5 * v_sig, v_rst - .5 * v_sig, v_rst - .5 * v_sig,
353 v_rst - .5 * v_sig, v_rst - .5 * v_sig, v_rst - .5 * v_sig),
354 v_rst - v_sig, v_rst);
355 f_cube->SetLineWidth(1);
357 result->r_lf = g->Fit(f_lin,
"QSR");
358 result->g_lf = f_lin->GetParameter(1);
359 result->e_lf = f_lin->GetParError(1);
360 result->ndf_lf = f_lin->GetNDF();
361 result->chi2_lf = f_lin->GetChisquare();
363 result->r_qf = g->Fit(f_quad,
"QSR");
364 result->g_qf = f_quad->GetParameter(1);
365 result->e_qf = f_quad->GetParError(1);
366 result->g2_qf = f_quad->GetParameter(2);
367 result->e2_qf = f_quad->GetParError(2);
368 result->off_qf = f_quad->GetParameter(0);
369 result->eff_qf = f_quad->GetParError(0);
370 result->ndf_qf = f_quad->GetNDF();
371 result->chi2_qf = f_quad->GetChisquare();
373 f_cube->SetParameters(f_quad->GetParameter(0), f_quad->GetParameter(1),
374 f_quad->GetParameter(2), 0);
375 result->r_cf = g->Fit(f_cube,
"QSR");
377 result->g_cf = f_cube->GetParameter(1);
378 result->e_cf = f_cube->GetParError(1);
379 result->g2_cf = f_cube->GetParameter(2);
380 result->e2_cf = f_cube->GetParError(2);
381 result->g3_cf = f_cube->GetParameter(3);
382 result->e3_cf = f_cube->GetParError(3);
383 result->off_cf = f_cube->GetParameter(0);
384 result->eff_cf = f_cube->GetParError(0);
385 result->ndf_cf = f_cube->GetNDF();
386 result->chi2_cf = f_cube->GetChisquare();
399 TH1D *dist_from_map(TH2D *h, Int_t x_low = 1, Int_t x_up = -1, Int_t y_low = 1,
400 Int_t y_up = -1, TString name =
"") {
403 name = (name.Length() == 0) ? TString::Format(
"dist_%s", h->GetName()) : name;
405 TH1D *dist =
new TH1D(
406 name, TString::Format(
";%s;probability", h->GetZaxis()->GetTitle()), 1000,
407 h->GetMinimum(), h->GetMaximum());
410 x_up = (x_up == -1) ? h->GetNbinsX() : x_up;
411 y_up = (y_up == -1) ? h->GetNbinsY() : y_up;
413 for (Int_t i_x = x_low; i_x <= x_up; ++i_x) {
414 for (Int_t i_y = y_low; i_y <= y_up; ++i_y) {
415 dist->Fill(h->GetBinContent(i_x, i_y));
419 dist->Scale(1. / dist->Integral());
424 class GainCorrection {
432 TH2 *fVresetNPROutMap;
457 delete fEffVresetMap;
460 if (fVresetNPROutMap) {
461 delete fVresetNPROutMap;
462 fVresetNPROutMap = 0x0;
485 TString eff_vrst_map_name = TString::Format(
486 "eff_vrst_map_vbb%0.1f_vrst%.2f_p%d_%s_chan%d", fVbb, fVrstRef,
487 Ex1Prop::p[fPitch], mem_str(fMem).c_str(), fChan);
488 gDirectory->GetObject(eff_vrst_map_name, fEffVresetMap);
489 if (!fEffVresetMap) {
490 fMapsAreLoaded =
false;
491 std::cerr <<
"Couldn't load the corresponding vrst map: "
492 << eff_vrst_map_name.Data() << std::endl;
495 TString vrst_npr_out_map_name = TString::Format(
496 "vrst_npr_out_map_vbb%0.1f_vrst%.2f_p%d_%s_chan%d", fVbb, fVrstRef,
497 Ex1Prop::p[fPitch], mem_str(fMem).c_str(), fChan);
498 gDirectory->GetObject(vrst_npr_out_map_name, fVresetNPROutMap);
499 if (!fVresetNPROutMap) {
500 fMapsAreLoaded =
false;
501 std::cerr <<
"Couldn't load the corresponding vrst map: "
502 << vrst_npr_out_map_name.Data() << std::endl;
506 TString offset_map_name = TString::Format(
507 "off_map_vbb%0.1f_vrst%.2f_p%d_%s_chan%d", fVbb, fVrstRef,
508 Ex1Prop::p[fPitch], mem_str(fMem).c_str(), fChan);
509 gDirectory->GetObject(offset_map_name, fOffsetMap);
511 fMapsAreLoaded =
false;
512 std::cerr <<
"Couldn't load the corresponding gain map: "
513 << offset_map_name.Data() << std::endl;
518 TString::Format(
"g_map_vbb%0.1f_vrst%.2f_p%d_%s_chan%d", fVbb, fVrstRef,
519 Ex1Prop::p[fPitch], mem_str(fMem).c_str(), fChan);
520 gDirectory->GetObject(g_map_name, fGainMap);
522 fMapsAreLoaded =
false;
523 std::cerr <<
"Couldn't load the corresponding gain map: "
524 << g_map_name.Data() << std::endl;
528 TString g2_map_name = TString::Format(
529 "g2_map_vbb%0.1f_vrst%.2f_p%d_%s_chan%d", fVbb, fVrstRef,
530 Ex1Prop::p[fPitch], mem_str(fMem).c_str(), fChan);
531 gDirectory->GetObject(g2_map_name, fGain2Map);
533 fMapsAreLoaded =
false;
534 std::cerr <<
"Couldn't load the corresponding gain correction map: "
535 << g2_map_name.Data() << std::endl;
539 TString g3_map_name = TString::Format(
540 "g3_map_vbb%0.1f_vrst%.2f_p%d_%s_chan%d", fVbb, fVrstRef,
541 Ex1Prop::p[fPitch], mem_str(fMem).c_str(), fChan);
542 gDirectory->GetObject(g3_map_name, fGain3Map);
544 fMapsAreLoaded =
false;
545 std::cerr <<
"Couldn't load the corresponding gain correction map: "
546 << g3_map_name.Data() << std::endl;
556 "[0]+[1]*(x-[4])+[2]*(x-[4])*(x-[4])+[3]*(x-[4])*(x-[4])*(x-[4])", 0.5,
559 return fMapsAreLoaded;
564 : fMapFile(0x0), fOffsetMap(0x0), fGainMap(0x0), fGain2Map(0x0),
565 fGain3Map(0x0), fEffVresetMap(0x0), fVresetNPROutMap(0x0), fFit(0x0),
566 fVsig(0.1), fPitch(-1), fMem(1), fVbb(1.8), fVrstRef(0.7), fChan(-1),
567 fOffset(0.), fGain(0.), fGain2(0.), fGain3(0.), fEffVrst(0.),
568 fVrstNPROut(0.), fMapsAreLoaded(false) {}
569 bool SetDataFile(TString filename) {
570 TCanvas *mydummycanvas =
new TCanvas();
575 fMapFile =
new TFile(filename.Data());
576 return (fMapFile && fMapFile->IsOpen());
578 void SetPitch(
int p) {
580 fMapsAreLoaded =
false;
582 void SetVbb(
float vbb) {
584 fMapsAreLoaded =
false;
586 void SetVrstRef(
float vrr) {
588 fMapsAreLoaded =
false;
590 void SetMem(
int mem) {
592 fMapsAreLoaded =
false;
594 void SetVsig(
float vsig) {
596 fMapsAreLoaded =
false;
598 void SetChan(
int chan) {
600 fMapsAreLoaded =
false;
603 float CorrectValue(
float value,
int i_row,
int i_col,
bool woOffset =
true) {
606 if (!fMapsAreLoaded) {
607 std::cerr <<
"Failed to load the corresponding map!" << std::endl;
610 if (i_row < 0 || i_row >= Ex1Prop::w[fPitch]) {
611 std::cerr <<
"row index out of bounds" << std::endl;
614 if (i_col < 0 || i_col >= Ex1Prop::w[fPitch]) {
615 std::cerr <<
"column index out of bounds" << std::endl;
618 fOffset = fOffsetMap->GetBinContent(i_col + 1, i_row + 1);
619 fGain = fGainMap->GetBinContent(i_col + 1, i_row + 1);
620 fGain2 = fGain2Map->GetBinContent(i_col + 1, i_row + 1);
621 fGain3 = fGain3Map->GetBinContent(i_col + 1, i_row + 1);
622 fEffVrst = fEffVresetMap->GetBinContent(i_col + 1, i_row + 1);
623 fVrstNPROut = fVresetNPROutMap->GetBinContent(i_col + 1, i_row + 1);
659 value = ADC_counts_to_V(value, !woOffset);
670 Float_t vref = fVrstNPROut + 0.01 - fVsig / 2;
671 fFit->SetParameters(fOffset, fGain, fGain2, fGain3, vref);
673 ? fFit->Eval(fVrstNPROut) - fFit->Eval(fVrstNPROut - value)
676 return V_to_ADC_counts(value, !woOffset);