# CDC algo

## Contents

- 1 CDC time & integral algorithm
- 1.1 Quantities to be returned, if a hit is found
- 1.2 Variable configuration parameters (all integers)
- 1.3 Obsolete variable configuration parameters necessary for mode 8 commissioning data analysis (all integers)
- 1.4 Configuration constants (all values are integers)
- 1.5 Safety checks to go into the driver
- 1.6 Hit finding module
- 1.7 Time finding module
- 1.8 Signal maximum module
- 1.9 Signal integral module

- 2 Error codes from Run 1602
- 2.1 Error codes with faulty channels included
- 2.2 Error codes with most of faulty channels excluded from data
- 2.3 Error codes with faulty channels included, mimicked overflow detection in C++ code
- 2.4 Examples, in order of q code population (click image twice to expand)
- 2.4.1 Q=0, good
- 2.4.2 Q=6, overflow
- 2.4.3 Q=5, ADC value=0
- 2.4.4 Q=7, Pedestal>511
- 2.4.5 Q=1, ADC data<ADC_subset_value[PED_SAMPLE] + HIGH_THRESHOLD
- 2.4.6 Q=3, last upsampled point is too low (very rare with fully functioning fADCs)
- 2.4.7 Q=2, leading edge time too late to upsample (very rare with fully functioning fADCs)
- 2.4.8 Q=8, calculated an upsampled value < 0 (very rare with fully functioning fADCs)
- 2.4.9 Q=4, upsampled values too high (very rare with fully functioning fADCs)

- 2.5 Upsampled data - old example
- 2.6 Upsampling error check prior to error correction - copied from CDC_run_1280_bad_events
- 2.7 Sample data overlay plots
- 2.8 Sample data overlay plots for set thresholds
- 2.9 Events with overflows

# CDC time & integral algorithm

## Quantities to be returned, if a hit is found

- Leading edge time (11 bits, units of sample/10)
- Time quality factor (1 bit) set to 0 if time is good, 1 if time is rough estimate
- Pedestal immediately before the hit (8 bits, all bits set if value > field max, scaled down by a factor 2^r, r is 0 to 2)
- Signal integral (n bits, scaled down by factor 2^m, all bits set if greater than range; n,m are 14,4)
- Signal maximum (p bits, scaled down by factor 2^q; p,q approx 8,2) this is the first maximum in the signal after the threshold crossing
- Overflow count (3 bits, set to 7 if >6)
- FDC only: Sample number of signal maximum

## Variable configuration parameters (all integers)

- NW: number of samples in readout window
- NPED: number of samples in pedestal window (hit window is immediately after this). (default 16, must be 2**integer)
- NPED2: number of samples to use to calculate pedestal just before hit, this is the pedestal value to be returned (default 16, must be 2**integer)
- HIT_THRES: threshold to identify hit (default 5σ ~100, range 50 to 300)
- XTHR_SAMPLE: position in subset of first sample above hit_threshold (default 9, starts with 0)
- HIGH_THRESHOLD: High timing threshold (default 4σ ~ 80, range 40 to 270) must be lower than hit threshold
- LOW_THRESHOLD: Low timing threshold (default 1σ ~ 20, range 5 to 30)
- INT_END: integration ends with the earlier of this many samples after the hit threshold crossing, or NW-7 (=WINDOW_END).
- PBIT: scale factor for pedestal is 2**PBIT
- ABIT: scale factor for amplitude is 2**ABIT
- IBIT: scale factor for integral is 2**IBIT
- NPK: max number of peaks to find per trigger

## Obsolete variable configuration parameters necessary for mode 8 commissioning data analysis (all integers)

- WINDOW_START: position in buffer of first sample in hit search window, immediately after the pedestal window; in future WINDOW_START will be equal to NPED
- WINDOW_END: position in buffer of last sample in hit search window; in future WINDOW_END will be equal to NW-7.

## Configuration constants (all values are integers)

