17 #include "Riostream.h"
24 #include "TSpectrum.h"
25 #include "TVirtualFitter.h"
27 #include "TDirectory.h"
34 Double_t fpeaks(Double_t *x, Double_t *par) {
35 Double_t result = par[0] + par[1]*x[0];
36 for (Int_t p=0;p<npeaks;p++) {
37 Double_t norm = par[3*p+2];
38 Double_t mean = par[3*p+3];
39 Double_t sigma = par[3*p+4];
40 result += norm*TMath::Gaus(x[0],mean,sigma);
45 void peaks(TH1* h, Int_t np=10, Int_t ij=0) {
47 npeaks = TMath::Abs(np);
48 if (! c1) c1 =
new TCanvas();
50 if (c2 && ij > 0) {c2->cd(ij); h->Draw(); c2->Update();}
54 TH1F *h2 = (TH1F*)h->Clone(
"h2");
56 TSpectrum *s =
new TSpectrum(2*npeaks);
57 Int_t nfound = s->Search(h,5,
"",0.05);
58 printf(
"Found %d candidate peaks to fit\n",nfound);
61 TH1 *hb = s->Background(h,20,
"same");
64 if (c2 && ij > 0) {c2->cd(ij); h->Draw(); c2->Update();}
69 TF1 *fline =
new TF1(
"fline",
"pol1",0,1000);
70 fline->FixParameter(1,0.);
71 h->Fit(
"fline",
"qnlw");
72 if (c2 && ij > 0) {c2->cd(ij+1); h->Draw(); c2->Update(); c1->cd(2);}
75 par[0] = fline->GetParameter(0);
76 par[1] = fline->GetParameter(1);
78 Float_t *xpeaks = s->GetPositionX();
80 for (Int_t p=0;p<nfound;p++) {
81 Float_t xp = xpeaks[p];
82 Int_t bin = h->GetXaxis()->FindBin(xp);
83 Float_t yp = h->GetBinContent(bin);
84 if (yp-3*TMath::Sqrt(yp) < fline->Eval(xp))
continue;
86 if (yp > ymax) ymax = yp;
91 cout <<
"Found " << npeaks <<
" useful peaks to fit" << endl;
94 TString LineH(
" {\""); LineH += h->GetName(); LineH +=
"\"";
96 struct ParErr_t {Double_t par, err;};
99 if (ymax > 2*par[0]) {
100 cout <<
"Now fitting: Be patient" << endl;
101 fit =
new TF1(
"fit",fpeaks,0,1000,2+3*npeaks);
102 TVirtualFitter::Fitter(h2,10+3*npeaks);
103 fit->SetParameter(0,par[0]);
104 fit->FixParameter(1,0.);
105 for (Int_t p = 0; p < npeaks; p++) {
106 fit->SetParName(3*p+2,Form(
"A%i",p));
107 fit->SetParLimits(3*p+2,0,1e6);
108 fit->SetParameter(3*p+2,par[3*p+2]);
109 fit->SetParName(3*p+3,Form(
"#mu%i",p));
110 fit->SetParLimits(3*p+3,TMath::Max(0.,par[3*p+3]-2), TMath::Min(240.,par[3*p+3]+2));
111 fit->SetParameter(3*p+3,par[3*p+3]);
112 fit->SetParName(3*p+4,Form(
"#sigma%i",p));
113 fit->SetParLimits(3*p+4,0.01,20);
114 fit->SetParameter(3*p+4,par[3*p+4]);
119 if (c2 && ij > 0) {c2->cd(ij); h2->Draw(
"same"); c2->Update(); c1->cd(2);}
120 fit->GetParameters(par);
121 for (Int_t p = 0; p<np;p++) {
122 if (p < npeaks && par[3*p+2] > 5*fit->GetParError(3*p+2) &&
123 par[3*p+2] > par[0]) {
124 if (TMath::Abs(par[3*p+4]) > 5.0) nbad++;
126 parErr[NP].par = par[3*p+3];
127 parErr[NP].err = TMath::Abs(par[3*p+4]);
128 for (Int_t i = 0; i < NP; i++) {
129 if (parErr[i].par > parErr[NP].par) {
130 ParErr_t temp = parErr[i];
131 parErr[i] = parErr[NP];
139 for (Int_t p = 0; p < np; p++) {
140 if (p < NP)
Line += Form(
",%7.2f,%5.2f",parErr[p].par,parErr[p].err);
144 if (nbad > 1) NP = -NP;
145 LineH += Form(
",%3i",NP);
146 cout << LineH <<
Line << endl;
147 out << LineH <<
Line << endl;
149 if (c2) c2->Update();
154 void FindPeaks(Int_t np=10) {
155 TString Out(
"Results.");
156 Out += gSystem->BaseName(gDirectory->GetName());
157 Out.ReplaceAll(
".root",
"");
158 Out.ReplaceAll(
" ",
"");
159 out.open(Out, ios::out);
160 TIter nextkey(gDirectory->GetListOfKeys() );
164 while ((key = (TKey*) nextkey())) {
165 TObject *obj = key->ReadObj();
166 if (! obj->IsA()->InheritsFrom(
"TH1" ) )
continue;
168 if (h1->GetEntries() < 1000)
continue;
172 Int_t nx = (Int_t) TMath::Sqrt(nxy) + 1;
173 Int_t ny = nxy/nx + 1;
174 c2 =
new TCanvas(
"Anodes",
"Anodes");
178 while ((key = (TKey*) nextkey())) {
179 TObject *obj = key->ReadObj();
180 if (! obj->IsA()->InheritsFrom(
"TH1" ) )
continue;
181 if ( obj->IsA()->InheritsFrom(
"TH1C" ) ||
182 obj->IsA()->InheritsFrom(
"TH1S" ) ||
183 obj->IsA()->InheritsFrom(
"TH1I" ) ||
184 obj->IsA()->InheritsFrom(
"TH1F" ) ) {
185 cout <<
"Found histogram " << obj->GetName() << endl;
187 if (h1->GetEntries() < 1000) {
188 TString LineH(
" {\""); LineH += h1->GetName(); LineH +=
"\"";
191 for (Int_t p = 0; p < np; p++)
Line +=
",0,0";
193 cout << LineH <<
Line << endl;
194 out << LineH <<
Line << endl;
201 cout <<
"Type something" << endl;