StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StGlauberHistogramMaker.cxx
1 /******************************************************************************
2  * $Id: StGlauberHistogramMaker.cxx,v 1.2 2012/04/25 05:03:06 hmasui Exp $
3  * $Log: StGlauberHistogramMaker.cxx,v $
4  * Revision 1.2 2012/04/25 05:03:06 hmasui
5  * Use StCentralityMaker. Added weight for 2D fill. Use STAR logger instead of iostream
6  *
7 ******************************************************************************/
8 
9 #include <assert.h>
10 #include <fstream>
11 
12 #include "TError.h"
13 #include "TGraphErrors.h"
14 #include "TH1.h"
15 #include "TH2.h"
16 #include "TProfile.h"
17 
18 #include "StMessMgr.h"
19 
20 //#include "StCentralityMaker/StNegativeBinomial.h"
21 #include "StCentralityMaker/StCentralityMaker.h"
22 #include "StCentralityMaker/StCentrality.h"
23 #include "StGlauberConstUtilities.h"
24 #include "StGlauberTree/StGlauberTree.h"
25 #include "StGlauberHistogramMaker.h"
26 
28 
29 using std::ofstream ;
30 using std::endl ;
31 using std::vector ;
32 
33  const TString StGlauberHistogramMaker::mXAxisName[] = { "b", "Npart", "mult", "cent" };
34  const TString StGlauberHistogramMaker::mXAxisTitle[] = { "impact parameter (fm)", "N_{part}", "multiplicity", "centrality (%)" };
35  const Int_t StGlauberHistogramMaker::mXAxisBin[] = {
36  400, // Impact parameter bin up to 20 fm, 0.2 fm increment
37  100, // Npart bin (5 Npart per bin)
38  100, // Multiplicity bin (20 multiplicity per bin)
39  StGlauberConstUtilities::GetCentralityBin() // Centrality bin
40  };
41 
43  const Double_t StGlauberHistogramMaker::mXAxisMax[] = {
44  20.0, // Maximum impact parameter
45  500, // Maximum Npart
46  2000, // Maximum multiplicity
47  StGlauberConstUtilities::GetCentralityBin() // Maximum centrality
48  };
49 
50 //____________________________________________________________________________________________________
51 // Default constructor
52 StGlauberHistogramMaker::StGlauberHistogramMaker()
53  : mName("hTest"), mTitle("Test"), mYTitle("Test"), mYbin(1), mYmin(0), mYmax(1), mIsUnitWeight(kTRUE)
54 {
55  Init();
56 }
57 
58 
59 //____________________________________________________________________________________________________
60 StGlauberHistogramMaker::StGlauberHistogramMaker(const TString name, const TString title, const TString ytitle,
61  const Int_t ybin, const Double_t ymin, const Double_t ymax, const Bool_t isUnitWeight)
62  : mName(name), mTitle(title), mYTitle(ytitle), mYbin(ybin), mYmin(ymin), mYmax(ymax), mIsUnitWeight(isUnitWeight)
63 {
64  Init();
65 }
66 
67 //____________________________________________________________________________________________________
68 // Default destructor
69 StGlauberHistogramMaker::~StGlauberHistogramMaker()
70 {
71  Reset() ;
72 }
73 
74 //____________________________________________________________________________________________________
75 void StGlauberHistogramMaker::SetTableDirectory(const TString directory)
76 {
77  mTableDirectory = directory ;
78  LOG_INFO << "StGlauberHistogramMaker::SetTableDirectory Set output directory for table : "
79  << mTableDirectory.Data() << endm;
80 }
81 
82 //____________________________________________________________________________________________________
84 {
85  mDebug = 0 ;
86 
88  Reset() ;
89 
91  for(UInt_t ix=0; ix<mNXaxis; ix++){
92  mXaxis.push_back( -9999.0 );
93  }
94 
96  for(UInt_t ix=0; ix<mNXaxis; ix++){
97  // 1D, g + "histogram name" (will be used later to store Profile/Weight)
98  // This is the output for final average quantities
99  TH1* h1D = (TH1D*) GetTH1D(mName, ix) ;
100  mHistogram1D.push_back( (TH1D*) h1D );
101 
102  // 2D
103  TH2* h2D = (TH2D*) GetTH2D(mName, ix) ;
104  mHistogram2D.push_back( (TH2D*) h2D );
105 
106  // Profile. Need to be corrected by weight histogram (hWeight)
107  TProfile* hProfile = (TProfile*) GetTProfile(mName, ix, "Profile");
108  mProfile.push_back( (TProfile*) hProfile );
109 
111  TProfile* hWeight = (TProfile*) GetTProfile(mName, ix, "Weight");
112  mWeight.push_back( (TProfile*) hWeight);
113  }
114 
116  for(vector<TProfile*>::iterator iter = mProfile.begin();
117  iter != mProfile.end(); iter++){
118  TProfile* h = (TProfile*) (*iter);
119  LOG_INFO << Form("StGlauberHistogramMaker::Init Initialize TProfile: %s (%s), x:(bin, min, max) = (%4d, %1.2f, %1.2f)",
120  h->GetName(), h->GetTitle(), h->GetNbinsX(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax())
121  << endm;
122  }
123 }
124 
125 //____________________________________________________________________________________________________
127 {
128  mHistogram1D.clear();
129  mHistogram2D.clear();
130  mProfile.clear();
131  mWeight.clear();
132  mXaxis.clear();
133 }
134 
135 //____________________________________________________________________________________________________
136 void StGlauberHistogramMaker::SetXaxis(const StGlauberTree& tree, const StCentralityMaker& centralityMaker, const TString type)
137 {
139  mXaxis[0] = tree.GetB() ; // impact parameter
140  mXaxis[1] = tree.GetNpart() ; // Npart
141 
142  // Get multiplicity from tree
143  mXaxis[2] = tree.GetMultiplicity() ; // Multiplicity
144 
146  UInt_t mode = 0 ; // default
147  if( type.CompareTo("smalltotal", TString::kIgnoreCase) == 0 ) mode = 1 ; // -5% total Xsection
148  else if( type.CompareTo("largetotal", TString::kIgnoreCase) == 0 ) mode = 2 ; // +5% total Xsection
149 
150  const StCentrality* centrality = centralityMaker.GetCentrality() ;
151 
152  if(mDebug){
153  LOG_INFO << Form("StGlauberHistogramMaker::SetXaxis mult=%6d, centrality: (default, -5%, +5%) = (%1.1f, %1.1f, %1.1f)",
154  static_cast<Int_t>(mXaxis[2]),
155  centrality->GetCentrality(mXaxis[2], 0),
156  centrality->GetCentrality(mXaxis[2], 1),
157  centrality->GetCentrality(mXaxis[2], 2)
158  ) << endm;
159  }
160 
161  mXaxis[3] = centrality->GetCentrality(mXaxis[2], mode) ; // Centrality
162 }
163 
164 //____________________________________________________________________________________________________
166 {
167  UInt_t isXaxisBad = 0 ;
168 
169  for(vector<Double_t>::const_iterator iter=mXaxis.begin(); iter != mXaxis.end(); iter++){
170  if( (*iter) == -9999. ) isXaxisBad++ ;
171  }
172 
173  return (isXaxisBad==0) ? kTRUE : kFALSE ;
174 }
175 
176 //____________________________________________________________________________________________________
177 void StGlauberHistogramMaker::Fill2D(vector<TH2*> collection, const Double_t y, const Double_t weight)
178 {
180  if( mXaxis.size() != collection.size() ){
181  Error("StGlauberHistogramMaker::Fill2D", Form("Array size is different: (x-axis, 2D) = (%3d, %3d)",
182  mXaxis.size(), collection.size()));
183  assert(0);
184  }
185 
186  for(UInt_t ix=0; ix<collection.size(); ix++){
187  TH2* h = (TH2D*) collection[ix] ;
188  const TString name(h->GetName());
189 
190  // Centrality bin is inclusive
191  if( name.Contains("cent") ){
192  const Double_t centrality = mXaxis[ix] ;
193 
194  // Loop over all centrality bins
195  for(Int_t icent=0; icent<h->GetNbinsX(); icent++){
196  // Fill histogram if current centrality is included
197  if(StGlauberConstUtilities::IsCentralityOk(icent, centrality)){
198  h->Fill(icent+0.5, y, weight);
199  }
200  }
201  }
202  else{
203  // Others (except for centrality) fill as it is
204  h->Fill(mXaxis[ix], y, weight);
205  }
206  }
207 }
208 
209 //____________________________________________________________________________________________________
210 void StGlauberHistogramMaker::FillProfile(vector<TProfile*> collection, const Double_t y)
211 {
213  if( mXaxis.size() != collection.size() ){
214  Error("StGlauberHistogramMaker::FillProfile", Form("Array size is different: (x-axis, Weight) = (%3d, %3d)",
215  mXaxis.size(), collection.size()));
216  assert(0);
217  }
218 
219  for(UInt_t ix=0; ix<collection.size(); ix++){
220  TProfile* h = (TProfile*) collection[ix] ;
221  const TString name(h->GetName());
222 
223  // Centrality bin is inclusive
224  if( name.Contains("cent") ){
225  const Double_t centrality = mXaxis[ix] ;
226 
227  // Loop over all centrality bins
228  for(Int_t icent=0; icent<h->GetNbinsX(); icent++){
229  // Fill histogram if current centrality is included
230  if(StGlauberConstUtilities::IsCentralityOk(icent, centrality)){
231  h->Fill(icent, y) ;
232  }
233  }
234  }
235  else{
236  // Others (except for centrality) fill as it is
237  h->Fill(mXaxis[ix], y);
238  }
239  }
240 }
241 
242 
243 //____________________________________________________________________________________________________
244 void StGlauberHistogramMaker::Fill(const TString type, const Double_t y, const Double_t weight)
245 {
248  //
253 
254  if( type.CompareTo("2d", TString::kIgnoreCase) == 0 ){
255  Fill2D(mHistogram2D, y, weight) ;
256  }
257  else if ( type.CompareTo("profile", TString::kIgnoreCase) == 0 ){
258  FillProfile(mProfile, y*weight) ;
259  }
260  else if ( type.CompareTo("weight", TString::kIgnoreCase) == 0 ){
261  FillProfile(mWeight, weight) ;
262  }
263  else{
264  Error("StGlauberHistogramMaker::Fill", "Unknown option, option=%s", type.Data());
265  assert(0);
266  }
267 
268 }
269 
270 //____________________________________________________________________________________________________
271 void StGlauberHistogramMaker::Fill(const Double_t y, const Double_t weight)
272 {
275 
277  if(!IsXaxisOk()){
278  Error("StGlauberHistogramMaker::Fill", "x-axis has not defined yet for %s", mName.Data());
279  assert(0);
280  }
281 
283  Fill("2d", y, 1.0) ; // No weight. Don't use this histogram for final result. Just for drawing.
284  Fill("profile", y, weight);
285  Fill("weight", y, weight) ;
286 }
287 
288 //____________________________________________________________________________________________________
289 void StGlauberHistogramMaker::DoWeightCorrection(vector<TH1*> collection1d, vector<TProfile*> collectionp)
290 {
293  LOG_INFO << Form("StGlauberHistogramMaker::DoWeightCorrection %s: particle-wise weight correction, profile/weight",
294  mName.Data()) << endm;
295 
296  for(UInt_t ix=0; ix<collectionp.size(); ix++){
297  TH1* h1 = collection1d[ix] ;
298 
300  TH1* p1 = (TH1D*) collectionp[ix]->ProjectionX();
301  TH1* w1 = (TH1D*) mWeight[ix]->ProjectionX();
302  p1->Divide(w1);
303 
304  p1->SetXTitle(h1->GetXaxis()->GetTitle());
305  p1->SetYTitle(h1->GetXaxis()->GetTitle());
306 
308  p1->SetMinimum(mYmin);
309  p1->SetMaximum(mYmax);
310 
312  for(Int_t i=0; i<p1->GetNbinsX(); i++){
313  collection1d[ix]->SetBinContent(i+1, p1->GetBinContent(i+1));
314  collection1d[ix]->SetBinError(i+1, p1->GetBinError(i+1));
315  }
316  collection1d[ix]->SetEntries(p1->GetEntries());
317  collection1d[ix]->Print() ;
318  delete p1 ;
319  delete w1 ;
320  }
321 }
322 
323 //____________________________________________________________________________________________________
324 void StGlauberHistogramMaker::WriteTable(vector<TH1*> collection, const TString name)
325 {
328  const TString tableName(Form("%s/table_%s_vs_centrality.txt",
329  mTableDirectory.Data(), name.Data()));
330  ofstream fout(tableName.Data());
331  LOG_INFO << "StGlauberHistogramMaker::WriteTable Write table " << tableName.Data() << endm;
332 
333  const UInt_t centId = 3 ; // 4-th histogram has centrality in x-axis
334  for(UInt_t ic=0; ic<StGlauberConstUtilities::GetCentralityBin(); ic++){
335  const Double_t val = collection[centId]->GetBinContent(ic+1);
336  const Double_t error = collection[centId]->GetBinError(ic+1);
337 
338  const Double_t centmin = StGlauberConstUtilities::GetCentralityMin(ic) ;
339  const Double_t centmax = StGlauberConstUtilities::GetCentralityMax(ic) ;
340  fout << Form("%10d %1.1f %1.1f %1.5f %1.5f",
341  ic, centmin, centmax, val, error) << endl;
342  }
343  fout << endl << endl ;
344  fout << "# <centrality bin> <minimum centrality> <maximum centrality> <value> <stat. error>" << endl;
345  fout << Form("# %s", mTitle.Data()) << endl; // description (type, node name in tree)
346 }
347 
348 //____________________________________________________________________________________________________
349 void StGlauberHistogramMaker::WriteGraphs(vector<TH1*> collection)
350 {
352  const UInt_t centId = 3; // 4-th histogram has centrality in x-axis
353 
354  TGraphErrors* graph = new TGraphErrors() ;
355 
356  TString name(collection[centId]->GetName()); // should be g + getHistogramName()
357  name.Replace(0, 1, "graph");
358  graph->SetName(name);
359  graph->SetTitle(collection[centId]->GetTitle());
360 
361  LOG_INFO << Form("StGlauberHistogramMaker::WriteGraphs Write graph %s (vs centrality)", graph->GetName()) << endm;
362 
363  // Fill up to 80 %
364  const UInt_t ncentrality = 9 ;
365  for(UInt_t ic=0; ic<ncentrality; ic++){
366  const Double_t centmin = StGlauberConstUtilities::GetCentralityMin(ic) ;
367  const Double_t centmax = StGlauberConstUtilities::GetCentralityMax(ic) ;
368 
369  const Double_t cent = ( centmin + centmax)/2.0 ;
370  const Double_t val = collection[centId]->GetBinContent(ic+1) ;
371  const Double_t err = collection[centId]->GetBinError(ic+1) ;
372  graph->SetPoint(ic, cent, val);
373  graph->SetPointError(ic, 0.0, err);
374  }
375 
376  graph->Write() ;
377 
378 }
379 
380 
381 //____________________________________________________________________________________________________
382 void StGlauberHistogramMaker::Finish(const TString type)
383 {
384  LOG_INFO << "StGlauberHistogramMaker::Finish ";
385  LOG_INFO << Form("Finish %s. Correction weight for TProfile, ", mName.Data());
386  LOG_INFO << "and store it into 1D. Write averate qunatity vs centrality" << endm;
387 
389  DoWeightCorrection(mHistogram1D, mProfile) ;
390 
392  const TString name(type + "_" + mName);
393  WriteTable(mHistogram1D, name) ;
394 
396  WriteGraphs(mHistogram1D) ;
397 }
398 
399 //____________________________________________________________________________________________________
400 const TString StGlauberHistogramMaker::GetHistogramName(const TString name, const UInt_t ix) const
401 {
402  return Form("%s_%s", name.Data(), mXAxisName[ix].Data());
403 }
404 
405 //____________________________________________________________________________________________________
406 TH1* StGlauberHistogramMaker::GetTH1D(const TString name, const UInt_t ix)
407 {
408  TH1* h = new TH1D("g" + GetHistogramName(name, ix),
409  Form("%s vs %s, %s", mYTitle.Data(), mXAxisTitle[ix].Data(), mTitle.Data()), mXAxisBin[ix], 0.0, mXAxisMax[ix]);
410  h->SetXTitle(mXAxisTitle[ix].Data());
411  h->SetYTitle(mYTitle.Data());
412 
413  return h ;
414 }
415 
416 //____________________________________________________________________________________________________
417 TH2* StGlauberHistogramMaker::GetTH2D(const TString name, const UInt_t ix)
418 {
419  TH2* h = new TH2D("h" + GetHistogramName(name, ix),
420  Form("%s vs %s, %s (2D)", mYTitle.Data(), mXAxisTitle[ix].Data(), mTitle.Data()),
421  mXAxisBin[ix], 0.0, mXAxisMax[ix], mYbin, mYmin, mYmax);
422  h->SetXTitle(mXAxisTitle[ix].Data());
423  h->SetYTitle(mYTitle.Data());
424 
425  return h ;
426 }
427 
428 //____________________________________________________________________________________________________
429 TProfile* StGlauberHistogramMaker::GetTProfile(const TString name, const UInt_t ix, const TString title)
430 {
431  const TString prefix = (title.CompareTo("profile", TString::kIgnoreCase)==0) ? "p" : "w" ;
432  TProfile* h = new TProfile(prefix + GetHistogramName(name, ix),
433  Form("%s vs %s, %s (%s)", mYTitle.Data(), mXAxisTitle[ix].Data(), mTitle.Data(), title.Data()), mXAxisBin[ix], 0.0, mXAxisMax[ix]);
434  h->SetXTitle(mXAxisTitle[ix].Data());
435  h->SetYTitle(mYTitle.Data());
436 
437  return h ;
438 }
439 
440 //____________________________________________________________________________________________________
441 const TString StGlauberHistogramMaker::GetName() const
442 {
443  return mName ;
444 }
445 
446 //____________________________________________________________________________________________________
448 {
449  mDebug = 1 ;
450  LOG_INFO << "StGlauberHistogramMaker::DebugOn Print debug messages" << endm;
451 }
452 
Definition: FJcore.h:367
void FillProfile(std::vector< TProfile * > collection, const Double_t y)
void WriteTable(std::vector< TH1 * > collection, const TString name)
Write text table, average quantity vs centrality (table: table_{mName}_vs_centrality.txt)
void SetTableDirectory(const TString directory)
Default destructor.
void SetXaxis(const StGlauberTree &tree, const StCentralityMaker &centralityMaker, const TString type)
Initialize histograms.
void DoWeightCorrection(std::vector< TH1 * > collection1d, std::vector< TProfile * > collectionp)
Calculate sum(w*val)/sum(w) for each profile histogram.
virtual void Reset()
Debug flag.
virtual void Fill(const Double_t y, const Double_t weight)
Set X-axis variable.
void DebugOn()
Get histogram name.
void Fill2D(std::vector< TH2 * > collection, const Double_t y, const Double_t weight)
Check xAxis has been filled, abort if empty.
virtual void Finish(const TString type)
Fill histogram &#39;y&#39; value with &#39;weight&#39;.
Bool_t IsXaxisOk() const
Reset all data members.
Double_t GetCentrality(const UInt_t multiplicity, const UInt_t mode=0) const
Print help messages.
void WriteGraphs(std::vector< TH1 * > collection)
Write TGraphErrors (vs centrality, 0-80%)