- NSAMPLES: number of ADC samples in subset to pass to time finding module (default 15)
- PED_SAMPLE: position in subset of sample to be used as local pedestal (default 5, starts with 0)
- ROUGH_DT: rough time - if timing fails, return hit time of XTHR_SAMPLE - ROUGH_DT (default 24, units sample/10)
- INT_SAMPLE: if timing fails, start integration with this sample (default 6).
- NUPSAMPLED: number of upsampled values to calculate (default 8, minimum 8)
- LIMIT_PED_MAX: do not calculate accurate time if any of samples 0 to PED_SAMPLE in subset exceeds this (default 511)
~~LIMIT_ADC_MAX: do not calculate accurate time if any sample in the subset exceeds this (default 4095)~~- SET_ADC_MIN: reduce chances of calculating a negative upsampled value by adding a constant offset to the subset values such that the minimum is equal to SET_ADC_MIN (default 20)
~~LIMIT_UPS_ERR: do not calculate accurate time if the sum of the error of the 2 upsampled values exceeds this (default 30)~~

## Safety checks to go into the driver

- NP and NP2 must be powers of 2
- NP2 <= NP
- PED_SAMPLE >= 5
- XTHR_SAMPLE >= PED_SAMPLE+3 (for valid math only >PED_SAMPLE is required)
- HIGH_THRESHOLD > LOW_THRESHOLD
- NPK > 0

## Hit finding module

- Calculate start_pedestal as mean of NPED samples from 0 (WINDOW_START-NPED) to WINDOW_START-1
- Search from WINDOW_START to WINDOW_END for the earliest sample with ADC value >= start_pedestal + HIT_THRES. If not found, go back to sleep. If found, continue, this is sample X.
- Call up time-finding module and send in NSAMPLES ADC values from the hit threshold crossing region, with sample X in position XTHR_SAMPLE (starting at 0)
- Call up signal maximum module
- Call up signal integral module
- Return pedestal_at_hit as mean of NPED2 samples ending with sample number X + PED_SAMPLE - XTHR_SAMPLE, or 255 if pedestal_at_hit > field max
- Return overflow count from integral module
- Return q_code from time module
- Return total integral: sum of contributions from time module and integral module
- Return time = (X - XTHR_SAMPLE)*10 + le_time returned from time module, units are 0.1*sample-period (0.8ns)

## Time finding module

This returns an error code q_code and the leading edge time le_time, in units of sample/10 and relative to the first sample in the subset. The hit time returned falls into one of three categories: an accurate estimate of the leading edge time, where the low threshold crossing time was found using upsampled data, a midpoint time, where the low threshold crossing time was found using sample data, and a rough time estimate, XTHR_SAMPLE*10 - ROUGH_DT. If the time returned is the accurate leading edge time, q_code is set to 0, otherwise it is set to 1.

- Inspect ADC samples 0 to PED_SAMPLE. If any sample values are 0 or greater than LIMIT_PED_MAX, return the rough time, XTHR_SAMPLE*10 - ROUGH_DT, q_code=1 and rough integral=sum of samples INT_SAMPLE to XTHR_SAMPLE-1.
~~Inspect ADC samples PED_SAMPLE+1 to NSAMPLES-1. If any sample values are 0 or greater than LIMIT_ADC_MAX, return the rough time, q_code=1 and rough integral.~~- Find the minimum sample value in the subset. Subtract a constant offset from all sample values so that the minimum value is now SET_ADC_MIN. This is to decrease the likelihood of calculating any negative upsampled values.
- Calculate the timing thresholds thres_hi = value of sample PED_SAMPLE + HIGH_THRESHOLD and thres_lo = value of sample PED_SAMPLE + LOW_THRESHOLD
- Search the samples from PED_SAMPLE+1 to NSAMPLES-1 for the first sample with value >= thres_hi. If this threshold is not met, return the rough time, q_code=1 and rough integral.
- Search the samples from the first sample with value >= thres_hi down to PED_SAMPLE to find the first sample (Y) with value <= thres_lo
- If Y is > NSAMPLES-7, there are not enough samples to calculate upsampled values, return the rough time, q_code=1 and rough integral.
- Calculate NUPSAMPLED (8) upsampled values, starting with Y-0.2.
- If any upsampled value is negative, return the midpoint time, Y*10+5, q_code=1, and good integral=sum of samples from Y to XTHR_SAMPLE-1.
- Calculate two upsampling errors, as the difference between upsampled point 1 and sample Y, and the difference between upsampled point 6 and sample Y+1
~~Sum the errors and compare them with LIMIT_UPS_ERR, if this is exceeded then return the midpoint time, Y*10+5, q_code=1, and good integral.~~- Calculate the mean of the 2 errors, ups_err and the adjusted threshold, thres_adj = thres_lo + ups_err
- Search the upsampled values from NUPSAMPLED-1 down to 0 to find upsampled point Z where the value <= thres_adj
- If Z=NUPSAMPLED-1 or Z is not found, return the midpoint time, Y*10+5, q_code=1, and good integral.
- Interpolate between the upsampled points Z and Z+1 to find the crossing time in units of sample/10 and relative to the first upsampled point
- Calculate the leading edge time, le_time, as the crossing time found in previous step + Y*10-2, in units of sample/10 and relative to subset sample 0
- Return time=le_time, q_code=0 and good integral

