Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Df125EmulatorAlgorithm_v2.cc
Go to the documentation of this file.
2 
3 // Some masks that are useful for getting data from BORConfig registers
4 // from fa125Lib.h
5 /* 0x1058 FE nw register defintions */
6 #define FA125_FE_NW_MASK 0x000003FF
7 /* 0x105C FE pl register defintions */
8 #define FA125_FE_PL_MASK 0x0000FFFF
9 /* 0xN070 - 0xN084 threshold register defintions */
10 #define FA125_FE_THRESHOLD_MASK 0x00000FFF
11 /* 0xN0A0 FE ped_sf definitions */
12 #define FA125_FE_PED_SF_P1_MASK 0x000000FF
13 #define FA125_FE_PED_SF_P2_MASK 0x0000FF00
14 #define FA125_FE_PED_SF_IBIT_MASK 0x00070000
15 #define FA125_FE_PED_SF_ABIT_MASK 0x00380000
16 #define FA125_FE_PED_SF_PBIT_MASK 0x01C00000
17 #define FA125_FE_PED_SF_PBIT_SIGN (1<<25)
18 /* 0xN0A4 FE timing_thres definitions */
19 #define FA125_FE_TIMING_THRES_HI_MASK(x) (0x1FF<<((x%3)*9))
20 #define FA125_FE_TIMING_THRES_LO_MASK(x) (0xFF<<(8+((x%2)*16)))
21 /* 0xN0B0 FE integration_end definitions */
22 #define FA125_FE_IE_INTEGRATION_END_MASK 0x00000FFF
23 #define FA125_FE_IE_PEDESTAL_GAP_MASK 0x000FF000
24 
26 
27  // Normal use - BORConfig params are used if found. If not, default values are used
28  // EMULATION125:FORCE_DEFAULT_CDC=1 - use default values for CDC instead of BORConfig params
29  // EMULATION125:FORCE_DEFAULT_FDC=1 - use default values for FDC instead of BORConfig params
30  // Params in command line override both default and BORConfig
31  //
32  // eg EMULATION125:CDC_H=200 will cause the emulation to use CDC hit threshold=200, and either the BORConfig values (if present)
33  // or the default emulation parameter values for everything else.
34  //
35  // EMULATION125:CDC_H=200 used with EVIO:F125_EMULATION_MODE=1 will replace the firmware quantities with those emulated using CDC_H=200.
36  //
37 
38  // Enables forced use of default values
41 
42  // Default values for the essential parameters
43 
44  // PG or 'pedestal gap' is the number of samples between the end of the initial pedestal window and start of the hit search
45  // and also the number of samples between the local pedestal window and the hit threshold crossing sample
46 
47  // 2**P2 samples are summed to give the integrated local pedestal
48  // The firmware returns the (integrated local pedestal)>>(P2+PBIT)
49  // Firmware 2_00_F + accepts a negative value for PBIT, but the driver ensures that 3 >= PBIT >= -P2
50  // Using PBIT=-P2 obtains pedestal = P2 summed samples
51  // Using PBIT=0 obtains pedestal = mean of P2 samples
52 
53 
54  CDC_WS_DEF = 16; // hit window start - must be >= F125_CDC_NP
55  CDC_WE_DEF = 179; // hit window end - must be at least 20 less than number of samples available, eg WE=179 for 200 samples
56  CDC_IE_DEF = 200; // end integration at the earlier of WE, or this many samples after threshold crossing of TH
57  CDC_P1_DEF = 4; // 2**P1 = # samples used for initial pedestal, used to find hit
58  CDC_P2_DEF = 4; // 2**P2 = # samples used for pedestal calculated just before hit, and returned
59  CDC_PG_DEF = 4; // # samples between hit threshold crossing and local pedestal sample 'pedestal gap'
60  CDC_H_DEF = 125; // 5 sigma hit threshold
61  CDC_TH_DEF = 100; // 4 sigma high timing threshold
62  CDC_TL_DEF = 25; // 1 sigma low timing threshold
63 
64  CDC_IBIT_DEF = 4; // Scaling factor for integral
65  CDC_ABIT_DEF = 3; // Scaling factor for amplitude
66  CDC_PBIT_DEF = 0; // Scaling factor for pedestal
67 
68  FDC_WS_DEF = 16; // hit window start - must be >= F125_FDC_NP
69  FDC_WE_DEF = 59; // hit window end - must be at least 20 less than number of samples available, eg WE=59 for 80 samples
70  FDC_IE_DEF = 16; // end integration at the earlier of WE, or this many samples after threshold crossing of TH
71  FDC_P1_DEF = 4; // 2**P1 = # samples used for pedestal used to find hit
72  FDC_P2_DEF = 4; // 2**P2 = # samples used for pedestal calculated just before hit, and returned
73  FDC_PG_DEF = 4; // # samples between hit threshold crossing and local pedestal sample
74  FDC_H_DEF = 50; // 5 sigma hit threshold
75  FDC_TH_DEF = 40; // 4 sigma high timing threshold
76  FDC_TL_DEF = 10; // 1 sigma low timing threshold
77 
78  FDC_IBIT_DEF = 4; // Scaling factor for integral
79  FDC_ABIT_DEF = 0; // Scaling factor for amplitude
80  FDC_PBIT_DEF = 0; // Scaling factor for pedestal
81 
82 
83  // Default values for parameters which can be set in the command line
84  // The parameters are ignored if their value is negative or for IBIT, below -7.
85  // If set in the command line, they override both BORConfig and the default parameter values above
86  // The default parameters above are used if BORConfig is not found and there are no command line parameter overrides
87 
88  CDC_WS = -9; // hit window start - must be >= F125_CDC_NP
89  CDC_WE = -9; // hit window end - must be at least 20 less than number of samples available, eg WE=179 for 200 samples
90  CDC_IE = -9; // end integration at the earlier of WE, or this many samples after threshold crossing of TH
91  CDC_P1 = -9; // 2**P1 = # samples used for initial pedestal, used to find hit
92  CDC_P2 = -9; // 2**P2 = # samples used for pedestal calculated just before hit, and returned
93  CDC_PG = -9; // # samples between hit threshold crossing and local pedestal sample 'pedestal gap'
94  CDC_H = -9; // 5 sigma hit threshold
95  CDC_TH = -9; // 4 sigma high timing threshold
96  CDC_TL = -9; // 1 sigma low timing threshold
97 
98  CDC_IBIT = -9; // Scaling factor for integral
99  CDC_ABIT = -9; // Scaling factor for amplitude
100  CDC_PBIT = -9; // Scaling factor for pedestal
101 
102 
103  FDC_WS = -9; // hit window start - must be >= F125_FDC_NP
104  FDC_WE = -9; // hit window end - must be at least 20 less than number of samples available, eg WE=179 for 200 samples
105  FDC_IE = -9; // end integration at the earlier of WE, or this many samples after threshold crossing of TH
106  FDC_P1 = -9; // 2**P1 = # samples used for initial pedestal, used to find hit
107  FDC_P2 = -9; // 2**P2 = # samples used for pedestal calculated just before hit, and returned
108  FDC_PG = -9; // # samples between hit threshold crossing and local pedestal sample 'pedestal gap'
109  FDC_H = -9; // 5 sigma hit threshold
110  FDC_TH = -9; // 4 sigma high timing threshold
111  FDC_TL = -9; // 1 sigma low timing threshold
112 
113  FDC_IBIT = -9; // Scaling factor for integral
114  FDC_ABIT = -9; // Scaling factor for amplitude
115  FDC_PBIT = -9; // Scaling factor for pedestal
116 
117 
118 
119  // Set verbosity
120  VERBOSE = 0;
121 
122  if(gPARMS){
123  gPARMS->SetDefaultParameter("EMULATION125:FORCE_DEFAULT_CDC", FORCE_DEFAULT_CDC,"Set to >0 to force use of CDC default values");
124  gPARMS->SetDefaultParameter("EMULATION125:FORCE_DEFAULT_FDC", FORCE_DEFAULT_FDC,"Set to >0 to force use of FDC default values");
125  gPARMS->SetDefaultParameter("EMULATION125:CDC_WS", CDC_WS, "Set CDC_WS for firmware emulation, will be overwritten by BORConfig if present");
126  gPARMS->SetDefaultParameter("EMULATION125:CDC_WE", CDC_WE, "Set CDC_WE for firmware emulation, will be overwritten by BORConfig if present");
127  gPARMS->SetDefaultParameter("EMULATION125:CDC_IE", CDC_IE, "Set CDC_IE for firmware emulation, will be overwritten by BORConfig if present");
128  gPARMS->SetDefaultParameter("EMULATION125:CDC_P1", CDC_P1, "Set CDC_P1 for firmware emulation, will be overwritten by BORConfig if present");
129  gPARMS->SetDefaultParameter("EMULATION125:CDC_P2", CDC_P2, "Set CDC_P2 for firmware emulation, will be overwritten by BORConfig if present");
130  gPARMS->SetDefaultParameter("EMULATION125:CDC_PG", CDC_PG, "Set CDC_PG for firmware emulation, will be overwritten by BORConfig if present");
131  gPARMS->SetDefaultParameter("EMULATION125:CDC_H", CDC_H, "Set CDC_H (hit threshold) for firmware emulation, will be overwritten by BORConfig if present");
132  gPARMS->SetDefaultParameter("EMULATION125:CDC_TH", CDC_TH, "Set CDC_TH for firmware emulation, will be overwritten by BORConfig if present");
133  gPARMS->SetDefaultParameter("EMULATION125:CDC_TL", CDC_TL, "Set CDC_TL for firmware emulation, will be overwritten by BORConfig if present");
134  gPARMS->SetDefaultParameter("EMULATION125:CDC_IBIT",CDC_IBIT,"Set CDC_IBIT for firmware emulation, will be overwritten by BORConfig if present");
135  gPARMS->SetDefaultParameter("EMULATION125:CDC_ABIT",CDC_ABIT,"Set CDC_ABIT for firmware emulation, will be overwritten by BORConfig if present");
136  gPARMS->SetDefaultParameter("EMULATION125:CDC_PBIT",CDC_PBIT,"Set CDC_PBIT for firmware emulation, will be overwritten by BORConfig if present");
137  gPARMS->SetDefaultParameter("EMULATION125:FDC_WS", FDC_WS, "Set FDC_WS for firmware emulation, will be overwritten by BORConfig if present");
138  gPARMS->SetDefaultParameter("EMULATION125:FDC_WE", FDC_WE, "Set FDC_WE for firmware emulation, will be overwritten by BORConfig if present");
139  gPARMS->SetDefaultParameter("EMULATION125:FDC_IE", FDC_IE, "Set FDC_IE for firmware emulation, will be overwritten by BORConfig if present");
140  gPARMS->SetDefaultParameter("EMULATION125:FDC_P1", FDC_P1, "Set FDC_P1 for firmware emulation, will be overwritten by BORConfig if present");
141  gPARMS->SetDefaultParameter("EMULATION125:FDC_P2", FDC_P2, "Set FDC_P2 for firmware emulation, will be overwritten by BORConfig if present");
142  gPARMS->SetDefaultParameter("EMULATION125:FDC_PG", FDC_PG, "Set FDC_PG for firmware emulation, will be overwritten by BORConfig if present");
143  gPARMS->SetDefaultParameter("EMULATION125:FDC_H", FDC_H, "Set FDC_H (hit threshold) for firmware emulation, will be overwritten by BORConfig if present");
144  gPARMS->SetDefaultParameter("EMULATION125:FDC_TH", FDC_TH, "Set FDC_TH for firmware emulation, will be overwritten by BORConfig if present");
145  gPARMS->SetDefaultParameter("EMULATION125:FDC_TL", FDC_TL, "Set FDC_TL for firmware emulation, will be overwritten by BORConfig if present");
146  gPARMS->SetDefaultParameter("EMULATION125:FDC_IBIT",FDC_IBIT,"Set FDC_IBIT for firmware emulation, will be overwritten by BORConfig if present");
147  gPARMS->SetDefaultParameter("EMULATION125:FDC_ABIT",FDC_ABIT,"Set FDC_ABIT for firmware emulation, will be overwritten by BORConfig if present");
148  gPARMS->SetDefaultParameter("EMULATION125:FDC_PBIT",FDC_PBIT,"Set FDC_PBIT for firmware emulation, will be overwritten by BORConfig if present");
149  gPARMS->SetDefaultParameter("EMULATION125:VERBOSE", VERBOSE,"Set verbosity for f125 emulation");
150  }
151 }
152 
154 
155  if (VERBOSE > 0) {
156  jout << "=== Entering f125 Firmware Emulation === ROCID: " << rawData->rocid << " SLOT: " << rawData->slot << " CHANNEL: " << rawData->channel <<endl;
157  }
158 
159  // This is the main routine called by JEventSource_EVIO::GetObjects() and serves as the entry point for the code.
160  bool isCDC = cdcPulse != NULL ? true : false;
161  bool isFDC = fdcPulse != NULL ? true : false;
162 
163  if (isCDC && isFDC){
164  jout << " Df125EmulatorAlgorithm_v2::EmulateFirmware Both FDC and CDC words present??? " << endl;
165  return;
166  } else if (!isCDC && !isFDC){
167  jout << " Df125EmulatorAlgorithm_v2::EmulateFirmware Neither FDC or CDC words present??? " << endl;
168  return;
169  }
170 
171  // channel is needed for the config lookup
172  uint32_t channel = rawData->channel;
173 
174  // The following are the essential values needed for the emulation
175  // (will use ROOT types since that is what the existing f125_algos code uses)
176  Int_t WS=0,WE=0,IE=0,P1=0,P2=0,PG=0,H=0,TH=0,TL=0;
177  Int_t IBIT=0, ABIT=0, PBIT=0;
178 
179  Int_t NE = 20; // This is a hardcoded constant in the firmware WE = NW - NE - 1
180 
181  // Field max (saturation) values
182 
183  Int_t CDC_IMAX = 16383; //field max for integral
184  Int_t CDC_AMAX = 511; //field max for max amp
185  Int_t CDC_PMAX = 255; //field max for pedestal
186  Int_t CDC_OMAX = 7; // field max for overflows
187 
188  Int_t FDC_IMAX = 4095; //field max for integral
189  Int_t FDC_AMAX = 4095; //field max for max amp
190  Int_t FDC_PMAX = 2047; //field max for pedestal
191  Int_t FDC_OMAX = 7; // field max for overflows
192 
193 
194  // Now try to get the configuration form the BOR record, if this does not exist,
195  // or is forced, use the default values.
196  const Df125BORConfig *BORConfig = NULL;
197  //rawData->GetSingle(BORConfig); // DEBUG
198 
199  if(BORConfig != NULL){
200  if (VERBOSE > 0) jout << "--Found BORConfig" << endl;
201  Int_t NW = BORConfig->fe[0].nw;
202  P1 = BORConfig->fe[0].ped_sf & FA125_FE_PED_SF_P1_MASK;
203  P2 = (BORConfig->fe[0].ped_sf & FA125_FE_PED_SF_P2_MASK) >> 8;
204  if (NW != Int_t(rawData->samples.size())) jout << "WARNING Df125EmulatorAlgorithm_v2::EmulateFirmware NW != rawData->samples.size()" << endl;
205  WE = NW - NE - 1;
206  IE = BORConfig->fe[0].ie & FA125_FE_IE_INTEGRATION_END_MASK;
207  PG = (BORConfig->fe[0].ie & FA125_FE_IE_PEDESTAL_GAP_MASK) >> 12;
208  WS = 1<<P1;
209  H = BORConfig->fe[channel/6].threshold[channel%6] & FA125_FE_THRESHOLD_MASK;
210  TH = (BORConfig->fe[channel/6].timing_thres_hi[(channel/3)%2] & FA125_FE_TIMING_THRES_HI_MASK(channel)) >> ((channel%3) * 9);
211  TL = (BORConfig->fe[channel/6].timing_thres_lo[(channel/2)%3] & FA125_FE_TIMING_THRES_LO_MASK(channel)) >> ((channel%2) * 16 + 8);
212  IBIT = (BORConfig->fe[0].ped_sf & FA125_FE_PED_SF_IBIT_MASK)>>16;
213  ABIT = (BORConfig->fe[0].ped_sf & FA125_FE_PED_SF_ABIT_MASK)>>19;
214  PBIT = (BORConfig->fe[0].ped_sf & FA125_FE_PED_SF_PBIT_MASK)>>22;
215  if (BORConfig->fe[0].ped_sf & FA125_FE_PED_SF_PBIT_MASK) PBIT = -1*PBIT;
216  }
217 
218  // Set defaults if BORConfig missing or if forced
219  if( isCDC && ((BORConfig == NULL) || FORCE_DEFAULT_CDC) ){
220  if (VERBOSE > 0) jout << "WARNING Df125EmulatorAlgorithm_v2::EmulateFirmware Using CDC Default values" << endl;
221  WS = CDC_WS_DEF;
222  WE = CDC_WE_DEF;
223  IE = CDC_IE_DEF;
224  P1 = CDC_P1_DEF;
225  P2 = CDC_P2_DEF;
226  PG = CDC_PG_DEF;
227  H = CDC_H_DEF;
228  TH = CDC_TH_DEF;
229  TL = CDC_TL_DEF;
230  IBIT= CDC_IBIT_DEF;
231  ABIT= CDC_ABIT_DEF;
232  PBIT= CDC_PBIT_DEF;
233  }
234 
235 
236 
237  //Set override params if given in command line PBIT can be negative
238  if ( isCDC ) {
239  if (VERBOSE > 0) jout << "WARNING Df125EmulatorAlgorithm_v2::EmulateFirmware Using CDC override values" << endl;
240  if (CDC_WS >= 0) WS = CDC_WS;
241  if (CDC_WE >= 0) WE = CDC_WE;
242  if (CDC_IE >= 0) IE = CDC_IE;
243  if (CDC_P1 >= 0) P1 = CDC_P1;
244  if (CDC_P2 >= 0) P2 = CDC_P2;
245  if (CDC_PG >= 0) PG = CDC_PG;
246  if (CDC_H >= 0) H = CDC_H;
247  if (CDC_TH >= 0) TH = CDC_TH;
248  if (CDC_TL >= 0) TL = CDC_TL;
249  if (CDC_IBIT >= 0) IBIT = CDC_IBIT;
250  if (CDC_ABIT >= 0) ABIT = CDC_ABIT;
251  if (CDC_PBIT >= -7) PBIT = CDC_PBIT;
252  }
253 
254 
255  if( isFDC && ((BORConfig == NULL) || FORCE_DEFAULT_FDC) ){
256  if (VERBOSE > 0) jout << "WARNING Df125EmulatorAlgorithm_v2::EmulateFirmware Using FDC Default values" << endl;
257  WS = FDC_WS_DEF;
258  WE = FDC_WE_DEF;
259  IE = FDC_IE_DEF;
260  P1 = FDC_P1_DEF;
261  P2 = FDC_P2_DEF;
262  PG = FDC_PG_DEF;
263  H = FDC_H_DEF;
264  TH = FDC_TH_DEF;
265  TL = FDC_TL_DEF;
266  IBIT= FDC_IBIT_DEF;
267  ABIT= FDC_ABIT_DEF;
268  PBIT= FDC_PBIT_DEF;
269  }
270 
271 
272  //Set override params if given in command line PBIT can be -ve
273  if ( isFDC ) {
274  if (VERBOSE > 0) jout << "WARNING Df125EmulatorAlgorithm_v2::EmulateFirmware Using FDC override values" << endl;
275  if (FDC_WS >= 0) WS = FDC_WS;
276  if (FDC_WE >= 0) WE = FDC_WE;
277  if (FDC_IE >= 0) IE = FDC_IE;
278  if (FDC_P1 >= 0) P1 = FDC_P1;
279  if (FDC_P2 >= 0) P2 = FDC_P2;
280  if (FDC_PG >= 0) PG = FDC_PG;
281  if (FDC_H >= 0) H = FDC_H;
282  if (FDC_TH >= 0) TH = FDC_TH;
283  if (FDC_TL >= 0) TL = FDC_TL;
284  if (FDC_IBIT >= 0) IBIT = FDC_IBIT;
285  if (FDC_ABIT >= 0) ABIT = FDC_ABIT;
286  if (FDC_PBIT >= -7) PBIT = FDC_PBIT;
287  }
288 
289 
290 
291  if (VERBOSE > 0) {
292  jout << "============ Parameters used for emulation ================" << endl;
293  jout << "WS: " << WS << " WE: " << WE << " IE: " << IE << " P1: " << P1 << " P2: " << P2 << endl;
294  jout << "PG: " << PG << " H: " << H << " TH: " << TH << " TL: " << TL << endl;
295  jout << "IBIT: " << IBIT << " ABIT: " << ABIT << " PBIT: " << PBIT << endl;
296  }
297 
298  // The calculated quantities are passed by reference
299  Int_t time=0, q_code=0, pedestal=0, overflows=0, maxamp=0, pktime=0;
300  Long_t integral=0;
301 
302 
303 
304  // Perform the emulation
305  fa125_algos(time, q_code, pedestal, integral, overflows, maxamp, pktime, &rawData->samples[0], WS, WE, IE, P1, P2, PG, H, TH, TL);
306 
307  // Scale down
308 
309  integral = integral >> IBIT;
310  maxamp = maxamp >> ABIT;
311  pedestal = pedestal >> (P2 + PBIT);
312 
313 
314  // Put the emulated values in the objects
315  if (isCDC){
316  cdcPulse->le_time_emulated = time;
317  cdcPulse->time_quality_bit_emulated = q_code;
318  cdcPulse->overflow_count_emulated = ( overflows > CDC_OMAX) ? CDC_OMAX : overflows;
319  cdcPulse->pedestal_emulated = ( pedestal > CDC_PMAX ) ? CDC_PMAX : pedestal;
320  cdcPulse->integral_emulated = ( integral > CDC_IMAX ) ? CDC_IMAX : integral;
321  cdcPulse->first_max_amp_emulated = ( maxamp > CDC_AMAX ) ? CDC_AMAX : maxamp;
322  }
323  else{
324  fdcPulse->le_time_emulated = time;
325  fdcPulse->time_quality_bit_emulated = q_code;
326  fdcPulse->overflow_count_emulated = ( overflows > FDC_OMAX) ? FDC_OMAX : overflows;
327  fdcPulse->pedestal_emulated = ( pedestal > FDC_PMAX ) ? FDC_PMAX : pedestal;
328  fdcPulse->integral_emulated = ( integral > FDC_IMAX ) ? FDC_IMAX : integral;
329  fdcPulse->peak_amp_emulated = ( maxamp > FDC_AMAX ) ? FDC_AMAX : maxamp;
330  fdcPulse->peak_time_emulated = pktime;
331  }
332 
333  // Copy the emulated values to the main values if needed
334  if (isCDC && cdcPulse->emulated){
335  cdcPulse->le_time = cdcPulse->le_time_emulated;
336  cdcPulse->time_quality_bit = cdcPulse->time_quality_bit_emulated;
337  cdcPulse->overflow_count = cdcPulse->overflow_count_emulated;
338  cdcPulse->pedestal = cdcPulse->pedestal_emulated;
339  cdcPulse->integral = cdcPulse->integral_emulated;
340  cdcPulse->first_max_amp = cdcPulse->first_max_amp_emulated;
341  }
342  else if (isFDC && fdcPulse->emulated){
343  fdcPulse->le_time = fdcPulse->le_time_emulated;
344  fdcPulse->time_quality_bit = fdcPulse->time_quality_bit_emulated;
345  fdcPulse->overflow_count = fdcPulse->overflow_count_emulated;
346  fdcPulse->pedestal = fdcPulse->pedestal_emulated;
347  fdcPulse->integral = fdcPulse->integral_emulated;
348  fdcPulse->peak_amp = fdcPulse->peak_amp_emulated;
349  fdcPulse->peak_time = fdcPulse->peak_time_emulated;
350  }
351 
352  if (VERBOSE > 0) jout << "=== Exiting f125 Firmware Emulation === " << endl;
353 
354  return;
355 }
356 
357 void Df125EmulatorAlgorithm_v2::fa125_algos(Int_t &time, Int_t &q_code, Int_t &pedestal, Long_t &integral, Int_t &overflows, Int_t &maxamp, Int_t &pktime, const uint16_t adc[], Int_t WINDOW_START, Int_t WINDOW_END, Int_t INT_END, Int_t P1, Int_t P2, Int_t PG, Int_t HIT_THRES, Int_t HIGH_THRESHOLD, Int_t LOW_THRESHOLD) {
358 
359  const Int_t NU = 20; //number of samples sent to time algo
360  const Int_t PED = 5; //sample to be used as pedestal for timing is in place 5
361 
362  const Int_t XTHR_SAMPLE = PED + PG;
363  Int_t adc_subset[NU];
364 
365  Int_t hitfound=0; //hit found or not (1=found,0=not)
366  Int_t hitsample=-1; // if hit found, sample number of threshold crossing
367  Int_t timesample=0;
368 
369  Int_t i=0;
370 
371  time=0; // hit time in 0.1xsamples since start of buffer passed to fa125_time
372  q_code=-1; // quality code, 0=good, 1=returned rough estimate
373  pedestal=0; // pedestal just before hit
374  integral=0; // signal integral, total
375  overflows=0; // count of samples with overflow bit set (need raw data, not possible from my root files)
376  maxamp=0; // signal amplitude at first max after hit
377  pktime=0; // sample number containing maxamp
378 
379  // look for hit using mean pedestal of NPED samples before trigger
380  fa125_hit(hitfound, hitsample, pedestal, adc, WINDOW_START, WINDOW_END, HIT_THRES, P1, P2, PG);
381 
382  if (hitfound==1) {
383  for (i=0; i<NU; i++) {
384  adc_subset[i] = adc[hitsample+i-XTHR_SAMPLE];
385  }
386 
387  fa125_time(time, q_code, adc_subset, NU, PG, HIGH_THRESHOLD, LOW_THRESHOLD);
388 
389  timesample = hitsample-XTHR_SAMPLE + (Int_t)(0.1*time); //sample number containing leading edge sample
390 
391  fa125_integral(integral, overflows, timesample, adc, WINDOW_END, INT_END);
392 
393  fa125_max(maxamp, pktime, timesample, adc, WINDOW_END);
394 
395  time = 10*(hitsample-XTHR_SAMPLE) + time; // integer number * 0.1 samples
396  }
397 }
398 
399 void Df125EmulatorAlgorithm_v2::fa125_hit(Int_t &hitfound, Int_t &hitsample, Int_t &pedestal, const uint16_t adc[], Int_t WINDOW_START, Int_t WINDOW_END, Int_t HIT_THRES, Int_t P1, Int_t P2, Int_t PG) {
400 
401  pedestal=0; //pedestal
402  Int_t threshold=0;
403  Int_t i=0;
404 
405  Int_t NPED = 1<<P1;
406  Int_t NPED2 = 1<<P2;
407 
408  // calc pedestal as mean of NPED samples before trigger
409  for (i=0; i<NPED; i++) {
410  pedestal += adc[WINDOW_START-NPED+i];
411  }
412 
413  pedestal = pedestal>>P1;
414  threshold = pedestal + HIT_THRES;
415 
416 
417 
418  // look for threshold crossing
419  i = WINDOW_START - 1 + PG;
420  hitfound = 0;
421 
422  while ((hitfound==0) && (i<WINDOW_END-1)) {
423  i++;
424  if (adc[i] >= threshold) {
425  if (adc[i+1] >= threshold) {
426  hitfound = 1;
427  hitsample = i;
428  }
429  }
430  }
431 
432 
433  if (hitfound == 1) {
434  //calculate INTEGRATED pedestal ending just before the hit (this is rightshifted by P2+PBIT later on)
435  pedestal = 0;
436  for (i=0; i<NPED2; i++) {
437  pedestal += adc[hitsample-PG-i];
438  }
439  }
440 
441 
442 }
443 
444 void Df125EmulatorAlgorithm_v2::fa125_integral(Long_t& integral, Int_t& overflows, Int_t timesample, const uint16_t adc[], Int_t WINDOW_END, Int_t INT_END) {
445 
446  Int_t i=0;
447 
448  integral = 0;
449  overflows = 0;
450 
451  if (timesample <= WINDOW_END) {
452 
453  Int_t lastsample = timesample + INT_END - 1;
454 
455  if (lastsample > WINDOW_END) lastsample = WINDOW_END;
456 
457  for (i = timesample; i <= lastsample; i++ ) {
458 
459  integral += (Long_t)adc[i];
460  if (adc[i]==(Long_t)4095) overflows++;
461 
462  }
463 
464  }
465 
466 }
467 
468 void Df125EmulatorAlgorithm_v2::fa125_max(Int_t& maxamp, Int_t &maxsample, Int_t hitsample, const uint16_t adc[], Int_t WINDOW_END) {
469 
470  int i;
471  int ndec = 0; //number of decreasing samples
472 
473  //make sure we are on an up-slope
474 
475  while ((adc[hitsample] <= adc[hitsample-1]) && (hitsample <= WINDOW_END)) hitsample++;
476 
477  maxamp = adc[hitsample];
478  maxsample = hitsample;
479 
480  for (i=hitsample; i<=WINDOW_END; i++) {
481 
482  if (adc[i] > adc[i-1]) {
483  maxamp = adc[i];
484  maxsample = i;
485  ndec = 0;
486  }
487 
488  if (adc[i] <= adc[i-1]) ndec++;
489  if (ndec==2) break;
490  }
491 
492  if (hitsample >= WINDOW_END) {
493  maxamp = adc[WINDOW_END];
494  maxsample = WINDOW_END;
495  }
496 
497 }
498 
499 void Df125EmulatorAlgorithm_v2::fa125_time(Int_t &le_time, Int_t &q_code, Int_t adc[], Int_t NU, Int_t PG, Int_t THRES_HIGH, Int_t THRES_LOW) {
500 
501  // adc[NU] array of samples
502  // NU=20 size of array
503  // PG pedestal gap - hit threshold crossing is PG samples after adc[PED] - the single sample to be used as pedestal here
504  // THRES_HIGH high timing threshold (eg 4 x pedestal-width )
505  // THRES_LOW high timing threshold (eg 1 x pedestal-width )
506  //
507  // le_time leading edge time as 0.1x number of samples since first sample supplied
508  // q_code quality code, 0=good, >0=rough estimate (firmware returns 0=good, 1=not so good)
509  //
510  // q_code Time returned Condition
511  // 0 Leading edge time Good
512  // 1 X*10 - 29 Sample value of 0 found
513  // 1 X*10 - 28 Sample value greater than PED_MAX found in adc[0 to PED]
514  // 1 X*10 - 27 Sample values lie below the high timing threshold
515  // 1 TCL*10 + 4 Low timing threshold crossing sample TCL occurs too late to upsample
516  // 1 TCL*10 + 5 One or more upsampled values are negative
517  // 1 TCL*10 + 9 The upsampled values are too low
518  //
519  const Int_t NUPSAMPLED = 6; // number of upsampled values to calculate, minimum is 6
520  const Int_t SET_ADC_MIN = 20; // adjust adc values so that the min is at 20
521  const Int_t LIMIT_PED_MAX = 511; // max acceptable value in adc[0 to PED]
522  const Int_t PED = 5; // take local pedestal to be adc[PED]
523 
524  const Int_t START_SEARCH = PED+1; // -- start looking for hi threshold xing with this sample
525 
526  const Int_t X = PED + PG; // hit threshold crossing sample is adc[X]
527  const Int_t ROUGH_TIME = (X*10)-30; // -- add onto this to return rough time estimates
528 
529  Int_t iubuf[NUPSAMPLED] = {0}; // array of upsampled values; iubuf[0] maps to low thres xing sample
530 
531  Int_t adc_thres_hi = 0; // high threshold
532  Int_t adc_thres_lo = 0; // low threshold
533 
534  // -- contributions to hit time, these are summed together eventually, units of sample/10
535  Int_t itime1 = 0; // which sample
536  Int_t itime2 = 0; // which minisample
537  Int_t itime3 = 0; // correction from interpolation
538 
539  // -- search vars
540  Int_t adc_sample_hi = 0; // integer range 0 to NU := 0; --sample number for adc val at or above hi thres
541  Int_t adc_sample_lo = 0; // integer range 0 to NU := 0; -- sample num for adc val at or below lo thres
542  Int_t adc_sample_lo2 = 0; // integer range 0 to 12:= 0; -- minisample num for adc val at or below lo thres
543 
544  Bool_t over_threshold = kFALSE;
545  Bool_t below_threshold = kFALSE;
546 
547  // upsampling checks
548  Int_t ups_adjust = 0;
549  Int_t i = 0;
550 
551 
552  //check all samples are >0
553  //check all samples from 0 to pedestal are <= LIMIT_PED_MAX
554  //adc=zero and pedestal limit checks are in same fadc clock cycle
555 
556  while (i<NU) {
557  if (adc[i] == 0) {
558  le_time = ROUGH_TIME + 1;
559  q_code = 1;
560  }
561 
562  if ((i < PED+1) && (adc[i] > LIMIT_PED_MAX)) {
563  le_time = ROUGH_TIME + 2;
564  q_code = 2;
565  }
566  i++;
567  }
568 
569  if (q_code>0) return;
570 
571 
572 
573  // add offset to move min val in subset equal to SET_ADC_MIN
574  // this is to move samples away from 0 to avoid upsampled pts going -ve (on a curve betw 2 samples)
575  Int_t adcmin = 4095;
576  i=0;
577  while (i<NU) {
578  if (adc[i] < adcmin) {
579  adcmin = adc[i];
580  }
581  i++;
582  }
583 
584  Int_t adcoffset = SET_ADC_MIN - adcmin;
585  i=0;
586  while (i<NU) {
587  adc[i] = adc[i] + adcoffset;
588  if (adc[i] > 4095) adc[i] = 4095; //saturate
589  i++;
590  }
591 
592  // eg if adcmin is 100, setmin is 30, adcoffset = 30 - 100 = -70, move adc down by 70
593 
594  //////////////////////////////
595 
596  // calc thresholds
597  adc_thres_hi = adc[PED] + THRES_HIGH;
598  adc_thres_lo = adc[PED] + THRES_LOW;
599 
600  // search for high threshold crossing
601  over_threshold = kFALSE;
602  i = START_SEARCH;
603 
604  while ((!over_threshold)&&(i<NU)) {
605  if (adc[i] >= adc_thres_hi) {
606  adc_sample_hi = i;
607  over_threshold = kTRUE;
608  }
609  i++;
610  }
611 
612  if (!over_threshold) {
613  le_time = ROUGH_TIME + 3;
614  q_code = 3;
615  return;
616  }
617 
618  // search for low threshold crossing
619  below_threshold = kFALSE;
620  i = adc_sample_hi-1;
621 
622  while ((!below_threshold) && (i>=PED)) {
623  if (adc[i] <= adc_thres_lo) {
624  adc_sample_lo = i;
625  itime1 = i*10;
626  below_threshold = kTRUE;
627  }
628  i--;
629  }
630 
631  if (adc[adc_sample_lo] == adc_thres_lo) { // no need to upsample
632  le_time = itime1;
633  q_code = 0;
634  return;
635  }
636 
637  if (adc_sample_lo > NU-7) { // too late to upsample
638  le_time = itime1 + 4;
639  q_code = 4;
640  return;
641  }
642 
643  //upsample values from adc_sample_lo to adc_sample_lo + 1
644  upsamplei(adc, adc_sample_lo, iubuf, NUPSAMPLED);
645 
646  //check upsampled values are >0
647  Bool_t negups = kFALSE;
648  i=0;
649  while ((!negups)&&(i<NUPSAMPLED)) {
650  if (iubuf[i] < 0 ) {
651  negups = kTRUE;
652  }
653  i++;
654  }
655 
656  if (negups) {
657  le_time = itime1 + 5;
658  q_code = 5;
659  return;
660  }
661 
662  // correct errors
663  // iubuf[0] should be equal to adc[adc_sample_lo] and iubuf[5] should equal adc[adc_sample_lo+1]
664  // very steep pulse gradients cause errors in upsampling with larger errors in the later values
665  // match iubuf[0] to adc[adc_sample_lo] so that the threshold crossing must be at or after iubuf[0]
666  ups_adjust = iubuf[0] - adc[adc_sample_lo];
667 
668  // move threshold correspondingly instead of correcting upsampled values
669  adc_thres_lo = adc_thres_lo + ups_adjust;
670 
671  // check that threshold crossing lies within the range of iubuf[0 to 5]
672  if (iubuf[NUPSAMPLED-1]<= adc_thres_lo) { //bad upsampling
673  le_time = itime1 + 9; //midway
674  q_code = 6;
675  return;
676  }
677 
678  // search through upsampled array
679  below_threshold = kFALSE;
680  i = NUPSAMPLED-2;
681 
682  while ((!below_threshold) && (i>=0)) {
683  if (iubuf[i] <= adc_thres_lo) {
684  adc_sample_lo2 = i;
685  below_threshold = kTRUE;
686  }
687  i--;
688  }
689 
690  if (!below_threshold) { //upsampled points did not go below thres
691  printf("upsampled points did not go below threshold - should be impossible\n");
692  le_time = 0;
693  q_code = 9;
694  return;
695  }
696 
697  itime2 = adc_sample_lo2*2; // convert from sample/5 to sample/10
698 
699  //interpolate
700  itime3 = 0;
701  if (iubuf[adc_sample_lo2] != adc_thres_lo) {
702  if (2*adc_thres_lo >= iubuf[adc_sample_lo2] + iubuf[adc_sample_lo2+1]) itime3 = 1;
703  }
704  le_time = itime1 + itime2 + itime3; // -- this is time from first sample point, in 1/10ths of samples
705  q_code = 0;
706 }
707 
708 
709 void Df125EmulatorAlgorithm_v2::upsamplei(Int_t x[], Int_t startpos, Int_t z[], const Int_t NUPSAMPLED) {
710 
711  // x is array of samples
712  // z is array of upsampled data
713  // startpos is where to start upsampling in array x, only need to upsample a small region
714  const Int_t nz = NUPSAMPLED;
715 
716  Int_t k,j,dk;
717  const Int_t Kscale = 16384;
718  const Int_t K[43] = {-4, -9, -13, -10, 5, 37, 82, 124, 139, 102, -1, -161, -336, -455, -436, -212, 241, 886, 1623, 2309, 2795, 2971, 2795, 2309, 1623, 886, 241, -212, -436, -455, -336, -161, -1, 102, 139, 124, 82, 37, 5, -10, -13, -9, -4};
719 
720  //don't need to calculate whole range of k possible
721  //earliest value k=42 corresponds to sample 4.2
722  // k=43 sample 4.4
723  // k=46 sample 5.0
724 
725  // sample 4 (if possible) would be at k=41
726  // sample 4.2 k=42
727  // sample 5 k=46
728 
729  // sample x k=41 + (x-4)*5
730  // sample x-0.2 k=40 + (x-4)*5
731 
732  Int_t firstk = 41 + (startpos-4)*5;
733  for (k=firstk; k<firstk+nz; k++) {
734  dk = k - firstk;
735  z[dk]=0.0;
736  for (j=k%5;j<43;j+=5) {
737  z[dk] += x[(k-j)/5]*K[j];
738  }
739  // printf("dk %i z %i 5z %i 5z/scale %i\n",dk,z[dk],5.0*z[dk],5.0*z[dk]/Kscale);
740  z[dk] = (Int_t)(5*z[dk])/Kscale;
741  }
742 }
uint32_t first_max_amp
from second word
Definition: Df125CDCPulse.h:68
void fa125_time(Int_t &, Int_t &, Int_t[], Int_t, Int_t, Int_t, Int_t)
uint32_t threshold[6]
Definition: bor_roc.h:103
void fa125_max(Int_t &, Int_t &, Int_t, const uint16_t[], Int_t)
uint32_t time_quality_bit_emulated
emulated from raw data when available
Definition: Df125CDCPulse.h:75
#define FA125_FE_PED_SF_P2_MASK
uint32_t peak_time
from second word
Definition: Df125FDCPulse.h:73
#define FA125_FE_PED_SF_ABIT_MASK
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
#define FA125_FE_IE_INTEGRATION_END_MASK
void EmulateFirmware(const Df125WindowRawData *, Df125CDCPulse *, Df125FDCPulse *)
uint32_t peak_time_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:85
uint32_t peak_amp
from second word (type 9)
Definition: Df125FDCPulse.h:72
uint32_t pedestal
from second word
Definition: Df125CDCPulse.h:66
uint32_t integral
from second word (type 6)
Definition: Df125FDCPulse.h:71
f125config_fe fe[12]
Definition: bor_roc.h:127
uint32_t timing_thres_hi[2]
Definition: bor_roc.h:109
uint32_t overflow_count
from first word
Definition: Df125CDCPulse.h:65
uint32_t peak_amp_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:84
uint32_t time_quality_bit_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:80
#define X(str)
Definition: hddm-c.cpp:83
#define FA125_FE_TIMING_THRES_LO_MASK(x)
uint32_t le_time
from first word
Definition: Df125CDCPulse.h:63
#define FA125_FE_TIMING_THRES_HI_MASK(x)
uint32_t le_time
from first word
Definition: Df125FDCPulse.h:67
#define H(x, y, z)
void fa125_hit(Int_t &, Int_t &, Int_t &, const uint16_t[], Int_t, Int_t, Int_t, Int_t, Int_t, Int_t)
uint32_t first_max_amp_emulated
emulated from raw data when available
Definition: Df125CDCPulse.h:79
uint32_t timing_thres_lo[3]
Definition: bor_roc.h:107
#define FA125_FE_IE_PEDESTAL_GAP_MASK
uint32_t ie
Definition: bor_roc.h:108
vector< uint16_t > samples
uint32_t ped_sf
Definition: bor_roc.h:106
uint32_t le_time_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:79
uint32_t time_quality_bit
from first word
Definition: Df125CDCPulse.h:64
uint32_t time_quality_bit
from first word
Definition: Df125FDCPulse.h:68
void fa125_algos(Int_t &, Int_t &, Int_t &, Long_t &, Int_t &, Int_t &, Int_t &, const uint16_t[], Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t)
bool emulated
true if emulated values are copied to the main input
Definition: Df125FDCPulse.h:78
#define FA125_FE_PED_SF_P1_MASK
uint32_t integral_emulated
emulated from raw data when available
Definition: Df125CDCPulse.h:78
void upsamplei(Int_t[], Int_t, Int_t[], Int_t)
uint32_t pedestal
from second word
Definition: Df125FDCPulse.h:70
uint32_t channel
Definition: DDAQAddress.h:34
uint32_t le_time_emulated
emulated from raw data when available
Definition: Df125CDCPulse.h:74
uint32_t overflow_count_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:81
static TH1I * pedestal[nChan]
uint32_t pedestal_emulated
emulated from raw data when available
Definition: Df125CDCPulse.h:77
uint32_t rocid
Definition: DDAQAddress.h:32
void fa125_integral(Long_t &, Int_t &, Int_t, const uint16_t[], Int_t, Int_t)
uint32_t overflow_count_emulated
emulated from raw data when available
Definition: Df125CDCPulse.h:76
uint32_t pedestal_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:82
uint32_t nw
Definition: bor_roc.h:101
uint32_t integral
from second word
Definition: Df125CDCPulse.h:67
bool emulated
true if emulated values are copied to the main input
Definition: Df125CDCPulse.h:73
printf("string=%s", string)
#define FA125_FE_PED_SF_IBIT_MASK
#define FA125_FE_PED_SF_PBIT_MASK
uint32_t overflow_count
from first word
Definition: Df125FDCPulse.h:69
#define FA125_FE_THRESHOLD_MASK
uint32_t slot
Definition: DDAQAddress.h:33
uint32_t integral_emulated
emulated from raw data when available
Definition: Df125FDCPulse.h:83