14 using namespace Diana;
36 err.SetDescription(__FILE__,__LINE__,
"Size of input QVectors mismatches");
73 if(p.Size() !=
fSize) {
79 Diana::QVector
diff = p;
107 double dummy, yb,chib,leftb,rightb;
121 err =
Parabola(xa,xb,xc,ya,yb,yc,amplitude,intJitter);
127 int low = floor(intJitter);
130 double chi1Low, chi1High;
155 double x = intJitter-low;
157 chi2 = (chi1High-chi1Low)*x+chi1Low;
170 if(intJitter > (
int)
fSize/2) intJitter-=
fSize;
178 QVector baseline(ret.Size());
179 baseline.Initialize(ret[0]);
195 for(
int i =
fMaxPos; i > 0; i--) {
202 if(fAvgPulseHalfTimeToMax < 1 || fAvgPulseHalfTimeToMax >=
fMaxPos) {
204 err.SetDescription(__FILE__,__LINE__,
"failed to autoset the maximum jitter");
212 err.SetDescription(__FILE__,__LINE__,
"failed to autoset the maximum jitter");
240 for(
size_t i = 0; i <
fSize; i++){
241 if(i <= averageNoise.Size()/2) averageNoise[i] *= 2.*(1-
cos(2.*pi/(averageNoise.Size())*i));
242 else averageNoise[i] *= 2.*(1-
cos(2.*pi/(averageNoise.Size())*(averageNoise.Size()-i)));
244 averagePulse.Differentiate();
251 QVector
ap = averagePulse.Mult(window);
263 anc.SetRe(averageNoise);
265 QVector SNR = ap1f.GetModulusSquare().Div(averageNoise);
266 double M = 1./SNR.Sum(
fSize-1,1);
283 for(
size_t i = 1; i <
fSize/2; i++) {
288 QVector filteredAverageNoise =
fFilter1.GetModulusSquare().Mult(averageNoise);
292 size_t cutOffFrequency =
fSize/2;
293 for( ; cutOffFrequency > 1; cutOffFrequency--) {
300 for(
size_t i = 1; i < cutOffFrequency; i++)
fSNRNorm[i] = SNR[i];
309 if(firData.
fM%2 == 0) firData.
fM--;
314 fir.
Filter(kernel,kernelout);
315 for(
size_t i = reduction/2; i <
fSize-reduction/2; i++) kernel[i]=kernelout[i-reduction/2];
325 for(
size_t i = 0; i <
fSize; i++) {
326 kernel[i] *= window2[i];
332 double integral = kernel.Sum(
fSize,0);
344 for(
size_t i = 0; i <
fSize; i++) {
345 if(kernel[i] < 0) add += kernel[i];
347 for(
size_t i = 0; i <
fSize; i++) {
349 if(integral > 0 && kernel[i] < 0) kernel[i] *= (add-integral)/add;
350 else if(integral < 0 && kernel[i] > 0) kernel[i] *= add/(add-integral);
372 for(
size_t i = 0; i <
fSize/2; i++) {
391 QVector autoCorrelation;
392 QVectorC noiseC(
fSize);
393 noiseC.Initialize(0);
395 fTransformer->TransformFromFreq(noiseC,autoCorrelation);
407 for(
size_t j = 0; j <
fSize; j++) {
411 ap1Shifted = averagePulse;
416 ap1Shifted = averagePulse;
417 ap1Shifted.Shift(j+1);
421 ap1Shifted = averagePulse;
422 ap1Shifted.Shift(j-1);
460 if(searchinterval == 0) searchinterval = 1;
462 size_t beforemax =
fFiltered1.GetSubVector(searchinterval,
fFiltered1.Size()-searchinterval).GetMaxIndex();
463 beforemax +=
fFiltered1.Size()-searchinterval;
465 size_t aftermax =
fFiltered1.GetSubVector(searchinterval).GetMaxIndex();
477 if(triggerpos < 0) triggerpos +=
fSize;
478 if(triggerpos < (
int)
fSize)
482 err.SetDescription(__FILE__,__LINE__,
"Fixed jitter provided is out of range");
490 err.SetDescription(__FILE__,__LINE__,
"Jitter mode not implemented");
497 std::stringstream msg;
498 msg<<
"Maximum position "<<
fOptimumJitter<<
" lies outside the filter effective length";
499 err.SetDescription(__FILE__,__LINE__,msg.str());
544 for(
size_t i = 1; i <
fSNRNorm.Size(); i++) {
546 chi2 += residuals[i];
552 err.SetDescription(__FILE__,__LINE__,
"Number of degrees of freedom is < 1");
566 std::vector<double> results;
579 results.push_back(chi2);
588 output.ShiftReal(jitter);
598 std::stringstream msg;
599 msg<<
"y "<<yb<<
" not at maximum. Boundaries: ["<<ya<<
" "<<yc<<
"]";
600 err.SetDescription(__FILE__,__LINE__,msg.str());
604 double detA = xa*xa*(xb-xc)-xb*xb*(xa-xc)+xc*xc*(xa-xb);
605 double detA1 = ya*(xb-xc)-yb*(xa-xc)+yc*(xa-xb);
606 double detA2 = xa*xa*(yb-yc)-xb*xb*(ya-yc)+xc*xc*(ya-yb);
607 double detA3 = xa*xa*(xb*yc-yb*xc)-xb*xb*(xa*yc-ya*xc)+xc*xc*(xa*yb-ya*xb);
609 double p0 = detA1/detA;
610 double p1 = detA2/detA;
611 double p2 = detA3/detA;
613 max = -p1*p1/(4.*p0)+p2;
616 if(maxPos <xa || maxPos >xc) {
618 std::stringstream msg;
619 msg<<
"Interpolated position "<<maxPos<<
" out of boundaries ["<<xa<<
" "<<xc<<
"]";
620 err.SetDescription(__FILE__,__LINE__,msg.str());
Diana::QComplex pow(const Diana::QComplex &z, double a)
Raise a complex number to a real power.
Diana::QVector cos(const Diana::QVector &v)
Data class for QFir (Ported from Calder)
error class with error type and description
void SetDescription(const std::string &descr)
set error description
static QVector ZeroPad(const QVector &input, size_t n_zeros, int Side=kMiddle, double zeroVal=0.)
Add zeros to the input.
static QVector GetWindow(WindowType wt, size_t size, size_t zeros=0, int coherent=0, int param=0)
create window and add zeros/2 to the left and zeros/2 to the right
QFir FIR low pass filter (Ported from Calder)
QError Filter(const Diana::QVector &input, Diana::QVector &output) const
size_t GetFilterReduction() const
Optimum filter implemented with windowing and zeros.
Diana::QVector fAverageNoiseForChi2
QError GetInterpolated(double &jitter, double &chi2, double &litude, double &integral, double &left, double &right) const
get values at interpolated chi^2 minimum. Three points around the minimum are used for a parabolic in...
QError fCheckForFilteredSamples
Diana::QVector NormalizeVector(const Diana::QVector &vec) const
std::vector< Diana::QVector > fDebugSpectra
std::vector< Diana::QVector > fDebugVectors
QError Parabola(double xa, double xb, double xc, double ya, double yb, double yc, double &min, double &minpos) const
QError GetHighSNRChi2(const double &threshold, double &chi2) const
get chi^2 (mean 0, variance 1) restricting the DoF to frequencies with SNR > threshold
virtual ~QOptimumFilter()
Diana::QVector fAveragePulseEnergySpectrum
Diana::QRealComplexFFT * fTransformer
Diana::QVector GetFilteredShifted() const
get filtered and shifted samples by fMaxPos
int fFilteredAveragePulseHalfWidth
int fAvgPulseHalfTimeToMax
Diana::QVector GetFitFunction(const double jitter, const double a1) const
Diana::QVector fFiltered1
double fFilteredAveragePulseHalfWidthValueLeft
size_t fEffectiveFilterLength
Diana::QVectorC fTransformedWaveform
QError fCheckForBuiltFilter
double fAvgPulseIntegral1
virtual QError ManipulateInputs()
QError SetJitter(JitterMode mode, int start=0)
Diana::QVector fAveragePulse1
QOptimumFilter(const Diana::QVector &ap1, const Diana::QVector &an, int maxJitter, bool useDiff=false, bool debugOn=false)
constructor
std::vector< Diana::QVectorC > fAveragePulse1Shifted
std::vector< bool > fValidSample
Diana::QVector fAverageNoise
std::vector< double > Get() const
const Diana::QVector & GetFiltered() const
get filtered samples
double fFilteredAveragePulseHalfWidthValueRight
QError Filter(const Diana::QVector &p)
filter. In case of failure an error is returned.
Diana::QVector fFilteredAverageNoise
double fFilteredAutoCorrelation
Wrapper for a specific QRealComplexFFT algorithm class.
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...