## Signal maximum module

This returns the signal maximum

- Inspect ADC values after sample X, find the first value which is less than its predecessor
- Return value of the predecessor scaled down by 2^p

## Signal integral module

This returns the signal integral and overflow count

- Sum ADC values from sample X to sample WINDOW_END, and count the number of samples with overflow bit set
- Return integral scaled down by 2^m (return all bits set if value exceeds range maximum)
- Return overflow count (return 7 if count>6)

# Error codes from Run 1602

Settings used:

#define WINDOW_START 46 //earliest sample for start of hit #define WINDOW_END 130 //last sample for hit arrival, and last sample included in integral #define HIT_THRES 300 // "5 sigma" hit threshold *** set this VERY high to cut out persistent noise in a handful of channels *** #define NPED 16 // number of samples used for pedestal used to find hit. must be 2**integer #define NPED2 16 // number of samples used for pedestal calculated just before hit (returned, not used here). must be 2**integer // cdc_time #define HIGH_THRESHOLD 80 // 4 sigma threshold #define LOW_THRESHOLD 20 // 1 sigma threshold #define ROUGH_DT 24 // if pulse fails QA, return this many tenth-samples before threshold xing #define INT_SAMPLE 6 // if pulse fails QA, start integration with this sample //cdc_time good pulse criteria #define LIMIT_PED_MAX 511 //return rough time if any sample in 0 to PED_SAMPLE exceeds this #define LIMIT_ADC_MAX 4095 // return rough time if any sample in PED_SAMPLE+1 to NSAMPLES exceeds this // cdc_time upsampling #define NSAMPLES 15 //number of samples in subset of array to pass to cdc_time #define XTHR_SAMPLE 9 // the hit_thres xing sample is sample[9] passed into cdc_time, starting with sample[0] #define PED_SAMPLE 5 // take local ped as sample[5] passed into cdc_time #define NUPSAMPLED 8 // number of upsampled values to calculate, minimum is 8 #define SET_ADC_MIN 20 // add an offset to the adc values to set the min value equal to SET_ADC_MIN #define LIMIT_UPS_ERR 30 // upsampling error tolerance, return midpoint time if error is greater than this

## Error codes with faulty channels included

Error codes are listed in the order that the event is removed from processing. ADC overflows are not identified by the C++ code as it only looks at Df125WindowRawData.

q_code | reason | entries | percent of total | percent of q>0 entries |
---|---|---|---|---|

5 | ADC value = 0 | 26458 | 2.3% | 31% |

6 | ADC value > 4095 | 0 | 0% | 0% |

7 | Pedestal > 511 | 44830 | 3.9% | 53% |

1 | ADC data did not go over threshold adc_thres_hi | 576 | 0.050% | 0.6888% |

2 | Leading edge time is too late in the buffer to upsample | 82 | 0.007% | 0.096% |

8 | Upsampled value is negative | 15 | 0.001% | 0.018% |

9 | Upsampling error sum > 30 | 13225 | 1.1% | 16% |

3 | Last upsampled point is too low (below or equal to low timing threshold) | 28 | 0.002% | 0.033% |

4 | Upsampled points are too high (did not go below low timing threshold) | 2 | 0.000% | 0.002% |

0 | Good | 1078072 | 93% |

## Error codes with most of faulty channels excluded from data

Error codes are listed in the order that the event is removed from processing. ADC overflows are not identified by the C++ code as it only looks at Df125WindowRawData.

q_code | reason | entries | percent of total | percent of q>0 entries |
---|---|---|---|---|

5 | ADC value = 0 | 26433 | 2.3% | 31% |

6 | ADC value > 4095 | 0 | 0% | 0% |

7 | Pedestal > 511 | 44747 | 3.9% | 53% |

