Skip to content

Linearity of the ADC vs input charge

verenamh edited this page Jul 29, 2025 · 1 revision

The purpose of this page is to summarize the work done on testing the ADC linearity and to formulate some open questions for future testing. Currently, it is focused on the testing that has been done at Lund. More plots and information can be found in this github issue. For more information on the HGCROC and the circuit, check the following PhD thesis, on page 82 is the circuit diagram: Design and characterization of readout ASICs for SiPM detectors in pico-second timing measurements for the CMS HGCAL experiment..

The following plots were produced using parameter-time-scan.py and highrange_correction.py.


Background and summary of work

When injecting charge into any of the capacitors in the HGCROC (lowrange, highrange, pre-CC), the pulse amplitude (of ADC vs time) will vary depending on the amount of injected charge. The injected charge is changed by inputting different CALIB (for lowrange and highrange) or CALIB_2V5 (pre-Current Conveyor) values. It is expected that when plotting the maximum ADC value vs the injected charge, the result should be close to being linear, up until the point where the ADC saturates at 1023. This was indeed found to be the case (first plot is lowrange and highrange, second is pre-CC single channel, and the third is using all channels from the pre-CC, meaning CMD_120P was set to 1):

combinedlowrangeandhighrange param-time-scan_20250626_145012 param-time-scan_20250626_155315

It can be useful to convert the CALIB-axis to charge Q[fC] instead. However, one needs to be cautious about the interpretation, as many assumptions are made, and it may differ between different HGCROC setups. Here, it assumes that the capacitances $$C$$ are exactly as written in the H2GCROC3 datasheet (500fF for lowrange and 8pF for highrange), for all the channels. Furthermore, it should be measured what applied voltage $$V_{max}$$ the maximum CALIB (which is 4095 for a 12-bit DAC) corresponds to. At Lund, this was measured to be 0.871V. Then we can say that

$$ Q [fC] = \frac{CALIB}{CALIB_{max}} \cdot C[F] \cdot V_{max}[V] \cdot 10^{15} $$

To have better comparability between the lowrange and highrange injections, it can be of use to correct one dataset towards the other, while leaving the ADC values unchanged. At Lund, we chose that lowrange is "right" and to correct the highrange data to align with it. The corrected charge values $$q'$$ for highrange are found with

$$ q' = \frac{m_h \cdot q_h + b_h - b_l}{m_l} $$

where $$m_l$$ and $$m_h$$ are the slopes, and $$b_l$$ and $$b_h$$ are the intercepts of the linear fits for lowrange and highrange, respectively. More information and the derivation can be found here. The following is an exemplary plot for channel 61, when injecting into all channels at once (discussed in the next step), selecting only values up to an ADC value of 600 to only include the linear region. Notice also that both lowrange and highrange go down to the pedestal at zero charge being injected, in the HGCROC-v2 there was an offset between the two. This seems to have been fixed with version 3.

HR_CORR_CH61

It is also desirable that this behaviour is consistent across all HGCROC channels. A good comparison is to do linear fits and then plot the slope of the fit against the channel number. Ideally, there should be little variation in the slope between the channels. To obtain this, the PARAMETER_TIMESCAN function in tasks.cxx was modified to inject charges into all channels simultaneously. The two current options are either injecting into all channels from 0 to 71 or only into channel 61. If another combination is desired, tasks.cxx needs to be modified manually. When injecting into all channels at once, the slope plots for lowrange and highrange look like the following:

m_low m_high

As can be seen, both seem to vary depending on the channel number and are not constant as expected. For highrange, there is a drop in between the two chip halves as well.

The above led to further studies of the behaviour of the chip when injecting into channels simultaneously. The following two plots both show channel 0 for lowrange and highrange. Left is the case, where the charge is only injected into channel 0 alone, and on the right is the case, where the charge is injected into all channels simultaneously.

HR_CORR_CH0 HR_CORR_CH0

When looking especially at the saturation point for highrange (where it goes from linear to constant), it becomes clear that the behaviour is very different for the two cases. In a series of measurements, there were indications that this effect varies with the number of channels that charge is injected into, and also the spatial distance between them (for example, when comparing the case of injecting into channels 0,1,2,3,4,5, with the case of injecting into channels 5,10,15,20,25,30). Note that this also happens for lowrange.

In an attempt to explain this, we also did cross-talk measurements. This was done by injecting high charge only into channel 5, but then recording the data also for the neighbouring channels 3,4,6 and 7. On the left is an exemplary plot for lowrange, and on the right for highrange, as the pattern is similar for all neighbouring channels, respectively.

ADC_TIME_CH6 ADC_TIME_CH6

For lowrange, the pedestal seems to have a small dip around t=20ns. For highrange, there is a smaller pulse visible, though it seems quite small to maybe be cross-talk. A potential explanation for the above-described variation in the saturation point may be the following: when injecting charge into channel 5, it "induces" this small other pulse in e.g. channel 4. If now charge is also injected into channel 4, it will still have this smaller pulse induced by channel 5. The two combined may lower the pulse amplitude, resulting in a lower maximum ADC value. For this speaks that the maximum ADC value chosen for the linearity check is at similar time values as the dip visible in the plots (though, especially for lowrange, the dip is not necessarily coinciding with the minimum ADC value across the whole timespan).

Open questions/Future work

In general, it would be useful to repeat these measurements at the other available HGCROC setups.

  • Why is there a small pulse in the neighbouring channels during the cross-talk measurements? Is it cross-talk, or is there any other explanation?
  • The slope plots should be redone with charge injections into the channels one by one. The slope is expected to be hopefully more constant this way.
  • The charge injections into multiple channels should be redone with levelled pedestals to have better comparability.
  • When studying the variation of the saturation point and for the cross-talk, it was only done for half 0 of the chip. There should be measurements done comparing the two halves, and also the interaction between them (e.g. injecting into all channels on half zero while also recording the data on half 1, potentially, we still see the same behaviour as for the cross-talk measurements).
  • Study how the pulses look over time when injecting into multiple channels at once, to see if the pulse amplitudes are lower than in the case when injecting into a single channel, or if there is maybe a deformation of the pulse.
  • It could be a good idea to confirm the capacitances of all the channels. This could be achieved by doing external charge injections.
  • The channel variation could become a separate function, where it could be made easier to select the desired channels in the menu, instead of manually having to change them. There, it could also be good to differentiate between injected channels (where charge is actually injected) and recorded channels (where no charge is injected, but the data is still recorded in the csv), and make it easier for the user to select those options.
Clone this wiki locally