## 19. Calibrations Appendix

This appendix explains the different calibrations that need to be performed for the Timepix to bring it into its operating window, sec. 19.1. Then in sec. 19.2 we present additional calibrations for all chips.

### 19.1. Timepix calibrations

Before a Timepix based detector can be used for data taking, different calibrations have to be performed. We will discuss those calibrations, which are performed before any data taking here.

First, the `THS`

optimization and threshold equalization
(sec. 19.1.1). These two are
calibrations that are used to set different DACs on the Timepix to
good working points. The very important ToT calibration was already
introduced in the main body, section
8.1.1. Its purpose is to
interpret the ToT values in amount of charge of recorded electrons. In
principle there are many other calibrations one could perform, as the
Timepix has 13 different DACs. Most are used with default values that
are seen in tab. 8. S-Curve scans are
introduced in sec. 19.1.3, which can
be used to map `THL`

threshold DAC values to charges and determine the
activation threshold. Similarly, the Pólya distribution can also act
as a means to determine the activation threshold, see sec. 19.1.4.

Important references for the Timepix in general and for the calibration procedures explained below are (Llopart et al. 2007; Llopart Cudie 2007; Llopart and Poikela 2006; Lupberger 2016).

#### 19.1.1. `THS`

optimization and threshold equalization

For an optimal operation of a Timepix based detector, each pixel
should ideally have the same threshold. While all pixels are
theoretically identical, imperfections in the production process will
always lead to slight differences, either locally (transistor
threshold voltage or current mismatches
(Llopart et al. 2007; Pelgrom, Duinmaijer, and Welbers 1989) ) or global effects
like small supply voltage instabilities. Therefore, each pixel has 4
independently selectable current sources to minimize the spread of
threshold values
(Llopart and Poikela 2006; Llopart et al. 2007). Together all 4 sources
act as an effective 4-bit DAC to slightly adjust the threshold. The
absolute current for the 4 sources is dependent on the global `THS`

DAC, allowing currents in the range of \(\SIrange{0}{40}{nA}\).

To achieve a good calibration for a homogeneous threshold, first the
`THS`

DAC has to be set correctly. This is referred to as the `THS`

optimization. Once the correct value is found, the 4-bit DAC on each
pixel can be adjusted to minimize the spread of threshold values of
all pixels together.

If the `THS`

DAC is set too high, the 4-bit DAC on each pixel will be
too coarse for a fine adjustment (as the 'current steps' will be too
large). If it is too low, not enough range will be available to adjust
each pixel to an equal noise / sensitivity level (not enough current
available via the 4 current sources). The goal of the `THS`

optimization is therefore to find just the right value, as to provide
a range of values such that all values can be shifted to the same
threshold of the threshold DAC `THL`

.

The algorithm scans a range of `THL`

values through a subset of
\(\num{4096}\) pixels using different 4-bit DAC values. First 0 for all
pixels and then the maximum value of 15. At each `THL`

and 4-bit
value the number of hits due to pure noise is recorded for each
pixel. The weighted mean of the `THL`

values, using the number of hits
as weight, is the value of interest for each pixel and each 4-bit DAC
value: the effective `THL`

noise value for that pixel. For each of the
two cases (4-bit value 0 and 15) we can then compute a histogram of the
number of pixels at each `THL`

value. The resulting histogram will be
a normal distribution around a specific `THL`

value. The stopping
criterion, which defines the final `THS`

value, is such that these two
distributions overlap at the 3 RMS level. This is performed by
comparing the means of the 0 and 15 value distribution at a starting
`THS`

value and again at half of that `THS`

value. Using linear
regression of the two differences, the optimal `THS`

value is
computed.

With a suitable `THS`

value set, the actual threshold equalization can
start. The algorithm used is fundamentally very similar to the logic
of the `THS`

optimization. Each pixel of the chip is scanned for a
range of `THL`

values and the weighted `THL`

noise mean is computed
both at a 4-bit DAC value of 0 and at 15. The normalized deviation of
each pixel's `THL`

value to the mean `THL`

value of all pixels is
computed. Using a linear regression the optimal required shift (in
units of the 4-bit DAC) yields the final 4-bit DAC value for each
pixel.

An example of the 0 and 15 value distributions as well as the
distribution using the final 4-bit DAC values for each pixel is shown
in fig. 1(a). ^{ 1} Each
of the distributions represent different 4-bit DAC settings of all
pixels of the chip. Orange ("min") represents all pixels using a 4-bit
DAC value of 0, purple ("max") of 15. In green is the same
distribution for the case where every pixel uses its optimal 4-bit DAC
value. The threshold equalization thus yields a very strong reduction
in the `THL`

spread of all pixels. Fig. 1(b)
shows how all pixels are spread in the values of the 4-bit DAC. The
narrow equalized line of fig. 1(a) is
achieved by a normal distribution around \(\num{8}\) of the 4-bit DAC
values, with only very few at the edges of the DAC (\(\num{0}\) and
\(\num{15}\)). Finally, fig. 2 shows a heatmap of
an entire chip with its 4-bit DAC values after equalization.

Similar plots for all other chips during both run periods can be found in the extended thesis.

##### 19.1.1.1. Generate the plot for the THS optimization result extended

import std / strformat import ggplotnim proc csbs(): Theme = result = sideBySide() result.titleFont = some(font(7.0)) proc main(fname, runPeriod: string, chip: int) = var df = readCsv(fname, sep = '\t', colNames = @["x", "y", "min", "max", "bit", "opt"]) let breaks = linspace(-0.5, 15.5, 17).toSeq1D echo breaks ggplot(df, aes("bit")) + geom_histogram(breaks = breaks, hdKind = hdOutline) + scale_x_continuous() + xlim(-0.5, 16.5) + xlab("4-bit DAC") + margin(left = 3.5) + themeLatex(fWidth = 0.5, width = 600, height = 420, baseTheme = csbs) + ggtitle(&"All equalization bits after optimization, {runPeriod}, chip {chip}") + ggsave(&"/home/basti/phd/Figs/detector/calibration/optimized_equalization_bits_{runPeriod}_chip_{chip}.pdf", useTeX = true, standalone = true) df = df.gather(["min", "max", "opt"], "type", "THL") ggplot(df.filter(f{`THL` > 330.0 and `THL` < 460.0}), aes("THL", fill = "type")) + geom_histogram(binWidth = 1.0, position = "identity", hdKind = hdOutline, alpha = 0.7) + ggtitle(&"All equalization bits at 0, 15 and optimized, {runPeriod}, chip {chip}") + #xlim(330, 460) + margin(left = 3.5) + themeLatex(fWidth = 0.5, width = 600, height = 420, baseTheme = csbs) + ggsave(&"/home/basti/phd/Figs/detector/calibration/ths_optimization_distributions_{runPeriod}_chip_{chip}.pdf", useTeX = true, standalone = true) when isMainModule: import cligen dispatch main

