// $Id$ //----------------------------------------------------------------------- // The GSI Online Offline Object Oriented (Go4) Project // Experiment Data Processing at EE department, GSI //----------------------------------------------------------------------- // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH // Planckstr. 1, 64291 Darmstadt, Germany // Contact: http://go4.gsi.de //----------------------------------------------------------------------- // This software can be used under the license agreements as stated // in Go4License.txt file which is part of the distribution. //----------------------------------------------------------------------- #include "TGo4FitPeakFinder.h" #include "TMath.h" #include "TH1D.h" #include "TMatrixD.h" #include "TVectorD.h" #include "TArrayD.h" #include "TArrayI.h" #include "TSpectrum.h" #include "TGo4Fitter.h" #include "TGo4FitData.h" #include "TGo4FitModelPolynom.h" TGo4FitPeakFinder::TGo4FitPeakFinder() : TGo4FitterAction() { } TGo4FitPeakFinder::TGo4FitPeakFinder(const char* Name, const char* DataName, Bool_t ClearModels, Int_t PolOrder) : TGo4FitterAction(Name, "Peak finder action"), fiPeakFinderType(0), fxDataName(DataName), fbClearModels(ClearModels), fbUsePolynom(PolOrder>=0), fiPolynomOrder(PolOrder>=0 ? PolOrder : 0), fd0MinWidth(5.), fd0MaxWidth(30.), fd0MaxAmplFactor(0.2), fd1LineWidth(5.), fd2NoiseFactor(2.), fd2NoiseMinimum(5.), fi2ChannelSum(2) { } TGo4FitPeakFinder::~TGo4FitPeakFinder() { } void TGo4FitPeakFinder::SetupPolynomialBackground(Int_t PolynomOrder) { if (PolynomOrder<0) SetUsePolynom(kFALSE); else { SetUsePolynom(kTRUE); SetPolynomOrder(PolynomOrder); } } void TGo4FitPeakFinder::SetupForFirst(Double_t MaxAmplFactor, Double_t MinWidth, Double_t MaxWidth) { SetPeakFinderType(0); Set0MaxAmplFactor(MaxAmplFactor); Set0MinWidth(MinWidth); Set0MaxWidth(MaxWidth); } void TGo4FitPeakFinder::SetupForSecond(Double_t LineWidth) { SetPeakFinderType(1); Set1LineWidth(LineWidth); } void TGo4FitPeakFinder::SetupForThird(Double_t NoiseFactor, Double_t NoiseMinimum, Int_t ChannelSum) { SetPeakFinderType(2); Set2NoiseFactor(NoiseFactor); Set2NoiseMinimum(NoiseMinimum); Set2ChannelSum(ChannelSum); } void TGo4FitPeakFinder::DoAction(TGo4FitterAbstract* Fitter) { TGo4Fitter* fitter = dynamic_cast (Fitter); if (fitter==0) return; TGo4FitData* data = fitter->FindData(GetDataName()); if (data==0) return; if (GetClearModels()) fitter->DeleteModelsAssosiatedTo(data->GetName()); if (GetPeakFinderType()==0) SergeyLinevPeakFinder(fitter, data, GetUsePolynom() ? GetPolynomOrder() : -1, Get0MaxAmplFactor(), Get0MinWidth(), Get0MaxWidth()); if (GetPeakFinderType()==1) ROOTPeakFinder(fitter, data, GetUsePolynom() ? GetPolynomOrder() : -1, Get1LineWidth()); if (GetPeakFinderType()==2) HansEsselPeakFinder(fitter, data, 500, Get2ChannelSum(), Get2NoiseFactor(), Get2NoiseMinimum(), GetUsePolynom() ? GetPolynomOrder() : -1); } void TGo4FitPeakFinder::Print(Option_t* option) const { TGo4FitterAction::Print(option); } /* void TGo4FitPeakFinder::ROOTPeakFinder(TGo4Fitter* fitter, TGo4FitData* data, Int_t PolynomOrder, Double_t Sigma) { if ((fitter==0) || (data==0)) return; TGo4FitDataIter* iter = data->MakeIter(); if (iter==0) return; Int_t size = iter->CountPoints(); if ((size<10) || (iter->ScalesSize()!=1)) { delete iter; return; } TArrayF Bins(size), Scales(size); Int_t nbin = 0; if (iter->Reset()) do { Bins[nbin] = data->GetAmplValue() * iter->Value(); Scales[nbin] = iter->x(); nbin++; } while (iter->Next()); delete iter; if (PolynomOrder>=0) fitter->AddPolynomX(data->GetName(), "Pol", PolynomOrder); TSpectrum sp(100); sp.Search1(Bins.GetArray(), size, Sigma); for(Int_t n=0;nAddGauss1(data->GetName(), fitter->FindNextName("Gauss",n), pos, width); } } */ void TGo4FitPeakFinder::ROOTPeakFinder(TGo4Fitter* fitter, TGo4FitData* data, Int_t PolynomOrder, Double_t Sigma) { if ((fitter==0) || (data==0)) return; TGo4FitDataIter* iter = data->MakeIter(); if (iter==0) return; Int_t size = iter->CountPoints(); if ((size<10) || (iter->ScalesSize()!=1)) { delete iter; return; } TArrayD Bins(size), Scales(size), HScales(size+1); Int_t nbin = 0; if (iter->Reset()) do { Bins[nbin] = data->GetAmplValue() * iter->Value(); Double_t pos = iter->x(); Double_t width = iter->HasWidths() ? iter->Widths()[0] : 1.; Scales[nbin] = pos; HScales[nbin] = pos - width/2.; HScales[nbin+1] = pos + width/2; nbin++; } while (iter->Next()); delete iter; if (PolynomOrder>=0) fitter->AddPolynomX(data->GetName(), "Pol", PolynomOrder); TH1D histo("ROOTPeakFinder", "ROOTPeakFinder spectrum", size, HScales.GetArray()); histo.SetDirectory(0); for (Int_t i=0;i=size) right = size-1; Double_t pos = Scales[TMath::Nint(dindx)]; Double_t width = TMath::Abs(Scales[right]-Scales[left]); */ fitter->AddGauss1(data->GetName(), fitter->FindNextName("Gauss",n), pos, width); } } Double_t TGo4FitPeakFinder::CalcPolynom(const TArrayD& Coef, Double_t x) { Double_t power = 1., sum = 0.; for(Int_t n=0;n=size) rbound=size-1; for(Int_t i=lbound;i<=rbound;i++) use[i]=1; DefinePolynom(size, bins, scales, Coef, weight, backgr, use.GetArray()); } Bool_t FindValue(Double_t* bins, Double_t* backgr, Char_t* use, Int_t size, Int_t& p, Int_t dir, Double_t value) { p += dir; while ((p>=0) && (pMakeIter(); if (iter==0) return; Int_t size = iter->CountPoints(); if ((size<10) || (iter->ScalesSize()!=1)) { delete iter; return; } TArrayD Bins(size), Scales(size), Weights(size), Background(size); Weights.Reset(1.); Background.Reset(0.); Double_t* bins = Bins.GetArray(); Double_t* scales = Scales.GetArray(); Double_t* weights = Weights.GetArray(); Double_t* backgr = Background.GetArray(); Int_t nbin = 0; if (iter->Reset()) do { bins[nbin] = data->GetAmplValue() * iter->Value(); if (iter->StandardDeviation()>0) weights[nbin] = 1./iter->StandardDeviation(); scales[nbin] = iter->x(); nbin++; } while (iter->Next()); delete iter; if ((PolOrder>=0) && (PolOrder<(size+1)*5)) { Int_t nsegments = (PolOrder+1)*2; TArrayC usage(size); usage.Reset(0); for (Int_t nseg=0; nsegAddPolynomX(data->GetName(), "Pol", Coef); } Double_t max=0.; for(Int_t i=0;imax) max = zn; } AmplThreshold = AmplThreshold*max; TArrayC usage(size); usage.Reset(1); Char_t* use = usage.GetArray(); Bool_t validline = kFALSE; do { validline = kFALSE; Int_t pmax=-1; Double_t max=0.; for(Int_t i=0;imax)) { pmax = i; max = zn; } } Double_t sigma = TMath::Sqrt(1./weights[pmax]); if ((max<2.*sigma) || (max=size) rbound=size-1; for(Int_t i=lbound;i<=rbound;i++) use[i]=0; if(lok && rok && (width>=MinWidth) && (width<=MaxWidth) && (amplitude>AmplThreshold) && (amplitude>2*sigma)) fitter->AddGauss1(data->GetName(), fitter->FindNextName("Gauss",0), middle, width, amplitude); } } while(validline); } #include "f_find_peaks.c" void TGo4FitPeakFinder::HansEsselPeakFinder(TGo4Fitter* fitter, TGo4FitData* data, Int_t MaxNumPeaks, Int_t ChannelSum, Double_t NoiseFactor, Double_t NoiseMinimum, Int_t MinimasOrder) { if ((fitter==0) || (data==0) || (MaxNumPeaks<1)) return; TGo4FitDataIter* iter = data->MakeIter(); if (iter==0) return; Int_t size = iter->CountPoints(); if ((size<10) || (iter->ScalesSize()!=1)) { delete iter; return; } TArrayD Bins(size), Scales(size); Double_t* bins = Bins.GetArray(); Double_t* scales = Scales.GetArray(); Int_t nbin = 0; if (iter->Reset()) do { bins[nbin] = data->GetAmplValue() * iter->Value(); scales[nbin] = iter->x(); nbin++; } while (iter->Next()); delete iter; int NumPeaks = 0; TArrayI Minimas(MaxNumPeaks), Maximas(MaxNumPeaks), MaximaWidths(MaxNumPeaks); TArrayI PeaksLeft(MaxNumPeaks), PeaksRight(MaxNumPeaks), PeaksMaximum(MaxNumPeaks); TArrayD MinimaValues(MaxNumPeaks), MinimaScales(MaxNumPeaks), MaximaIntegrals(MaxNumPeaks); go4fit_find_peaks(bins, TYPE__DOUBLE, 0, size, ChannelSum, NoiseFactor, NoiseMinimum, 0, MaxNumPeaks, &NumPeaks, Minimas.GetArray(), MinimaValues.GetArray(), Maximas.GetArray(), MaximaWidths.GetArray(), MaximaIntegrals.GetArray(), PeaksLeft.GetArray(), PeaksMaximum.GetArray(), PeaksRight.GetArray(), 0, 0); if (NumPeaks<=0) return; Int_t NumMinimas = (NumPeaks=0) && (NumMinimas>1)) { Int_t order = MinimasOrder; if (order>=NumMinimas) order = NumMinimas-1; TArrayD Coef(order+1); DefinePolynom(NumMinimas, MinimaValues.GetArray(), MinimaScales.GetArray(), Coef); fitter->AddPolynomX(data->GetName(), "Pol", Coef); } for(int n=0;nAddGauss1(data->GetName(), fitter->FindNextName("Gauss",0), pos, width, ampl); } }