StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
QinvEbyECorrFctn.cxx
1 #include "StHbtMaker/CorrFctn/QinvEbyECorrFctn.h"
2 #include <cstdio>
3 
4 #ifdef __ROOT__
5 ClassImp(QinvEbyECorrFctn)
6 #endif
7  //____________________________
8  QinvEbyECorrFctn::QinvEbyECorrFctn(char* title, const int& nbins, const float& QinvLo, const float& QinvHi){
9  // set up numerator
10  // title = "Num Qinv (MeV/c)";
11  char TitNum[100] = "Num";
12  strcat(TitNum,title);
13  mNumerator = new StHbt1DHisto(TitNum,title,nbins,QinvLo,QinvHi);
14  // set up denominator
15  //title = "Den Qinv (MeV/c)";
16  char TitDen[100] = "Den";
17  strcat(TitDen,title);
18  mDenominator = new StHbt1DHisto(TitDen,title,nbins,QinvLo,QinvHi);
19  // set up ratio
20  //title = "Ratio Qinv (MeV/c)";
21  char TitRat[100] = "Rat";
22  strcat(TitRat,title);
23  mRatio = new StHbt1DHisto(TitRat,title,nbins,QinvLo,QinvHi);
24  // this next bit is unfortunately needed so that we can have many histos of same "title"
25  // it is neccessary if we typedef StHbt1DHisto to TH1d (which we do)
26  mNumerator->SetDirectory(0);
27  mDenominator->SetDirectory(0);
28  mRatio->SetDirectory(0);
29  // by default point to 0; only if its filled we will use it
30  mCorrection = 0;
31 
32  // Integrated over all events
33  // set up numerator
34  char TitIntNum[100] = "IntNum";
35  strcat(TitIntNum,title);
36  mIntNumerator = new StHbt1DHisto(TitIntNum,title,nbins,QinvLo,QinvHi);
37  // set up denominator
38  char TitIntDen[100] = "IntDen";
39  strcat(TitIntDen,title);
40  mIntDenominator = new StHbt1DHisto(TitIntDen,title,nbins,QinvLo,QinvHi);
41  // set up ratio
42  char TitIntRat[100] = "IntRat";
43  strcat(TitIntRat,title);
44  mIntRatio = new StHbt1DHisto(TitIntRat,title,nbins,QinvLo,QinvHi);
45 
46 
47  // radii histo
48  mThreeFitLambda = new StHbt1DHisto("ThreeFitLambda","ThreeFitLambda",100,0,2);
49  mThreeFitRadius = new StHbt1DHisto("ThreeFitRadius","ThreeFitRadius",100,0,50);
50  mTwoFitLambda = new StHbt1DHisto("TwoFitLambda","TwoFitLambda",100,0,2);
51  mTwoFitRadius = new StHbt1DHisto("TwoFitRadius","TwoFitRadius",100,0,50);
52  mRmsByHandMeV = new StHbt1DHisto("RmsByHandMeV","RmsByHandMeV",100,0.0,0.2);
53  mRmsByHandFm = new StHbt1DHisto("RmsByHandFm","RmsByHandFm",100,0,20);
54  mThreeFitLambda->SetDirectory(0);
55  mThreeFitRadius->SetDirectory(0);
56  mTwoFitLambda->SetDirectory(0);
57  mTwoFitRadius->SetDirectory(0);
58  mRmsByHandMeV->SetDirectory(0);
59  mRmsByHandFm->SetDirectory(0);
60 
61  // Set (1) or Unset (0) debug option
62  m_Debug_ebye = 1 ;
63 
64  // to enable error bar calculation...
65  mNumerator->Sumw2();
66  mDenominator->Sumw2();
67  mRatio->Sumw2();
68 
69  //mTagWriter = StHbtTagWriter::Instance();
70 }
71 
72 //____________________________
73 QinvEbyECorrFctn::~QinvEbyECorrFctn(){
74  delete mThreeFitLambda;
75  delete mThreeFitRadius;
76  delete mTwoFitLambda;
77  delete mTwoFitRadius;
78  delete mRmsByHandMeV;
79  delete mRmsByHandFm;
80  delete mNumerator;
81  delete mDenominator;
82  delete mRatio;
83  delete mIntNumerator;
84  delete mIntDenominator;
85  delete mIntRatio;
86  if (mCorrection) delete mCorrection;
87 }
88 //_________________________
89 void QinvEbyECorrFctn::Finish(){
90  // now produce the inclusive correlation function
91  mIntRatio->Divide(mIntNumerator,mIntDenominator,1.0,1.0) ;
92 
93  // fit it
94  threeFit fit3 = { 0,0,0,0,0,0,0,0 };
95  Three_param_fit( fit3 , mRatio);
96  cout << " Inclusive fit : " << fit3.radius << endl ;
97 }
98 
99 //____________________________
100 StHbtString QinvEbyECorrFctn::Report(){
101  string stemp = "Qinv Correlation Function Report:\n";
102  char ctemp[100];
103  sprintf(ctemp,"Number of entries in numerator:\t%E\n",mNumerator->GetEntries());
104  stemp += ctemp;
105  sprintf(ctemp,"Number of entries in denominator:\t%E\n",mDenominator->GetEntries());
106  stemp += ctemp;
107  sprintf(ctemp,"Number of entries in ratio:\t%E\n",mRatio->GetEntries());
108  stemp += ctemp;
109  // stemp += mCoulombWeight->Report();
110  StHbtString returnThis = stemp;
111  return returnThis;
112 }
113 //____________________________
114 void QinvEbyECorrFctn::AddRealPair(const StHbtPair* pair){
115  mNumerator->Fill( fabs(pair->qInv()) );
116 }
117 //____________________________
118 void QinvEbyECorrFctn::AddMixedPair(const StHbtPair* pair){
119  mDenominator->Fill( fabs(pair->qInv()) );
120 }
121 //_____________________________
122 void QinvEbyECorrFctn::SetCorrection(const StHbt1DHisto* correc){
123  mCorrection = (StHbt1DHisto*)correc;
124 }
125 //_____________________________
126 void QinvEbyECorrFctn::EventBegin(const StHbtEvent* myev)
127 {
128  //reset histos
129  mNumerator->Reset();
130  mDenominator->Reset();
131  mRatio->Reset();
132 }
133 //_____________________________
134 void QinvEbyECorrFctn::EventEnd(const StHbtEvent* myev)
135 {
136  // without ebye background we can't do anything
137  // except we have ebye background ...
138  if (mDenominator->GetEntries() == 0) return ;
139  if (m_Debug_ebye)
140  {
141  cout << "Start ebye." << endl ;
142  }
143 
144  // Create Correlation function !
145  mRatio->Divide(mNumerator,mDenominator,1.0,1.0) ;
146 
147  //Fill_ratio_artificial() ;
148 
149  // Normalize by integral
150  cout << "Scale ratio by (integral method) : " << Norm_by_integral(0.1,0.2) << endl ;
151  mRatio->Scale(Norm_by_integral(0.1,0.2)) ;
152 
153  // Perform Coulomb Correction if one is defined
154  if (mCorrection){
155  cout << "Going to Coulomb correct now..." << endl;
156  mRatio->Divide(mCorrection);
157  }
158  else {
159  cout << "NOT Coulomb correcting..." << endl;
160  }
161 
162  // Fill inclusive histos
163  mIntNumerator->Add(mNumerator);
164  mIntDenominator->Add(mDenominator);
165 
166 
167  // calculate rms by hand : only after normalization
168  double Width_MeV = 0 ;
169  double Width_fm = 0 ;
170  Rms_by_hand(Width_MeV, Width_fm) ;
171  mRmsByHandMeV->Fill(Width_MeV) ;
172  mRmsByHandFm->Fill(Width_fm) ;
173 
174  // calculate radius with 2 parameter fit : only after normalization
175  twoFit fit2 = { 0.,0.,0.,0., 0., 0. };
176  Two_param_fit( fit2 );
177  mTwoFitLambda->Fill( fit2.lambda);
178  mTwoFitRadius->Fill( fit2.radius);
179 
180  // calculate radius with 3 parameter fit
181  mRatio->Reset();
182  mRatio->Divide(mNumerator,mDenominator,1.0,1.0) ; // get back the not normalized correlation function
183  // Perform Coulomb Correction if one is defined
184  if (mCorrection){
185  cout << "Going to Coulomb correct now for the 3 Fit ..." << endl;
186  mRatio->Divide(mCorrection);
187  }
188  else {
189  cout << "NOT Coulomb correcting for the 3 Fit ..." << endl;
190  }
191  threeFit fit3 = { 0.2,0.0,0.5,0.0,10.,0., 0., 0. };
192  Three_param_fit( fit3 , mRatio);
193  mThreeFitLambda->Fill( (fit3.lambda*1/(fit3.constant+0.000001)) );
194  mThreeFitRadius->Fill( fit3.radius );
195 
196  // just for debugging
197  if (m_Debug_ebye)
198  {
199  // do coulomb again to see it after everything was run
200  if (mCorrection){
201  cout << "Going to Coulomb correct a second time just to see it ..." << endl;
202  mRatio->Divide(mCorrection);
203  }
204  else {
205  cout << "NOT Coulomb correcting..." << endl;
206  }
207  // some output
208  cout << endl << endl ;
209  cout << " twoFit: ";
210  cout << " lambda=" << fit2.lambda << " radius=" << fit2.radius << endl;
211  cout << " threeFit: ";
212  cout << " lambda=" << (fit3.lambda/(fit3.constant+0.000001)) << " radius=" << fit3.radius ;
213  cout <<" constant :" << fit3.constant << endl;
214  cout << " RmsByHand ";
215  cout << " Width MeV " << Width_MeV << " Width FM " << Width_fm << endl;
216  double norm3=0;
217  if (fit3.constant!=0) norm3 = 1/(fit3.constant) ;
218 
219  cout << " Norm by integ : " << Norm_by_integral(0.1,0.2) << endl;
220  cout << " Norm by line fit : " << Norm_by_fit(0.1,0.2) << endl;
221  cout << " Norm by 3d fit : " << norm3 << endl;
222 
223  cout << " Scaled by : " << Norm_by_integral(0.1,0.2) << endl;
224  cout << endl << endl ;
225  }
226 
227 
228  // fill tagdb
229  //cout << " QinvEbyECorrFctn::EventEnd() - fill tags now " << endl;
230  // domimik's 3 parameter fit
231  // mTagWriter->SetTag(mTagMeans,0, fit3.constant);
232  // mTagWriter->SetTag(mTagMeans,1, fit3.lambda);
233  // mTagWriter->SetTag(mTagMeans,2, fit3.radius);
234  // mTagWriter->SetTag(mTagMeans,3, fit3.chi2/fit3.ndf );
235  // mTagWriter->SetTag(mTagSigmas,0, fit3.constantErr );
236  // mTagWriter->SetTag(mTagSigmas,1, fit3.lambdaErr );
237  // mTagWriter->SetTag(mTagSigmas,2, fit3.radiusErr );
238  // mTagWriter->SetTag(mTagSigmas,3, fit3.chi2 );
239  // mTagWriter->SetTag(mTagSigmas,4, fit3.ndf );
240 
241 } ;
242 //_______________________________________
243 void QinvEbyECorrFctn::Three_param_fit( threeFit& fit , StHbt1DHisto* histo ) {
244  // Fit the unnormalized correlation function with A + B exp(-qinv^2 * C^2)
245  // Unfortunately we have to define the fit function here, if we do it
246  // somewhere else we can't set the sart values for the fit !
247  StHbtTF1* f3param = new StHbtTF1("f3param","[0]+[1]*exp(- (x**2) * ([2]**2) / (0.197327**2))",0.0,0.2) ;
248  f3param->SetParNames("Normfactor","Lambda","Rinv") ;
249  f3param->SetParameters(0.2,0.5,10) ; // Set start values for fitting
250  histo->Fit("f3param","R0") ; // Fit (option Q == quiet!)
251 
252  // fill results
253  fit.constant = histo->GetFunction("f3param")->GetParameter(0);
254  fit.lambda = histo->GetFunction("f3param")->GetParameter(1);
255  fit.radius = histo->GetFunction("f3param")->GetParameter(2);
256  fit.constantErr = histo->GetFunction("f3param")->GetParError(0);
257  fit.lambdaErr = histo->GetFunction("f3param")->GetParError(1);
258  fit.radiusErr = histo->GetFunction("f3param")->GetParError(2);
259  fit.chi2 = histo->GetFunction("f3param")->GetChisquare();
260  fit.ndf = histo->GetFunction("f3param")->GetNDF() ;
261 
262  // clean up
263  delete f3param ;
264 } ;
265 //_______________________________________
266 void QinvEbyECorrFctn::Two_param_fit(twoFit& fit) {
267  // Fit the normalized correlation function with 1 + A exp(-qinv^2 * B^2)
268  // Unfortunately we have to define the fit function here, if we do it
269  // somewhere else we can't set the sart values for the fit !
270  StHbtTF1* f2param = new StHbtTF1("f2param"," 1 + [0]*exp(- (x**2) * ([1]**2) / (0.197327**2))",0.0,0.2) ;
271  f2param->SetParNames("Lambda","Rinv") ;
272  f2param->SetParameters(0.5,10) ;// Set start values for fitting
273  mRatio->Fit("f2param","R0+") ;// Fit (option Q == quiet!)
274 
275  // fill results
276  fit.lambda = mRatio->GetFunction("f2param")->GetParameter(0);
277  fit.radius = mRatio->GetFunction("f2param")->GetParameter(1);
278  fit.lambdaErr = mRatio->GetFunction("f2param")->GetParError(0);
279  fit.radiusErr = mRatio->GetFunction("f2param")->GetParError(1);
280  fit.chi2 = mRatio->GetFunction("f2param")->GetChisquare();
281  fit.ndf = mRatio->GetFunction("f2param")->GetNDF() ;
282 
283  // clean up
284  delete f2param ;
285 } ;
286 //_______________________________________
287 void QinvEbyECorrFctn::Rms_by_hand(double& Width_MeV, double& Width_fm) {
288  // "calculate width of the bump" : no fitting of Minuit, ROOT or whatever needed
289  double sum =0 ;
290  double S_y =0 ;
291 
292  // loop over bins in histo with correlation function
293  for(int hist_index=1; hist_index <= (int) mRatio->GetNbinsX() ; hist_index++)
294  {
295  double x = (double) (mRatio->GetBinCenter(hist_index)) ;
296  double y = (double) (mRatio->GetBinContent(hist_index)) ;
297  sum = sum + x * x * ( y -1 ) ;
298  S_y = S_y + ( y -1 ) ;
299  }
300  //cout << "sum "<< sum << endl;
301  //cout << "S_y " << S_y << endl;
302 
303  Width_MeV = ::sqrt(fabs(sum/(S_y))) ;
304  Width_fm = 0.197327/Width_MeV ;
305 
306  cout << "Rough rms calculation : " << (double) Width_MeV << "\t";
307  cout << "Rough rms calculation : " << (double) Width_fm << endl ;
308 }
309 //_______________________________________
310 void QinvEbyECorrFctn::Fill_ratio_artificial()
311 {
312  // Fill ratio histo with an function
313  // r = 1 + exp( x^2 * R^2 )
314  mRatio->Reset() ;
315  double radius = 10 ;
316  for(int i = 1 ; i < mRatio->GetNbinsX() ; i++)
317  {
318  double x = (double) (mRatio->GetBinCenter(i));
319  double y = 1 + exp(-(x*x)*(radius*radius)/(0.2*0.2));
320  mRatio->Fill(x,y) ;
321  //cout << x << "\t";
322  //cout << y << endl ;
323  };
324 };
325 //_______________________________________
326 void QinvEbyECorrFctn::Fill_ratio_artificial_random()
327 {
328  // Fill ratio histo with an distribution
329  // r = 1 + lam * exp( x^2 * R^2 )
330  mRatio->Reset();
331  double lam = rand()/RAND_MAX; // lam = [0..1]
332  double R = 1 + 10 * rand()/RAND_MAX; // R = [1..11]
333  R =10 ; lam = 0.5 ;
334  for(int i = 1 ; i < mRatio->GetNbinsX() ; i++)
335  {
336  double x = (double) (mRatio->GetBinCenter(i));
337  double y = 1 + lam * exp(-(x*x)*(R*R)/(0.2*0.2));
338  mRatio->Fill(x,y) ;
339  //cout << x << "\t";
340  //cout << y << endl ;
341  } ;
342 } ;
343 //_______________________________________
344 double QinvEbyECorrFctn::Norm_by_integral(double min_GeV = 0.1,double max_GeV = 0.2 )
345 {
346  // Divide integral (0.1 - 0.2) over background by integral over signal
347  double norm = 0;
348  int minbin = mDenominator->GetXaxis()->FindFixBin(min_GeV);
349  int maxbin = mDenominator->GetXaxis()->FindFixBin(max_GeV);
350  double numinteg = mNumerator->Integral(minbin,maxbin) ;
351  double denominteg = mDenominator->Integral(minbin,maxbin) ;
352 
353  if ( numinteg != 0 )
354  {
355  norm = denominteg / numinteg ;
356  // cout << "Normalized via integral by " << norm << endl ;
357  }
358  else
359  {
360  cout << "Cannot normlize, because denominator equals 0." << endl ;
361  }
362  return norm ;
363 } ;
364 //_______________________________________
365 double QinvEbyECorrFctn::Norm_by_fit(double min_GeV = 0.1,double max_GeV = 0.2)
366 {
367  // Fit the flat part of the correlation function by a straight line
368  StHbtTF1* line = new StHbtTF1("line","[0]+[1] * x",min_GeV,max_GeV) ;
369  line->SetParameters(0.3,0.0) ; // set starting values
370  mRatio->Fit("line","QR0") ; // fit
371  if ( m_Debug_ebye )
372  {
373  //cout << "Normalized via fit. " << endl ;
374  cout << "Fit result line fit, norm : " << mRatio->GetFunction("line")->GetParameter(0) << " " << mRatio->GetFunction("line")->GetParameter(1) << endl ;
375  }
376 
377  double norm = 0 ;
378  double a = mRatio->GetFunction("line")->GetParameter(0) ;
379  double b = mRatio->GetFunction("line")->GetParameter(1) ;
380  double c = (max_GeV+min_GeV)/2 * b + a ; // get value at (max_GeV+min_GeV)/2
381  if ( c!= 0 )
382  {
383  norm = 1/c ;
384  }
385 
386  // clean up and go home
387  delete line ;
388  return norm ;
389 } ;