Laptop:

for chip in {0..6}; do ./code/ths_optimization -f ~/septemH_calibration/SeptemH_FullCalib_2018_2/chip$chip/thresholdMeans$chip.txt --runPeriod Run3 --chip $chip &; done

Desktop / Laptop:

for run in 2 3; do for chip in {0..6}; do ./code/ths_optimization -f ~/CastData/ExternCode/TimepixAnalysis/resources/ChipCalibrations/Run$run/chip$chip/thresholdMeans$chip.txt --runPeriod Run$run --chip $chip &; done done

resources/ths_optimization.html

import ggplotnim import std / [sequtils, strutils, strformat] proc main(fname, runPeriod: string, chip: int) = let aranged = toSeq(0 .. 255).mapIt($it) var df = readCsv(fname, sep = '\t', colNames = aranged) df["y"] = toSeq(0 .. 255) df = df.gather(aranged, "x", "4-bit DAC") .mutate(f{"x" ~ `x`.parseInt}) echo df ggplot(df, aes("x", "y", fill = "4-bit DAC")) + geom_raster() + #scale_x_continuous() + #xlim(-0.5, 16.5) + coord_fixed(1.0) + xlab("x [pixel]") + ylab("y [pixel]") + xlim(0, 255) + ylim(0, 255) + themeLatex(fWidth = 0.9, width = 600, baseTheme = singlePlot) + ggtitle(&"Equalization bits after optimization, {runPeriod}, chip: {chip}") + ggsave(&"/home/basti/phd/Figs/detector/calibration/heatmap_threshold_equalization_{runPeriod}_chip_{chip}.pdf", useTeX = true, standalone = true) when isMainModule: import cligen dispatch main

./code/threshold_equalization_heatmap -f ~/septemH_calibration/SeptemH_FullCalib_2018_2/chip3/threshold3.txt

for run in 2 3; do for chip in {0..6}; do ./code/threshold_equalization_heatmap -f ~/CastData/ExternCode/TimepixAnalysis/resources/ChipCalibrations/Run$run/chip$chip/threshold$chip.txt --runPeriod Run$run --chip $chip &; done done

All plots are found under sec. 19.2.

##### 19.1.1.2. Relevant code for calculation of mean values from TOS extended

Filling of `sum`

in `THscan`

. `array_pos`

is effectively the `THL`

value currently being scanned. `pix_tempdata`

is the response matrix
of each pixel (contains hit counter for each pixel). Also fills
`hit_counter`

, which is simply the counts.

fpga->DataFPGAPC(pix_tempdata2,chp); //!!!only one chip!!! for(short y=step;y<256;y+=(256/pix_per_row)){ for(short x=0;x<256;x++){ if(pix_tempdata2[y][x]>=20 and pix_tempdata2[y][x]!=11810){ //if (pix_tempdata2[y][x]>=200) {std::cout << "hits for thl " << thl <<" :" << pix_tempdata2[y][x] << std::endl;} p3DArray[y][x][array_pos] = pix_tempdata2[y][x]; //if(LFSR_LookUpTable[(*VecData)[chp][y][x]]>=20 and LFSR_LookUpTable[(*VecData)[chp][y][x]]!=11810){ //p3DArray[y][x][array_pos] = LFSR_LookUpTable[(*VecData)[chp][y][x]]; sum[y][x]+=p3DArray[y][x][array_pos]*(array_pos); hit_counter[y][x]+=p3DArray[y][x][array_pos]; } else{ p3DArray[y][x][array_pos] = 0; sum[y][x]+=0; hit_counter[y][x]+=0; } } }

And in the `THSopt`

the code to compute the mean:

for(y=0;y<256;y++){ for(x=0;x<256;x++){ if (hit_counter0[y][x]!=0){ mean0[y][x] = sum0[y][x]/hit_counter0[y][x]; mean0entries += 1; summean0 += mean0[y][x]; } if (hit_counter15[y][x]!=0){ mean15[y][x] = sum15[y][x]/hit_counter15[y][x]; mean15entries += 1; summean15 += mean15[y][x]; } } }

Length of shutter used is

// calling CountingTime with second argument == 1 // corresponds to n = 1, power of 256 fpga->CountingTime(10, 1);

(could compute the length, but not important right now)

Given that the `THscan`

is run for each THL value (and thus summing up
all contributions of all THL values for `sum0`

), the algorithm
effectively computes:

mean = Σ_i #hits_i * THL_i / Σ_i #hits_i

which is simply **the weighted mean of the THL value, weighted by the
number of hits.** Essentially we compute the THL value with the most
dominant noise? In a sense it makes sense as changing the 4-bit DAC
will move around the position of that noise effectively. The

The point of interest then here is the fact that the number of hits
depends on the THL value strongly. We only see the number of injected
test pulses, if we're above the noise. Ideally we don't want to see
any noise due to too low `THL`

range. Therefore let's check what is
used in TOS.

We will verify this by computing the same value for an S-curve calibration file:

import ggplotnim const path = "/home/basti/septemH_calibration/SCurve/chip_3/voltage_100.txt" let df = readCsv(path, sep = '\t', header = "#", colNames = @["THL", "counts"]) .filter(f{`THL` > 424}) echo df let thls = df["THL", float] let counts = df["counts", float] var sum = 0.0 var hits = 0.0 for (thl, count) in zip(thls, counts): sum += count * thl hits += count echo "Mean value = ", sum / hits

which results in a mean value of 463.8. Given the range of data that's, surprise, what we would expect from a weighted mean with the hit counter used.

