@@ -196,28 +196,16 @@ public int waveformADCProcessing(AHDCPulse p)
196196 return 0 ;
197197 } // classification before the fit
198198
199- if (p .wftype == 1 ) { // special case of saturated signals
200- float slope_max = 0 ;
201- for (int bin = 0 ; bin < p .binMax ; bin ++) {
202- float slope = (p .samples [bin +1 ] - p .samples [bin ])/samplingTime ;
203- if (slope > slope_max ) {
204- slope_max = slope ;
205- }
206- }
207- // empirical formula
208- p .adcMax = -28.753520f + 191.791679f *slope_max ;
209199
210- } else {
211- //If there are 2*npts+1 points around the peak
212- //(if the peak is not at an edge of the window)
213- //Then the peak ADC value is revisited to be the average of these
214- //TO DO: just use the adcmax???
215- int npts = 1 ;
216- if ((p .binMax - npts >= 0 ) && (p .binMax + npts <= p .numberOfBins - 1 )){
217- p .adcMax = 0 ;
218- for (int bin = p .binMax - npts ; bin <= p .binMax + npts ; bin ++) p .adcMax += p .samples [bin ];
219- p .adcMax = p .adcMax /(2 *npts +1 );
220- }
200+ //If there are 2*npts+1 points around the peak
201+ //(if the peak is not at an edge of the window)
202+ //Then the peak ADC value is revisited to be the average of these
203+ //TO DO: just use the adcmax???
204+ int npts = 1 ;
205+ if ((p .binMax - npts >= 0 ) && (p .binMax + npts <= p .numberOfBins - 1 )){
206+ p .adcMax = 0 ;
207+ for (int bin = p .binMax - npts ; bin <= p .binMax + npts ; bin ++) p .adcMax += p .samples [bin ];
208+ p .adcMax = p .adcMax /(2 *npts +1 );
221209 }
222210
223211
@@ -240,64 +228,99 @@ public int waveformCFAprocessing(AHDCPulse p){
240228 p .timeOverThreshold = -9999 ;
241229
242230 if (p .binMax < 0 ) return 0 ;
243-
244- //Set the CFA threshold
245- float threshold = Math .min (this .amplitudeFractionCFA *p .adcMax , p .samples [p .binMax ]);
246-
247- //Crossing the threshold before the peak
248- int binRise = -99 ;
249- for (int bin = 0 ; bin < p .binMax - 1 ; bin ++){
250- if (p .samples [bin ] < threshold && p .samples [bin +1 ] >= threshold )
251- binRise = bin ; //Here we keep only the last time the signal crosses the threshold
252- }
253- //If the waveform does not cross the ths before the peak
254- //it was early or remant from a previous event and we cannot define a leading time
255- //we set the time at zero
256- if (binRise ==-99 ) {
257- this .assignValidType (5 , p );
258- p .leadingEdgeTime = (0 + p .time_ZS )*this .samplingTime ;
231+
232+ // update adcMax for saturated signals
233+ float slope_max = 0 ;
234+ int bin_slope_max = -1 ;
235+ if (p .wftype == 1 ) {
236+ for (int bin = 0 ; bin < p .binMax ; bin ++) {
237+ float slope = (p .samples [bin +1 ] - p .samples [bin ])/samplingTime ;
238+ if (slope > slope_max ) {
239+ slope_max = slope ;
240+ bin_slope_max = bin ;
241+ }
242+ }
243+ // update adcMax: empirical formula
244+ p .adcMax = -16.371574f + 191.277306f *slope_max ;
259245 }
260- else
261- {
246+
247+ // threshold
248+ float threshold = this .amplitudeFractionCFA *p .adcMax ;
249+
250+ if (threshold < ADC_LIMIT ) {
251+
252+ //Crossing the threshold before the peak
253+ int binRise = -99 ;
262254 float slopeRise = 0 ;
263- //linear interpolation
264- //threshold = leadingtime*(ADC1-ADC0)+ADC0
265- if (binRise + 1 <= p .numberOfBins -1 )
266- slopeRise = p .samples [binRise +1 ] - p .samples [binRise ];
267- float fittedBinRise = (slopeRise == 0 ) ? binRise : binRise + (threshold - p .samples [binRise ])/slopeRise ;
268- p .leadingEdgeTime = (fittedBinRise + p .time_ZS )*this .samplingTime ;
269- }
270-
271- //Crossing the threshold back down after the peak
272- int binFall = -99 ;
273- for (int bin = p .binMax ; bin < p .numberOfBins -1 ; bin ++){
274- if (p .samples [bin ] > threshold
275- && p .samples [bin +1 ] <= threshold
276- && p .samples [bin ]>0
277- && p .samples [bin +1 ]>0 ){
278- binFall = bin +1 ;
279- break ; //We keep only the first time the signal crosses back the threshold
255+ for (int bin = 0 ; bin < p .binMax - 1 ; bin ++){
256+ if (p .samples [bin ] < threshold && p .samples [bin +1 ] >= threshold && p .samples [bin +1 ] < ADC_LIMIT ) {
257+ binRise = bin ; //Here we keep only the last time the signal crosses the threshold
258+ slopeRise = p .samples [binRise +1 ] - p .samples [binRise ];
259+ }
260+ else if (bin > 0 && p .samples [bin ] < threshold && p .samples [bin +1 ] >= threshold ) { // we enter here if p.samples[bin+1] >= ADC_LIMIT; in that scenario, the slope is underestimated
261+ binRise = bin ;
262+ slopeRise = p .samples [binRise ] - p .samples [binRise -1 ]; // we extrapolate using the previous slope
263+ }
264+ }
265+ //If the waveform does not cross the ths before the peak
266+ //it was early or remant from a previous event and we cannot define a leading time
267+ //we set the time at zero
268+ if (binRise ==-99 ) {
269+ this .assignValidType (5 , p );
270+ p .leadingEdgeTime = (0 + p .time_ZS )*this .samplingTime ;
271+ }
272+ else
273+ {
274+ //linear interpolation
275+ //threshold = leadingtime*(ADC1-ADC0)+ADC0
276+ float fittedBinRise = (slopeRise == 0 ) ? binRise : binRise + (threshold - p .samples [binRise ])/slopeRise ;
277+ p .leadingEdgeTime = (fittedBinRise + p .time_ZS )*this .samplingTime ;
278+ }
279+
280+ //Crossing the threshold back down after the peak
281+ int binFall = -99 ;
282+ for (int bin = p .binMax ; bin < p .numberOfBins -1 ; bin ++){
283+ if (p .samples [bin ] > threshold
284+ && p .samples [bin +1 ] <= threshold
285+ && p .samples [bin ]>0
286+ && p .samples [bin +1 ]>0 ){
287+ binFall = bin +1 ;
288+ break ; //We keep only the first time the signal crosses back the threshold
289+ }
290+ }
291+ //If the waveform does not cross the ths again
292+ //it was late and falling edge cannot be defined
293+ //the time correspond to the end of the signal
294+ if (binFall ==-99 ) {
295+ this .assignValidType (2 , p );
296+ p .trailingEdgeTime = (p .effectiveNumberOfBins -1 + p .time_ZS )*this .samplingTime ;
297+ }
298+ else
299+ {
300+ float slopeFall = 0 ;
301+ if (binFall - 1 >= 0 )
302+ slopeFall = p .samples [binFall ] - p .samples [binFall -1 ];
303+ float fittedBinFall = (slopeFall == 0 ) ? binFall : binFall -1 + (threshold - p .samples [binFall -1 ])/slopeFall ;
304+ p .trailingEdgeTime = (fittedBinFall + p .time_ZS )*this .samplingTime ;
305+ }
306+
307+ p .timeOverThreshold = p .trailingEdgeTime - p .leadingEdgeTime ;
308+ //if ((this.pulse.timeOverThreshold < 300) || (this.pulse.timeOverThreshold > 750)) this.assignValidType(4); // bad tot
309+ if (p .timeOverThreshold < 300 ) this .assignValidType (4 , p ); // tot too small
310+ }
311+ else { // there are necessary type 1, so we use the slope_max
312+ if (p .wftype == 1 ) {
313+ // extraplote the leading edge of the signal using the slope: caution, slope_max is in ADC/ns
314+ float extrapolatedTime = (threshold -p .samples [bin_slope_max ])/slope_max + samplingTime *bin_slope_max ;
315+ p .leadingEdgeTime = extrapolatedTime + p .time_ZS *samplingTime ;
316+ p .timeOverThreshold = p .effectiveNumberOfBins *samplingTime - extrapolatedTime ;
317+ } else { // unexpected behavior
318+ p .leadingEdgeTime = 0 ;
319+ p .timeOverThreshold = 0 ;
280320 }
281321 }
282- //If the waveform does not cross the ths again
283- //it was late and falling edge cannot be defined
284- //the time correspond to the end of the signal
285- if (binFall ==-99 ) {
286- this .assignValidType (2 , p );
287- p .trailingEdgeTime = (p .effectiveNumberOfBins -1 + p .time_ZS )*this .samplingTime ;
288- }
289- else
290- {
291- float slopeFall = 0 ;
292- if (binFall - 1 >= 0 )
293- slopeFall = p .samples [binFall ] - p .samples [binFall -1 ];
294- float fittedBinFall = (slopeFall == 0 ) ? binFall : binFall -1 + (threshold - p .samples [binFall -1 ])/slopeFall ;
295- p .trailingEdgeTime = (fittedBinFall + p .time_ZS )*this .samplingTime ;
296- }
297322
298- p .timeOverThreshold = p .trailingEdgeTime - p .leadingEdgeTime ;
299- //if ((this.pulse.timeOverThreshold < 300) || (this.pulse.timeOverThreshold > 750)) this.assignValidType(4); // bad tot
300- if (p .timeOverThreshold < 300 ) this .assignValidType (4 , p ); // tot too small
323+
301324
302325 return 0 ;
303326 }
0 commit comments