1 | ADC data did not go over threshold adc_thres_hi | 575 | 0.050% | 0.68% |

2 | Leading edge time is too late in the buffer to upsample | 82 | 0.007% | 0.096% |

8 | Upsampled value is negative | 0 | 0% | 0% |

9 | Upsampling error sum > 30 | 13188 | 1.2% | 16% |

3 | Last upsampled point is too low (below or equal to low timing threshold) | 2 | 0.000% | 0.002% |

4 | Upsampled points are too high (did not go below low timing threshold) | 0 | 0% | 0% |

0 | Good | 1075754 | 93% |

## Error codes with faulty channels included, mimicked overflow detection in C++ code

The C++ code is not finding overflows because it is only using Df125WindowRawData; overflows are in a different branch of DAQTree. The VHDL code will be able to find overflows by testing for sample value > 4095 because the overflow bit is passed in as a 13th sample value bit (bits 0-11 are the ADC value), so samples with the overflow bit set will have value > 4095. This was mimicked in the C++ code by testing for ADC value > 4094.

#define LIMIT_ADC_MAX 4094 // return rough time if any sample in PED_SAMPLE+1 to NSAMPLES exceeds this

q_code | reason | entries | percent of total | percent of q>0 entries |
---|---|---|---|---|

5 | ADC value = 0 | 52559 | 3.9% | 25% |

6 | ADC value > 4094 | 97939 | 7.2% | 46% |

7 | Pedestal > 511 | 51244 | 3.8% | 24% |

1 | ADC data did not go over threshold adc_thres_hi | 9787 | 0.72% | 4.6% |

2 | Leading edge time is too late in the buffer to upsample | 700 | 0.051% | 0.33% |

8 | Upsampled value is negative | 15 | 0.001% | 0.007% |

9 | Upsampling error sum > 30 | 61 | 0.004% | 0.029% |

3 | Last upsampled point is too low (below or equal to low timing threshold) | 813 | 0.060% | 0.38% |

4 | Upsampled points are too high (did not go below low timing threshold) | 8 | 0.001% | 0.004% |

0 | Good | 1148835 | 84% |

## Examples, in order of q code population (click image twice to expand)

### Q=0, good

### Q=6, overflow

### Q=5, ADC value=0

### Q=7, Pedestal>511

### Q=1, ADC data<ADC_subset_value[PED_SAMPLE] + HIGH_THRESHOLD

### Q=3, last upsampled point is too low (very rare with fully functioning fADCs)

### Q=2, leading edge time too late to upsample (very rare with fully functioning fADCs)

### Q=8, calculated an upsampled value < 0 (very rare with fully functioning fADCs)

### Q=4, upsampled values too high (very rare with fully functioning fADCs)

## Upsampled data - old example

## Upsampling error check prior to error correction - copied from CDC_run_1280_bad_events

After excluding known CDC_bad_channels I compared the upsampled data with the original samples for the first 10000 events of run 1602. This is a high-intensity run so some of the pedestals are lower than they should be.

ups_err1 is the upsampled value iubuf[1] - the original sample adc[adc_sample_lo]

ups_err2 is the upsampled value iubuf[6] - the original sample adc[adc_sample_lo+1]

q_code list: 0: Good 1: ADC data did not go over threshold adc_thres_hi 2: Leading edge time is outside the upsampled region (cross adc_thres_lo too late in the buffer subset ) 3: Last upsampled point is <= low timing threshold 4: Upsampled points did not go below low timing threshold

Looking at upsampling errors - occur when gradient is very large

Following this the error correction step was added to the algorithm, where the sum of errors ups_err1+ups_err2 is calculated and compared with LIMIT_UPS_ERR and then, if below this limit, halved (to calculate the mean) and subtracted from the upsampled data. The corrected upsampled points are the green circles in the 'example of Q code' plots above.

## Sample data overlay plots

.

## Sample data overlay plots for set thresholds

## Events with overflows

After removing the LIMIT_ADC_MAX so that overflow events would reach the upsampling section of code, events are treated as shown:

If the sum of the upsampling errors exceeds LIMIT_UPS_ERROR then the midpoint of the upsample region is returned as the time. This might not be necessary, the ups_error sum is proportional to the slope in ADC amplitude and with the current value (30) it is mostly picking out overflow events, which could be identified offline. Run 3221 (first file) has 0 events with q=9 and overflows=0.