Of course, in the `THS`

optimization the input is purely noise and not
a fixed set of test pulses.

#### 19.1.2. Final `THL`

(threshold) DAC value selection

Once the detector is `THS`

optimized and threshold equalized, the
final threshold value of the `THL`

DAC can be determined for the data
taking. While measurements like an S-Curve scan (see
sec. 19.1.3) can be used to understand
where the noise level of the chip is in terms of `THL`

values, it is
typically not a reliable measure as the real noise depends strongly on
the shutter length. If an experiment – like a low rate experiment as
CAST – requires long shutter lengths, the best way to determine the
lowest possible noise-free `THL`

value is to perform a simple scan
through all `THL`

values using the shutter length in use for the
experiment.

For a correctly equalized chip a sharp drop off of noisy pixels should
be visible at a certain threshold. In principle the `THL`

value at
which no more pixels are noisy is the ideal `THL`

value.

TOS first performs a quick scan in a `THL`

range given by the
user, using short shutter lengths. The determined drop values that
still see some noise to a noise-free range is used as a basis for a
long shutter length scan using a shutter length given by the user. For
safe noise free operation one should choose a `THL`

value 2 or 3 above
the first noise-free THL value at the target shutter
length. Especially for long shutter lengths it is important to perform
this calibration without any high voltage applied to the detector as
otherwise cosmic background starts to affect the data.

#### 19.1.3. S-Curve scan

The S-Curve scan is one of 2 different ways to determine the optimal
`THL`

value.

The purpose of the S-curve scan is to understand the relationship
between injected charges in electron and the `THL`

