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:
The plot is generated from the
thresholdMeans.txt
file created as part of the equalization
procedure in TOS.