FairRoot/PandaRoot
PndEmcPSAFPGAPileupAnalyser.cxx
Go to the documentation of this file.
2 
8 
9 #include "TF1.h"
10 
11 #include <iostream>
12 
14  PndEmcPSAFPGASampleAnalyser(), fVerbose(0), Int_thres(NULL), Int_mean(NULL), MWD_filter1(NULL), MWD_filter2(NULL), MWD_filter3(NULL), CF_prev(NULL), func_defined(false) {
15 }
16 
18  if(Int_thres!=NULL) delete Int_thres;
19  if(Int_mean!=NULL) delete Int_mean;
20  if(MWD_filter1!=NULL) delete MWD_filter1;
21  if(MWD_filter2!=NULL) delete MWD_filter2;
22  if(MWD_filter3!=NULL) delete MWD_filter3;
23  if(CF_prev!=NULL) delete CF_prev;
24 }
25 
26 void PndEmcPSAFPGAPileupAnalyser::reset() { //reset for every waveform to process
27  local_time = 0;
29  Number_of_hits = 0;
36  pulse_detected = false;
37  BaselineSum = 0;
38  return;
39 }
40 
41 
42 void PndEmcPSAFPGAPileupAnalyser::InitParameters(const std::vector<Double_t> &params) {
43 
44  //define parameter initialization, otherwise conflict with clock_unit and iafactor parameters, which have been added to PndEmcPSAFPGASampleAnalyser
45  //
46  const Int_t size = params.size();
47  if(size!=14) {
48  std::cerr << "-W PndEmcPSAFPGAPileupAnalyser::InitParameters Mismatch in number of parameters (" << size << "!=14). Filling missing parameter values up with zeros..." << std::endl;
49  }
50 
51  SampleAnalyserParams newParams;
52  newParams.ma_trig_M = (size>0) ? (int) params.at(0): 0;
53  newParams.hit_threshold = (size>1) ? params.at(1): 0;
54  newParams.cf_delay = (size>2) ? (int) params.at(2): 0;
55  newParams.cf_ratio = (size>3) ? params.at(3): 0;
56  newParams.cf_fitter_length = (size>4) ? (int) params.at(4): 0;
57  newParams.cf_fit_offset = (size>5) ? (int) params.at(5): 0;
58  newParams.mwd_length = (size>6) ? (int) params.at(6): 0;
59  newParams.mwd_tau = (size>7) ? params.at(7): 0;
60  newParams.mwd2_length = (size>8) ? (int) params.at(8): 0;
61  newParams.mwd2_tau = (size>9) ? params.at(9): 0;
62  newParams.mwd3_length = (size>10) ? (int) params.at(10): 0;
63  newParams.mwd3_tau = (size>11) ? params.at(11): 0;
64  newParams.sig_delay = (size>12) ? params.at(12): 0;
65  newParams.rough_timing_corr = (size>13) ? params.at(13): 0;
66 
68 }
69 
70 void PndEmcPSAFPGAPileupAnalyser::Init(const std::vector<Double_t> &params, TF1* r_thres, TF1* r_mean, float extBaselineValue) {
71  Init2(params, r_thres, r_mean);
72  setBaseline(extBaselineValue);
73 }
74 
75 void PndEmcPSAFPGAPileupAnalyser::Init(const std::vector<Double_t> &params, TF1* r_thres, TF1* r_mean, unsigned int baselineStartSample, unsigned int baselineStopSample) {
76  Init2(params, r_thres, r_mean);
77  setBaselineWindow(baselineStartSample, baselineStopSample);
78 }
79 
80 
81 void PndEmcPSAFPGAPileupAnalyser::Init2(const std::vector<Double_t> &params, TF1* r_thres, TF1* r_mean) {
82 
83  InitParameters(params);
85 
86  if(MWD_filter1!=NULL) delete MWD_filter1;
88  if(MWD_filter2!=NULL) delete MWD_filter2;
90  if(MWD_filter3!=NULL) delete MWD_filter3;
92  if(CF_prev!=NULL) delete CF_prev;
94 
98  CF_prev->set(1);
99 
100  if(r_mean!=NULL && r_thres!=NULL) {
101  func_defined = true;
102 
103  if(Int_thres!=NULL) delete Int_thres;
104  Int_thres = new TF1("intThres", "(" +r_thres->GetExpFormula() + ")*x", r_thres->GetXmin(), r_thres->GetXmax());
105  Int_thres->SetParameters(r_thres->GetParameters());
106  Int_thres->SetNpx(1000);
107 
108  if(Int_mean!=NULL) delete Int_mean;
109  Int_mean = new TF1("intMean", "(" +r_mean->GetExpFormula() + ")*x", r_mean->GetXmin(), r_mean->GetXmax());
110  Int_mean->SetParameters(r_mean->GetParameters());
111  Int_mean->SetNpx(1000);
112 
113  } else {
114  std::cerr << "-W PndEmcPSAFPGAPileupAnalyser:Init2 no pileup separation function defined. All hits will be treated as single pulses" << std::endl;
115  }
116 }
117 
118 //TODO: Baseline follower (baselineMode = kFollow)
119 
123 }
124 
125 void PndEmcPSAFPGAPileupAnalyser::setBaselineWindow(unsigned int startSample, unsigned int stopSample) {
126  BaselineStartSample = startSample;
127  BaselineStopSample = stopSample;
129 }
130 
131 
133  Energy = sampleAmplitude(i);
134  Time = sampleTime(i);
135 }
136 
137 
138 void PndEmcPSAFPGAPileupAnalyser::GetHit(Int_t i, Double_t &Energy, Double_t& Time, pileup_t& PileupType) {
139  GetHit(i, Energy, Time);
140  if(i < nHits() && i >=0) {
141  PileupType = pileups[i];
142  } else {
143  PileupType = kInvalid;
144  }
145 }
146 
147 
149  Amplitude = sampleAmplitude(i);
150  Integral = sampleIntegral(i);
151 }
152 
153 void PndEmcPSAFPGAPileupAnalyser::put(float valueToStore) {
154 
157  BaselineSum += valueToStore;
158  }
161  }
162  } else {
163 
164  float signal = valueToStore - baseline_value;
165  float signal_delayed = (analyserParams.sig_delay>0) ? Signal_delay->put(signal) : signal;
166 
167  float mwd_value = MWD_filter1->put(signal);
168  float mwd2_value = MWD_filter2->put(mwd_value);
169  float mwd3_value = MWD_filter3->put(mwd2_value);
170 
171  float cf_value = CF_filter->put(mwd3_value);
172  float cf_value_delayed = (analyserParams.cf_fit_offset>0) ? CF_delay->put(cf_value) : cf_value;
173  float cf_value_prev = CF_prev->put(cf_value_delayed);
174 
175  status = kUndefined;
176 
177  if (!pulse_detected) {
178  if(signal > analyserParams.hit_threshold) { // new pulse detected..reset pulse specific quantities
180  energy_finished = false;
181  timing_finished = false;
182  pulse_detected = true;
184  cf_crossing = 0;
185  in_cfRise = false;
186  integral[Number_of_hits] = 0.0;
187  amplitude[Number_of_hits] = 0.0;
188 
189  if(fVerbose>=5) std::cout << "first time over thres: " << local_time << std::endl;
190  } else {
191  status = kBaseline;
192  }
193  }
194 
195  int dT = local_time - rough_pulse_timing;
196 
197  if(pulse_detected) { // over thres
198 
200 
201  if( (!(dT<analyserParams.sig_delay)) && (!energy_finished) ) { // delayed over thres
202  if(fVerbose>=5) std::cout << local_time << " ";
203  // Integral
204  integral[Number_of_hits] += signal_delayed;
205  // Amplitude
206  if(cf_crossing==0 && (signal_delayed > amplitude[Number_of_hits])) {
207  amplitude[Number_of_hits] = signal_delayed;
208  }
209  if(signal_delayed < analyserParams.hit_threshold) {
210  energy_finished = true;
211  if(fVerbose>=5) std::cout << local_time << std::endl;;
212  }
213  }
214 
215 
216  if( (!(dT<analyserParams.cf_delay)) && (!timing_finished) ) {
217  if((cf_value_prev < 0.0) && (cf_value_delayed >= 0.0)) { // new zero crossing
218  CF_Fitter->reset();
219  CF_Fitter->putPoint(local_time-1, cf_value_prev);
220  CF_Fitter->putPoint(local_time, cf_value_delayed);
221  CF_Fitter->fit();
222  double a = CF_Fitter->offset();
223  double k = CF_Fitter->slope();
224  cfZero[cf_crossing++] = (k>0) ? -a/k : 0;
225  in_cfRise = true;
226  }
227 
228  if(cf_value_delayed< cf_value_prev) {
229  if(in_cfRise) {
230  cfRise[cf_crossing-1] = cf_value_prev - cfRise[cf_crossing-1];
231  in_cfRise = false;
232  } else {
233  cfRise[cf_crossing] = cf_value_delayed;
234  }
235  }
236  if(energy_finished) {
237  timing_finished = true;
238  }
239  }
240 
242 
243  time[Number_of_hits] = (cf_crossing>0) ? cfZero[0] : rough_pulse_timing-analyserParams.rough_timing_corr;
244 
245  if(fVerbose>=2) {
246  std::cout << "Finaliyzing " << Number_of_hits << " hit" << std::endl;
247  std::cout << " time: " << time[Number_of_hits] << std::endl;
248  std::cout << " ampitude: " << amplitude[Number_of_hits] << "\t";
249  std::cout << " integral: " << integral[Number_of_hits] << std::endl;
250  }
251 
252  if(fVerbose >= 3) {
253  std::cout << "all zeroCrossings t/rise" << std::endl;
254  for(unsigned int i=0; i<cf_crossing; ++i) {
255  std::cout << cfZero[i] << "/" << cfRise[i] << std::endl;
256  }
257  }
258 
259 
260  if( (!func_defined) || (integral[Number_of_hits] < Int_thres->Eval(amplitude[Number_of_hits]))) { //single pulse
262  if(fVerbose>=2) std::cout << "single hit" << std::endl;
264  Number_of_hits++;
265  } else { //pileup pulse
267  if(fVerbose>=2) std::cout << "pileup hit" << std::endl;
268  //i2 = i_ges - i1
269  integral[Number_of_hits+1] = integral[Number_of_hits] - Int_mean->Eval(amplitude[Number_of_hits]);
270  //i1 = i_ges - i2
271  integral[Number_of_hits]-= integral[Number_of_hits+1];
272  amplitude[Number_of_hits+1] = Int_mean->GetX(integral[Number_of_hits+1], 0, 0, 5.e-4, 100, kTRUE);
273 
274  if(cf_crossing>1) {
275  float max_rise = 0;
276  for(unsigned int i=1; i<cf_crossing; ++i) {
277  if(cfRise[i] > max_rise) {
278  max_rise = cfRise[i];
279  time[Number_of_hits+1] = cfZero[i];
280  }
281  }
282  } else {
283  time[Number_of_hits+1] = rough_pulse_timing-analyserParams.rough_timing_corr;
284  }
286  pileups[Number_of_hits+1] = kPileup2;
287 
288 
289  if(fVerbose>=2) {
290  std::cout << "amp1: " << amplitude[Number_of_hits] << "\tint1: " << integral[Number_of_hits] << "\tamp2: " << amplitude[Number_of_hits+1] << "\tint2: " << integral[Number_of_hits+1] << std::endl;
291  }
292 
293  Number_of_hits+=2;
294  }
295  pulse_detected = false;
296  }
297  }
298 
299  if(fVerbose>=9) {
300  using namespace std;
301  cout << "#" << local_time <<" ";
302  cout << "mwd: " << mwd_value <<" ";
303  cout << "mwd 2: " << mwd2_value <<" ";
304  cout << "mwd 3: " << mwd3_value <<" ";
305  cout << "cf delay: " << cf_value_delayed <<" ";
306  if(pulse_detected) cout << "detec ";
307  if(!energy_finished) cout << "energy method running ";
308  if(!timing_finished) cout << "timing method running ";
309  cout << endl;
310  }
311  }
312  local_time++;
313 }
314 
int fVerbose
Definition: poormantracks.C:24
float integral[MAX_NUMBER_OF_HITS]
Int_t i
Definition: run_full.C:25
void set(unsigned int newBufferSize)
PndEmcPSAFPGAFilterMWD * MWD_filter2
virtual void Init2(const std::vector< Double_t > &params, TF1 *R_thres, TF1 *R_mean)
float put(float valueToStore)
void set(float tau, unsigned int newBufferSize)
void putPoint(double ix, double iy)
void GetEnergyMeasures(Int_t i, Double_t &Amplitude, Double_t &Integral)
virtual void put(float valueToStore)
pileup_t pileups[MAX_NUMBER_OF_HITS]
PndEmcPSAFPGAFilterDelay * CF_prev
float amplitude[MAX_NUMBER_OF_HITS]
virtual void InitParameters(const std::vector< Double_t > &params)
Int_t a
Definition: anaLmdDigi.C:126
enum PndEmcPSAFPGAPileupAnalyser::@0 baselineMode
Double_t
virtual float put(float valueToStore)
PndEmcPSAFPGAFilterMWD * MWD_filter3
PndEmcPSAFPGAFilterMWD * MWD_filter1
PndEmcPSAFPGAFilterDelay * Signal_delay
virtual void GetHit(Int_t i, Double_t &Energy, Double_t &Time)
Get energy and time of hit.
virtual float put(float valueToStore)
ClassImp(PndAnaContFact)
virtual void setBaseline(float newBaseline)
virtual void Init(const std::vector< Double_t > &params, TF1 *R_thres, TF1 *R_mean, float extBaselineValue=0)
virtual void setBaselineWindow(unsigned int startSample, unsigned int stopSample)
virtual void setBaseline(float newBaseline)
PndEmcPSAFPGAFilterDelay * CF_delay
virtual void init(SampleAnalyserParams &params)