KaliVeda
Toolkit for HIC analysis
KVSignal.cpp
1 //Created by KVClassFactory on Mon Dec 22 15:46:46 2014
2 //Author: ,,,
3 
4 #include "KVSignal.h"
5 #include "KVString.h"
6 #include "TMath.h"
7 #include "KVDigitalFilter.h"
8 #include "KVEnv.h"
9 #include "TMatrixD.h"
10 #include "TMatrixF.h"
11 #include "TClass.h"
12 
13 #define LOG2 (double)6.93147180559945286e-01
14 # define M_PI 3.14159265358979323846 /* pi */
15 
17 
18 
19 
21 void KVSignal::init()
22 {
23  fPSAIsDone = kFALSE;
24  fYmin = fYmax = 0;
25  fAmplitude = 0;
26  fRiseTime = 0;
27  fIMax = 0;
28  fTMax = 0;
29  fBaseLine = 0;
30  fSigmaBase = 0;
31  fChannelWidth = -1;
32  fChannelWidthInt = -1;
33  fFirstBL = -1;
34  fLastBL = -1;
35  fTauRC = -1;
36  fTrapRiseTime = -1;
37  fTrapFlatTop = -1;
38  fSemiGaussSigma = -1;
39  fWithPoleZeroCorrection = kFALSE;
40  fWithInterpolation = kFALSE;
41  fMinimumValueForAmplitude = 0;
42  SetDefaultValues();
43 }
44 
45 
46 
49 
51 {
52  // Default constructor
53  init();
54 }
55 
56 
57 
58 
61 
62 KVSignal::KVSignal(const char* name, const char* title) : TGraph()
63 {
64  // Write your code here
65  SetNameTitle(name, title);
66  init();
67 }
68 
69 
70 
71 
73 
74 KVSignal::KVSignal(const TString& name, const TString& title) : TGraph()
75 {
76  SetNameTitle(name, title);
77  init();
78 
79 }
80 
81 
82 
84 
86 {
87  auto sig = MakeSignal(type);
88  if (sig) {
89  sig->SetData(this->GetN(), this->GetX(), this->GetY());
90  sig->LoadPSAParameters();
91  }
92  return sig;
93 }
94 
95 
96 
98 
100 {
101  if (fLastBL > GetN()) return kFALSE;
102  else return kTRUE;
103 }
104 
105 
106 
108 
110 {
111  return (GetN() > fLastBL + 10);
112 }
113 
114 
115 
117 
119 {
120  fPSAIsDone = kFALSE;
121  TGraph::Set(n);
122  fAdc.Set(GetN());
123 
124 }
125 
126 
127 
129 
131 {
132  Set(nn);
133  if (nn == 0) {
134  Info("SetData", "called with points number=%d", nn);
135  return;
136  }
137  Int_t np = 0;
138  fYmin = fYmax = yy[np];
139  SetPoint(np, xx[np], yy[np]);
140  for (np = 1; np < nn; np += 1) {
141  SetPoint(np, xx[np], yy[np]);
142  if (yy[np] < fYmin) fYmin = yy[np];
143  if (yy[np] > fYmax) fYmax = yy[np];
144  }
145  SetADCData();
146 }
147 
148 
149 
151 
153 {
154 
156  fAdc.Set(GetN());
157  for (int ii = 0; ii < GetN(); ii++) fAdc.AddAt(fY[ii], ii);
158 
159 }
160 
161 
162 
164 
166 {
167  for (Int_t ii = 0; ii < par->GetNpar(); ii += 1) {
168  TString nameat(par->GetNameAt(ii));
169  if (nameat == "BaseLineLength") SetBaseLineLength(par->GetDoubleValue(ii));
170  else if (nameat == "ChannelWidth") SetChannelWidth(par->GetDoubleValue(ii));
171  else if (nameat == "ShaperRiseTime") SetShaperRiseTime(par->GetDoubleValue(ii));
172  else if (nameat == "ShaperFlatTop") SetShaperFlatTop(par->GetDoubleValue(ii));
173  else if (nameat == "TauRC") SetTauRC(par->GetDoubleValue(ii));
174  else if (nameat == "MinimumAmplitude") SetAmplitudeTriggerValue(par->GetDoubleValue(ii));
175  else if (nameat == "InterpolatedChannelWidth") SetInterpolatedChannelWidth(par->GetDoubleValue(ii));
176  else if (nameat == "Interpolation") SetInterpolation((par->GetDoubleValue(ii) == 1));
177  else if (nameat == "PZCorrection") SetPoleZeroCorrection((par->GetDoubleValue(ii) == 1));
178  else {
179  if (nameat == "Detector" || nameat == "Signal" || nameat == "RunRange") {
180 
181  }
182  else {
183  Warning("UpdatePSAParameter", "Not supported PSA parameter : %d %s\n", ii, nameat.Data());
184  }
185  }
186  }
187 }
188 
189 
190 
192 
194 {
195  Info("LoadPSAParameters", "To be defined in child class");
196 }
197 
198 
199 
202 
204 {
205  //To be defined in child class
206 }
207 
208 
209 
211 
213 {
214  Info("TreateSignal", "To be defined in child class");
215 }
216 
217 
218 
220 
222 {
223  printf("################\nPSA parameters:\n");
224  printf("\tBaseLine: length: %lf first: %lf\n", GetBLLength(), GetBLFirst());
225  printf("\tChannelWidth: %lf\n", GetChannelWidth());
226  printf("\tTauRC: %lf\n", GetTauRC());
227  printf("\tShaperRiseTime: %lf\n", GetShaperRiseTime());
228  printf("\tShaperFlatTop: %lf\n", GetShaperFlatTop());
229  printf("\tWith Interpolation: %d", Int_t(fWithInterpolation));
230  if (fWithInterpolation)
231  printf(" %1.2lf", GetInterpolatedChannelWidth());
232  printf("\n");
233  printf("\tWith PoleZero correction: %d\n", Int_t(fWithPoleZeroCorrection));
234 }
235 
236 
237 
239 
241 {
242  Info("Print", "\nName: %s - Title: %s", GetName(), GetTitle());
244 
245 }
246 
247 
248 
249 
251 
253 {
254  Double_t xx, yy;
255  Int_t np = 0;
256  GetPoint(np++, xx, yy);
257  fYmin = fYmax = yy;
258 
259  for (np = 1; np < GetN(); np += 1) {
260  GetPoint(np, xx, yy);
261  if (yy < fYmin) fYmin = yy;
262  if (yy > fYmax) fYmax = yy;
263  }
264 }
265 
266 
267 
269 
271 {
272  Double_t x0, x1, y0, y1;
273 
274  GetPoint(0, x0, y0);
275  GetPoint(1, x1, y1);
276 
277  Double_t actual_width = x1 - x0;
278  return ((actual_width == GetChannelWidth()));
279 }
280 
281 
282 
283 
285 
287 {
288  Double_t xx, yy;
289  for (Int_t ii = 0; ii < GetN(); ii += 1) {
290  GetPoint(ii, xx, yy);
291  SetPoint(ii, ii * newwidth, yy);
292  }
293 }
294 
295 
296 
297 
298 
302 
304 {
305  //compute mean value of the signal and the rms between
306  // limits defined by fFirstBL and fLastBL
307  if (fLastBL >= GetN()) {
308  fBaseLine = -1;
309  fSigmaBase = -1;
310  return -1;
311  }
313  return fBaseLine;
314 }
315 
316 
317 
320 
322 {
323  // calculate the time during which the signal is higher than th*fAmplitude
324  if (fAmplitude <= 0) {
325  SetADCData();
327  }
328 
329  Multiply(-1);
330  fAmplitude *= -1;
331  Double_t qstart = FindTzeroCFDCubic(th, 3);
333  Double_t qend = FindTzeroCFDCubic(th, 3);
335  Multiply(-1);
336  fAmplitude *= -1;
337 
338  //printf("qstart=%lf - qend=%lf\n",qstart,qend);
339  if (qend < qstart || qstart <= 0 || qend <= 0)
340  return -1;
341  //Double_t deltat = GetN() * fChannelWidth - qstart - qend;
342  Double_t deltat = ((GetN() * fChannelWidth - qend) - qstart);
343  return deltat;
344 }
345 
346 
347 
350 
352 {
353  // calculate the time during which the signal is higher than th*fAmplitude
354  if (fAmplitude <= 0) {
355  SetADCData();
357  }
358 
359  Multiply(-1);
360  fAmplitude *= -1;
361 
362  Double_t qstart = FindTzeroCFDCubic(threshold, 3);
363 
364  Multiply(-1);
365  fAmplitude *= -1;
366 
367  return qstart;
368 }
369 
370 
371 
375 
377 {
378  //same as ComputeBaseLine method but made on the end of the signal
379  //in the same length as for the base line
380  if ((fLastBL - fFirstBL) >= GetN()) {
381  fEndLine = -1;
382  fSigmaEnd = -1;
383  }
385  return fEndLine;
386 }
387 
388 
389 
392 
394 {
395  //ComputeBaseLine and ComputeEndLine methods have to be called before
396 
398  return kTRUE;
399  return kFALSE;
400 }
401 
402 
403 
405 
407 {
408 
409  Add(-1.*ComputeBaseLine());
411 
412 }
413 
414 
415 
417 
419 {
420  TArrayF copy(fAdc);
421  Int_t np = fAdc.GetSize();
422 
423  for (int i = 0; i < np; i++) fAdc.AddAt(copy.GetAt(np - i - 1), i);
424 }
425 
426 
427 
430 
432 {
433  //Compute and return the absolute value of the signal amplitude
434  int i_max = 0;
435  for (int i = 0; i < fAdc.GetSize(); i++) {
436  if (fAdc.At(i_max) < fAdc.At(i)) i_max = i;
437  }
438  fIMax = i_max;
440  fAmplitude = fAdc.At(i_max);
441  return fAmplitude;
442 }
443 
444 
445 
447 
449 {
450  Multiply(-1);
451  fAmplitude *= -1;
452  Double_t qt70 = FindTzeroCFDCubic(0.7, 3);
453  Double_t qt20 = FindTzeroCFDCubic_rev(0.2, qt70, 3);
454  Double_t qtrise72 = qt70 - qt20;
455  Multiply(-1);
456  fAmplitude *= -1;
457  fRiseTime = qtrise72;
458  return fRiseTime;
459 }
460 
461 
462 
465 
467 {
468  //time of passage of the threshold
469 
470  Double_t rtime = GetRiseTime();
471  if (!(tdelay < (1 - threshold)*rtime))
472  return -1;
473 
474  rtime *= 2;
475  double time = GetAmplitude() / ((1 - threshold) * (rtime / tdelay));
476  Multiply(-1);
477  double re = FindTzeroLeadingEdgeCubic(time, 3);
478  Multiply(-1);
479 
480  return re;
481 
482 }
483 
484 
485 
487 
488 double KVSignal::FindTzeroLeadingEdgeCubic(double LEVEL, int Nrecurr)
489 {
490 
491  int i = 0;
492  float* data = fAdc.GetArray();
493  for (; i < fAdc.GetSize() - 1; i++)
494  if (-data[i] > LEVEL && -data[i + 1] > LEVEL) //to skip noise.
495  break;
496  if (i >= fAdc.GetSize() - 3) return -1;
497  i--;
498 
499  return CubicInterpolation(data, i, - LEVEL, Nrecurr);
500 }
501 
502 
503 
504 //----------------------------------
506 //----------------------------------
507 
508 
516 {
517  //compute mean value and sigma values
518  //between "start" point included and "stop" point excluded
519  //for example :
520  // ComputeMeanAndSigma(0,50,mean,sigma)
521  // compute values for the first 50 points
522  //
523  Int_t np = 0;
524  Double_t xx;
525  mean = 0;
526  Double_t mean2 = 0;
527  if (stop > GetN()) {
528  Warning("ComputeMeanAndSigma",
529  "stop position greater than number of samples %d/%d, set stop to %d", GetN(), stop, GetN());
530  stop = GetN();
531  }
532  if (start < 0) {
533  Warning("ComputeMeanAndSigma",
534  "start position unrealistic %d, set start to 0", start);
535  start = 0;
536  }
537 
538  for (Int_t ii = start; ii < stop; ii += 1) {
539  xx = fAdc.At(ii);
540  mean += xx;
541  mean2 += xx * xx;
542  np += 1;
543  }
544 
545  if (np == 0) {
546  Error("ComputeMeanAndSigma", "values cannot be computed with 0 sample");
547  return kFALSE;
548  }
549  mean /= np;
550  mean2 /= np;
551  sigma = TMath::Sqrt(mean2 - mean * mean);
552  return kTRUE;
553 }
554 
555 
556 //----------------------------------
558 //----------------------------------
559 
560 
568 {
569  //
570  //assuming that X axis is in time unit (ms)
571  //divide the X values by the fChannelWidth value which allow to set the Xaxis in time units
572  //compute mean value and sigma values
573  //between "start" and "stop" point included
574  //
576 }
577 
578 
579 // double KVSignal::FindMedia(double tsta, double tsto)
580 // {
581 // Info("FindMedia(double tsta, double tsto)","Appel ...");
582 // int n1 = (int)(tsta / fChannelWidth); // Non molto preciso, ma tant'e'...
583 // int n2 = (int)(tsto / fChannelWidth);
584 //
585 // return FindMedia(n1, n2);
586 // }
587 //
588 // double KVSignal::FindMedia(int tsta, int tsto)
589 // {
590 // // Calcolo della media nel tratto tra tsta e tsto.
591 // // NOTA: questo ha senso solo se il segnale e' piatto in quella regione!!
592 //
593 // int n1 = (int)(tsta);
594 // int n2 = (int)(tsto);
595 //
596 // int N = n2 - n1 + 1;
597 // //// printf("n1=%d, n2=%d, n=%d, fChannelWidth=%e \n",n1, n2, N, fChannelWidth);
598 // if (n1 < 0 || n1 >= fAdc.GetSize() ||
599 // n2 < n1 || n2 >= fAdc.GetSize() ||
600 // N <= 0 || N >= fAdc.GetSize()) {
601 // printf("--- FSignal::FindMedia: tsta=%d, tsto=%d ?? (%d)\n", tsta, tsto, fAdc.GetSize());
602 // return -1E10;//non cambiare, serve a FindSigma2!!
603 // }
604 // double media = 0;
605 // for (int i = n1; i <= n2; i++)
606 // media += fAdc.At(i);
607 //
608 // media /= N;
609 // return media;
610 // }
611 //
612 // double KVSignal::FindSigma2(double tsta, double tsto)
613 // {
614 // // Calcolo della varianza nel tratto tra tsta e tsto.
615 // // NOTA: questo ha senso solo se il segnale e' piatto in quella regione!!
616 //
617 // int n1 = (int)(tsta / fChannelWidth); // Non molto preciso, ma tant'e'...
618 // int n2 = (int)(tsto / fChannelWidth);
619 //
620 // return FindSigma2(n1, n2);
621 // }
622 //
623 // double KVSignal::FindSigma2(int tsta, int tsto)
624 // {
625 // // Calcolo della varianza nel tratto tra tsta e tsto.
626 // // NOTA: questo ha senso solo se il segnale e' piatto in quella regione!!
627 //
628 // int n1 = (int)(tsta);
629 // int n2 = (int)(tsto);
630 //
631 // int N = n2 - n1 + 1;
632 // double sigma2 = 0;
633 // double media = FindMedia(tsta, tsto);
634 // if (media == -1E10) {
635 // printf("--- FSignal::FindSigma2(double tsta, double tsto) ---: errore nella media\n");
636 // return -1;
637 // }
638 //
639 // for (int i = n1; i <= n2; i++)
640 // sigma2 += (media - fAdc.At(i)) * (media - fAdc.At(i));
641 //
642 // sigma2 /= N-1;
643 //
644 // return sigma2;
645 // }
646 
647 
648 
650 
651 void KVSignal::FIR_ApplyTrapezoidal(double trise, double tflat) // trise=sqrt(12)*tausha di CR-RC^4 se tflat=trise/2
652 {
653  if (tflat < 0) tflat = trise / 2.;
654  int irise = (int)(1e3 * trise / fChannelWidth);
655  int iflat = (int)(1e3 * tflat / fChannelWidth);
656 
657 // Info("FIR_ApplyTrapezoidal","irise %d iflat %d chw %lf",irise,iflat, fChannelWidth);
658 
659  TArrayF sorig(fAdc);
660  float* data = fAdc.GetArray();
661  float* datao = sorig.GetArray();
662  int N = sorig.GetSize();
663 
664  // 1
665  for (int i = irise; i < N; i++) data[i] -= datao[i - irise];
666  for (int i = irise + iflat; i < N; i++) data[i] -= datao[i - irise - iflat];
667  for (int i = 2 * irise + iflat; i < N; i++) data[i] += datao[i - 2 * irise - iflat];
668 
669  // normalizzazione
670  double amp = 1e3 * trise / fChannelWidth;
671  data[0] /= amp;
672  for (int i = 1; i < N; i++) data[i] = data[i] / amp + data[i - 1];
673 }
674 
675 
676 
677 //Double_t KVSignal::GetAmplitude()
678 //{
679 // //Compute and return the absolute value of the signal amplitude
680 // int i_max=0;
681 // for(int i=0;i<fAdc.GetSize();i++)
682 // {
683 // if(fAdc.At(i_max) < fAdc.At(i) ) i_max = i;
684 // }
685 // fIMax = i_max;
686 // fTMax = fIMax*fChannelWidth;
687 // fAmplitude = fAdc.At(i_max);
688 // return fAmplitude;
689 //}
690 
691 
692 
696 
697 Double_t KVSignal::FindTzeroCFDCubic(double level, int Nrecurr)
698 {
699  // recurr=1 means: linear + 1 approx
700  // recurr=0 == FindTzeroCFD
701  float* data = fAdc.GetArray();
702  int NSamples = fAdc.GetSize();
703  double fmax = level * fAmplitude;
704  /**** 1) ricerca del punto x2 tale che x2 e' il precedente di tcfd ****/
705  int x2 = 0;
706  for (; x2 < NSamples; x2++) if (data[x2] < fmax) break;
707  x2--;
708 
709  return CubicInterpolation(data, x2, fmax, Nrecurr);
710 }
711 
712 
713 /***************************************************************************************************/
714 
716 
717 inline unsigned int ReverseBits(unsigned int p_nIndex, unsigned int p_nBits)
718 {
719 
720  unsigned int i, rev;
721 
722  for (i = rev = 0; i < p_nBits; i++) {
723  rev = (rev << 1) | (p_nIndex & 1);
724  p_nIndex >>= 1;
725  }
726 
727  return rev;
728 
729 }
730 
731 
732 
733 /***************************************************************************************************/
734 
737 
738 void KVSignal::ApplyWindowing(int window_type) // 0: barlett, 1:hanning, 2:hamming, 3: blackman
739 {
740  // vedi pag. 468 oppenheim-shafer
741  int N = fAdc.GetSize() - 1;
742  switch (window_type) {
743  case 0:/*-------------------- BARLETT ----------------------*/
744  for (int n = 0; n <= N; n++)
745  fAdc.GetArray()[n] *= (n < N / 2 ? 2.*n / (double)N : 2. - 2.*n / (double)N);
746  break;
747  case 1:/*-------------------- HANNING ----------------------*/
748  for (int n = 0; n <= N; n++)
749  fAdc.GetArray()[n] *= 0.5 - 0.5 * cos(2 * M_PI * n / (double)N);
750  break;
751  case 2:/*-------------------- HAmmING ----------------------*/
752  for (int n = 0; n <= N; n++)
753  fAdc.GetArray()[n] *= 0.54 - 0.46 * cos(2 * M_PI * n / (double)N);
754  break;
755  case 3:/*-------------------- BLACKMAN --------------------*/
756  for (int n = 0; n <= N; n++)
757  fAdc.GetArray()[n] *= 0.42 - 0.5 * cos(2 * M_PI * n / (double)N) + 0.08 * cos(4 * M_PI * n / (double)N);
758  break;
759  default:
760  printf("ERROR in %s: windowtype %d not valid!\n", __PRETTY_FUNCTION__, window_type);
761  };
762 }
763 
764 
765 
766 
767 
768 /***************************************************************************************************/
769 
773 
774 int KVSignal::FFT(unsigned int p_nSamples, bool p_bInverseTransform,
775  double* p_lpRealIn, double* p_lpImagIn,
776  double* p_lpRealOut, double* p_lpImagOut)
777 {
778  // copiata e adattata da: http://www.codeproject.com/audio/waveInFFT.asp
779  // l'unico vettore che puo' essere NULL e' p_lpImagIn
780 
781  if (!p_lpRealIn || !p_lpRealOut || !p_lpImagOut) {
782  printf("ERROR in %s: NULL vectors!\n", __PRETTY_FUNCTION__);
783  return -1;
784  }
785 
786 
787  unsigned int NumBits;
788  unsigned int i, j, k, n;
789  unsigned int BlockSize, BlockEnd;
790 
791  double angle_numerator = 2.0 * M_PI;
792  double tr, ti;
793 
794  // if( !IsPowerOfTwo(p_nSamples) )
795  // {
796  // return;
797  // }
798  if (p_nSamples < 2 || p_nSamples & (p_nSamples - 1)) {
799  printf("ERROR in %s: %d not a power of two!\n", __PRETTY_FUNCTION__, p_nSamples);
800  return -1;
801  }
802 
803  if (p_bInverseTransform) angle_numerator = -angle_numerator;
804 
805  NumBits = 0; // NumberOfBitsNeeded ( p_nSamples );
806  for (NumBits = 0; ; NumBits++) {
807  if (p_nSamples & (1 << NumBits)) break;
808  }
809 
810  for (i = 0; i < p_nSamples; i++) {
811  j = ReverseBits(i, NumBits);
812  p_lpRealOut[j] = p_lpRealIn[i];
813  p_lpImagOut[j] = (p_lpImagIn == NULL) ? 0.0 : p_lpImagIn[i];
814  }
815 
816 
817  BlockEnd = 1;
818  for (BlockSize = 2; BlockSize <= p_nSamples; BlockSize <<= 1) {
819  double delta_angle = angle_numerator / (double)BlockSize;
820  double sm2 = sin(-2 * delta_angle);
821  double sm1 = sin(-delta_angle);
822  double cm2 = cos(-2 * delta_angle);
823  double cm1 = cos(-delta_angle);
824  double w = 2 * cm1;
825  double ar[3], ai[3];
826 
827  for (i = 0; i < p_nSamples; i += BlockSize) {
828 
829  ar[2] = cm2;
830  ar[1] = cm1;
831 
832  ai[2] = sm2;
833  ai[1] = sm1;
834 
835  for (j = i, n = 0; n < BlockEnd; j++, n++) {
836 
837  ar[0] = w * ar[1] - ar[2];
838  ar[2] = ar[1];
839  ar[1] = ar[0];
840 
841  ai[0] = w * ai[1] - ai[2];
842  ai[2] = ai[1];
843  ai[1] = ai[0];
844 
845  k = j + BlockEnd;
846  tr = ar[0] * p_lpRealOut[k] - ai[0] * p_lpImagOut[k];
847  ti = ar[0] * p_lpImagOut[k] + ai[0] * p_lpRealOut[k];
848 
849  p_lpRealOut[k] = p_lpRealOut[j] - tr;
850  p_lpImagOut[k] = p_lpImagOut[j] - ti;
851 
852  p_lpRealOut[j] += tr;
853  p_lpImagOut[j] += ti;
854 
855  }
856  }
857 
858  BlockEnd = BlockSize;
859 
860  }
861 
862 
863  if (p_bInverseTransform) {
864  double denom = (double)p_nSamples;
865 
866  for (i = 0; i < p_nSamples; i++) {
867  p_lpRealOut[i] /= denom;
868  p_lpImagOut[i] /= denom;
869  }
870  }
871  return 0;
872 }
873 
874 
875 
876 
877 
878 
879 
882 
883 int KVSignal::FFT(bool p_bInverseTransform, double* p_lpRealOut, double* p_lpImagOut)
884 {
885  // returns the lenght of FFT( power of 2)
886  static double* buffer = NULL;
887  static int bufflen = 0;
888  int NSA = fAdc.GetSize();
889  int ibits = (int)ceil(log((double)NSA) / LOG2);
890  NSA = 1 << ibits;
891 
892  if (buffer != NULL && bufflen < NSA) {
893  delete [] buffer;
894  buffer = NULL;
895  }
896 
897 
898  if (buffer == NULL) {
899  bufflen = NSA;
900  buffer = new double [NSA];
901  }
902  unsigned int N = fAdc.GetSize();
903  float* data = fAdc.GetArray();
904  for (unsigned int i = 0; i < N; i++)
905  buffer[i] = data[i];
906  // 0 padding
907  memset(buffer + N, 0, (NSA - N)*sizeof(double));
908  int r = FFT(NSA, p_bInverseTransform, buffer, NULL, p_lpRealOut, p_lpImagOut);
909  if (r < 0) return r;
910  return NSA;
911 }
912 
913 
915 
916 TH1* KVSignal::FFT2Histo(int output, TH1* hh) // 0 modulo, 1 modulo db (normalized), 2, re, 3 im
917 {
918  unsigned int N = fAdc.GetSize();
919  double* re = new double [2 * N];
920  double* im = new double [2 * N];
921  int NFFT = FFT(0, re, im);
922  if (NFFT < 0) {
923  printf("ERROR in %s: FFT returned %d!\n", __PRETTY_FUNCTION__, NFFT);
924  delete [] re;
925  delete [] im;
926  return NULL;
927  }
928  int NF = NFFT / 2;
929  TH1* h = 0;
930  if (!hh) h = new TH1F("hfft", "FFT of FSignal", NF, 0, 1. / fChannelWidth * 1000 / 2);
931  else h = hh;
932 
933  h->SetStats(kFALSE);
934  for (int i = 0; i < NF; i++) {
935  switch (output) {
936  case 0: // modulo
937  h->Fill(h->GetBinCenter(i + 1), sqrt(re[i]*re[i] + im[i]*im[i]));
938  break;
939  case 1: // modulo db
940  h->Fill(h->GetBinCenter(i + 1), log(sqrt(re[i]*re[i] + im[i]*im[i])) * 8.68588963806503500e+00); // numero=20./log(10.)
941  break;
942  case 2:
943  h->Fill(h->GetBinCenter(i + 1), re[i]);
944  break;
945  case 3:
946  h->Fill(h->GetBinCenter(i + 1), im[i]);
947  break;
948  default:
949  printf("ERROR in %s: output=%d not valid!!\n", __PRETTY_FUNCTION__, output);
950  break;
951  }
952  }
953 // h->GetXaxis()->SetTitle("Frequency");
954  delete [] re;
955  delete [] im;
956 
957  if (output != 1) return h;
958  /*** normalizzazione a 0 db ****/
959  int imax = 0;
960  for (int i = 1; i < NF; i++)
961  if (h->GetBinContent(i + 1) > h->GetBinContent(imax + 1))
962  imax = i;
963  double dbmax = h->GetBinContent(imax + 1);
964  for (int i = 0; i < NF; i++)
965  h->SetBinContent(i + 1, h->GetBinContent(i + 1) - dbmax);
966  h->GetYaxis()->SetTitle("Modulo (dB)");
967  return h;
968 }
969 
970 
974 
975 Double_t KVSignal::CubicInterpolation(float* data, int x2, double fmax, int Nrecurr)
976 {
977  /*
978  NOTA: tutti i conti fatti con i tempi in "canali". aggiungero' il *fChannelWidth
979  solo nel return.
980  */
981  /**** 2) normal CFD ***************************************************/
982  double xi0 = (fmax - data[x2]) / (data[x2 + 1] - data[x2]);
983  if (Nrecurr <= 0) return fChannelWidth * (x2 + xi0);
984 
985  /**** 3) approx successive. *******************************************/
986  // scrivo il polinomio come a3*xi**3+a2*xi**2+a1*xi+a0
987  // dove xi=tcfd-x2 (ovvero 0<xi<1)
988  // con maple:
989  // 3
990  // (1/2 y2 - 1/6 y1 + 1/6 y4 - 1/2 y3) xi
991  //
992  // 2
993  // + (-y2 + 1/2 y3 + 1/2 y1) xi
994  //
995  // + (- 1/2 y2 - 1/6 y4 + y3 - 1/3 y1) xi + y2
996 
997  double a3 = 0.5 * data[x2] - (1. / 6.) * data[x2 - 1] + (1. / 6.) * data[x2 + 2] - 0.5 * data[x2 + 1];
998  double a2 = (-data[x2] + 0.5 * data[x2 + 1] + 0.5 * data[x2 - 1]);
999  double a1 = (- 0.5 * data[x2] - 1. / 6. *data[x2 + 2] + data[x2 + 1] - 1. / 3.* data[x2 - 1]);
1000  double a0 = data[x2];
1001  double xi = xi0;
1002  for (int rec = 0; rec < Nrecurr; rec++) {
1003  xi += (fmax - a0 - a1 * xi - a2 * xi * xi - a3 * xi * xi * xi) / (a1 + 2 * a2 * xi + 3 * a3 * xi * xi);
1004  }
1005  return fChannelWidth * (x2 + xi);
1006 }
1007 
1008 
1009 
1010 
1012 
1013 double KVSignal::GetDataInter(double t)
1014 {
1015  if (fAdc.GetSize() <= 0) return 1E10;
1016 
1017  int n = (int)(floor(t / fChannelWidth));
1018  if (n <= 0) return fAdc.At(0);
1019  if (n > fAdc.GetSize() - 2) return fAdc.At(fAdc.GetSize() - 1);
1020  if (n * fChannelWidth == t) return fAdc.At(n);
1021  double y1 = fAdc.At(n);
1022  double y2 = fAdc.At(n + 1); //quello prima e quello dopo.
1023  double x1 = fChannelWidth * n;
1024 
1025  return (t - x1) / fChannelWidth * (y2 - y1) + y1;
1026 }
1027 
1028 
1029 
1031 
1033 {
1034  int x2 = (int)(t / fChannelWidth);
1035  if (x2 < 1 || x2 > fAdc.GetSize() - 2) return GetDataInter(t);
1036  float* data = fAdc.GetArray();
1037  /***** CUT & PASTE DA CubicInterpolation *****/
1038 
1039  double a3 = 0.5 * data[x2] - (1. / 6.) * data[x2 - 1] + (1. / 6.) * data[x2 + 2] - 0.5 * data[x2 + 1];
1040  double a2 = (-data[x2] + 0.5 * data[x2 + 1] + 0.5 * data[x2 - 1]);
1041  double a1 = (- 0.5 * data[x2] - 1. / 6. *data[x2 + 2] + data[x2 + 1] - 1. / 3.* data[x2 - 1]);
1042  double a0 = data[x2];
1043  double xi = (t / fChannelWidth - x2);
1044  return a3 * xi * xi * xi + a2 * xi * xi + a1 * xi + a0;
1045 }
1046 
1047 
1048 /***********************************************/
1049 
1052 
1054 {
1055  // see HSIEH S.HOU IEEE Trans. Acoustic Speech, vol. ASSP-26, NO.6, DECEMBER 1978
1057  Double_t xk = floor(t / h) * h;
1058  int xk_index = (int)(t / h);
1059  Double_t s = (t - xk) / h;
1060 
1061  float* data = fAdc.GetArray();
1062  int N = fAdc.GetSize();
1063  int dimensione = 18; //dimensione della matrice dei campioni.!!!!deve essere pari!!!!
1064  float cm1, cNm1;
1065 
1066 
1067  TMatrixD e(dimensione, dimensione);
1068  TArrayD data_e(dimensione * dimensione);
1069  for (int k = 0, i = 0; i < dimensione; i++) {
1070  data_e[k] = 4.;
1071  if ((k + 1) < pow(dimensione, 2)) data_e[k + 1] = 1.;
1072  if ((k - 1) > 0) data_e[k - 1] = 1.;
1073  k += dimensione + 1;
1074  }
1075  e.SetMatrixArray(data_e.GetArray());
1076  e *= 1. / 6 / h;
1077  e.Invert();
1078 
1079  double dati_b[] = { -1, 3, -3, 1, 3, -6, 3, 0, -3, 0, 3, 0, 1, 4, 1, 0};
1080  TMatrixD delta(4, 4, dati_b);
1081 
1082 
1083  TMatrixF samples(dimensione, 1);
1084  TMatrixF coeff(dimensione, 1);
1085  TMatrixF b(4, 1);
1086  TMatrixF coefficienti(4, 1);
1087 
1088  if (xk_index < (dimensione / 2 - 1)) {
1089  samples.SetMatrixArray(data);//prendiamo i dati a partire dal primo
1090  }
1091  else if (xk_index > (N - dimensione / 2 - 1)) {
1092  samples.SetMatrixArray(data + N - dimensione); //prendiamo 18 dati partendo dalla fine
1093  }
1094  else {
1095  samples.SetMatrixArray(data + xk_index - (dimensione / 2 - 1)); //perche l'interp deve avvenire tra i campioni centrali della matrice
1096  }
1097  float* samples_interp = samples.GetMatrixArray();
1098 
1099  // coeff=e*samples;
1100  coeff.Mult(e, samples);
1101  float* ck = coeff.GetMatrixArray();
1102 
1103  if (xk_index < (dimensione / 2 - 1)) {
1104  if (xk_index == 0) {
1105  cm1 = (*samples_interp) * 6 * h - ((*ck) * 4 + (*(ck + 1)));
1106  float caso_zero[4] = {cm1, *ck, *(ck + 1), *(ck + 2)};
1107  coefficienti.SetMatrixArray(caso_zero);
1108  }
1109  else coefficienti.SetMatrixArray(ck + xk_index - 1);
1110  }
1111  else if (xk_index > (N - dimensione / 2 - 1)) {
1112  if (xk_index == N - 2) {
1113  cNm1 = (*(samples_interp + dimensione - 1)) * 6 * h - (*(ck + dimensione - 1) * 4 + (*(ck + dimensione - 2)));
1114  float casoN[4] = {*(ck + dimensione - 3), *(ck + dimensione - 2), *(ck + dimensione - 1), cNm1};
1115  coefficienti.SetMatrixArray(casoN);
1116  }
1117  else coefficienti.SetMatrixArray(ck + dimensione - (N - xk_index + 1));
1118  }
1119  else {
1120  coefficienti.SetMatrixArray(ck + (dimensione / 2 - 2));
1121  }
1122 
1123  // b=delta*coefficienti;
1124  b.Mult(delta, coefficienti);
1125  float* b_interp = b.GetMatrixArray();
1126  float a0 = *b_interp;
1127  float a1 = *(b_interp + 1);
1128  float a2 = *(b_interp + 2);
1129  float a3 = *(b_interp + 3);
1130 
1131  return (1. / 6 / h * (a3 + a2 * s + a1 * s * s + a0 * s * s * s));
1132 }
1133 
1134 
1135 
1136 /***********************************************/
1137 
1139 
1141 {
1142  const int Nsa = fAdc.GetSize();
1143  const double tau = fChannelWidth;
1144 
1145  fChannelWidthInt = taufinal;
1146  TArrayF interpo;
1147  interpo.Set((int)(Nsa * tau / taufinal));
1148  int nlast = interpo.GetSize() - (int)(3 * tau / taufinal);
1149  if (nlast <= 0) return;
1150 
1151  for (int i = 0; i < interpo.GetSize(); i++) interpo.AddAt(GetDataCubicSpline(i * taufinal), i);
1152  fAdc.Set(0);
1153  fAdc.Set(interpo.GetSize());
1154  for (int i = 0; i < interpo.GetSize(); i++) fAdc.AddAt(interpo.At(i), i);
1155  for (int i = nlast; i < interpo.GetSize(); i++) fAdc.AddAt(interpo.At(nlast), i);
1156 
1157 }
1158 
1159 /***********************************************/
1160 
1162 
1164 {
1166 }
1167 
1168 
1169 
1170 
1171 /***********************************************/
1172 
1174 
1175 void KVSignal::BuildCubicSignal(double taufinal)
1176 {
1177  const int Nsa = fAdc.GetSize();
1178  const double tau = fChannelWidth;
1179 
1180  fChannelWidthInt = taufinal;
1181  TArrayF interpo;
1182  interpo.Set((int)(Nsa * tau / taufinal));
1183  int nlast = interpo.GetSize() - (int)(3 * tau / taufinal);
1184  if (nlast <= 0) return;
1185 
1186  for (int i = 0; i < interpo.GetSize(); i++) interpo.AddAt(GetDataInterCubic(i * taufinal), i);
1187  fAdc.Set(0);
1188  fAdc.Set(interpo.GetSize());
1189  for (int i = 0; i < nlast; i++) fAdc.AddAt(interpo.At(i), i);
1190  for (int i = nlast; i < interpo.GetSize(); i++) fAdc.AddAt(interpo.At(nlast), i);
1191 
1192 }
1193 
1194 /***********************************************/
1195 
1197 
1199 {
1201 }
1202 
1203 
1204 /***********************************************/
1205 
1207 
1208 void KVSignal::BuildSmoothingSplineSignal(double taufinal, double l, int nbits)
1209 {
1210  const int Nsa = fAdc.GetSize();
1211  const double tau = fChannelWidth;
1212 
1213  KVSignal coeff;
1214  ApplyModifications(&coeff);
1215  coeff.SetADCData();
1216  if (coeff.FIR_ApplySmoothingSpline(l, nbits) != 0) return;
1217 
1218  fChannelWidthInt = taufinal;
1219  TArrayF interpo;
1220  interpo.Set((int)(Nsa * tau / taufinal));
1221  int nlast = interpo.GetSize() - (int)(3 * tau);
1222  if (nlast <= 0) return;
1223 
1224  for (int i = 0; i < interpo.GetSize() - (int)(53 * tau / taufinal); i++) interpo.AddAt(coeff.GetDataSmoothingSplineLTI(i * taufinal), i);
1225  fAdc.Set(0);
1226  fAdc.Set(interpo.GetSize());
1227  for (int i = 0; i < nlast; i++) fAdc.AddAt(interpo.At(i), i);
1228  for (int i = nlast; i < interpo.GetSize(); i++) fAdc.AddAt(interpo.At(nlast), i);
1229 
1230 }
1231 
1232 /***********************************************/
1233 
1235 
1237 {
1239 }
1240 
1241 /***********************************************/
1242 
1243 
1248 
1249 int KVSignal::FIR_ApplySmoothingSpline(double l, int nbits)
1250 {
1251  // This method is never called with nbits>2, therefore nmax=50 ALWAYS
1252  // and dynamic arrays xvec & yvec can safely be of fixed size
1253  // If ever we want to use nbits>2, this will have to be changed
1254 
1255  if (l < 0.1) return -1;
1256  int i;
1257  double x0 = ApplyNewton(l, 1000);
1258  double r = sqrt(x0);
1259  double a = (1 - 24 * l) / (6 * l);
1260  double cphi = -a * r / (2 * (r * r + 1));
1261  if ((cphi < -1) || (cphi > 1) || (l < 0.1)) {
1262  printf("Error Aborting on FIR_ApplySmoothingSpline\n");
1263  return -1;
1264  }
1265  double sphi = sqrt(1 - cphi * cphi);
1266  double Re = sqrt(x0) * cphi;
1267  double Im = sqrt(x0) * sphi;
1268  double a1, a2, b1, b2, t;
1269  t = 4 * Re * Re * (x0 - 1) / (x0 + 1) + 1 - x0 * x0;
1270  b2 = 1 / (l * t);
1271  a2 = -2 * Re * x0 * b2 / (1 + x0);
1272  b1 = -x0 * x0 * b2;
1273  a1 = -a2;
1274  double czr, czi;
1275  czr = a1 / 2;
1276  czi = (-a1 * Re - b1) / (2 * Im);
1277  double phib, phiz;
1278  phiz = atan2(sphi, cphi);
1279  phib = atan2(czi, czr);
1280  double roB;
1281  roB = sqrt(czr * czr + czi * czi);
1282  double roZ = sqrt(x0);
1283  int nfloat = 0;
1284  int nmax(50);
1285  double imax, fmax;
1286  if (nbits > 2) {
1287  //Determination of best notation
1288  //1 bit always for the sign
1289  //#integer bit depends on output evaluated in 0//
1290  //#fixed to 0, l>0.1
1291  nfloat = nbits - 1;
1292  //1 represented as 2^(nfloats)...//
1293  imax = ((nbits + 1) * log(2) + log(roB)) / log(roZ) - 1.;
1294  nmax = floor(imax);
1295  do {
1296  fmax = std::abs(-2 * roB * cos(phib - (nmax + 1) * phiz) / pow(roZ, nmax + 1));
1297  if (fmax * pow(2, nfloat + 1) < 1) nmax--;
1298  }
1299  while (fmax * pow(2, nfloat + 1) < 1);
1300  }
1301  double* xvec = new double[2 * nmax + 1];
1302  double* yvec = new double[2 * nmax + 1];
1303  if (nbits > 2) {
1304  for (i = 0; i <= nmax; i++) {
1305  yvec[nmax + i] = yvec[nmax - i] = 0;
1306  xvec[nmax + i] = xvec[nmax - i] = ((double)floor(-2 * roB * cos(phib - (i + 1) * phiz) / pow(roZ, i + 1) * pow(2, nfloat) + 0.5)) / pow(2, nfloat);
1307  }
1308  }
1309  else {
1310  for (i = 0; i <= nmax; i++) {
1311  yvec[nmax + i] = yvec[nmax - i] = 0;
1312  xvec[nmax + i] = xvec[nmax - i] = -2 * roB * cos(phib - (i + 1) * phiz) / pow(roZ, i + 1);
1313  }
1314  }
1315  FIR_ApplyRecursiveFilter(0, 2 * nmax + 1, xvec, yvec, 0);
1316  ShiftLeft(nmax * fChannelWidth);
1317  delete [] xvec;
1318  delete [] yvec;
1319  return 0;
1320 }
1321 
1322 
1323 /***********************************************/
1324 
1326 
1327 double KVSignal::ApplyNewton(double l, double X0)
1328 {
1329  double a = (1 - 24 * l) / (6 * l);
1330  double b = (4 + 36 * l) / (6 * l);
1331  double A = 2 - b;
1332  double B = 2 + a * a - 2 * b;
1333  Double_t x1, x0, x2, x3;
1334  double der, fx;
1335  double fxold1;
1336  x0 = X0;
1337  x1 = X0;
1338  x2 = x0;
1339  fx = pow(x1, 4) + A * pow(x1, 3) + B * pow(x1, 2) + A * x1 + 1;
1340  fxold1 = fx + 1;
1341  int fexit = 0;
1342  int loopcount = 0;
1343  do {
1344  der = 4 * pow(x1, 3) + 3 * A * pow(x1, 2) + 2 * B * x1 + A;
1345  x3 = x2;
1346  x2 = x0;
1347  x0 = x1;
1348  x1 = x0 - fx / der;
1349  if (x1 == x2) {
1350  x1 = (x1 + x0) / 2.;
1351  loopcount++;
1352  }
1353  else if (x1 == x3) {
1354  x1 = (x1 + x0 + x2) / 3.;
1355  loopcount++;
1356  }
1357  if ((x1 == x0) && (x1 == x2) && (x1 == x3)) fexit = 1;
1358  if (loopcount == 100) fexit = 1;
1359  fxold1 = fx;
1360  fx = pow(x1, 4) + A * pow(x1, 3) + B * pow(x1, 2) + A * x1 + 1;
1361  }
1362  while (((fx > 0.000000001) || (fxold1 != fx)) && (fexit == 0));
1363  return x1;
1364 }
1365 
1366 /***********************************************/
1367 
1369 
1371 {
1372  double tsamp = t / fChannelWidth;
1373  int n0 = floor(tsamp);
1374  double tres = tsamp - n0;
1375  double res = 0;
1376  if (n0 == 0)return 0;
1377  else {
1378  for (int i = -1; i < 3; i++) {
1379  res += fAdc.At(n0 + i) * EvalCubicSpline(tres - i);
1380  }
1381  }
1382  return res;
1383 }
1384 
1385 /***********************************************/
1386 
1388 
1390 {
1391  double ax = TMath::Abs(X);
1392  if (ax > 2) return 0;
1393  else if (ax > 1) return pow(2 - ax, 3) / 6.;
1394  else return pow(ax, 3) / 2. - ax * ax + 2. / 3.;
1395 }
1396 
1397 /***********************************************/
1398 
1402 
1403 double KVSignal::FindTzeroCFDCubic_rev(double level, double tend, int Nrecurr)
1404 {
1405  // recurr=1 means: linear + 1 approx
1406  // recurr=0 == FindTzeroCFD
1407  /**************************************/
1408  float* data = fAdc.GetArray();
1409  int NSamples = fAdc.GetSize();
1410  double fmax = level * fAmplitude;
1411  /**** 1) ricerca del punto x2 tale che x2 e' il precedente di tcfd ****/
1412  int x2 = (int)(tend / fChannelWidth);
1413  if (x2 <= 0 || x2 >= NSamples) return -1;
1414  for (; x2 > 0 ; x2--)
1415  if (data[x2] > fmax)
1416  break;
1417  // x2--;
1418  return CubicInterpolation(data, x2, fmax, Nrecurr);
1419 }
1420 
1421 
1422 
1424 
1425 void KVSignal::FIR_ApplySemigaus(double tau_usec)
1426 {
1427  FIR_ApplyRCLowPass(tau_usec);
1428  FIR_ApplyRCLowPass(tau_usec);
1429  FIR_ApplyRCLowPass(tau_usec);
1430  FIR_ApplyRCLowPass(tau_usec);
1431 
1432  FIR_ApplyRCHighPass(tau_usec);
1433 
1434  Multiply(1. / (32. / 3.*TMath::Exp(-4.))); // normalizzazione
1435 }
1436 
1437 
1438 
1439 
1443 
1444 void KVSignal::FIR_ApplyRCLowPass(double time_usec, int reverse)
1445 {
1446  // f=1/(2*pi*tau) se tau[ns] allora f->[GHz]
1447  // fsampling=1/fChannelWidth [GHz]
1448 #define DUEPI 6.28318530717958623
1449  // printf("fChannelWidth=%f\n",fChannelWidth);
1450  double f = 1. / (DUEPI * time_usec * 1000.) * fChannelWidth;
1451  double x = TMath::Exp(-DUEPI * f);
1452  double a0 = 1 - x;
1453  double b = x;
1454  double a = 0;
1455  // printf("f=%f, x=%f\n",x,f);
1456  FIR_ApplyRecursiveFilter(a0, 1, &a, &b, reverse);
1457 }
1458 
1459 
1460 
1465 
1466 void KVSignal::FIR_ApplyRCHighPass(double time_usec, int reverse)
1467 {
1468  // f=1/(2*pi*tau) se tau[ns] allora f->[GHz]
1469  // fsampling=1/fChannelWidth [GHz]
1470 
1471  // printf("fChannelWidth=%f\n",fChannelWidth);
1472  double f = 1. / (DUEPI * time_usec * 1000.) * fChannelWidth;
1473  double x = TMath::Exp(-DUEPI * f);
1474  double a0 = (1 + x) / 2.;
1475  double a1 = -(1 + x) / 2.;
1476  double b1 = x;
1477  // printf("f=%f, x=%f\n",x,f);
1478  FIR_ApplyRecursiveFilter(a0, 1, &a1, &b1, reverse);
1479 }
1480 
1481 #undef DUEPI
1482 
1483 
1486 
1487 void KVSignal::FIR_ApplyRecursiveFilter(double a0, int N, double* a, double* b, int reverse)
1488 {
1489  // signal will be: y[n]=a0*x[n]+sum a[k] x[k] + sum b[k] y[k]
1490  int NSamples = fAdc.GetSize();
1491  double* datay = new double[NSamples];
1492  float* datax = fAdc.GetArray();
1493  // memset(datay, 0, NSamples*sizeof(float)); //azzero l'array.
1494  /*----------------------------------------------*/
1495  int i = 0, k = 0;
1496  switch (reverse) {
1497  case 0:// direct
1498  for (i = 0; i < N; i++) { // primo loop su Npunti
1499  datay[i] = a0 * datax[i];
1500  for (k = 0; k < i; k++)
1501  datay[i] += a[k] * datax[i - k - 1] + b[k] * datay[i - k - 1];
1502  }
1503  for (i = N; i < NSamples; i++) { //secondo loop. cambia l'indice interno.
1504  datay[i] = a0 * datax[i];
1505  for (k = 0; k < N; k++)
1506  datay[i] += a[k] * datax[i - k - 1] + b[k] * datay[i - k - 1];
1507  }
1508  break; // end of direct
1509  case 1: //reverse: cut & paste from direct and NSamples-1-
1510  for (i = 0; i < N; i++) { // primo loop su Npunti
1511  datay[NSamples - 1 - i] = a0 * datax[NSamples - 1 - i];
1512  for (k = 0; k < i; k++)
1513  datay[NSamples - 1 - i] += a[k] * datax[NSamples - 1 - (i - k - 1)]
1514  + b[k] * datay[NSamples - 1 - (i - k - 1)];
1515  }
1516  for (i = N; i < NSamples; i++) { //secondo loop. cambia l'indice interno.
1517  datay[NSamples - 1 - i] = a0 * datax[NSamples - 1 - i];
1518  for (k = 0; k < N; k++)
1519  datay[NSamples - 1 - i] += a[k] * datax[NSamples - 1 - (i - k - 1)]
1520  + b[k] * datay[NSamples - 1 - (i - k - 1)];
1521  }
1522  break;
1523  case -1: // bidirectional
1524  FIR_ApplyRecursiveFilter(a0, N, a, b, 0);
1525  FIR_ApplyRecursiveFilter(a0, N, a, b, 1);
1526  delete [] datay;
1527  return;
1528  default:
1529  printf("ERROR in %s: reverse=%d not supported\n", __PRETTY_FUNCTION__, reverse);
1530  }// end of reverse switch.
1531  /*----------------------------------------------*/
1532  // void *memcpy(void *dest, const void *src, size_t n);
1534  for (int i = 0; i < NSamples; i++)
1535  datax[i] = (float)datay[i];
1536  delete [] datay;
1537 }
1538 
1539 
1540 
1542 
1543 void KVSignal::FIR_ApplyMovingAverage(int npoints) // causal moving average
1544 {
1545  TArrayF sorig = fAdc;
1546  float* data = fAdc.GetArray();
1547  float* datao = sorig.GetArray();
1548 
1549  for (int n = npoints; n < GetNSamples(); n++)
1550  data[n] = data[n - 1] + (datao[n] - datao[n - npoints]) / npoints;
1551  for (int n = 0; n < npoints; n++) data[n] = data[npoints]; // first npoints samples are put equal to first good value
1552 
1553 }
1554 
1555 
1556 
1557 
1559 
1561 {
1562 
1563  KVDigitalFilter deconv_pa1, lp1, int1;
1566  deconv_pa1 = KVDigitalFilter::CombineStagesMany(&lp1, &int1);
1567 
1568  deconv_pa1.ApplyTo(this);
1569  Multiply(fChannelWidth / tauRC / 1000.);
1570 }
1571 
1572 
1573 
1576 
1578 {
1579 // Info("ApplyModifications","called with %d",((newSignal==0)?0:1));
1580  if (!newSignal) newSignal = this;
1581 
1582  Int_t nn = fAdc.GetSize();
1583  if (nsa > 0 && nsa < nn) nn = nsa;
1584  if (newSignal->InheritsFrom("KVSignal"))((KVSignal*)newSignal)->SetChannelWidth(fChannelWidthInt);
1585  for (int ii = 0; ii < nn; ii++) newSignal->SetPoint(ii, ii * fChannelWidthInt, fAdc.At(ii));
1586 }
1587 
1588 
1589 
1590 
1592 
1594 {
1595  for (int i = 0; i < fAdc.GetSize(); i++) fAdc.AddAt(fAdc.At(i)*fact, i);
1596 }
1597 
1598 
1599 
1601 
1603 {
1604  for (int i = 0; i < fAdc.GetSize(); i++) fAdc.AddAt(fAdc.At(i) + fact, i);
1605 }
1606 
1607 
1608 /***************************************************************************/
1609 
1611 
1612 void KVSignal::ShiftLeft(double tshift)//shift is in ns
1613 {
1614  if (fAdc.GetSize() <= 0) return;
1615  if (tshift < 0) {
1616  ShiftRight(-tshift);
1617  return;
1618  }
1619 
1620  int shift = (int)floor(tshift / fChannelWidth);
1621  if (shift == 0) return;
1622  for (int i = 0; i < fAdc.GetSize() - shift; i++)
1623  fAdc.AddAt(fAdc.At(i + shift), i);
1624  fAdc.Set(fAdc.GetSize() - shift);
1625 }
1626 
1627 /***************************************************************************/
1628 
1630 
1631 void KVSignal::ShiftRight(double tshift)//shift is in ns
1632 {
1633  if (fAdc.GetSize() <= 0) return;
1634  if (tshift < 0) {
1635  ShiftLeft(-tshift);
1636  return;
1637  }
1638 
1639  int shift = (int)floor(tshift / fChannelWidth);
1640  if (shift == 0) return;
1641 
1642  fAdc.Set(fAdc.GetSize() + shift);
1643  for (int i = fAdc.GetSize() - 1; i >= shift; i--)
1644  fAdc.AddAt(fAdc.At(i - shift), i);
1645  for (int i = 0; i < shift; i++)
1646  fAdc.AddAt(fAdc.At(shift), i);
1647 }
1648 
1649 /***************************************************************************/
1650 
1652 
1654 {
1655  this->Draw();
1656  getchar();
1657 }
1658 
1659 
1660 
1663 
1664 KVSignal* KVSignal::MakeSignal(const char* sig_type)
1665 {
1666  // Create new KVSignal instance corresponding to sig_type
1667 
1668  TPluginHandler* ph = KVBase::LoadPlugin("KVSignal", sig_type);
1669  if (!ph) {
1670  ::Error("KVSignal::MakeSignal", "No plugin found for : %s", sig_type);
1671  return nullptr;
1672  }
1673  KVSignal* sig = (KVSignal*)ph->ExecPlugin(0);
1674  return sig;
1675 }
1676 
1677 
1678 
int Int_t
ROOT::R::TRInterface & r
#define f(i)
#define e(i)
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
#define X(type, name)
#define N
winID w
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char y1
char name[80]
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:796
static KVDigitalFilter BuildRCLowPassDeconv(const double &tau_usec, const double &tau_clk)
void ApplyTo(double *data, const int N, int reverse=0) const
static KVDigitalFilter BuildIntegrator(const double &tau_clk)
static KVDigitalFilter CombineStagesMany(const KVDigitalFilter *f1, const KVDigitalFilter *f2, const KVDigitalFilter *f3=NULL, const KVDigitalFilter *f4=NULL, const KVDigitalFilter *f5=NULL, const KVDigitalFilter *f6=NULL, const KVDigitalFilter *f7=NULL, const KVDigitalFilter *f8=NULL, const KVDigitalFilter *f9=NULL, const KVDigitalFilter *f10=NULL)
se ne devi combinare + di 1 IN CASCATA!
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Double_t GetDoubleValue(const Char_t *name) const
const Char_t * GetNameAt(Int_t idx) const
Int_t GetNpar() const
return the number of stored parameters
void SetTauRC(Int_t taurc)
Definition: KVSignal.h:270
Double_t ComputeCFDThreshold(Double_t threshold=0.5)
calculate the time during which the signal is higher than th*fAmplitude
Definition: KVSignal.cpp:351
void FIR_ApplyMovingAverage(int npoints)
Definition: KVSignal.cpp:1543
Double_t CubicInterpolation(float *data, int x2, double fmax, int Nrecurr)
Definition: KVSignal.cpp:975
void Add(Double_t fact)
Definition: KVSignal.cpp:1602
Bool_t IsLongEnough() const
Definition: KVSignal.cpp:109
void ChangeChannelWidth(Double_t newwidth)
Definition: KVSignal.cpp:286
Double_t GetShaperRiseTime() const
Definition: KVSignal.h:241
virtual Double_t ComputeDuration(Double_t th=0.2)
calculate the time during which the signal is higher than th*fAmplitude
Definition: KVSignal.cpp:321
static int FFT(unsigned int p_nSamples, bool p_bInverseTransform, double *p_lpRealIn, double *p_lpImagIn, double *p_lpRealOut, double *p_lpImagOut)
Definition: KVSignal.cpp:774
void SetInterpolation(Bool_t with=kTRUE)
Definition: KVSignal.h:282
void ApplyModifications(TGraph *newSignal=0, Int_t nsa=-1)
apply modifications of fAdc to the original signal
Definition: KVSignal.cpp:1577
virtual void RemoveBaseLine()
Definition: KVSignal.cpp:406
Double_t fEndLine
mean value of the signal line at the end
Definition: KVSignal.h:24
Double_t fYmax
raw min/max of the signal
Definition: KVSignal.h:21
void SetShaperRiseTime(Double_t rise)
Definition: KVSignal.h:233
void FIR_ApplyRCLowPass(double time_usec, int reverse=0)
Definition: KVSignal.cpp:1444
Double_t fAmplitude
results of signal treatement
Definition: KVSignal.h:17
double FindTzeroCFDCubic_rev(double level, double tend, int Nrecurr)
Definition: KVSignal.cpp:1403
virtual void TreateSignal()
Definition: KVSignal.cpp:212
virtual Double_t ComputeBaseLine()
Definition: KVSignal.cpp:303
virtual void BuildCubicSplineSignal()
Definition: KVSignal.cpp:1163
void Set(Int_t n) override
Definition: KVSignal.cpp:118
Bool_t ComputeMeanAndSigma(Int_t start, Int_t stop, Double_t &mean, Double_t &sigma)
compute mean value and rms of a subset of samples
Definition: KVSignal.cpp:505
virtual double EvalCubicSpline(double X)
Definition: KVSignal.cpp:1389
Double_t fSigmaBase
base line rms
Definition: KVSignal.h:23
virtual double GetDataInter(double t)
Definition: KVSignal.cpp:1013
void SetData(Int_t nn, Double_t *xx, Double_t *yy)
operation on data arrays
Definition: KVSignal.cpp:130
void SetInterpolatedChannelWidth(double width)
Definition: KVSignal.h:286
virtual double GetDataCubicSpline(double t)
see HSIEH S.HOU IEEE Trans. Acoustic Speech, vol. ASSP-26, NO.6, DECEMBER 1978
Definition: KVSignal.cpp:1053
void ApplyWindowing(int window_type=3)
fast fourier transform and windowing of the signal (modify only fAdc)
Definition: KVSignal.cpp:738
Int_t GetNSamples() const
Definition: KVSignal.h:158
void print_psa_parameters() const
Definition: KVSignal.cpp:221
virtual void LoadPSAParameters()
Definition: KVSignal.cpp:193
Double_t GetAmplitude() const
Definition: KVSignal.h:220
void SetPoleZeroCorrection(Bool_t with=kTRUE)
Definition: KVSignal.h:266
Bool_t fWithInterpolation
use of interpolation or not
Definition: KVSignal.h:38
Double_t fChannelWidth
channel width in ns
Definition: KVSignal.h:30
Int_t fFirstBL
Definition: KVSignal.h:32
Double_t GetBLFirst() const
Definition: KVSignal.h:171
bool IsOK()
Definition: KVSignal.cpp:99
Double_t fYmin
Definition: KVSignal.h:21
static KVSignal * MakeSignal(const char *sig_type)
Create new KVSignal instance corresponding to sig_type.
Definition: KVSignal.cpp:1664
void ShiftLeft(double)
---------------— OPERATORI ------------------—//
Definition: KVSignal.cpp:1612
Double_t fSigmaEnd
rms value of the signal line at the end
Definition: KVSignal.h:25
Double_t fBaseLine
base line mean value
Definition: KVSignal.h:22
Double_t ARC_CFD(Double_t threshold=0.3, Double_t tdelay=10)
Interpolations.
Definition: KVSignal.cpp:466
Double_t fChannelWidthInt
internal parameter channel width of interpolated signal in ns
Definition: KVSignal.h:46
void SetBaseLineLength(Int_t length, Int_t first=0)
Definition: KVSignal.h:166
Double_t fIMax
position of the maximum in channel
Definition: KVSignal.h:19
virtual double GetDataInterCubic(double t)
Definition: KVSignal.cpp:1032
Double_t ComputeAmplitude()
Compute and return the absolute value of the signal amplitude.
Definition: KVSignal.cpp:431
KVSignal()
Default constructor.
Definition: KVSignal.cpp:50
void Multiply(Double_t fact)
multiply the signal (modify only fAdc)
Definition: KVSignal.cpp:1593
virtual void BuildSmoothingSplineSignal()
Definition: KVSignal.cpp:1236
void init()
Definition: KVSignal.cpp:21
void FIR_ApplyRCHighPass(double time_usec, int reverse=0)
Definition: KVSignal.cpp:1466
virtual double GetDataSmoothingSplineLTI(double t)
Definition: KVSignal.cpp:1370
void SetShaperFlatTop(Double_t flat)
Definition: KVSignal.h:237
int FIR_ApplySmoothingSpline(double l, int nbits=-1)
Definition: KVSignal.cpp:1249
Int_t fLastBL
first and last channel number to compute the base line
Definition: KVSignal.h:32
TArrayF fAdc
Definition: KVSignal.h:15
void TestDraw()
Definition: KVSignal.cpp:1653
void Print(Option_t *chopt="") const override
Definition: KVSignal.cpp:240
Bool_t IsFired()
ComputeBaseLine and ComputeEndLine methods have to be called before.
Definition: KVSignal.cpp:393
void SetADCData()
Definition: KVSignal.cpp:152
void SetChannelWidth(double width)
Definition: KVSignal.h:137
Double_t GetBLLength() const
Definition: KVSignal.h:175
Double_t GetShaperFlatTop() const
Definition: KVSignal.h:245
Double_t ComputeRiseTime()
Definition: KVSignal.cpp:448
Double_t fTMax
position of the maximum in ns
Definition: KVSignal.h:20
Double_t GetInterpolatedChannelWidth() const
Definition: KVSignal.h:290
void FIR_ApplyTrapezoidal(double trise, double tflat)
different shapers (modify only fAdc)
Definition: KVSignal.cpp:651
virtual void SetDefaultValues()
To be defined in child class.
Definition: KVSignal.cpp:203
void ShiftRight(double)
Definition: KVSignal.cpp:1631
void FIR_ApplyRecursiveFilter(double a0, int N, double *a, double *b, int reverse)
signal will be: y[n]=a0*x[n]+sum a[k] x[k] + sum b[k] y[k]
Definition: KVSignal.cpp:1487
KVSignal * ConvertTo(const Char_t *type)
Definition: KVSignal.cpp:85
double ApplyNewton(double l, double x0)
Definition: KVSignal.cpp:1327
virtual void ComputeRawAmplitude(void)
Definition: KVSignal.cpp:252
Double_t FindTzeroCFDCubic(double level, int Nrecurr)
Definition: KVSignal.cpp:697
void FIR_ApplySemigaus(double tau_usec)
Definition: KVSignal.cpp:1425
Bool_t fWithPoleZeroCorrection
use or nor pole zero correction
Definition: KVSignal.h:37
double FindTzeroLeadingEdgeCubic(double LEVEL, int Nrecurr)
Definition: KVSignal.cpp:488
Double_t fRiseTime
rise time of the signal
Definition: KVSignal.h:18
virtual void UpdatePSAParameter(KVNameValueList *par)
Definition: KVSignal.cpp:165
Bool_t fPSAIsDone
indicate if PSA has been done
Definition: KVSignal.h:45
TH1 * FFT2Histo(int output, TH1 *hh=0)
Definition: KVSignal.cpp:916
void PoleZeroSuppression(Double_t tauRC)
Definition: KVSignal.cpp:1560
virtual void BuildCubicSignal()
Definition: KVSignal.cpp:1198
void BuildReverseTimeSignal()
Definition: KVSignal.cpp:418
Double_t GetTauRC() const
Definition: KVSignal.h:274
Bool_t TestWidth() const
Definition: KVSignal.cpp:270
virtual Double_t ComputeEndLine()
Definition: KVSignal.cpp:376
Double_t GetRiseTime() const
Definition: KVSignal.h:211
Double_t GetChannelWidth() const
Definition: KVSignal.h:142
void SetAmplitudeTriggerValue(Double_t val)
Definition: KVSignal.h:317
Double_t * GetArray()
Float_t * GetArray()
Double_t GetAt(Int_t i) const override
Float_t At(Int_t i) const
void AddAt(Float_t c, Int_t i)
void Set(Int_t n) override
Int_t GetSize() const
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Double_t * GetY() const
Int_t GetN() const
Double_t * fY
Double_t * GetX() const
void Draw(Option_t *chopt="") override
void SetNameTitle(const char *name="", const char *title="") override
virtual void Set(Int_t n)
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
virtual Double_t GetBinCenter(Int_t bin) const
TAxis * GetYaxis()
virtual Int_t Fill(const char *name, Double_t w)
virtual void SetBinContent(Int_t bin, Double_t content)
virtual Double_t GetBinContent(Int_t bin) const
virtual void SetStats(Bool_t stats=kTRUE)
virtual TMatrixTBase< Element > & SetMatrixArray(const Element *data, Option_t *option="")
const Element * GetMatrixArray() const override
void Mult(const TMatrixT< Element > &a, const TMatrixT< Element > &b)
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
Longptr_t ExecPlugin(int nargs)
const char * Data() const
Expr< UnaryOp< Sqrt< T >, SMatrix< T, D, D2, R >, T >, T, D, D2, R > sqrt(const SMatrix< T, D, D2, R > &rhs)
RVec< PromoteType< T > > cos(const RVec< T > &v)
RVec< PromoteType< T > > floor(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
RVec< PromoteType< T > > ceil(const RVec< T > &v)
RVec< PromoteType< T > > log(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > atan2(const T0 &x, const RVec< T1 > &v)
RVec< PromoteType< T > > sin(const RVec< T > &v)
const Double_t sigma
Double_t x[n]
const Int_t n
TH1 * h
rec
start
Int_t Nint(T x)
Double_t Exp(Double_t x)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)
TLine l
TArc a
ClassImp(TPyArg)