DAC values by
providing a \({\text{\# } e^-}/\mathtt{THL}\text{ step}\) number (or
without a `ToT`

calibration \(\mathtt{ToT}/\mathtt{THL}\)).

It works by injecting charges onto each pixel and checking the pixel
response of each pixel at different `THL`

values. Below a certain
`THL`

value all pixels will respond to the injected charge. At some
point certain pixels will be insensitive to the induced charge and a
90° rotated "S" will form. By fitting an error function to this S an
ideal `THL`

value can be deduced.

By calculating `THL`

value at which half of all test pulses are
recorded, we can compute the number of electrons corresponding to that
`THL`

DAC value, as we know the amplitude of the test pulse and thus
number of injected electrons.

Fig. 3 shows an S-Curve scan of chip 0 of the Septemboard using the calibration from July 2018. The center peak in the middle is the noise peak of the detector at the shutter length used for the S-Curve scan. The symmetrical shape is due to specific implementation details of how the pixels function, the upper side is the one of interest. The center point (half way between both plateaus) corresponds to the effective threshold of the detector at that injected charge. The falling edge of each curve can be fit by the cumulative distribution function of a normal distribution, eq. \eqref{eq:daq:s_curve_fit_function}.

\begin{equation} \label{eq:daq:s_curve_fit_function} f(μ, σ, N) = \frac{N}{2} · \text{erfc}((x - μ) / (σ · \sqrt{2})) \end{equation}where the parameter \(N\) is simply a scaling factor and \(μ\) represents the x value of the half-amplitude point. \(σ\) is the spread of the drop and \(\text{erfc}\) is the complementary error function \(\text{erfc}(x) = 1 - \text{erf}(x)\). The error function is of course just the integral over a normal distribution up to the evaluation point \(x\):

\[ \text{erf}(x) = \frac{2}{\sqrt{π}} ∫_0^{x} e^{-t²} \dd t. \]

Given that the number of injected electrons is known for each test
pulse amplitude (see sec. 8.1.1), we can compute
the relationship of the number of electrons per `THL`

value step. This
is called the `THL`

calibration and an example corresponding to
fig. 3 is shown in
fig. 4, where the `THL`

values used
correspond to the \(μ\) parameters of
eq. \eqref{eq:daq:s_curve_fit_function}. The resulting fit is useful, as it
allows to easily convert a given `THL`

DAC value into an effective
number of electrons, which then corresponds to the effective threshold
in electrons required to activate a pixel on average. When looking at
the distribution of charges in a dataset, that cutoff in electrons is
of interest (see
sec. 19.1.4).

Table tab. 29 shows the fit parameters for the fits of fig. 3. See the extended thesis for all fit parameters and plots.

`THL`

calibration can be used to gauge the 'threshold gain' the `THL`

DAC has on the number of electrons required to cross the threshold. The `THL`

DAC in the Timepix normally adjusts the threshold by about \num{25} electrons per DAC value cite:timepix_manual, which is reproduced well here (parameter \(1/m\)). The root of the linear fit (written as \(f⁻¹(y=0)\) in the annotation) corresponds to the position of the noise peak in fig. 3.V [U] | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|

20 | 1001 | 0.37 | 421.3 | 0.004754 | 4.221 | 0.006294 |

25 | 1004 | 0.3732 | 430.8 | 0.004994 | 4.545 | 0.006582 |

30 | 1000 | 0.3867 | 440.1 | 0.004989 | 4.429 | 0.006561 |

35 | 1005 | 0.3935 | 449.3 | 0.005154 | 4.627 | 0.006748 |

40 | 1002 | 0.3842 | 459.4 | 0.005048 | 4.53 | 0.006635 |

50 | 1002 | 0.3928 | 478.2 | 0.005145 | 4.603 | 0.006741 |

60 | 1001 | 0.3806 | 497.6 | 0.00505 | 4.553 | 0.006643 |

100 | 1004 | 0.3936 | 569.8 | 0.005365 | 4.895 | 0.007004 |

##### 19.1.3.1. Fit function for S-Curve extended

The implementation of the S-Curve fit is found in ./../CastData/ExternCode/TimepixAnalysis/Analysis/ingrid/calibration/fit_functions.nim,

func sCurveFunc*(p: seq[float], x: float): float = ## we fit the complement of a cumulative distribution function ## of the normal distribution # parameter p[2] == sigma # parameter p[1] == x0 # parameter p[0] == scale factor result = normalCdfC(x, p[2], p[1]) * p[0]

which is typically called from ./../CastData/ExternCode/TimepixAnalysis/Analysis/ingrid/calibration/calib_fitting.nim, and for these plots used in file:///home/basti/CastData/ExternCode/TimepixAnalysis/Plotting/plotCalibration/plotCalibration.nim.

##### 19.1.3.2. Generate plots and compute electrons per THL DAC value `[0/2]`

extended

We generate both the S-Curve and THL calibration plots using
`plotCalibration`

. Let's simply generate all Run2 and Run3 plots for
S-Curves and THL values.

for run in Run2 Run3; do for chip in {0..6}; do plotCalibration --scurve --chip $chip --runPeriod $run --useTeX --legendX 425.0 --legendY 3050 --outpath ~/phd/Figs/detector/calibration --quiet &; done done

and for the THL calibration:

for run in Run2 Run3; do for chip in {0..6}; do plotCalibration --scurve --chip $chip --runPeriod $run --useTeX --legendX 422.0 --legendY 3550 --outpath ~/phd/Figs/detector/calibration --quiet &; done done

the only difference being the legend placement (as the coordinates are applied to both plots).

The following is essentially the main code required to plot the SCurves, determine the middle point and fit THL calib (not the SCurve fit though):

import std / [strutils, strscans, os, strformat] import ggplotnim import unchained proc charge(voltage: mV): UnitLess = ## Returns the number of electrons given a voltage pulse of amplitude `voltage` ## at the 8.fF capacitor of the Timepix1 result = 8.fF * voltage / e #const path = "/home/basti/septemH_calibration/SCurve/chip_3/voltage_*.txt" #const path = "/home/basti/septemH_calibration/CalibJul2018/SCurves/chip_1/voltage_*.txt" const path = "/home/basti/septemH_calibration/SeptemH_FullCalib_InGridDatabase/chip3/SCurve/voltage_*.txt" #const path = "/home/basti/septemH_calibration/SeptemH_FullCalib_2018_2/chip0/SCurve/voltage_*.txt" var charges = newSeq[float]() var thls = newSeq[int]() for file in walkFiles(path): let (success, _, voltage) = scanTuple(file.extractFilename, "$*_$i.txt$.") if voltage == 0: continue # skip 0 charges.add charge(voltage.mV) ## we'll do the simplest approach to get the correct THL value: ## - strip everything before noise peak (to have single THL value) ## - compute var df = readCsv(file, sep = '\t', header = "#", colNames = @["THL", "counts"]) let thlAtMax = df.filter(f{int: `counts` == `counts`.max})["THL", int][0] # must be single element const TestPulses = 1000 df = df.filter(f{`THL` > thlAtMax}) .mutate(f{int: "DiffHalf" ~ abs(`counts` - TestPulses div 2)}) .filter(f{int: `DiffHalf` == min(col("DiffHalf"))}) # f{int: `DiffHalf` < 200}) thls.add df["THL", int][0] # must be single element import polynumeric let fit = polyFit(thls.toTensor.asType(float), charges.toTensor, polyOrder = 1) echo fit proc linear(x, m, b: float): float = m * x + b let thlFit = linspace(thls.min, thls.max, 10) let chargesFit = linspace(charges.min, charges.max, 10) var dfFit = toDf({ "thls" : thlFit, "charges" : thlFit.map_inline(linear(x, fit[1], fit[0])) }) echo dfFit let df = toDf(thls, charges) ggplot(df, aes("thls", "charges")) + geom_point() + geom_line(data = dfFit, aes = aes("thls", "charges"), color = parseHex("FF00FF")) + xlab("THL DAC") + ylab("Injected charge [e⁻]") + ggtitle(&"Fit parameters: m = {fit[1]:.2f} e⁻/THL, b = {fit[0]:.2f} e⁻") + ggsave("/home/basti/phd/Figs/charge_per_thl.pdf")

All plots are found under sec. 19.2.

##### 19.1.3.3. Compute minimally detectable charge extended

Ref:

- (Llopart et al. 2007) Timepix paper
- (Llopart Cudie 2007) Llopert PhD thesis

The following quotes explain how to compute the effective threshold:

page 5/10:

The electronic noise and effective threshold can be measured using the s-curve method [8] when the pixel is set in counting mode.

page 5/10:

The effective threshold is at 50% of this s-curve. The charge difference between the 97.75% and 2.25% of the s- curve is four times the RMS noise of the front end assuming a gaussian distributed noise.

The measured electronic noise is 99:4 ± 3:8 e⁻ rms for hole collection and 104:8 ± 6 e⁻ rms for electron collection. The measured DAC step gain is 24:7 ± 0:7 e⁻ =step for hole collection and 25:4 ± 1:2 e⁻ =step for electron collection.

page 7/10:

The threshold variation before equalization is ~240 e⁻ rms and after equalization the achieved noise free threshold variation is ~35 e⁻ rms for both polarities.

page 7/10:

The minimum detectable charge can be calculated by quadratically adding the measured electronic noise and the threshold variation because both measurements are uncorrelated.

Before equalization the minimum detectable charge for the full matrix is ~1600 e⁻ and after equalization is ~650 e⁻ for both polarities.

This means:

`[ ]`

compute the 97.75 ⇔ 2.25% range of the S-curve. Yields 4 times RMS noise. Width in THL of that can be converted to #e⁻ using THL calibration. -> electronic noise \(N_e\)`[ ]`

compute width of optimized threshold variation based on histogram. Fit gaussian (?) to optimized threshold variation. σ of that gaussian is width in THL. Convert THL to electrons. -> threshold variation \(N_t\)`[ ]`

**CHECK IF THIS IS CORRECT**: If I'm not mistaken, the noise peak we see in the S-curve scan is essentially the same as the optimized distribution from the threshold equalization.

Then with those two parameters we compute the effective detectable charge as:

\[ N_d = √(N_e² + N_t²) \]

which for the numbers listed above yields

\[ N_d = √(105² + 35²) = 110 \]

which is not close to the expected 650 e⁻!

Checking in the PhD thesis of Llopert, page 115, equation 4.5 is:

\[ \text{MinDetect}Q = 6·\sqrt{ ENC² + σ_{\text{dist}}²} \] which then works out nicely (110·6 = 660 is close enough)!

So in theory we can compute this for all our chips and all calibrations.

`[ ]`

**CALCULATE FOR ALL CHIPS AND PUT INTO APPENDIX**

#### 19.1.4. Pólya distribution for threshold detection

In a gaseous detector the gas amplification (see
sec. 6.3.6) allows to easily exceed the minimum
detectable charge of \(\mathcal{O}(\SIrange{500}{1000}{e^-})\). The
typically used `THL`

threshold will be quite a bit higher than the
'theoretical limit' however for multiple reasons. One can either
compute the effective threshold in use based on the `THL`

calibration
as explained in sec. 19.1.3, or use an
experimental approach by utilizing the Pólya distribution as
introduced in sec. 6.3.6 and
8.1.2. By taking data over a certain period of
time and computing a histogram of the charge values recorded by each
pixel, a Pólya distribution naturally arises.

The Pólya distribution can be used to determine the actual activation threshold by simply checking what the lowest charge is that sees significant statistics.

An example of such a Pólya distribution with a very obvious cutoff at low charges is seen in fig. 5. We see chip 0 using the same calibration from July 2018 as in the figures in the previous section 19.1.3. The data is a \(\SI{90}{min}\) interval of background data at CAST. The pink line represents the fit of the Pólya distribution to the data. The dashed part of the line was not used for the fit and is only an extension using the final fit parameters. The cutoff at the lower end due to the chip's threshold is clearly visible. The fit determines a gas gain of about \(\num{2700}\), compared to the mean of the data yielding about \(\num{2430}\).

Based on the data a threshold value of – very roughly – \(\num{1000}\) can
be estimated. Using the `THL`

calibration of the chip as shown in
fig. 4 yields a value of

\[ Q(\text{THL} = 419) = 26.8 · 419 - 10300 = 929.2 \]

where we used the fit parameters as printed on the plot (\(1/m\) and
\(f⁻¹(y=0)\)) and the `THL`

DAC value of \(\num{419}\) as used during the
data taking for this chip. Indeed, the real threshold is in the same
range, but clearly a bit higher than the theoretical limit for this
chip. This matches our expectation.

##### 19.1.4.1. Generate Polya plot for chip 0, run period 3 `[0/1]`

extended

The current placeholder polya distribution (although it's the right chip and calibration) is:

basti at void in /mnt/1TB/CAST/2018_2/out/DataRuns2018_Raw_2020-04-28_16-13-28 λ cp gas_gain_run_306_chip_0_5_30_min_1545294386.pdf \ ~/phd/Figs/gas_gain_run_306_chip_0_placeholder_example.pdf

`[X]`

**REPLACE BY BETTER PLOT. USING 90MIN AMONG OTHER THINGS**

We simply use the existing reconstructed data and create the gas gain plots again:

WRITE_PLOT_CSV=true reconstruction -i ~/CastData/data/DataRuns2018_Reco.h5 \ --only_gas_gain \ --run 306 \ --plotOutPath ~/phd/Figs/gasGain/ \ --useTeX=true \ --overwrite

### 19.2. Septemboard calibration

In the extended thesis this section contains all `THS`

optimization,
S-Curves and `ToT`

calibrations for both run periods and all chips of
the Septemboard. As this leads to *a lot* of pages of figures, here we
only show a histogram of all optimized THL distributions for each run
period in sec. 19.2.5.

#### 19.2.1. Generate all ToT calibration plots extended

See sec. 8.1.1.1 for the section producing the single plot used in the thesis.

# To generate fig:septem:tot_calibration_example for run in 2 3; do for chip in {0..6}; do plotCalibration --tot --chip $chip --runPeriod Run$run --useTeX --file ~/CastData/ExternCode/TimepixAnalysis/resources/ChipCalibrations/Run$run/chip$chip/TOTCalib$chip.txt --outpath ~/phd/Figs/detector/calibration --quiet &; done done

#### 19.2.2. All ToT calibrations extended

All plots without caption, too much repetition and the run period & chip number are in the title. Looking at these plots one of the things I've long thought is that the fit function is way too overspecified, given that usually one parameter (most of the time \(t\)) is just zero. The errors go crazy in Run-2 for chip 0, because the fit produces crazily large errors. Not quite sure why, but I guess it's just another reason of the function having too many parameters. :)

##### 19.2.2.1. Investigate fit alone of Run-2, chip 0

```
plotCalibration --tot --chip 0 --runPeriod Run2 --useTeX --file ~/CastData/ExternCode/TimepixAnalysis/resources/ChipCalibrations/Run2/chip0/TOTCalib0.txt \
--outpath /tmp/
```

See the crazy errors on parameters 1, 2 and 3?

#### 19.2.3. All plots of THS optimization and equalization extended

Again, all plots without caption or anything. That's why they have titles, you know.

#### 19.2.4. All S-Curve plots extended

Excuse the mismatched order of the tables… I don't really expect anyone to be particularly interested in this, hence I didn't want to spend time sorting them by hand.

All figures:

All tables:

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

4 | 20 | Run3 | 999.7 | 0.4 | 437.3 | 0.004919 | 4.256 | 0.006459 |

4 | 25 | Run3 | 1003 | 0.376 | 446.7 | 0.005023 | 4.561 | 0.006614 |

4 | 30 | Run3 | 999.5 | 0.3509 | 455.5 | 0.004807 | 4.4 | 0.006384 |

4 | 35 | Run3 | 999.4 | 0.424 | 465.1 | 0.005229 | 4.494 | 0.0068 |

4 | 40 | Run3 | 997.6 | 0.372 | 474.8 | 0.004981 | 4.492 | 0.006571 |

4 | 50 | Run3 | 997.6 | 0.4397 | 492.6 | 0.005304 | 4.476 | 0.006868 |

4 | 60 | Run3 | 1004 | 0.3632 | 511.5 | 0.005063 | 4.706 | 0.006681 |

4 | 100 | Run3 | 998.8 | 0.3903 | 582.7 | 0.005315 | 4.818 | 0.00695 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

3 | 20 | Run2 | 1020 | 1.225 | 422.9 | 0.00906 | 4.107 | 0.009371 |

3 | 25 | Run2 | 1011 | 0.5655 | 428.1 | 0.005788 | 4.353 | 0.007229 |

3 | 30 | Run2 | 1003 | 0.3785 | 433.1 | 0.004842 | 4.303 | 0.006391 |

3 | 35 | Run2 | 1001 | 0.3727 | 438.4 | 0.004825 | 4.305 | 0.006377 |

3 | 40 | Run2 | 1001 | 0.3724 | 444.3 | 0.004802 | 4.272 | 0.00635 |

3 | 50 | Run2 | 1001 | 0.3643 | 454.1 | 0.004931 | 4.496 | 0.006519 |

3 | 60 | Run2 | 999.5 | 0.3824 | 464.3 | 0.005009 | 4.477 | 0.006591 |

3 | 100 | Run2 | 1005 | 0.4337 | 502.6 | 0.005988 | 5.397 | 0.007674 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

4 | 20 | Run2 | 1040 | 1.203 | 427.4 | 0.009416 | 4.453 | 0.009669 |

4 | 25 | Run2 | 1006 | 0.6367 | 433.2 | 0.006145 | 4.298 | 0.007513 |

4 | 30 | Run2 | 1005 | 0.3829 | 438.1 | 0.004901 | 4.371 | 0.006456 |

4 | 35 | Run2 | 1001 | 0.3561 | 443.3 | 0.004829 | 4.407 | 0.006405 |

4 | 40 | Run2 | 1001 | 0.4318 | 449.2 | 0.005384 | 4.642 | 0.006972 |

4 | 50 | Run2 | 999.3 | 0.362 | 459.1 | 0.004891 | 4.445 | 0.006473 |

4 | 60 | Run2 | 1010 | 0.4457 | 469.4 | 0.005662 | 4.944 | 0.00727 |

4 | 100 | Run2 | 1006 | 0.4092 | 507.6 | 0.005949 | 5.552 | 0.00768 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

1 | 20 | Run3 | 1007 | 0.5532 | 384.6 | 0.00592 | 4.532 | 0.007397 |

1 | 25 | Run3 | 1023 | 0.6033 | 393.6 | 0.007034 | 5.418 | 0.008488 |

1 | 30 | Run3 | 1000 | 0.467 | 403.7 | 0.005764 | 4.853 | 0.007362 |

1 | 35 | Run3 | 983.4 | 0.3714 | 413.1 | 0.004776 | 4.133 | 0.006327 |

1 | 40 | Run3 | 1013 | 0.3916 | 422 | 0.005359 | 4.966 | 0.006994 |

1 | 50 | Run3 | 1022 | 0.6807 | 440.9 | 0.007737 | 5.551 | 0.009052 |

1 | 60 | Run3 | 982.4 | 0.3855 | 461.3 | 0.005151 | 4.526 | 0.006767 |

1 | 100 | Run3 | 999.6 | 0.3774 | 534.6 | 0.005401 | 5.032 | 0.007076 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

5 | 20 | Run3 | 980.6 | 0.3185 | 351.3 | 0.004076 | 3.441 | 0.005511 |

5 | 25 | Run3 | 1012 | 0.4223 | 359.8 | 0.005834 | 5.346 | 0.007509 |

5 | 30 | Run3 | 1003 | 0.3553 | 369.1 | 0.00509 | 4.786 | 0.006727 |

5 | 35 | Run3 | 999.5 | 0.5331 | 378.9 | 0.006367 | 5.063 | 0.007928 |

5 | 40 | Run3 | 991.5 | 0.4121 | 388.8 | 0.005378 | 4.701 | 0.006998 |

5 | 50 | Run3 | 993.7 | 0.3681 | 406.8 | 0.004946 | 4.445 | 0.006536 |

5 | 60 | Run3 | 1009 | 0.3795 | 425.5 | 0.005705 | 5.503 | 0.007451 |

5 | 100 | Run3 | 1006 | 0.4792 | 498.9 | 0.006008 | 5.086 | 0.007616 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

0 | 20 | Run3 | 1001 | 0.37 | 421.3 | 0.004754 | 4.221 | 0.006294 |

0 | 25 | Run3 | 1004 | 0.3732 | 430.8 | 0.004994 | 4.545 | 0.006582 |

0 | 30 | Run3 | 1000 | 0.3867 | 440.1 | 0.004989 | 4.429 | 0.006561 |

0 | 35 | Run3 | 1005 | 0.3935 | 449.3 | 0.005154 | 4.627 | 0.006748 |

0 | 40 | Run3 | 1002 | 0.3842 | 459.4 | 0.005048 | 4.53 | 0.006635 |

0 | 50 | Run3 | 1002 | 0.3928 | 478.2 | 0.005145 | 4.603 | 0.006741 |

0 | 60 | Run3 | 1001 | 0.3806 | 497.6 | 0.00505 | 4.553 | 0.006643 |

0 | 100 | Run3 | 1004 | 0.3936 | 569.8 | 0.005365 | 4.895 | 0.007004 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

2 | 20 | Run2 | 998.4 | 0.8093 | 351.8 | 0.007102 | 4.242 | 0.008231 |

2 | 25 | Run2 | 1028 | 0.7173 | 356.9 | 0.006721 | 4.518 | 0.00796 |

2 | 30 | Run2 | 1006 | 0.396 | 362.3 | 0.005205 | 4.683 | 0.006806 |

2 | 35 | Run2 | 1003 | 0.3835 | 368.1 | 0.005318 | 4.898 | 0.006962 |

2 | 40 | Run2 | 1013 | 0.4821 | 373.9 | 0.006488 | 5.664 | 0.008148 |

2 | 50 | Run2 | 985.4 | 0.405 | 386.9 | 0.005722 | 5.14 | 0.007423 |

2 | 60 | Run2 | 1015 | 0.4928 | 397.8 | 0.006599 | 5.721 | 0.008248 |

2 | 100 | Run2 | 1002 | 0.4138 | 436 | 0.005847 | 5.353 | 0.007547 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

6 | 20 | Run2 | 1008 | 1.057 | 400.5 | 0.00954 | 4.876 | 0.01006 |

6 | 25 | Run2 | 981.7 | 0.433 | 407.7 | 0.005316 | 4.43 | 0.006901 |

6 | 30 | Run2 | 990.9 | 0.3359 | 413.2 | 0.004408 | 3.878 | 0.005909 |

6 | 35 | Run2 | 996.6 | 0.3557 | 417.6 | 0.004588 | 4.055 | 0.006108 |

6 | 40 | Run2 | 995.3 | 0.3669 | 423.4 | 0.004743 | 4.192 | 0.006287 |

6 | 50 | Run2 | 995.7 | 0.384 | 433.3 | 0.005026 | 4.464 | 0.006612 |

6 | 60 | Run2 | 990.4 | 0.3798 | 444.6 | 0.005093 | 4.542 | 0.006701 |

6 | 100 | Run2 | 998.2 | 0.4102 | 483.5 | 0.00559 | 5.026 | 0.007249 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

2 | 20 | Run3 | 1000 | 0.3853 | 366.4 | 0.005084 | 4.56 | 0.006677 |

2 | 25 | Run3 | 1001 | 0.3791 | 375.9 | 0.005146 | 4.689 | 0.006762 |

2 | 30 | Run3 | 1003 | 0.4448 | 384.9 | 0.005457 | 4.657 | 0.007037 |

2 | 35 | Run3 | 1001 | 0.3878 | 394.5 | 0.005168 | 4.66 | 0.006776 |

2 | 40 | Run3 | 1001 | 0.4325 | 405 | 0.005309 | 4.55 | 0.006881 |

2 | 50 | Run3 | 1002 | 0.3695 | 423.3 | 0.005096 | 4.69 | 0.006713 |

2 | 60 | Run3 | 1001 | 0.3829 | 443.1 | 0.005312 | 4.886 | 0.006957 |

2 | 100 | Run3 | 1003 | 0.3783 | 516.5 | 0.005342 | 4.972 | 0.007 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

3 | 20 | Run3 | 998.8 | 0.3833 | 436 | 0.004918 | 4.348 | 0.006479 |

3 | 25 | Run3 | 1002 | 0.377 | 445.6 | 0.005006 | 4.521 | 0.006593 |

3 | 30 | Run3 | 1001 | 0.3666 | 454.1 | 0.00497 | 4.537 | 0.006564 |

3 | 35 | Run3 | 1005 | 0.3822 | 463.6 | 0.005077 | 4.604 | 0.00667 |

3 | 40 | Run3 | 1001 | 0.3767 | 473.6 | 0.004984 | 4.488 | 0.006567 |

3 | 50 | Run3 | 1002 | 0.3772 | 491.7 | 0.005049 | 4.579 | 0.006646 |

3 | 60 | Run3 | 999.8 | 0.3738 | 511.6 | 0.00493 | 4.427 | 0.006506 |

3 | 100 | Run3 | 954.5 | 0.3897 | 583.8 | 0.005565 | 4.828 | 0.007279 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

0 | 20 | Run2 | 989.8 | 0.8928 | 408.9 | 0.007268 | 3.991 | 0.008277 |

0 | 25 | Run2 | 1006 | 0.4597 | 414.2 | 0.004923 | 3.974 | 0.006386 |

0 | 30 | Run2 | 1004 | 0.3651 | 419.2 | 0.004602 | 4.067 | 0.006111 |

0 | 35 | Run2 | 999.3 | 0.3604 | 424.4 | 0.004597 | 4.058 | 0.006113 |

0 | 40 | Run2 | 1003 | 0.3845 | 429.2 | 0.004994 | 4.465 | 0.006569 |

0 | 50 | Run2 | 1002 | 0.3689 | 439 | 0.00499 | 4.554 | 0.006585 |

0 | 60 | Run2 | 1004 | 0.4107 | 449.1 | 0.00541 | 4.834 | 0.007032 |

0 | 100 | Run2 | 1013 | 0.4559 | 486.9 | 0.006465 | 5.853 | 0.008183 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

5 | 20 | Run2 | 1017 | 0.9365 | 336 | 0.007614 | 4.191 | 0.008502 |

5 | 25 | Run2 | 1047 | 0.7914 | 341.5 | 0.00795 | 5.237 | 0.009016 |

5 | 30 | Run2 | 988 | 0.4721 | 347.8 | 0.005962 | 4.962 | 0.007589 |

5 | 35 | Run2 | 993.4 | 0.3367 | 352.5 | 0.004536 | 4.066 | 0.006067 |

5 | 40 | Run2 | 1002 | 0.3981 | 357.8 | 0.005052 | 4.453 | 0.00662 |

5 | 50 | Run2 | 999 | 0.3784 | 368.3 | 0.005305 | 4.891 | 0.006957 |

5 | 60 | Run2 | 982.6 | 0.4703 | 381.5 | 0.006751 | 5.831 | 0.0085 |

5 | 100 | Run2 | 1009 | 0.407 | 420.7 | 0.005546 | 5.066 | 0.007196 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

6 | 20 | Run3 | 993.9 | 0.375 | 413.2 | 0.004854 | 4.282 | 0.006414 |

6 | 25 | Run3 | 1002 | 0.3873 | 422.3 | 0.005074 | 4.549 | 0.006662 |

6 | 30 | Run3 | 997.5 | 0.3923 | 431.5 | 0.005272 | 4.74 | 0.006896 |

6 | 35 | Run3 | 1000 | 0.4067 | 441.1 | 0.005354 | 4.764 | 0.006972 |

6 | 40 | Run3 | 1001 | 0.379 | 450.8 | 0.005124 | 4.662 | 0.006734 |

6 | 50 | Run3 | 1005 | 0.4097 | 469.4 | 0.005494 | 4.956 | 0.007131 |

6 | 60 | Run3 | 1000 | 0.3918 | 489.3 | 0.005174 | 4.637 | 0.006778 |

6 | 100 | Run3 | 1009 | 0.4163 | 562.9 | 0.005794 | 5.32 | 0.007475 |

chip | voltage | runPeriod | N | ΔN | μ | Δμ | σ | Δσ |
---|---|---|---|---|---|---|---|---|

1 | 20 | Run2 | 1069 | 1.481 | 368.1 | 0.01156 | 4.832 | 0.01095 |

1 | 25 | Run2 | 1067 | 0.7955 | 374.7 | 0.009635 | 6.7 | 0.01062 |

1 | 30 | Run2 | 975.2 | 0.3802 | 382.1 | 0.005377 | 4.803 | 0.007053 |

1 | 35 | Run2 | 990.6 | 0.4188 | 387.6 | 0.005426 | 4.709 | 0.007046 |

1 | 40 | Run2 | 1023 | 0.6093 | 393.5 | 0.007115 | 5.453 | 0.008561 |

1 | 50 | Run2 | 989.8 | 0.4391 | 405.3 | 0.006054 | 5.321 | 0.007752 |

1 | 60 | Run2 | 987.7 | 0.3325 | 415.5 | 0.004108 | 3.466 | 0.005535 |

1 | 100 | Run2 | 1018 | 0.4941 | 452.2 | 0.006787 | 5.945 | 0.008457 |

#### 19.2.5. THL calibration

Figure 6 shows the optimized `THL`

distributions of all chips after threshold equalization for run 2
(left) and 3 (right).

`THL`

values of all Septemboard (board H) chips at the noise peak with the calibration for for run 2 on the left and run 3 on the right.##### 19.2.5.1. Generate facet plot of THL optimization extended

The plot is generated as part of sec. 8.1.3.1.

#### 19.2.6. All THL calibration plots extended

**Note**: The text should be placed in relative coordinates based on the
data range, but that's currently not done. Sorry about tcho "hat.

### 19.3. Calibration measurements of the veto scintillator paddle extended

The following is a set of notes taken when calibrating the scintillator paddle in the laboratory of the RD51 group at CERN. It is reproduced here for transparency and completeness.

#### 19.3.1. Scintillator paddle calibrations `[0/2]`

This document contains the data for the calibration of the MM veto scintillator. It is a 'report' created while data taking and thus may contain conflicting information. Not to be understood as a simple reference protocol.

The scintillator has a Canberra 2007 base, which accepts positive HV. The PMT is a Bicron Corp. 31.49x15.74M2BC408/2-X, where the first two numbers are the scintillators dimensions in inch.

```
For calibration we're using $\SI{1400}{\volt}$, while Juanan
mentioned in his mail to use $\SI{1200}{\volt}$ during data taking.
```

For calibration we're using an Ortec 9302 amplifier after the PMT with a gain of 20. This is fed into an LRS 621CL discriminator. The PMT and base are used at a HV of \(+\SI{1200}{\volt}\).

Scintillator is of size \(\SI{42}{\cm}\) times \(\SI{82}{\cm}\). Which is an area of

let x = 0.42 let y = 0.82 echo x * y

`[ ]`

**TODO: CROSS CHECK THESE NUMBERS HERE**

At a cosmic muon rate of \(\sim\SI{100}{\hertz \per \meter \squared \steradian}\), the expected signal rate of munons is thus \(\sim \SI{33}{\hertz}\).

let area = 0.34 let total_muons = 60000.0 echo area * total_muons

`[ ]`

**UPDATE**: Muon rate about \(\SI{1}{cm^{-2}.min^{-1}} \approx \SI{166.67}{m^{-2}.s^{-1}}\)

##### 19.3.1.1. Calibration

Threshold values are scaled by a factor of 10. Coincidence using Theodoros 2 scintillator paddles in RD51 lab.

- upper scinti: \(\SI{-2070}{\volt}\)
- lower scinti: \(\SI{-2050}{\volt}\)

Measurement time for each value: \(\SI{10}{\minute}\)

Note: The reason the coincidences are much lower than the single scintillator counts is of course due to the much smaller coincidence area of the small scintillators used for the measurement.

Threshold / mV | Counts Szinti | Counts Coincidence |
---|---|---|

-301.9 | 24062 | 760 |

-399 | 13332 | 496 |

-498 | 6584 | 300 |

-603 | 3363 | 167 |

-699 | 1900 | 104 |

-802 | 1087 | 83 |

-901 | 651 | 54 |

-1005 | 523 | 50 |

-1104 | 361 | 32 |

-1203 | 231 | 32 |

-1305 | 189 | 38 |

-1400 | 151 | 23 |

-1502 | 96 | 14 |

-1602 | 78 | 15 |

-1703 | 72 | 10 |

-1802 | 58 | 11 |

Second set of measurements around interesting point of \(\SI{1000}{\milli\volt}\)

Threshold / mV | Counts Szinti | Counts Coincidence |
---|---|---|

-1200 | 259 | 35 |

-1100 | 350 | 34 |

-1000 | 456 | 48 |

-900 | 774 | 42 |

A third measurement using an amplifier after the PMT, since the output signal of the PMT is so small (see mail of JuanAn). Now the HV was lowered to \(\SI{1200}{\volt}\) again, since it is not necessary.

Threshold / mV | Counts Szinti | Counts Coincidence |
---|---|---|

-598 | 31221 | 634 |

-700 | 30132 | 674 |

-804 | 28893 | 635 |

-903 | 28076 | 644 |

-1005 | 27012 | 684 |

-1103 | 25259 | 566 |

-1200 | 22483 | 495 |

-1303 | 19314 | 437 |

-1403 | 16392 | 356 |

-1505 | 13677 | 312 |

-1600 | 11866 | 267 |

-1701 | 10008 | 243 |

-900 | 28263 | 892 |

-1000 | 26789 | 991 |

import ggplotnim, sequtils proc parse(s: openArray[string]): seq[float] = s.filterIt(it.len > 0).mapIt(it.parseFloat) let df = toDf({ "Thr" : tbl["Threshold / mV"].parse, "Szinti" : tbl["Counts Szinti"].parse, "Coinc" : tbl["Counts Coincidence"].parse }) ggplot(df, aes("Thr", "Szinti")) + geom_point() + geom_line() + ggsave("/t/test.pdf")

Export this table using org-table-export to ./data/veto_szinti_counts.txt. Then remove unnecessary last line and add # to beginning of first line.

`[ ]`

**REWRITE TO USE AN INLINE GGPLOTNIM PLOTTING AND SHOW DATA**

Then use ./PyS_mm_veto_szinti_calib.py to plot the data.

A threshold of \(\SI{-110}{\milli\volt}\) was selected, after analysis.

## Footnotes:

^{ 1}

The plot is generated from the
`thresholdMeans.txt`

file created as part of the equalization
procedure in TOS.