StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
EEmcSectorFit.cxx
1 
15 #include <cassert>
16 
17 #include "EEmcSectorFit.h"
18 #include "eeSinglePeak.h"
19 #include "TH1F.h"
20 #include "TCanvas.h"
21 #include "TF1.h"
22 #include "TString.h"
23 #include <iostream>
24 #include <algorithm>
25 #include "TLine.h"
26 #include "TList.h"
27 ClassImp(EEmcSectorFit);
28 
29 // ----------------------------------------------------------------------------
30 // default constructor has enough parameters for 10 gammas per plane
31 EEmcSectorFit::EEmcSectorFit(Int_t max) : TMinuit(4*max)
32 {
33  fLwarn=false;
34  SetPrintLevel(-1);
35  Command("SET ERR 1");
36  mSMD[0]=0;
37  mSMD[1]=0;
38  doPermutations = true;
39  mNDF=0;
40  mChi2=0.;
41 }
42 
43 
45 {
46 }
47 
48 // ----------------------------------------------------------------------------
49 Double_t EEmcSectorFit::FitFunc( Double_t x, Int_t plane ) const
50 {
51  // loop over all gammas
52  Double_t sum = 0.;
53  for ( UInt_t i=0;i<yield.size();i++ )
54  {
55  Double_t a=yield[i];
56  Double_t s=sigma[i];
57  Double_t m=(plane==0)?umean[i]:vmean[i];
58  Double_t X[]={x,0.,0.};
59  Double_t P[]={a,m,s,0.2,3.5}; // norm, mean, sigma, frac2, rel width
60  sum += eeSinglePeak(X,P);
61  }
62  return sum;
63 }
64 // ----------------------------------------------------------------------------
65 Int_t EEmcSectorFit::Eval(Int_t np,Double_t* gr,Double_t& chi2,Double_t* par,Int_t flg)
66 {
67 
68  // initialize chi2 to zero
69  Double_t mychi2 = 0.;
70  mChi2 = 0.;
71  mNDF = 0;
72 
73  // pass paramerters to the arrays containing parameters
74  for ( UInt_t i=0;i<yield.size();i++ )
75  {
76  yield[i] = par[4*i+0];
77  sigma[i] = par[4*i+1];
78  umean[i] = par[4*i+2];
79  vmean[i] = par[4*i+3];
80  }
81 
82  // loop over both planes
83  for ( Int_t plane=0;plane<2; plane++ )
84  {
85 
86  // get histogram for this plane
87  TH1F *histo = mSMD[plane];
88  // loop over all smd strips
89  for ( Int_t strip=0;strip<288;strip++ )
90  {
91  // get n mips in this plane/strip
92  Double_t nmip = histo -> GetBinContent(strip+1);
93  // evaluate the fit function
94  Double_t x = (Double_t)strip + 0.5;
95  Double_t f = FitFunc(x, plane);
96  // add to chi2
97  if ( nmip > 0. ) {
98  mychi2 += (nmip-f)*(nmip-f)/nmip;
99  mNDF++;
100  }
101  // kludge to count 0's near mean against chi2
102  // need to go to a max likelyhood method
103  else if ( f > 0.499 ) {
104  mNDF++;
105  mychi2 += (nmip-f)*(nmip-f)/f;
106  }
107  }
108  }
109 
110  chi2 = mychi2;
111  mChi2 = mychi2;
112  mNDF -= 4*(int)yield.size();
113 
114  return 0;
115 
116 }
117 // ----------------------------------------------------------------------------
118 Double_t EEmcSectorFit::Residual( Int_t x, Int_t plane ) const
119 {
120  // zero residual if x is w/in +/- 2 strips of another gamma
121  for ( UInt_t i=0;i<yield.size();i++ )
122  {
123  Double_t xx=(plane==0)?umean[i]:vmean[i];
124  if ( TMath::Abs(xx-(Double_t)x-0.5) <= 1.0 ) return 0.;
125  }
126  TH1F *histo=mSMD[plane];
127  Int_t bin = x + 1;
128  Double_t r = histo->GetBinContent(bin) - FitFunc( (Double_t)x+0.5, plane );
129  return r;
130 }
131 // ----------------------------------------------------------------------------
132 Double_t EEmcSectorFit::Residual( Int_t x, Int_t plane, Int_t dx, Int_t side ) const
133 {
134 
135 
136  Int_t min;//=TMath::Max(x-dx,0);
137  Int_t max;//=TMath::Min(x+dx,288);
138 
139 
140  min=TMath::Max(x-dx,0);
141  max=TMath::Min(x+dx,288);
142 
143  if ( side==1 )
144  {
145  min=TMath::Max(x,0);
146  }
147  else if ( side==2 )
148  {
149  max=TMath::Min(x,288);
150  }
151 
152 
153  Double_t r=0.;
154  for ( Int_t xx=min;xx<=max;xx++ )
155  {
156  r += Residual( xx, plane );
157  }
158  return r;
159 }
160 // ----------------------------------------------------------------------------
161 Int_t EEmcSectorFit::MaxStrip(Int_t plane) const
162 {
163  Double_t max=0.;
164  Int_t imax=-1;
165  for ( Int_t i=0;i<288;i++ )
166  {
167  Double_t r=Residual(i,plane);
168  if ( r>max )
169  {
170  max=r;
171  imax=i;
172  }
173  }
174  return imax;
175 }
176 // ----------------------------------------------------------------------------
177 void EEmcSectorFit::AddCandidate(Double_t y, Double_t s, Double_t u, Double_t v)
178 {
179  // std::cout << "Adding candidate" << std::endl;
180  yield.push_back(y);
181  sigma.push_back(s);
182  umean.push_back(u);
183  vmean.push_back(v);
184 #if 0
185  TLine *lU = new TLine(u,0.,u,y);lU->SetLineColor(2);
186  TLine *lV = new TLine(v,0.,v,y);lV->SetLineColor(2);
187  mSMD[0]->GetListOfFunctions()->Add(lU);
188  mSMD[1]->GetListOfFunctions()->Add(lV);
189 #endif
190  InitParameters();
192 }
193 // ----------------------------------------------------------------------------
194 // initialzes parameters for the N-gamma fit
196 {
197  Int_t flg=0;
198  Command("CLEAR");
199  Command("SET ERR 1");
200  for ( Int_t i=0;i<(Int_t)yield.size();i++ )
201  {
202  mnparm(4*i+0, TString("yield"), yield[i], 0.1, 0.25*yield[i], 2.0*yield[i], flg );
203  mnparm(4*i+1, TString("sigma"), sigma[i], 0.1, 0.5, 2.5, flg );
204  mnparm(4*i+2, TString("umean"), umean[i], 0.1, 0.0, 288.0, flg );
205  mnparm(4*i+3, TString("vmean"), vmean[i], 0.1, 0.0, 288.0, flg );
206  }
207 }
208 // ----------------------------------------------------------------------------
209 void EEmcSectorFit::Draw(Option_t *opts)
210 {
211  // TCanvas *canvas = new TCanvas("c1","c1",800,400);
212  /*
213  TPad *canvas=gPad;
214  if ( !gPad ) {
215  gPad=(TPad *)new TCanvas("c1","c1",500,500);
216  gPad->Divide(2);
217  canvas=gPad;
218  }
219  */
220  // canvas->Divide(2);
221 
222  /*
223  mSMD[0]->GetListOfFunctions()->Delete();
224  mSMD[1]->GetListOfFunctions()->Delete();
225  */
226 
227  assert(mSMD[0]);
228  assert(mSMD[1]);
229 
230  Double_t umin=999.;
231  Double_t vmin=888.;
232  Double_t umax=-1.;
233  Double_t vmax=-1.;
234 
236  for ( UInt_t i=0;i<yield.size();i++ )
237  {
238  TString uname="fitu";uname+=i;
239  TString vname="fitv";vname+=i;
240  TF1 *fitu=new TF1(uname,eeSinglePeak,0.,288.,5);
241  TF1 *fitv=new TF1(vname,eeSinglePeak,0.,288.,5);
242  fitu->SetLineColor(4);
243  fitv->SetLineColor(4);
244  fitu->SetLineWidth(1);
245  fitv->SetLineWidth(1);
246  fitu->SetParameter(0, yield[i] );
247  fitu->SetParameter(1, umean[i] );
248  fitu->SetParameter(2, sigma[i] );
249  fitu->SetParameter(3, 0.2 );
250  fitu->SetParameter(4, 3.5 );
251  fitv->SetParameter(0, yield[i] );
252  fitv->SetParameter(1, vmean[i] );
253  fitv->SetParameter(2, sigma[i] );
254  fitv->SetParameter(3, 0.2 );
255  fitv->SetParameter(4, 3.5 );
256  mSMD[0]->GetListOfFunctions()->Add( fitu );
257  mSMD[1]->GetListOfFunctions()->Add( fitv );
258  umin=TMath::Min( fitu->GetParameter(1), umin );
259  umax=TMath::Max( fitu->GetParameter(1), umax );
260  vmin=TMath::Min( fitv->GetParameter(1), vmin );
261  vmax=TMath::Max( fitv->GetParameter(1), vmax );
262  }
263 
264  umin=TMath::Max(umin,1.0);
265  umax=TMath::Min(umax,287.0);
266  vmin=TMath::Max(vmin,1.0);
267  vmax=TMath::Min(vmax,287.0);
268 
269  if ( umin < umax )
270  mSMD[0]->GetXaxis()->SetRangeUser(umin-20.,umax+20.);
271  if ( vmin < vmax )
272  mSMD[1]->GetXaxis()->SetRangeUser(vmin-20.,vmax+20.);
273 
274 
275  // canvas->cd(1);
276  // mSMD[0]->Draw(opts);
277  // canvas->cd(2);
278  // mSMD[1]->Draw(opts);
279 
280 }
281 // ----------------------------------------------------------------------------
283 {
284 
285  if ( !doPermutations ) return;
286 
287  std::vector<Double_t> chi2vec;
288 
290  std::vector< std::vector<Double_t> > yields;
291  std::vector< std::vector<Double_t> > sigmas;
292  std::vector< std::vector<Double_t> > umeans;
293  std::vector< std::vector<Double_t> > vmeans;
294  std::vector< Double_t > mychi2;
295 
296  std::vector< Double_t > old_yield = yield;
297  std::vector< Double_t > old_sigma = sigma;
298  std::vector< Double_t > old_umean = umean;
299  std::vector< Double_t > old_vmean = vmean;
300 
302  while ( std::next_permutation( old_vmean.begin(), old_vmean.end() ) )
303  {
304 
306  vmean = old_vmean;
307 
309  InitParameters();
310 
312  for ( UInt_t i=0;i<sigma.size();i++ ) {
313  FixParameter(4*i+1);
314  }
316  Migrad();
318  mychi2.push_back( mChi2 );
319  yields.push_back( yield );
320  sigmas.push_back( sigma );
321  umeans.push_back( umean );
322  vmeans.push_back( vmean );
324  yield = old_yield;
325  sigma = old_sigma;
326  umean = old_umean;
327 
328  }
329 
331  Double_t min = 9.0E12;
332  for ( UInt_t i=0;i<mychi2.size();i++ )
333  {
334  if ( mychi2[i]< min )
335  {
336  min=mychi2[i];
337  yield=yields[i];
338  sigma=sigmas[i];
339  umean=umeans[i];
340  vmean=vmeans[i];
341  }
342  }
343 
345  InitParameters();
347  for ( UInt_t i=0;i<sigma.size();i++ ) {
348  Release(4*i+1);
349  }
350  Migrad();
351 
352 }
353 // ----------------------------------------------------------------------------
355 {
356  std::cout << "doPermutations=" << doPermutations << std::endl;
357  std::cout << "chi^2 =" << mChi2 << std::endl;
358  std::cout << "ndf =" << mNDF << std::endl;
359 }
360 // ----------------------------------------------------------------------------
361 void EEmcSectorFit::Clear(Option_t *opts)
362 {
363  yield.clear();
364  sigma.clear();
365  umean.clear();
366  vmean.clear();
367  Command("CLEAR");
368 }
369 // ----------------------------------------------------------------------------
370 void EEmcSectorFit::AddFits( TH1F *uu, TH1F *vv )
371 {
372 
373  assert(uu);
374  assert(vv);
375 
376  Double_t umin=999.;
377  Double_t vmin=888.;
378  Double_t umax=-1.;
379  Double_t vmax=-1.;
380 
382  for ( UInt_t i=0;i<yield.size();i++ )
383  {
384  TString uname="fitu";uname+=i;
385  TString vname="fitv";vname+=i;
386  TF1 *fitu=new TF1(uname,eeSinglePeak,0.,288.,5);
387  TF1 *fitv=new TF1(vname,eeSinglePeak,0.,288.,5);
388  fitu->SetLineColor(4);
389  fitv->SetLineColor(4);
390  fitu->SetLineWidth(1);
391  fitv->SetLineWidth(1);
392  fitu->SetParameter(0, yield[i] );
393  fitu->SetParameter(1, umean[i] );
394  fitu->SetParameter(2, sigma[i] );
395  fitu->SetParameter(3, 0.2 );
396  fitu->SetParameter(4, 3.5 );
397  fitv->SetParameter(0, yield[i] );
398  fitv->SetParameter(1, vmean[i] );
399  fitv->SetParameter(2, sigma[i] );
400  fitv->SetParameter(3, 0.2 );
401  fitv->SetParameter(4, 3.5 );
402  uu->GetListOfFunctions()->Add( fitu );
403  vv->GetListOfFunctions()->Add( fitv );
404  umin=TMath::Min( fitu->GetParameter(1), umin );
405  umax=TMath::Max( fitu->GetParameter(1), umax );
406  vmin=TMath::Min( fitv->GetParameter(1), vmin );
407  vmax=TMath::Max( fitv->GetParameter(1), vmax );
408  }
409 
410  umin=TMath::Max(umin,1.0);
411  umax=TMath::Min(umax,287.0);
412  vmin=TMath::Max(vmin,1.0);
413  vmax=TMath::Min(vmax,287.0);
414 
415  if ( umin < umax )
416  uu->GetXaxis()->SetRangeUser(umin-20.,umax+20.);
417  if ( vmin < vmax )
418  vv->GetXaxis()->SetRangeUser(vmin-20.,vmax+20.);
419 
420 
421 }
EEmcSectorFit(Int_t maxGammas=10)
Int_t mNDF
Degrees o&#39; freedom.
void print() const
print summary
void AddCandidate(Double_t yield, Double_t sigma, Double_t u, Double_t v)
Add a candidate to the list of candidate gammas.
void InitParameters()
Initialize parameters.
std::vector< Double_t > sigma
Width of N gammas.
Definition: EEmcSectorFit.h:94
void TryPermutations()
std::vector< Double_t > vmean
Mean V position of N gammas.
Definition: EEmcSectorFit.h:98
Double_t FitFunc(Double_t x, Int_t plane) const
Evaluate the N gamma fit for the specified plane.
Int_t MaxStrip(Int_t plane) const
Find maximum residual strip in specified plane. Returns strip index.
std::vector< Double_t > umean
Mean U position of N gammas.
Definition: EEmcSectorFit.h:96
virtual ~EEmcSectorFit()
Destructor.
TH1F * mSMD[2]
The histograms we fit.
Definition: EEmcSectorFit.h:89
Double_t mChi2
Chi^2 of the fit.
void Draw(Option_t *opts)
Draws the current fit.
virtual Int_t Eval(Int_t np, Double_t *gr, Double_t &x2, Double_t *p, Int_t flg)
Double_t Residual(Int_t x, Int_t plane) const
void Clear(Option_t *opts="")
Clear the array of photon candidates.
void AddFits(TH1F *u, TH1F *v)
Adds TF1 to histogram.
std::vector< Double_t > yield
Yield of N gammas.
Definition: EEmcSectorFit.h:92
Bool_t doPermutations
Flag to determine if we test all permutations or not.
Definition: EEmcSectorFit.h:84
TH1F * histo(Int_t plane)
Return the histogram for the specified plane.
Definition: EEmcSectorFit.h:74
Simultaneous fit of two smd planes to N gammas.
Definition: EEmcSectorFit.h:7